# Get post attributes in Franklin

**URL:** <https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430>\
**Category:** Web Stack\
**Tags:** question, website, franklin\
**Created:** [September 20, 2021, 4:03am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430 "2021-09-20T04:03:29Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [September 20, 2021, 4:03am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/1 "2021-09-20T04:03:29Z")

</div>

I’m in the process of migrating from Jekyll to Franklin for my static website ([Garrek.org](https://garrek.org)) hosted on GitHub. (In the near future, I will have LaTeX and plots and things, which Franklin seems to excel at). Jekyll has some nice features for retrieving site attributes and I’m trying to do something similar with Franklin. For example, my landing page is simply a list of all of my blog posts:

**Jekyll snippet**

```julia
{% for post in site.posts %}
<article>
	<h2>
		<a href="{{ post.url}}">{{ post.title }}</a>
	</h2>
	<p>{{ post.date | date_to_string }}</p>
	{{ post.content }}
</article>
{% endfor %}

```

I can almost replicate this by modifying `hfun_recentblogposts()` in `utils.jl` on [the Julia website](https://github.com/JuliaLang/www.julialang.org/blob/main/utils.jl). But I can’t grab the post contents. I wrote a function that writes out the following:

**Julia snippet within a function in `utils.jl`**

```julia
write(io, """
              <article>
                <h2><a href="$url">$title</a>
                </h2>
                <p>
                  $sdate
                  <a class="permalink" title="Permalink" href="$url">
                  ⚓︎
                  ︎</a>
                </p>
                {{include $surl}}
              </article>
            """)

```

but I don’t know how to use `include` to get the post contents. (`$surl` gives the path of a post) I’m sure it’s not difficult, but I can’t find instructions in the [Franklin.jl documentation](https://franklinjl.org/syntax/page-variables/).

1. How do I get the contents of a blog post in my example?
2. Is writing a Julia function like this in `utils.jl` the best way to go about implementing this sort of thing, or would it be better to put code in an html layout or something?

I understand that Franklin will work differently than Jekyll, and perhaps what I’m trying to do is not the best way to go about it; I’m struggling with how Franklin wants me to structure certain things.

> **My version of the "recent posts" function, which works except for grabbing the body of a post:**
>
> ```julia
> function hfun_recentposts()
> curyear = Dates.Year(Dates.today()).value
> ntofind = 2
> nfound = 0
> recent = Vector{Pair{String,Date}}(undef, ntofind)
> for year in curyear:-1:2020
> for month in 12:-1:1
> ms = "0"^(1-div(month, 10)) * "$month"
> base = joinpath("posts", "$year", "$ms")
> isdir(base) || continue
> posts = filter!(p -> endswith(p, ".md"), readdir(base))
> days = zeros(Int, length(posts))
> surls = Vector{String}(undef, length(posts))
> for (i, post) in enumerate(posts)
> ps = splitext(post)[1]
> surl = "posts/$year/$ms/$ps"
> surls[i] = surl
> pubdate = pagevar(surl, :published)
> days[i] = isnothing(pubdate) ?
> 1 : day(Date(pubdate, dateformat"d u Y"))
> end
> # go over month post in antichronological orders
> sp = sortperm(days, rev=true)
> for (i, surl) in enumerate(surls[sp])
> recent[nfound + 1] = (surl => Date(year, month, days[sp[i]]))
> nfound += 1
> nfound == ntofind && break
> end
> nfound == ntofind && break
> end
> nfound == ntofind && break
> end
> #
> io = IOBuffer()
> for (surl, date) in recent
> url = "/$surl/"
> title = pagevar(surl, :title)
> title === nothing && (title = "Untitled")
> sdate = "$(day(date)) $(monthname(date)) $(year(date))"
> write(io, """
> <article>
> <h2><a href="$url">$title</a>
> </h2>
> <p>
> $sdate
> <a class="permalink" title="Permalink" href="$url">
> ⚓︎
> ︎</a>
> </p>
> {{include $surl.html}}
> </article>
> """)
> end
> return String(take!(io))
> end
> 
> ```

Edit: clarified my question.

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [September 22, 2021, 7:45am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/2 "2021-09-22T07:45:06Z")

</div>

Hello! sorry I hadn’t seen your question, good that you also asked on Slack 🙂

> [@garrek](#):
>
> But I can’t grab the post contents.

If you want the generated HTML corresponding to the full post you can use the `fd_page_html` local variable (I acknowledge that this is not documented, it’s a trick used for the RSS generation where there’s a possibility to show the full page content).

> [@garrek](#):
>
> Is writing a Julia function like this in `utils.jl` the best way to go about implementing this sort of thing, or would it be better to put code in an html layout or something?

Yes generally when you want things a bit custom, it’s better to write a function for it so that you fully control the generated HTML (this is not unlike the Jekyll snippet you showed). You can play with the layout only if you want that generated HTML to be included in some specific HTML.

To give an example: each page will basically be `head * content * foot` (where `head` and `foot` are in your layout) but for some page you might want to use a different `head` or `foot`, you can do this by using `{{ispage ...}}` or `{{isnotpage ...}}` in the layout files. So in your case this is relevant if you would want the outer container of the list of blog posts to look something specific that’s different from the rest of your website.

I hope all this makes sense!

PS: side note, if you want custom “summary” of posts to show, then for this you should define your own local page variable a bit like the RSS description (in fact you can even re-use that variable), so you would do something like

```markdown
+++
author = "Garrek"
short = "A short description of the post"
# or you could do (if you're also generating rss etc that could be handy)
rss_descr = "A short description of the post"
+++

# My post

the text of the awesome post

```

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [September 22, 2021, 9:12am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/3 "2021-09-22T09:12:55Z")

</div>

Thank you for the response! That makes sense, but I still can’t quite get there. I’m able to use the `head * content * foot` and `{{ispage ...}}`, etc. to use different layouts.

I tried a couple of things following your suggestions:

1. I tried using `{{for post in posts/*}}` to iterate through each post, but I get the error `The iterable 'posts/*' is not recognised`. Using `{{ispage posts/*}}` elsewhere works as expected. (The file structure is `posts/year/month/post.md`). Also, my posts correctly display on a separate page where I just list the url of each post with a script in `utils.jl`.

2. Inside a function in `utils.jl`, I created the variable `content = pager(surl, :fd_page_html)` and inserted that into `write(io, """...""")`, but nothing is written (other than the other variables I have defined, which are `title = pagevar(surl, :title)`, the date, and a link). No error message either, the page just displays a list of titles with dates and permalinks.

3. I was able to make a summary of posts as you describe. Defining `short = pagevar(surl, :short)` works correctly when I define `short` on each post. Curiously, `rss_descr` renders the text, “nothing”. I’m guessing this is because I have set up the RSS settings incorrectly somewhere.

I think in the first case, my syntax is incorrect. But I’m not sure what’s going on in the second case. Do you have any insight?

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [September 22, 2021, 9:31am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/4 "2021-09-22T09:31:09Z")

</div>

> [@garrek](#):
>
> I tried using `{{for post in posts/*}}`

ah sorry I should have clarified, this is not allowed, the `{{for...}}` is very rudimentary and only unpacks iterables that are Franklin variables so for instance if you’ve defined `x = [1, 2, 3]` somewhere then `{{for xi in x}}{{fill xi}}{{end}}` will show `1 2 3` but you can’t loop over pages, here you should put the whole logic inside a `hfun` which I thought is what you were doing with the `recent_posts` function.

For 2-3 I think it’ll be easier if you point me to a repo where you have things and I’ll have a look, sorry for the inconvenience!

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [September 22, 2021, 10:01am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/5 "2021-09-22T10:01:54Z")

</div>

> [@](#):
>
> ah sorry I should have clarified, this is not allowed, the `{{for...}}` is very rudimentary and only unpacks iterables that are Franklin variables

Got it. Yes, `recent_posts` is in a `hfun`, but I also have just a couple of things in the HTML files.

That’s very generous of you to look at the repo! It’s [here](https://github.com/garrekstemo/garrek.org-Franklin) (if needed, the Jekyll version is [here](https://github.com/garrekstemo/garrekstemo.github.io)). I call `recent_posts` in `index.md` and I modify HTML layouts in `head.html`. No rush, since it seems like you’re busy trying to get version 1.0 out the door.

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [September 22, 2021, 12:14pm UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/6 "2021-09-22T12:14:04Z")

</div>

What you have is fine, there was a (fairly sneaky) bug in Franklin when querying this specific page variable `fd_page_html` via `pagevar`. Long story short when it’s `pagevar` that is doing the query for `fd_page_html`, that variable wasn’t filled properly.

There’s a [patch release (0.10.57)](https://github.com/tlienart/Franklin.jl/commit/5a2840e0c7ab317a9614f386d26600c9b0ad2356) with the fix, should be in within the next 10 mins. Thanks for your patience and glad that led to a bug fix 🙂

PS:

> [@garrek](#):
>
> you’re busy trying to get version 1.0 out the door.

haha yes, there’s a `0.11` planned first which is a very significant refactoring of Franklin and I’ll need a fair bit of help stress testing that version before making it the effective `1.0`, all this will take me a while though and `0.10.*` is expected to be kind of like a “LTS” for some time so I’m always glad to fix bugs for that version! (who knows maybe we’ll hit `0.10.100` 😂)

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [September 24, 2021, 4:21am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/7 "2021-09-24T04:21:30Z")

</div>

I see, that makes sense. I downloaded the patch and tried it out, but the page content is still not displayed. I fiddled around and couldn’t get it to work as expected. Any ideas?

Also, I merged my Franklin-generated repo into [my main website repo](https://github.com/garrekstemo/garrekstemo.github.io) and deleted the Jekyll code. It works correctly except for `fd_page_html` to grab the page HTML.

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [September 24, 2021, 7:40am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/8 "2021-09-24T07:40:34Z")

</div>

I’ll check it out and try to see what’s going on 🙂

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [September 24, 2021, 9:07am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/9 "2021-09-24T09:07:50Z")

</div>

@garrek isn’t that what you were expecting:

 ![Screenshot 2021-09-24 at 11.06.39](https://global.discourse-cdn.com/julialang/original/3X/2/7/27c7a12a8047f83ea8d767f1bfc1e554d23f693e.png)

this is with the latest patch, maybe run `serve(clear=true)` to start from scratch and check that you get the same output?

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [September 25, 2021, 2:38am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/10 "2021-09-25T02:38:09Z")

</div>

Yes, that is what I was expecting. I tried running with `serve(clear=true)`, but it still did not work. I did a test that worked:

I generating a completely new site with `newsite(".")` in a new directory (with the most recent patch). (I used `serve()` a few times at each step of the process to check). I created a directory called `posts` and made two dummy posts. I then copied just the `recentposts` function from my website into the new site’s `utils.jl` without modification. Then I deleted the content of `index.md` and replaced it with just `{{recentposts}}` and `+++title = "blog"+++`. After using `serve()` here, only the title and date of each post was displayed – no content. Then I used `serve(clear=true)` and it worked as expected. Subsequent calls also worked.

Perhaps there is something different about the template Franklin site from my site? But then why did it work on your end?

I’ll keep looking into it.

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [September 25, 2021, 3:17am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/11 "2021-09-25T03:17:15Z")

</div>

Ok. I got it to work, although I’m not sure what was wrong in the first place. I generated a new site from the default Franklin template and carefully replaced the template code with my code, checking with each change. Now it compiles correctly, but _sometimes_ it doesn’t fill the post content. Usually this is when there’s a layout change. Running `serve()` again fixes it, though.

---

<div class="post-metadata">

**Author:** ![tlienart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlienart/32/7640_2.png) [@tlienart](https://discourse.julialang.org/u/tlienart)\
**Post date:** [September 25, 2021, 8:02am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/12 "2021-09-25T08:02:10Z")

</div>

Glad it’s working, re the _sometimes_; is this with the server running and after trying to manually refresh the page? There shouldn’t be anything different happening when a layout file is updated though changing layout elements triggers a “full pass” which takes a bit longer than just updating a single page, in some circumstances that can mean that the browser doesn’t get refreshed at the right time but if you hit refresh things will show fine.

If you can reproduce this with a sequence that leads to the content not showing, please ping me from an issue in your repo and I’ll have a look.

Good luck with your new website 🙂

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [September 27, 2021, 1:49am UTC](https://discourse.julialang.org/t/get-post-attributes-in-franklin/68430/13 "2021-09-27T01:49:33Z")

</div>

Ok, I’ll take a closer look at this behavior and, if I can find something reproducible, ping you.

Thanks for all your help!
