Using Jinja variable in Yaml file - jinja2

I have a template folder containing a file.j2 , e.g
{% set summary %}
{% if summary %}
{{ summary }}
% endif %}
{% endset %}
I would like to use this summary variable in my yaml file but I can't seem to be able to find the information on how to reference the j2 file in the yaml file
Can I do this?
template: file.j2
summary: '{{ summary }}'
Any suggestions are greatly appreciated!

Related

how can i use jinja template and pillar in saltstack states

there is my sls file:
{% set java_script_path = salt['pillar.get']('script_path', default='/opt/java-app') %}
{% if salt['pillar.get']('script_path') %}
{% set file = {{ java_script_path }}/startup.sh %} ## seem this line have Jinja syntax error
{% if salt['file.file_exists']('{{ file }}') %}
cmd.run:
- name: mv {{ java_script_path }}/startup.sh {{ java_script_path }}/startup.sh.backup-$(date +"%Y-%m-%d-%H-%M-%S")
{% endif %}
{% endif %}
is using salt['pillar.get']('script_path') can not split other string?
example: name: {{ salt['pillar.get']('script_path') }}/startup.sh will raise error like: failed: Jinja syntax error: expected token ':', got '}' how can i fix ?
can you help me to fix my sls file to work?
{% already starts a Jinja context. You do not need to try to start another one with {{.
{% set file = java_script_path ~ "/startup.sh" %}
It was expecting a : because { starts a dict literal.
In simple use case such as shown in your question, you might not even need to set another variable at all. We could directly use {{ java_script_path }}/startup.sh in the if condition. Like below:
{% if salt['file.file_exists']("{{ java_script_path }}/startup.sh") %}
cmd.run:
- name: mv {{ java_script_path }}/startup.sh {{ java_script_path }}/startup.sh.backup-$(date +"%Y-%m-%d-%H-%M-%S")
{% endif %}
You could also reconsider using command to backup the file, and use an appropriate Saltstack module instead.

Can I include a file based on a variable

I am trying to include a template file dynamically, but the variable does not appear to expand in the include declaration. How is this best done?
{% for file in files %}
{% include "{{ file }}.txt" %}
{% endfor %}
The error I am getting is:
jinja2.exceptions.TemplateNotFound: {{ file }}.txt
The below works for me.
I would like to clarify having a "." in jinja2 might create an issue so it would be better to pass the entire filename with extension to jinja2.
The usage of double quotes would not render the variable value so it would remain as it is like {{ file }}
The below works:
from jinja2 import Environment, FileSystemLoader
data = '''
{% for file in files.split(",") %}
{% include file %}
{% endfor %}
'''
template = Environment(loader=FileSystemLoader("templates/")).from_string(data)
msg = template.render(files="1.txt")
print(msg)
Output:
1.txt

How to loop through all files in Jekyll's _data folder?

How can I loop through every file in my _data folder in Jekyll?
Currently I have a list of files in a file called sidebarlist.yml like this:
- file1
- file2
- file3
In order to loop through all of these files, I use this code:
{% for sidebar in site.data.sidebarlist %}
{% for entry in site.data.sidebars[sidebar].entries %}
...
{% endfor %}
{% endfor %}
I would like to avoid using sidebarlist.yml and just iterate through all files within _data automatically. Can I do this?
Nesting loops allows you to loop through the contents of _data files.
When I did this I used a subdirectory, since I didn't want to loop through every data file, and I think that applies to many use cases. It also keeps my _data directory a little tidier.
My _data directory looks like this:
_data/
navigation.yml
news.yml
people/
advisors.yml
board.yml
staff.yml
Each of the files within people/ uses a structure like this:
- name: Anne Smith
role: Role A
url: mysite.com
- name: Joe Shmoe
role: Role B
url: mysite.org
And on the page where I'm looping through each of these data files:
{% for people_hash in site.data.people %}
{% assign people = people_hash[1] %}
{% for person in people %}
<li>{{ person.name }}, {{ person.role }}</li>
{% endfor %}
{% endfor %}
This results in:
<li>Anne Smith, Role A</li>
<li>Joe Shmoe, Role B</li>
It's very similar to what you've already done, but eliminates the need for that extra yaml file.
Note the use of people_hash[1] - this is what is targeting the appropriate values within the array.
If instead you do:
{% for people_hash in site.data.people %}
{% assign people = people_hash[1] %}
<pre>{{ people }}</pre>
{% endfor %}
You'll get the array of values that is returned, which should help you debug your template.
I have read your question title, and I will answer your last question:
You can't loop through files you keep in _data folder. According to Jekyll Variable doc and Jekyll Directory structure all the file in _data with supported extension .yml .yaml .csv .jsonby default will be loaded in site.data like #wasthishelpfull's answered and you access it via {{site.data.*filename.data*}} and loop though like this answer
If you wanna loop through files, create a folder (no underscore) serve it as static files, and use jquery.get() for the data in the file.
Or change _data to data in _config.yml by adding data_source: data and access at a url endpoint /data see this post for more
According to the documentation, jekyll will load YAML resources (.yml, .yaml, .json, and .csv files) directly into site.data. If your files use one of these formats, you can do:
{% for data in site.data %}
...
{% endfor %}
I assume you need to access jekyll site.data in a way of looping multi levels object:
{% assign my_data = site.data %}
{% assign my_level = "sidebarlist.sidebars.sidebar" | split: "." %}
{% for level in my_level %}
{% assign my_data = my_data[level[i]] %}
{% for data in my_data %}
{{ data }} : {{ my_data[data] }}
{% endfor %}
{% endfor %}

Include a file, but only if it exists?

I'm creating a style guide in Jekyll and using Collections to define different elements of the guide. For example, headings, lists, etc.
I'm trying to separate the Sass into files that match up with the partials, one to one, and I'd like to render the Sass files as part of each collection.
So, something like:
{% if _includes/_sass/{{ entry.title | append: ".scss"}} %}
{% highlight sass %}
{% include _includes/_sass/{{ entry.title | append: ".scss" }} %}
{% endhighlight %}
{% endif %}
Basically, what I want is "Include a file in this directory that has the same name as this entry in my collection. If it doesn't exist, don't break."
How do I do this? I've explored storing the file path in a variable but can't seem to get that to work.
Thanks in advance.
It can be done.
This works on Jekyll 3 but it can certainly be ported to Jekyll 2.
Starting from a base install (jekyll new)
_config.yml
collections:
guide:
sasssamples:
Style guide files
Our samples will be grouped in the _guide collection.
Example file : _guide/header/header1.hmtl
---
title: Header level 1
---
<h1>Header level 1</h1>
SCSS samples
We want our SCSS samples to be included in our css/main.scss and use variables defined in our other SCSS files. Our samples will be integrated at the end of our css/main.scss
We don't want our SCSS samples to render as css so no .scss extension. Switch to .txt extension
We want to access SCSS samples from a list. Let's put them in a sasssamples collection.
Example file : _sasssamples/header/header1.txt
---
---
h1{
color: $brand-color;
border: 1px solid $brand-color;
}
SCSS samples integration
Add this code at the very end of you bootstraping scss file (css/main.scss on a base Jekyll install)
css/main.scss
[ original code ... ]
{% comment %} Selecting a collection the Jekyll 3 way. See https://github.com/jekyll/jekyll/issues/4392 {% endcomment %}
{% assign scssCollection = site.collections | where: 'label', 'sasssamples' | first %}
{% comment %}
Printing documents in sasssamples collection.
All SCSS from style guide are sandboxed in .guide class
This allows us to apply styles only to style guide html samples
{% endcomment %}
.guide{
{% for doc in scssCollection.docs %}
{{ doc.content }}
{% endfor %}
}
The style guide
<h2>Style guide</h2>
{% comment %}Selecting a collection the Jekyll 3 way. See https://github.com/jekyll/jekyll/issues/4392 {% endcomment %}
{% assign guideCollection = site.collections | where: 'label', 'guide' | first %}
{% assign scssCollection = site.collections | where: 'label', 'sasssamples' | first %}
{% comment %} Looping hover style guide samples {% endcomment %}
{% assign samples = guideCollection.docs %}
{% for sample in samples %}
<article>
<h3>Element : {{ sample.title }}</h3>
<h4>Render</h4>
<div class="guide">
{{ sample.content }}
</div>
<h4>html code</h4>
{% highlight html %}{{ sample.content }}{% endhighlight %}
{% comment %}
Changing a path like : _guide/headers/header1.html
to : _sasssamples/headers/header1.txt
{% endcomment %}
{% assign scssPath = sample.path | replace: '_guide', '_sasssamples' %}
{% assign scssPath = scssPath | replace: '.html', '.txt' %}
{% comment %} Try to find a SCSS sample with equivalent path {% endcomment %}
{% assign scssSample = scssCollection.docs | where: 'path', scssPath | first %}
{% comment %}We print SCSS sample only if we found an equivalent path{% endcomment %}
{% if scssSample != nil %}
<h4>SCSS code</h4>
{% highlight css %}{{ scssSample.content }}{% endhighlight %}
{% endif %}
</article>
{% endfor %}
Done!
Seems it only miss on assigning the correct path
{% if _includes/_sass/{{ entry.title | append: ".scss"}}
Need to be replaced to relative path to the scss file:
{% assign scssPath = 'relative/path/to/your/scss/' %}
{% if {{ entry.title | append: ".scss" | prepend: scssPath }} != nil %}

Comparing variables in template to build JSON - Ansible

Starting off with Ansible and I am trying to use ReST API to interact with an external application.Maybe I am missing something simple here.
I am trying to compare every host in my inventory file with the POD name specified in the variable file used by the role that invokes the jinja2 template.
My inventory file looks like this:
[all]
'POD-9'
'POD-10'
Variable file :
pods:
params:
- name: POD-9
- name: POD-10
{% for pod in pods.params %}
{% if '{{ inventory_hostname }}' == '{{ pod.name }}' %}
<generate JSON template here>
{% endif %}
{% endfor %}
The if statement however does not take effect. I want the template to be generated only in the inventory_hostname is equal to the pod name in the variable file
The current JSON file includes both :
{
"pod": {
"name": "POD-9"
}
"pod": {
"name": "POD-10"
}
}
In Jinja2 the double curly braces are used as a print statement. If you access variables inside tags don’t put the braces around them
{% for pod in pods.params %}
{% if inventory_hostname == pod.name %}
<generate JSON template here>
{% endif %}
{% endfor %}
Found the problem :
{% if pod.name == inventory_hostname %}