Determine the current output format from templates, partials, and shortcodes

I’d really benefit from being able to reach any kind of higher-order context from a shortcode. In particular, I have a shortcode that should render nothing if the current output format is RSS/Atom but even if I set such a format on the .Scratch there’s no way to read the scratch from the shortcode.

Example:

In layouts/_default/baseof.html:

<!DOCTYPE html>
{{- .Scratch.Set "output-format" "html" }}

In layouts/list.atom.xml:

<?xml version="1.0" encoding="utf-8"?>
{{- .Scratch.Set "output-format" "atom" }}

Then in various templates, partials, and shortcodes I’d like to be able to branch based on the value of “output-format” in the scratch, like:

{{ if eq ($.Scratch.Get "output-format") "html" }}
  …
{{ end }}

So far I’ve failed to figure out how to do this from shortcodes, where the scratch is always unset

If you want to reach the page context from within a shortcode, you need to use the .Page method.

For example, to retrieve the page title from within a shortcode:

{{ .Page.Title }}

The $ gets you to the root context of the current template, not the page.

Thanks, that helps! I’m now able to access the scratch from shortcodes.

Unfortunately, now I’ve hit the next snag I’ve hit every time I’ve tried to use the scratch: the value for the scratch seems to be wrong.

In my Atom feed, where (at the top), the Scratch "output-format" is set to "atom", pages that contain something like this:

{{< foo.inline >}}{{ .Page.Scratch.Get "output-format" }}{{< /foo.inline >}}

Will print "html" and not "atom" in my /index.xml file. This doesn’t make sense to me, since the "html" is only set on the scratch in layouts/_default/baseof.html, which isn’t the template being rendered. I ran into this same problem in a totally different context trying to branch templating behavior based on Scratch behaviors and it made me feel like compilation of partial templates is being memoized or something.

Wait a second…

Are you trying to set a page level scratch, using the same identifier, to two different values for the same page?

What I’m trying to accomplish is if-else branches in templates and shortcodes based on whether an HTML file is being rendered or my RSS feed. Because there’s (AFAICT), no built-in variable or method to report the currently-rendered output format, I’m trying to set it in the scratch.

To try to achieve this, I am setting a .Scratch.Set "output-format" "atom" from the top of my Atom feed list.atom.xml file and setting .Scratch.Set "output-format" "html" from the top of my layouts/_default/baseof.html file. Goal being to be able to branch inside templates/partials/shortcodes based on output format (e.g. {{- if eq (.Page.Scratch.Get "output-format") "html" -}} )

Sorry, still trying to get the bigger picture. Are you including .Content in your RSS feed?

Yep! Something like this for each entry:

<content type="html">{{ "<![CDATA[" | safeHTML }}
  {{ .Content | safeHTML }}
{{ "]]>" | safeHTML}}</content>

So, the only thing that will affect .Content is the content of the markdown files, and any shortcodes that they may call. Is that also correct?

Yes, if I understand you right. It’s why I’m trying to set some kind of higher order variable like a scratch so that the .Content will render differently based on whether the overall file being rendered is an HTML file or my Atom/XML feed

The current main reason why this is is that we reuse, especially, rendered content, across output formats if possible. If you had 2 output formats (HTML + RSS), 10K markdown files and 10 languages that would need to render 200K markdown files if we couldn’t reuse anything.

You’ll need to do this:

layouts/shortcodes/
├── foo.html
└── foo.rss

And in markdown:

{{< foo >}}
1 Like

I suspected this would be it. Thanks for clarifying!

Thanks, that’ll work! In my case leaving transcript.html as-is and an empty transcript.atom.xml is working as you’d hope and the right layout is calling the right one.

Thanks!

Also, in your rss template I would do:

{{ $content := trim .Content "\r\n"}}
<content type="html">
  {{ printf "<![CDATA[%q]]>" $content  | safeHTML }}
</content>

It’s a bit easier to read, and will strip leading and trailing newlines regardless of OS EOL format.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.