Page variable in for loop file name - jekyll

For a bilingual website, i have yaml data files for 2 languages.
files example:
en_services.yml
fr_services.yml
Variable example in my page:
---
lang: en
---
I want to loop trough the file with the lang as the prefix, something like that:
{% for service in site.data.{{ page.lang }}_services %}
{% endfor %}
This doesn't work, is there a way I can do that?
By the way, I don't think I can add subfolders in the _data folder, right?
Thanks.

While that doesn't work, if you are able to put them both in the same file (grouped under the appropriate language code) there is a solution.
This gist was for another example based on post authors, but your should be able to use the same setup using language codes instead of author names.

You should use:
site.data[{{ page.lang }} + '_services']
data[i] has key/value entries for all the files in your _data directory, and passing the string in, like so (for /_data/book.yaml):
site.data['book']
...totally works and opens up the possibility of concatenating strings inside the brackets with whatever variable you want. :)

{% capture thefile %}{{ page.lang }}_services{% end capture %}
{% for service in site.data[thefile] %}
...
{% endfor %}
Should do the trick.

Related

How to dynamically assign _data variable?

I'm using staticman to enable comments on my blog. It puts the comments in the _data folder. My folder structure then looks like this:
_data/
comments/
blog-post-1/
entry1542891129928.yml
...
blog-post-2/
entry1542891129928.yml
...
...
In my _layouts/post.html I want to access comments for a specific blog. This is the code that I expect to work to get to the comments:
{% assign comments = site.data.comments[page.slug] | sort %}
But when I run build, I get the following error:
Liquid Exception: Liquid error (line 39): Cannot sort a null object. in /_layouts/post.html
It seems to be something to do with page.slug because if I replace it with the string 'blog-post-1' it works.
How to get the post slug dynamically in post.html?
Solved the problem!
The issue is when the folder does not exist. I circumvent this by moving the sort filter:
{% assign comments = site.data.comments[page.slug] %}
{% if comments %}
{% assign comments = comments | sort %}
...do things...
{% endif %}
Now the build doesn't fail.

How to use Liquid include variable within a for loop?

I have this Liquid template which looks like this:
# /_includes/slideshow.html
{% for image in {{ include.images }} %}
...
{% endfor %}
which I'm trying to use with a YAML file (for my Jekyll site) like this:
# /index.md
{% include slideshow.html images='site.data.homepage_images' %}
The reason I see this failing is because my include variable {{ include.images }} resolves to a string within the for loop. Is there a different way to accomplish this? I'm still rather new to Liquid, YAML, Jekyll, and well, web development altogether, so any help in doing this is much appreciated!
(Note: the problem goes away if I replace {{ include.images }} with site.data.homepage_images.)
Additionally, the reason why I'm doing this (and why that crude fix isn't the solution I'm looking for) is for the ability to inject my image slideshow elsewhere around my site. It'd save a lot of code to abuse my include variable in this way.
Correct syntax in for loop is : {% for image in include.images %}

Set twig variable to json file as an include

I have created twig templates and save all the content in a jsonfile. Like this:
Json Data:
{% set contentElements = {
"json structur": {....}
"json structur": {....}
%}
Unfortunately over the years the json files has become bigger and bigger.
So i want to splitt the json data into snippets.
It is possible to set the variable contentElements to an include?
It is not working but something like this:
{% set contentElements = include"content.json "%}
Its an static HTML Project.
To capture chunks of text it is better to use the {% set var %}/{% endset %} tag. This allows you to assign "larger" amount of data to a variable. It's also possible to pass content from another file to the variable this way in combination with include.
{% set json %}
{% include "content.json" %}
{% endset %}
{{ json }}
(sidenote: Content captured as chunk is being treated as safe)

How to I include all files from inside a directory in jinja2?

A normal jinja2 include looks like {% include 'directory/filename.html' %} but I am looking to do something like `{% include 'dropins/*.html' % where obviously the order would be alphabetically.
Is this possible? How?
You could pass a list of file names, then iterate over them:
{% for file_name in file_list %}
{% include file_name %}
{% endfor %}
And of course, inside file_list you should have already built your list of file names
file_list = ['dropins/file1.html', 'dropins/file2.html']
In Python, I would write some function that could discover all files inside that directory and then save their filenames to the list... or if you know the list just hard code them like above

jinja2 load template file from template

Is there a way I can load a jinja2 template from within another template file? Something like
{{ render_template('path/to/file.html') }}
I have some snippets which I want to reuse, so it's important for me to have this functionality.
{% include "file" %} does this. See the jinja2 docs for more information.
Use either the extends tag or the include tag, depending on how you want to design your multi-file views.
You should make template files with {% macro -%}s and use {% import "file" as file %} to use the macros in other template files. See the docs.
Here is an example:
<!- in common_macros.html ->
{% macro common_idiom1(var1, var2, ... varN) -%}
<!- your idiom, where you can use var1 through varN ->
{%- endmacro %}
<!- in my_template.html ->
{% import "common_macros.html" as idioms %}
{{ idioms.common_idiom1(a, b, ... N) }}
Specifically this answer allows the OP to pass arguments to his macros, similar to the behavior he desired like how render_template behaves (simply including the file as previous answers have stated above does not achieve the same behavior as render_template).
This is generally better than making a fresh template for every idiom, or than using inheritance, which is a special case solution (what if you want to use the snippet multiple times in one template)?