Tyler Hayes
Tyler Hayes

Reputation: 51

Passing filename as variable to Jekyll include doesn't work

This works perfectly fine:

{% capture foo %}{% include test.html %}{% endcapture %}

I want to do this:

frontmatter.md:

---
baaz: test.html
layout: layout.html
---    

layout.html:

{% capture foo %}{% include {{ page.baaz }} %}{% endcapture %}

But when I do I'm given this error:

"Liquid Exception: Invalid syntax for include tag. File contains invalid characters or sequences: Valid syntax: {% include file.ext param='value' param2='value' %}"

I've seen this addressed in several other questions, with the most recent explanation I've found being this:

"...dynamic filename paths can't be added due to the fact that the included files are calculated and added at the compilation phase and not at run time phase. And compilation phase means dynamic paths aren't yet recognized."

But that source is nearly two years old. Does anyone have a solution to this yet? Or a workaround that would allow me to include a file defined as a variable in frontmatter?

Upvotes: 1

Views: 1437

Answers (3)

eQ19
eQ19

Reputation: 10711

I just came to this case recently. I assume the syntax works as expected. See sample and result.

   {% include {{ page.baaz }} %}

enter image description here

However in your case it might be the page name could not be put in a variable as the error stated:

Error:  Invalid syntax for include tag:

  File contains invalid characters or sequences

Valid syntax:

  ***% include file.ext param='value' param2='value' %***

So to come out from the problem I would suggest you to inventory all file names and choose it:

{% case page.baaz %}
{% when 'test.html' %}
    {% capture foo %}{% include test.html %}{% endcapture %}
{% when 'othertest.html' %}
    {% capture foo %}{% include othertest.html %}{% endcapture %}
{% else %}
    This is not a test
{% endcase %}

Upvotes: 1

David Jacquel
David Jacquel

Reputation: 52829

You can try {% include page.baaz %}

Edit : after some investigations, it appears that your syntax is correct, and that the error fires only when page.baaz is not present.

This ends up in an include tag which looks like this for liquid :

{% include %}

In order to avoid this error on certain pages/post with no baaz set, you can use a condition.

{% if page.baaz %}
  {% capture foo %}{% include {{ page.baaz }} %}{% endcapture %}
{% endif %}

Upvotes: 1

Mr. Hugo
Mr. Hugo

Reputation: 12590

I had a similar issue... I have found a very usable work-around. Allow me to share my experience and solution. I hope it helps you to find a suitable solution for your problem.

 

What I wanted to build
I wanted to make a page with multiple sections. The sections should be reusable, be able to contain includes and they should be easy to manage in the CloudCannon CMS.


What I came up with
I ended up using the following front matter:

---
title: Lorem ipsum
description: Lorem ipsum
image: /img/default.jpg
section_blocks:
  - section: sectionwithinclude
  - section: anothersection
  - section: andyetanothersection
---

... and the following tempate:

{% for item in page.section_blocks %}
{% for section in site.sections %}
    {% if item.section == section.slug %}
        <div class="section {{ item.section }}">
            {{ section.content }}
        </div>
    {% endif %}
{% endfor %}
{% endfor %}

Within the _sections folder/collection I have a file called sectionwithinclude.md that looks like this:

---
---

{% include mycustominclude.html %}

Why this is great
When you edit your page, CloudCannon will show the section_blocks as an array with reorder buttons. Additionally, CloudCannon will automagically recognize section as a collection and show the options in a dropdown. Therefore adding a section is a matter of adding an empty item to the array, selecting a section from the dropdown and reordering it with the array buttons. On the same time, the inline editing option of CloudCannon still works. So management of text can be WYSIWYG, while block management can be done in the front matter array.

Super easy and powerful for (you and) your editors.

 

PS. You might find out that you will have some 'scope' issues, because page no longer relates to the actual page, but to the section. To solve this you can/should alter the loop in the template. You can let the loop manage the include instead of the section.

Upvotes: 0

Related Questions