-
Notifications
You must be signed in to change notification settings - Fork 38
Some rendering ideas #109
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
Some rendering ideas #109
Conversation
- separated markdown rendering from custom function rendering
- split rendering into phases
- generating data, a map of `{"page" {:render-data ... :entry ...}}`
- rendering to file
- metadata modification
- remove `:groupby` option from `collection` task
- add new `assortment` task, which replaces `:groupby` and adds more flexibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few quick thoughts, may take a more thorough look later.
src/io/perun.clj
Outdated
| "Generate Atom feed" | ||
| [f filename FILENAME str "generated Atom feed filename" | ||
| _ filterer FILTER code "predicate to use for selecting entries (default: `:content`)" | ||
| _ filterer FILTER code "predicate to use for selecting entries (default: `:body`)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this change to :body as default filterer wouldn't all files show up in feeds/sitemap etc? Like we probably don't want index.html to show up in an atom feed for example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically yes, but I don't think this is a change in behavior. Previously by default, all files touched by render and collection would have a :content key. For render, it's because :content was the default filterer, and for collection, :content was explicitly set in the task (https://github.com/hashobject/perun/blob/master/src/io/perun.clj#L498). You didn't mention how your example index.html was generated, but I assume it was either via render or collection? I think in order to exclude index.html from an atom feed, a custom filterer would have needed to be supplied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- All files the
renderandcollectiontasks rendered had to have a:contentkey. - That key was set by the
markdowntask usually but could have been set by other tasks in theory. - I think setting
:contentto the rendered HTML inside thecollectiontask (as in the line you linked) does not make much sense but I might be missing something. - Now with
:bodybeing the default filterer tasks after therenderandcollectiontasks would see all the files rendered by those tasks. Previously they only respected files that had the:contentkey — in this case indicating they are original units of content. (With the exception of files rendered by the collection task. Not sure why:contentis being set there.)
It seems that the :content key was added to the files generated by the collection task here: 69a7149. I think overloading the meaning of the :content key like this can end up being very confusing so I'm thinking that maybe we should reconsider this one @podviaznikov (perhaps use :body or something similar as @bhagany does in this PR)
In this regard it may also make sense to start using namespaced keywords like io.perun/markdown or whatever to indicate what can be expected to be the value of these keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hrm, replying by email didn't put my comments in the right place. My apologies, they should have gone here.
| (-> fileset | ||
| (perun/merge-meta new-metadata) | ||
| (commit tmp)))))) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be nice to add docstrings to those fns if we end up merging them :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, will do
src/io/perun.clj
Outdated
| "Generate Atom feed" | ||
| [f filename FILENAME str "generated Atom feed filename" | ||
| _ filterer FILTER code "predicate to use for selecting entries (default: `:content`)" | ||
| _ filterer FILTER code "predicate to use for selecting entries (default: `:body`)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fwiw, my interpretation was that :content was added to the metadata in collection so that collection pages would be present in sitemaps by default. I agree that something more fine-grained would be desirable. Seems like that should be a separate pull request though?
On Nov 18, 2016, 8:06 AM -0600, Martin Klepsch [email protected], wrote:
In src/io/perun.clj (#109 (comment)):
:out-dir "public"}) > > (deftask atom-feed > "Generate Atom feed" > [f filename FILENAME str "generated Atom feed filename" > - _ filterer FILTER code "predicate to use for selecting entries (default:
:content)" > + _ filterer FILTER code "predicate to use for selecting entries (default::body)"
All files the render and collection tasks rendered had to have a :content key.
That key was set by the markdown task usually but could have been set by other tasks in theory.
I think setting :content to the rendered HTML inside the collection task (as in the line you linked (https://github.com/hashobject/perun/blob/master/src/io/perun.clj#L498)) does not make much sense but I might be missing something.
Now with :body being the default filterer tasks after the render and collection tasks would see all the files rendered by those tasks. Previously they only respected files that had the :content key — in this case indicating they are original units of content. (With the exception of files rendered by the collection task. Not sure why :content is being set there.)It seems that the :content key was added to the files generated by the collection task here: 69a7149 (69a7149). I think overloading the meaning of the :content key like this can end up being very confusing so I'm thinking that maybe we should reconsider this one @podviaznikov (https://github.com/podviaznikov) (perhaps use :body or something similar as @bhagany (https://github.com/bhagany) does in this PR)
In this regard it may also make sense to start using namespaced keywords like io.perun/markdown or whatever to indicate what can be expected to be the value of these keys.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub (https://github.com/hashobject/perun/pull/109/files/fc71654711af0c716d5374eb045a3bdedaa7fef3#r88661956), or mute the thread (https://github.com/notifications/unsubscribe-auth/AAbIcpUif3NwAKNjYfWDo21DckWthHktks5q_bDvgaJpZM4K2Mwt).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I just realized I could resolve the immediate tension by using :content as the default filterer for tasks like rss-feed and atom-feed, and :body for sitemap. I'll make that change when I'm back at my computer.
On Nov 18, 2016, 8:06 AM -0600, Martin Klepsch [email protected], wrote:
In src/io/perun.clj (#109 (comment)):
:out-dir "public"}) > > (deftask atom-feed > "Generate Atom feed" > [f filename FILENAME str "generated Atom feed filename" > - _ filterer FILTER code "predicate to use for selecting entries (default:
:content)" > + _ filterer FILTER code "predicate to use for selecting entries (default::body)"
All files the render and collection tasks rendered had to have a :content key.
That key was set by the markdown task usually but could have been set by other tasks in theory.
I think setting :content to the rendered HTML inside the collection task (as in the line you linked (https://github.com/hashobject/perun/blob/master/src/io/perun.clj#L498)) does not make much sense but I might be missing something.
Now with :body being the default filterer tasks after the render and collection tasks would see all the files rendered by those tasks. Previously they only respected files that had the :content key — in this case indicating they are original units of content. (With the exception of files rendered by the collection task. Not sure why :content is being set there.)It seems that the :content key was added to the files generated by the collection task here: 69a7149 (69a7149). I think overloading the meaning of the :content key like this can end up being very confusing so I'm thinking that maybe we should reconsider this one @podviaznikov (https://github.com/podviaznikov) (perhaps use :body or something similar as @bhagany (https://github.com/bhagany) does in this PR)
In this regard it may also make sense to start using namespaced keywords like io.perun/markdown or whatever to indicate what can be expected to be the value of these keys.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub (https://github.com/hashobject/perun/pull/109/files/fc71654711af0c716d5374eb045a3bdedaa7fef3#r88661956), or mute the thread (https://github.com/notifications/unsubscribe-auth/AAbIcpUif3NwAKNjYfWDo21DckWthHktks5q_bDvgaJpZM4K2Mwt).
…, so that collections and assortments aren't included in feeds by default
|
I forgot to mention above - I've also added docstrings and changed the default filterer for |
…ctions Since collections are entries in their own right, their metadata should be accessible to render functions. This commit also allows custom metadata to be set for assortments.
|
While playing around with the assortment functionality, I had a desire for collection-specific metadata to be available in my render functions. It turned out to be a small addition, so I decided to submit it for consideration here. I also added the ability to specify collection-level metadata in custom |
|
Overall I liked this a lot. |
|
Great, I'm glad you liked it! I'm definitely open to ideas on the names. My reason for differentiating between As for naming, I'll explain how I came up with the names, to get the conversation started.
Happy to make changes if anyone has suggestions, please let me know. |
|
|
I would argue that collection and assortment shouldn't populate :content with a completely rendered page. Instead, it should only do the rendering that is unique to the collection. After all, a collection of posts should still have the same headers and sidebars as the rest of the site. |
|
Also, if we want to filter the rss feeds, then it is better done by adding a new key to the metadata. Something like :include-rss or :skip-rss. This way the code communicates it's intent better. |
The only downside that comes to mind is the one you mentioned - the overhead of having a new task that does a closely-related thing. To me, it is clearer to draw a distinction between a task that creates one page, and a task that creates many. However, we could roll the functionality of both tasks into one, and still call the combined task
I'm a little confused here -
For this, we'd need a more convenient way to add metadata keys to collections/assortments. But I think you're right. |
|
First, I am not sure I like the separate keys for markdown and render. If nothing else, because it prevents multiple independent render steps from being pipelined. In my mind, the
Essentially. From my perspective, there isn't a lot of difference between the output of a collection task and a markdown task. When I build a website, there is usually a lot of front matter that I want shared between all my pages. Render is what puts that on. This way any shared content can be in the top level renderer, and I don't have to call it from within my collection task or renderer. (I think that, currently, if you put the collection task before the render task, that is what would happen.) As for how to add metadata keys to collections/assortments, might I suggest an option that adds a metadata key to every file output from the task. That way you could say if something should be in the rss feed by saying: (collection :renderer 'my.pkg/collection-renderer :page "index.html" :meta {:skip-feed true})Also, I certainly think that assortment has it's uses. For instance, right now, I have a situation where I have a bunch of collections of images that need index pages generated. One for each set of pictures. It sounds like an assortment task might prevent me from having to write that from scratch. |
Okay, I've let this one percolate for a while, and I think I can get on board with it. It definitely makes arbitrary pipelining easier, and I like the run-everything-through-render part. It also resolves any lingering doubts about the I think I still like the
I like this too. I'm not sure when I'll get back around to this, but hopefully soon. In the meantime, please weigh in - I always like having buy-in before the coding :) |
|
I guess the part about the |
|
As for content, I sort of like it, especially when it is setup to make adding new parsers / selecting parsers easy, though I might call it |
|
really, when it comes to |
|
Brought this branch up to date with @Deraen's render pod improvements. |
|
I've had some time to think more about this, and I've come to the conclusion that this pull request will grow to gargantuan proportions if I let it. So I'm going to take a step back and concentrate on some smaller, standalone pieces as separate PR's, while still aiming at the overall goal of making an arbitrary rendering pipeline possible. I'm also going to let #113 sit for a while, because decisions here will affect decisions there, and possibly make #113 obsolete altogether. Stay tuned. |
This is a subset of the changes in hashobject#109 that seemed to get the most positive response. It's almost purely a refactor intended to make rendering more pluggable. The only new feature is the addition of tracing to (aka `:io.perun/trace` metadata) `render` and `collection`.
|
I've split the ideas here into several different PR's and future PR's, and I'm pretty happy with that direction, so I'm closing this PR in favor of the others. |
Executive summary:
{"page" {:render-data ... :entry ...}}:groupbyoption fromcollectiontaskassortmenttask, which replaces:groupbyand adds more flexibilityFor those not following along on Slack, this PR was motivated by wanting some rendering functionality that wasn't available out of the box. The use case is: suppose you have a blog with multiple tags per article, and you want to generate a collection for each tag without knowing what the tags are ahead of time. The
:groupbyfunctionality incollectionisn't sufficient, because it can only group each article into a single collection. You could write your own task, but this is rather involved, because perun doesn't expose its rendering machinery to client code. So, an enhancement to perun itself seemed appropriate.This is by no means a final product, and it's quite likely that I've made changes here that have knock-on effects that I haven't taken into account, so please feel free to be critical.
The first thing I wanted to do was make
renderandcollectionmore like each other, so I abstracted their common operations into therender-pre-wrapfunction. As a part of this, I also made a distinction between rendering markdown, and rendering via a custom function a larenderorcollection. The former still results in a:contentmetadata key, while the latter now produces a:bodykey. This was necessary in order to have a common abstraction betweenrenderandcollection, but it also "feels" better to me. Now,:contentalways contains an intermediate form, while:bodyalways contains the final product, instead of both kinds of data being mixed into:content.Once that was accomplished, I added a new level to perun's content taxonomy, which was previously two things: articles and collections. I called the new level "assortments". Here's how I think about it:
Instead of passing a
group-bypredicate, as you would tocollection,assortmenttakes a user-defined:grouperfunction that can implement any sort of grouping you might want. To achieve the familiar:groupbybehavior, you can pass#(group-by your-predicate %)as thegrouperargument.I removed the
:groupbyoption fromcollectionso that there would be a clear separation between collections and assortments, but it could easily be added to my implementation if backwards compatibility is a concern. Aside from this and the addition ofassortment, the API should be the same.Please let me know what you think.