-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accessing global aggregate data in PostProcess phase #216
Comments
I just figured out that the archive example in the statiq.web repo shows how to do this. |
Glad you got it worked out (especially since I was disconnected for the US Thanksgiving holiday 😄)! Let me know if anything jumped out as needing better documentation or more details in the docs. |
Actually, in the end the statiq.web stuff didn't work out the way I hoped, but I was able to do what I wanted to do via a BeforeEngineExecution event handler. The metadata for my posts is in sidecar JSON files, so I was able to build an event handler that looped thru the sidecar files, parsed them as json, extract the category and tag data, generate the HTML from the aggregated data and add that to engine settings for later retrieval during razor template rendering. It's not the most performant solution - it requires parsing the sidecar files twice - but I like this approach better than treating the rendered, shared HTML as an IDocument. As far as I can tell, in Statiq the only places to put this kind of data are Settings (which need to be generated in full before execution starts) or Documents (which are obviously generated during execution). However, neither is a good fit in this specific case. I want to generate the shared HTML from a pipeline, but use it as a setting. I'm new to statiq (but very impressed!) so maybe I'm missing something. I'm OK with the solution I ended up on, but being able to have pipeline specific settings come from previous pipeline executions - similar to how pipelines can pull documents from dependency pipelines - would be a good add to the library. |
I think you're bumping up against the entire reason process and post-process were created as separate phases, and if I'm understanding correctly, it may already do what you're looking for. The idea between having those two phases, and why Razor is rendered during post-process, is because there's definitely a cart-before-the-horse element to this. Consider a simple case of blog posts and tags. Let's say you want to render a tag cloud on every blog post page. Or maybe you want to list other posts with the same tag as the current one on each post page. In both cases we need to have fully "processed" the posts before rendering the post page so that we know the full set of posts for each tag in order to do our rendering. If we did everything in one pass, I'd get to a post before visiting other posts and I wouldn't have the full picture. So I think that's sort of related to what you're trying to do here. You have some data that comes from your files (in this case from sidecar files that are getting processed automatically and included as metadata in your documents) and you want to access that aggregate data from Razor templates (during the post-process phase). The trick to understanding all this is the way the phases allow access to other data - the post-processing phase can access all documents from any pipeline as output from those piplines process phases. And because metadata (including sidecar files) are parsed during the process phase, Razor should have access to all the aggregate data already. Maybe what's missing is a good example of how to get at it. When inside a Razor page, you can call Is this along the lines of what you were looking for? Or have I totally misunderstood 😆. In any case, happy you were able to figure something out anyway - I love it when folks find features like the event handlers and use them in creative ways! |
You've got the basic tag cloud scenario down, I guess it's not clear to me the best way to make the aggregate data available in a way the render razor module can get to it. The way I've done it, the aggregate data is available via settings, so I can call I know how to produce the aggregate data in a pipeline, but I don't understand how to "publish" it so downstream pipelines and modules can access it. I have an 'Inputs'" pipeline that reads all the files + handles sidecar processing and I have a So I guess I don't understand how to publish and then access the aggregate info during the |
I think I need to take a deeper look at https://github.com/dotnet-foundation/website. They seem to be doing what I need |
The dotnet foundation blog is an example of what I'm trying to do. The "archives" section on the right hand side of the page is implemented as an HTML partial. Does that partial get implemented on every page execution? Or is the value cached? |
This is a great question! By default it's re-rendered (but not recompiled) on every page. It's worth noting that the Razor engine has two main "phases": compiling and rendering. The compilation page creates an in-memory assembly (which Statiq actually saves to disk for caching from run-to-run) that includes a class for each page, layout, partial, etc. which literally consists of your Razor code (I.e. In the case of partials, the compilation is only performed once and cached for each path on disk to a partial file. However, the rendering is performed each time the partial is used inside some other page. That can be really expensive if the partial does computationally heavy work. For that reason, I recently introduced |
That is exactly what I need. Thanks! |
Cool, let me know if you run into any problems. It's a new feature and not documented yet, so if you need to refer to the code it's here: Statiq.Framework/src/extensions/Statiq.Razor/IHtmlHelperExtensions.cs Lines 293 to 432 in 0c192e4
|
worked exactly as expected first time I tried it |
Awesome! |
My post metadata include categories and tags. I can aggregate the category and tag data from IExecutionContext easily enough, but I don't understand where to put that aggregate category and tag data so that it can be accessed while rendering razor templates during the PostProcess phase. Obviously, I could loop thru all the post IDocument instances and add the aggregated data as metadata, but that doesn't seem very elegant. I'm just learning Statiq, so I am wondering if there's a better way for handling such scenarios
The text was updated successfully, but these errors were encountered: