Jekyll - Include multiple parameters in single include? - jekyll

Is it possible to include multiple parameters in single include?
Single:
{% include card.html class=include.class1 %}
Multiple??
{% include card.html class=include.class1 && include.class2 %}
Or do I have to do class1=include.class1 class2=include.class2?

Multiple include parameters can be passed separated with a space param1=value1 param2=value2,e.g.:
{% include image.html url="http://jekyllrb.com"
max-width="200px" file="logo.png" alt="Jekyll logo"
caption="This is the Jekyll logo." %}
Then you can access them inside the include file prefixing it with include., for example:
{{include.file}} {{include.caption}}

As stated by #marcanuy,
One way is to use the capture function to include multiple values into a single parameter.
{% capture classes %} {{include.class1}} {{include.class2}} {% endcapture %}
{% include card.html class=classes %}

Here's my use case for this-
an include that has html for a radiobutton set, like so:
<label>{{include.label}}</label>
{% for option in include.options %}
<input type="radio" name="{{include.label}}" id="{{include.option}}" value="{{include.option}}" checked="checked"/><label for=" {{include.option}}">{{include.option}}</label>
{% endfor %}
that you call like this:
{% include radiobuttons.html label="favorite color" options="green", "blue", "orange", "red" %}

Related

Jekyll/liquid list parameter?

I wanted to create a simply include which simplifies creating a carousel. So I was looking for the syntax to give a list of image urls as a parameter. However I couldn't find anything about this.
{% include carousel.html images=WHAT HERE? %}
You can create a list as a string then convert it into an array inside your snippet. This is the way I would do it.
{% assign urls = 'url1.jpg,url2.jpg,url3.jpg' %}
{% include carousel.html images=urls %}
Of course this is the same as:
{% include carousel.html images='url1.jpg,url2.jpg,url3.jpg' %}
carousel.html
{% assign images = include.images | split: ',' %}
{% for image in images %}
{{ image }}
{% endfor %}

Check markdown file has value with Jekyll template

I have a loop that goes through a folder of markdown files and displays the titles of each in a dropdown. I need to be able to filter the results of the loop based on whether or not a markdown file has an "office" value in it.
I currently have this:
<select name="practice-area" type="search" class="practice-areas-list select-table-filter" data-table="order-table">
<option value="default">Practice Areas</option>
{% for practice_area in site.practice_areas %}
{% unless practice_area.office %}
<option value="{{ practice_area.title }}">{{ practice_area.title }}</option>
{% endunless %}
{% endfor %}
<select>
where {% unless practice_area.office %} should be checking if the file has office in it. If so, pull title into list.
Sample Markdown File
---
title: page title
slug: page-title
office:
-22
---
Not sure of the proper Jekyll syntax for this to work correctly.
if tag contains a section of template which will only be run if the condition is true while unless would be run if the condition is false.
So to check if that key is present in your post front-matter, then you need to use the if statement:
{% if practice_area.office %}
...
{% endif %}
Realized I needed the opposite values so this works:
{% unless practice_area.office %}
{% endunless %}
Gives me all that don't have an office.

Is there a way in Liquid to use the contains operator to check for an exact match?

When searching an array for a match in a Liquid template, how do you call contains exactly? For example, if tag of a page may contain separable or non-separable, how do you find the pages that contain only the separable and not the non-separable tag? In my experience, the {% if post.tags contains 'separable' %} statement considers both cases.
Refer to the documentation you can use this filter
{% assign tags = post.tags | where:"tag","separable" %}
Loop through the array and check the values with a match operator. If it matches change a variable from false to true:
{% assign found_seperable = false %}
{% for tag in post.tags %}
{% if tag == 'separable' %}
{% assign found_seperable = true %}
{% endif %}
{% endfor %}
Then check the variable:
{% if found_seperable %}
do what you want if true
{% else %}
do what you want if false
{% endif %}

How to remove white space from html source code

I am using django and python. In the template file, I have a drop-down list which is shown as below. It works. The only problem is that there is a lot of white space between in the source html code. Is there any way to remove the white space? Thanks.
{% for lang_ele in video.languages.all %}
{% ifequal lang_ele.lang display_language %}
{% for key, value in language_table.items %}
{% ifequal lang_ele.lang key%}
<option selected = "selected" value={{lang_ele.lang}}>{{value}}</option>
{% endifequal %}
{% endfor %}
{% else %}
{% for key, value in language_table.items %}
{% ifequal lang_ele.lang key%}
<option value={{lang_ele.lang}}>{{value}}</option>
{% endifequal %}
{% endfor %}
{% endifequal %}
{% endfor %}
The output html souce code looks like this:
<option value=de>German</option>
<option value=el>Greek</option>
<option value=hi>Hindi</option>
You can use the spaceless template tag. It:
Removes whitespace between HTML tags.
{% spaceless %}
<p>
Foo
</p>
{% endspaceless %}
Look toward middelware, eg "htmlmin". It processes the file at a time. In addition it has a decorator.
https://crate.io/packages/django-htmlmin
gzip will give the same effect. Probably would have cost to opt out of trimming.
Look towards django middelware or nginx gzip.
django.middleware.gzip.GZipMiddleware
http://wiki.nginx.org/HttpGzipModule
You use the controller/model logic in the template. This is wrong way.
I used custom helper function with stripping. Here is a an example I used too: https://web.archive.org/web/20140729182917/http://cramer.io/2008/12/01/spaceless-html-in-django/

Check if an array is not empty in Jinja2

I need to check if the variable texts is defined or not in index.html.
If the variable is defined and not empty then I should render the loop. Otherwise, I want to show the error message {{error}}.
Basically this in PHP
if (isset($texts) && !empty($texts)) {
for () { ... }
}
else {
print $error;
}
index.html
{% for text in texts %}
<div>{{error}}</div>
<div class="post">
<div class="post-title">{{text.subject}}</div>
<pre class="post-content">{{text.content}}</pre>
</div>
{% endfor %}
How do I say this in jinja2?
I think your best bet is a combination of defined() check along with looking at the length of the array via length() function:
{% if texts is defined and texts|length > 0 %}
...
{% endif %}
To test for presence ("defined-ness"?), use is defined.
To test that a present list is not empty, use the list itself as the condition.
While it doesn't seem to apply to your example, this form of the emptiness check is useful if you need something other than a loop.
An artificial example might be
{% if (texts is defined) and texts %}
The first text is {{ texts[0] }}
{% else %}
Error!
{% endif %}
Take a look at the documentation of Jinja2 defined(): http://jinja.pocoo.org/docs/templates/#defined
{% if variable is defined %}
value of variable: {{ variable }}
{% else %}
variable is not defined
{% endif %}
Is it clear enough? In your case it could look like this:
{% if texts is defined %}
{% for text in texts %}
<div>{{ error }}</div>
<div class="post">
<div class="post-title">{{ text.subject }}</div>
<pre class="post-content">{{ text.content }}</pre>
</div>
{% endfor %}
{% else %}
Error!
{% endif %}
As mentioned in the documentation, you could also write:
{% for text in texts %}
<div class="post">
<div class="post-title">{{text.subject}}</div>
<pre class="post-content">{{text.content}}</pre>
</div>
{% else %}
<div>{{ error }}</div>
{% endfor %}
It handles both the case where texts is undefined, and the case where texts is empty.
This is a neat and simple solution that worked well for me!
{% if texts is defined and texts[0] is defined %}
...
{% endif %}
It's possible that texts could be defined but contain a single list element which is an empty string; For example:
texts = ['']
In this case, testing if texts is defined will produce a true result so you should test the first element instead:
{% if texts[0] != '' %}
..code here..
{% endif %}
You might also want to combine that with the |length filter to make sure it only has one element.
This worked for me when working with the UPS API where if there is only one object in a parent object the child is just an object, but when there is more than one child it's a array of objects.
{% if texts[0] %}
..code here..
{% endif %}
This is what worked for my use case in my Django app:
I needed to pass a queryset as context to an html template and display the block only if the queryset had values
Queryset:
events = Event.objects.filter(schedule_end__gte=date.today()).order_by('-created_at')
Passed context dictionary as follows:
{ "events" : events }
HTML template
{% if events %}
<h3>Upcoming Events</h3>
<ul>
{% for event in events %}
<li><h4>{{ event.title }}</h4></li>
{% endfor %}
</ul>
{% endif %}
This works for me ( But I make sure to return an empty array [] and not None if its empty )
{% if array %}
<table class="table">
...
</table>
{% endif %}
We can check if array is not empty by writing below jinja code.
where the content2 is an array defined under py file. #app.route("/<name>") def home(name): return render_template("index.html", content=name, content2=[])
{% if content2 %}
<div>
<h2>Array elements are available</h2>
{% for con2 in content2 %}
<p> {{con2}} </p>
{% endfor %}
</div>
{% endif %}
Thanks