File generated by extension is deleted during build

I created an extension, which generates files within the build directory - actually within a subdir of build, but I assume that does not make a difference.

The files are generated by helper functions, but later during the build - or maybe some after build hooks, the files are deleted again. If I run the build with the --no-clean option, everything is fine.

Do I somehow have to add the files to a list so middleman knows that they are part of the build?

Unless someone gives a more competent answer – maybe take a look at how https://github.com/Aupajo/middleman-search_engine_sitemap works? It generates a sitemap.xml file into the build directory.

Thank you for the hint! Unfortunately, there is not a lot of documentation in this extension. It’s hard to find something, when you actually don’t know, what you’re looking for. Maybe, I just missed the obvious?

My impression is that Middleman uses its sitemap to decide what ‘should’ be in the final build folder. Anything that’s not explicitly represented in the sitemap will be deleted during the build process.

This makes a kind of sense, because it ensures that you don’t get stale files lying around: if you delete something from the source folder and do a build, you want the corresponding file to be removed from the build directory. However, it does mean that Middleman will cheerfully blow away anything that is built by a non-Middleman process.

There are exceptions to this. The new ‘external pipeline’ feature invokes other tools to place content in the ‘build’ folder. Middleman can’t know what files are created by these, but when the build is done, those files are present in the build folder. However, I think that may be because the external pipeline runs after Middleman has already done all its work; on the next cycle, Middleman will delete those files and the external pipeline will recreate them (I think that’s how it works).

I’ve always wanted the ability to put an entry in config.rb that says “File X should be present; don’t delete it.” As far as I know, that doesn’t exist.

My guess is that what you need to do is to somehow add items to the sitemap, so that Middleman knows that they’re supposed to be present. This may involve manipulating the Sitemap object directly from Ruby code. It’s possible, however, that there may be a way to do it in a config file. The rather terse page on The Sitemap may be helpful here. Or it may not.

Sorry I can offer only vague speculation instead of concrete information, but perhaps this will help a little.

Thank you! Sounds like a reasonable explanation. I will look into that and see, if I can solve my problem then.

I did try to add an entry to the sitemap from the extension. This did not prevent middleman from deleting the file though. Maybe, I used some wrong parameter?

As an alternative, I am using the external pipeline now. In principle it’s working but I don’t really like the solution. Since the external files are generated by helpers in an extension, there is no external program to be called for the pipeline. I had to define a dummy entry like

activate :external_pipeline
    name: :mytask,
    command: "ls",
    source: "destination folder for generated files 
            (becomes source for external pipeline)",
    latency: 1

I’m just calling some dummy command to have the command field not empty. Furthermore, I don’t really like that I have to define this separately in config.rb, so the extension requires to actually activate two extensions (itself and the external pipeline) and it requires this to be configured correctly. I’d rather do this as part of the extension initialization, so it’s more robust. Does anybody know how to do that? Any more elegant solutions? I just can’t envision that this is how it’s intended (despite it’s actually working).

I had a look into the middleman-search_engine_sitemap extension (just for curiosity and contemplation if I should do my stuff same way) and you can try to mimick its behaviour. Take a look there, hermanndetz.

As I said above, I did look into middleman-search_engine_sitemap_extension. I can create resources from my extension, temporarily store them in an array and have them added to the sitemap via the manipulate_resource_list callback. The problem is that the callback is being processed way to early. My extension creates the resources through the public helper methods, which seem to be called during the rendering process of the individual pages. manipulate_resource_list on the other hand, i called before the rendering process is started. Therefore, there are no resources added to the global sitemap by my extension.

To re-phrase the problem: At the time, the extension is initialized and manipulate_resource_list is called, the extension is not yet aware of the files, which are created later by the helper methods.

Is there a way to add to the resources list at a later point?

Any more directed help towards a possible solution would be appreciated.