Jekyll: Liquid filter "cgi_escape" returns error for some variables - jekyll

The short version: have you managed to use something like {{ page.title | cgi_escape }} in an {% include %}-ed partial?
Details follow:
I have a partial that I use like so:
{% include mainContainer.html %}
Works fine. Then, in that partial, try to display some liquid variables:
{{ page.title }} displays the title.
{{ page.content }} Displays the content.
{{ page.content | cgi_escape }} displays the content, but escaped.
{{ page.title | cgi_escape }} doesn't work at all. Creates the following error:
Liquid Exception: undefined method `encoding' for nil:NilClass
Aside from {{ page.content }} I get the error for any of the {{ page }} variables (category, title, etc) but all of them will display fine without the filter. Also, {{ page.title | cgi_escape }} works okay in the...uhhh...'content' part of the layout (I'm not sure what to call it--the {{ content }} section). I only seem to get the error with {% include %}

Nevermind. The build was failing because a few of the pages using {% include mainContainer.html %} didn't have any front matter and thus no page.title (or whatever). Apparently, Liquid is willing to let {{ page.title }} pass if the variable isn't set, but not {{ page.title | cgi_encode }}

Related

Trying to use a front matter element in a liquid {% for %} loop

I have the following front matter in an html file:
---
layout: default
title: Fausto Bellino Tasca | Montecito
permalink: "/montecito.html"
imageSet: "montecito"
---
In the body of the html, I have the following:
{% for image-info in galleries.{{ imageSet }} %}
<li class="splide__slide">
<img src="/images/{{ imageSet }}/{{ image-info.filename }}" alt="{{ image-info.caption }}">
<div class="main-slider-caption">
{{ image-info.caption }}
</div>
</li>
{% endfor %}
The {{ imageSet }} within the img tag works fine, but when I attempt to use it in the for loop, eleventy throws an error with the following:
`TemplateContentRenderError` was thrown
> Having trouble compiling template ./src/montecito.html
`TemplateContentCompileError` was thrown
> illegal tag: {% for image-info in galleries.{{ imageSet }} %}, file:./src/montecito.html, line:11
`ParseError` was thrown
> illegal tag: {% for image-info in galleries.{{ imageSet }} %}
`AssertionError` was thrown:
AssertionError: illegal tag: {% for image-info in galleries.{{ imageSet }} %}
There is additional error info, noting the liquid js files that threw the error.
When I simply replace the {{ imageSet }} with the text itself, i.e., 'montecito' in this case, it works fine.
Any thoughts would be welcome as I've got a lot of pages that will look like this and I'd like to make a shortcode out of this look and pass in the front matter item.
Thanks.
I found the answer. The correct syntax in this context is galleries[imageSet] instead of galleries.{{ imageSet }}.

Why does this jekyll template not work?

Short Version:
Why does the following code not produce an output when navbox.next_article is the string '2018-01-05-man-command'?!
{% capture np %} {{ site.posts | where:"post","navbox.next_article contains post.title" }} {% endcapture %}
The next post is {{ np.title }}
Details
My post 2018-01-05-man-command.md has a YAML front matter:
---
layout : post
title : 'Man Command'
tags : [RHCSA, RHCSA_mod, Using Essential Tools, Man Command]
categories: [RHCSA]
navbox:
# prev_article:
next_article: 2018-01-05-understanding-globbing-and-wildcards
---
This is accessed by the _includes/post.html file through:
{% unless include.excerpt %}
{{ post.content }}
{% include navbox.html navbox=page.navbox %}
{% endunless %}
This is used by the _layout/post.html which sets the layout for the post:
{% include post.html post=page link_title=false %}
My navbox.html contains:
{% assign navbox = include.navbox %}
{% capture np %} {{ site.posts | where:"post","navbox.next_article contains post.title" }} {% endcapture %}
The next post is {{ np.title }}
However, all I get when I run bundle exec jekyll serve is:
The next post is
Why does that line not work? I'm new to jekyll so it's possible I've made a blunder somewhere that's intuitive to most. Please tell me what I can fix.
I believe that the capture tag only captures strings, not posts. See here for more info.
I'm not convinced that a where filter supports the contains syntax you're using. See here for more info.
On top of that, where returns an array. You have to get the first item from that array.
You need to fix these issues. Use an assign instead of a capture to store a post. And change your where filter to not use the contains syntax, which isn't valid. (Unless it's been added since the issue I just linked.)
Here is how I've done it:
{% assign post = site.posts | where:"url", targetUrl | first %}

In Jekyll, how do I render custom metadata for a collection?

I have the following in my _config.yml file:
collections:
nr_qa:
output: true
permalink: /:collection/:name
title: 'Node-RED Questions and Answers'
descriptions: 'Node-RED is a flow-based (visual) programming tool. These pages have some information that may be currently missing from the documentaiton.'
github_pages:
title: 'GitHub Pages and Jekyll/Liquid'
description: 'Hints and tips on using Jekyll for publishing to GitHub Pages.'
output: true
permalink: /:collection/:name
and I want to create an automatic index for my collections. So I use code like this:
## {{ site.collections.github_pages.title }}
{{ site.collections.github_pages.description }}
<ul>
{% for item in site.github_pages %}
<li>
{{ item.title | replace:'_',' ' }}
<p>{% if item.description %}
{{ item.description }}
{% else %}
{{ item.excerpt | strip_html }}
{% endif %}</p>
</li>
{% endfor %}
</ul>
And yes, I know I've rather mixed up my markdown and html there. Not relevant to this question.
The problem is that {{ site.collections.github_pages.title }} and {{ site.collections.github_pages.description }} don't render anything even though I think they should.
Can anyone point out my mistake please?
The problem is that title and description should be included in each collection, and not in _config.yml.
Check out Accessing Collection AttributesPermalink for further details.
update
title can be present in each collection metadata in _config.yml. The problem is how you are accessing those variables.
One approach is to have a specific layout for each collection, then you can access them like:
{% assign col = site.collections | where: 'label','github_pages' | first%}.
TITLE: {{ col.title }}.
DESCRIPTION: {{ col.description }}.

Liquid shorthands?

Are there any liquid shorthands? For example I'm trying to express this in a more concise way:
{% if job.offsite %}}
{{job.offsite}}
{{% else %}}
{{ job.url }}
{% endif %}
For this particular example, you could write:
{{ job.offsite | default: job.url }}
The value provided to the default filter will be used if the left side of the expression is false or nil.

Is there a way to loop through the front matter of a jekyll collection?

I have a Jekyll collection which is not being output, but elements of which are being displayed on a single page, like this:
{% for element in site.collection %}
{{ element.content }}
{% endfor %}
I would like to be able to do something like this:
{% for element in site.collection %}
{{ element.content }}
{% for front_matter in element %}
<!-- do stuff -->
{% endfor %}
{% endfor %}
This is possible with YAML hashes in YAML _data files, but doesn't work here because, it seems {{ element }} on its own is identical to {{ element.content }}. There doesn't seem to be any variable designated for this either like, {{ element.front_matter }}. Is it possible to loop through the front matter of an element in a jekyll collection?
I know that the ideal way to do this would be to include all the front_matter I want to loop through in a variable, like:
---
front_matter:
foo: bar
bar: foo
---
But, as I'm trying to configure these pairings (foo and bar) to be easily updatable through prose.io, they can't be nested under other values. If there is a
way around this with prose though, I would accept that answer.
Much appreciated!
It is possible to loop through the variables of an element in a Jekyll collection:
{% for items in site.my_collection %}
{% for item in items %}
{{ item }}: {{ items[item] }}
{% endfor %}
{% endfor %}
But it is important to remember that there is other metadata that is also available and will be included in the iteration, like path, url, etc and your front matter, e.g. for _my_collection/something.md:
next:
path: _my_collection/something.md
output: <p></p>
url: /my_collection/something.html
id: /my_collection/something
content: <p></p>
collection: my_collection
relative_path: _my_collection/something.md
excerpt: <p></p>
previous:
draft: false
categories:
slug: something
ext: .md
tags:
date: 2017-05-23 14:43:57 -0300