weblorg icon indicating copy to clipboard operation
weblorg copied to clipboard

Question: How to explicitly set all posts in a route or site?

Open markokocic opened this issue 4 years ago • 6 comments

I want to have a list of all posts/pages matching some filter and have it available inside a route or site. Lets say I have a rout to render all posts:

(weblorg-route
 ;; route for rendering each post
 :site blog
 :name "posts"
 :input-pattern "posts/*.org"
 :template "post.html"
 :output "output/posts/{{ slug }}.html"
 :url "/posts/{{ slug }}.html")

I want to add two more variable to the each page, so that I can list links to pages in sidebar, and display 4 recent posts title in footer. For that I would like to have something like:

(weblorg-route
 ;; route for rendering each post
 :site blog
 :name "posts"
 :input-pattern "posts/*.org"
 :template "post.html"
 :output "output/posts/{{ slug }}.html"
 :url "/posts/{{ slug }}.html"
 :template-vars '(("all_posts" (some-function "posts/*.org"))
                  ("all_pages" (some-function "pages/*.org")))

or directly in weblorg-site, in order to avoid duplication for each route.

(weblorg-site
 :template-vars '(("all_posts" (some-function "posts/*.org"))
                  ("all_pages" (some-function "pages/*.org")))
)

Is something like this already possible in weblorg?

markokocic avatar Apr 12 '21 12:04 markokocic

oh hi @markokocic you might be interested in trying out the experimental (and undocumented 😢) weblorg_route_posts.

Here's an example: https://github.com/emacs-love/weblorg/blob/main/themes/autodoc/templates/doc.html#L18-L26

It can take arbitrary route names and it will return all the posts of that route! Let me know if that works for you!

and sorry for taking so long to answer things! I'm catching up 😄

clarete avatar Apr 21 '21 00:04 clarete

Works like charm. Thanks 😊

markokocic avatar Apr 22 '21 11:04 markokocic

Nice! I'll keep this open as a documentation issue then! Thank you for trying it out, @markokocic 🙇🏾

clarete avatar Apr 25 '21 15:04 clarete

Hi @clarete

Actually, after some testing I noticed that weblorg_route_posts doesn't really work.

I have the following snippet in my sidebar template which is included from the base template:

        <section>
          <h3>Recent Posts</h3>
          <ul>
            {% for recent in weblorg_route_posts("archive")|take(4) %}
            <li><a href="{{ url_for("posts", slug=recent.slug) }}">{{ recent.title }}</a></li>
            {% endfor %}
          </ul>
        </section>

I also have the following routes defined in publish.el:

(weblorg-route
 ;; route for rendering each post
 :site blog
 :name "posts"
 :input-pattern "posts/*.org"
 :template "post.html"
 :output "output/posts/{{ slug }}.html"
 :url "/posts/{{ slug }}.html")

(weblorg-route
 ;; route for rendering archive page
 :site blog
 :name "archive"
 :input-pattern "posts/*.org"
 :input-aggregate #'weblorg-input-aggregate-all-desc
 :template "archive.html"
 :output "output/archive.html"
 :url "/archive.html")

If I use weblorg_route_posts("posts") in the template, I get unordered list of all posts, but when I use weblorg_route_posts("archive") I get undefined in output.

Could be something to do with how the posts are aggregated, since the structure returned by weblorg_route_posts when using :input-aggregate option in route definition is different.

markokocic avatar May 03 '21 16:05 markokocic

oh, thank you for the feedback on this @markokocic. I think you might be right about the relationship with how aggregation works. That's still a bit too entangled to just the Org-Mode parsing. I want to make it more generic so we can address this sort of use case you presented. Thank you for the good repro of the issue, I'll take a stab at fixing it!

clarete avatar May 26 '21 01:05 clarete

In the end I was able to list recent posts by using the following template.

        <section>
          <h3>Recent Posts</h3>
          <ul>
            {% for recent in weblorg_route_posts("archive") | attr("posts") | take(4) %}
            <li><a href="{{ url_for("posts", slug=recent.slug) }}">{{ recent.title }}</a></li>
            {% endfor %}
          </ul>
        </section>

It works, but the solution looks wrong.

markokocic avatar Jun 02 '21 11:06 markokocic