Custom Front Matter

I still post my long articles to my hosted blog. I just don’t automatically include them in the timeline. I write custom short notes instead. For example, this long blog post was promoted on the timeline by this short post.

Alright, alright, I got all excited but now I’m stuck. How/where do I tell to display the summary?

I changed the index.json template so that the “content_html” is the summary, not the full content.

But that doesn’t show in the timeline, it still just shows the title and link.

My “Edit Sources” is pulling from feed.json

Can you point me at what template or part of this template I need to change in order to have the summary and the link show up in the timeline?

You might have stumbled upon a race condition. When making a change to a template, it sometimes takes a while before rebuilds your site.

It could be that when added your test post to the timeline, the JSON feed was still the old version (with the full post). Try removing the latest post from the timeline (just from the timeline, not the actual post), and then try refetching the feed by navigating to the feeds page (linked above) and hitting the :arrows_counterclockwise: button.

Also, it’s worth noting that the changes you make to the feed only affect future posts. Posts that are already on the timeline will remain the same (unless you explicitly remove them to be re-added, but then you probably lose their comments).

Oh, sorry! You should remove the title from the feed as well. :blush: That’s what’s triggering to just link to the post. More about timeline display rules.

Hmmm. Removing the title does show the summary, but no link back to the post.

Ah. So I’ve removed the title, and made “content_html” be the summary - however, this summary is not 300 characters, so it’s just being displayed as-is without a link. But if I make a summary that is longer than 300 characters, it’ll just be truncated, too.

This just isn’t very feasible, I don’t think. Not for my use case, anyway.

So I’ll just go back to my feature request: the ability to specify how long posts are displayed, whether with the title+link or the title+summary+link (or even just summary+link, while we’re at it).

Oooh, weirdly, the timeline posts did change retroactively! I just deleted my custom index.json template, and now they appear like this

You could add a link to the post in your feed template. But you’re right about the 300-character limit. If the summary + link text are longer than 300 characters, will truncate. Unless you make it a quote, then you get 600 characters, but that’s kind of a hack. :blush:

And even if you get your feature request realized, I would be very surprised if @manton would allow arbitrary long summaries. They would probably still be truncated if they were longer than 300 characters.

I don’t need them to be longer than 300 characters, so that’s fine by me!

Well, then you’re almost there with your custom feed template; add the post’s title and link to content_html. And as long as you make sure that the title, link text, and summary are less than 300 characters total (or 600 with the quote hack), you will get what you want.

Cool about the updated timeline! That’s more than I knew about.

@sod Would the link characters also count in the 300-character limit if done this way? If it is hyperlinked to “Read More,” then that’s fewer characters, no?

Ok, I know next to nothing about json formatting, but I’m assuming I need some sort escaping or somesuch for the html elements here. Can you help with that?

"content_html": <a href="{{ .Permalink }}">{{ .Title }}</a> {{ $s }},

($s is the summary)

My impression is that you know quite a lot. :blush: This should do it:

"content_html": "<a href=\"{{ .Permalink }}\">{{ .Title }}</a> {{ $s }}",

Yes, the link text would count against the 300 characters.

Oh. my. goodness. I have been at this for hours, but I think I’ve finally got it.

Your code didn’t work - it kept sticking in weird extra quote marks and <p> elements and was just generally being disagreeable.

I kept digging through docs, figuring I might need to build the whole string before sticking it in the “content_html” line.

String concatenation in Hugo, is, uh, pretty arcane, as best as I can see. So this is the final result. It lives in the index.json template, and for truncated posts (those with a <!--more--> tag), it shows the summary/excerpt and then a link to read more. For other posts, it follows the standard rules.

{{- if .Truncated -}}
  {{- $tt := .Title -}}
  {{- $sm := .Summary -}}
  {{- $lk := .Permalink -}}
  {{- $lkb := " Read more: <a href='" -}}
  {{- $lke := "' >" -}}
  {{- $lkc := "</a> " -}}
  {{- $tp := printf "%s" $lkc | printf "%s%s" $tt | printf "%s%s" $lke | printf "%s%s" $lk | printf "%s%s" $lkb | printf "%s%s" $sm | printf "%s" -}}
  {{- $tp := $tp | jsonify -}}
  {{- $tp := replace $tp "\\u003c" "<" -}}
  {{- $tp := replace $tp "\\u003e" ">" -}}
  {{- $tp := replace $tp "\\u0026" "&" }}
  "content_html": {{ $tp }},
{{- else -}}
  {{- $tp := .Content -}}
  {{- $tp := $tp | jsonify -}}
  {{- $tp := replace $tp "\\u003c" "<" -}}
  {{- $tp := replace $tp "\\u003e" ">" -}}
  {{- $tp := replace $tp "\\u0026" "&" }}
  "content_html": {{ $tp }},
{{- end -}}

I’m sure there’s a more elegant way to do this, but outside of the crazy printf incantation, it’s at least fairly clear what it’s doing.

1 Like

Awesome work! Sorry about my code snippet; I should have tested it before posting. :sweat_smile: And, yep, Hugo certainly has its quirks. In my world, there’s no right or wrong way to express the templates. If it works, it works.

That said, here’s an alternative take that should be functionally equal to your template. And actually tested this time around. :blush: Instead of the if/else statement, this snippet uses Hugo’s cond. That first line says, “If .Truncated is true, evaluate this printf stuff and put the result into $s. If not, just put .Content into $s.”

{{- $s := cond .Truncated (printf "%s Read more: <a href=\"%s\">%s</a>" .Summary  .Permalink .Title) .Content -}}
{{- $s := $s | jsonify -}}
{{- $s := replace $s "\\u003c" "<" -}}
{{- $s := replace $s "\\u003e" ">" -}}
{{- $s := replace $s "\\u0026" "&" }}
"content_html": {{ $s }},

@laura May I steal this and test on my blog?

Have at it! :sunglasses:

I’ve had to change the code I posted earlier for displaying the post without the summary in the article.html template. Try this:

<div class="post-content">
{{ if in .Content "--excerpt--" }}
	{{ $body := replace .Content .Summary "" }}
	{{ $body | safeHTML }}
{{ else }}
	{{ .Content }}
{{ end }}

And when you write the summary, you should end it with <!--excerpt--><!--more-->.

This seems to be working - that is, it shows just the body without the summary if you’ve included the <!--excerpt--> tag, and if it’s a longer post without the <!--excerpt--> tag, it shows the whole post.

I’m using @sod’s code above in the index.json file, and so far, it seems to be working. Just remember to remove the {{ .Title }} part of the index.json file as well as the replacing the {{ .Content }} part with the code.

Good luck!

1 Like

Thanks so much for this - much cleaner, and I’ve learned a new way to do conditionals in Hugo. Win win!

1 Like

Just wanted to add one comment here on excerpts… For some reason Hugo strips out the <!--more--> tag when the post gets back into the XML / JSON Feed. It doesn’t strip other HTML comments. This matters because we use the feed to populate the timeline, so without the text cut marker, doesn’t know this post has an excerpt.

There are work-arounds, of course. We can pull up the original Markdown for the post and use that to determine the excerpt.

This comes up enough that I would like to solve it. Personally, I don’t think the timeline should be full of summaries, but automatic truncates aren’t good either.

Thanks y’all.

1 Like