Whitespace control fails to compile - jekyll

I am working with a pretty simple template for my Jekyll site in Liquid:
{% if page.title == "Home" %}
{{ site.title }} · {{ site.tagline }}
{% else %}
{{ page.title }} · {{ site.title }}
{% endif %}
This yields a lot of undesired whitespace, so I did the following:
{%- if page.title == "Home" -%}
{{ site.title }} · {{ site.tagline }}
{%- else -%}
{{ page.title }} · {{ site.title }}
{%- endif -%}
This is precisely what the Liquid docs say to do, but it fails to compile in Jekyll:
Liquid Exception: Liquid syntax error (line 1): Tag '{%- if page.title == "Home" -%}' was not properly terminated with regexp: /\%\}/ in /_layouts/default.html
I seem to be on the latest version of Liquid, 3.0.6.
Is there something I'm doing wrong?

Jekyll might not be using the latest version of Liquid. This means
that the tags and filters listed on this site may not work in Jekyll.
Often the Jekyll project will wait for a stable release of Liquid
rather than using a beta or release candidate version.
Current Jekyll version: 3.3.1 list their Liquid dependency: liquid ~> 3.0 This is the Luiqid version that Jekyll is using.
The Whitespace control feature you are trying was released in Liquid 4.0.0.
Look at the following commit: Add whitespace control character and associated tests. It was made on 27 Jun 2016 and is present in tags:
v4.0.0
v4.0.0.rc3

Jekyll does not necessarily use the latest Liquid Version so this might be the issue.
You could use a plugin (e.g. octopress/minify-html) to minify your html as a simple solution.

Related

For loop in HTML file, {% for x in xxx %}. Native or framework?

I was looking at some HTML code and I encountered this syntax that I had not seen before:
{% for x in xxx %} \n
<li>{{x.something|e}}</li> \n
{% endfor %}
I was wondering if this was native HTML, or if it was some special framework. For the record, I saw it in a Jekyll template for github pages but when I tried searching it up, I couldn't find much clarification.
That is Liquid, the templating language that Jekyll uses to process templates.
The code you posted is a for loop:
Liquid allows for loops over collections:
{% for item in array %}
{{ item }}
{% endfor %}
You can check the project doc: Liquid for Designers and how Jekyll uses it.

Getting current url from a collection in Jekyll

If I want to get a page's url it's not exactly complicated:
page.url
However, what if I make a collection who's job it is to be used like an include instead of like a page?
If I make such a collection and ask for page.url it gives me the path to the collection instead of the path to the current url.
Is there a way to get the real current URL in Jekyll?
Edit: example
test.md:
---
title: Test page
permalink: /test/
---
Test page
{% for block in site.blocks %}
{% if block.whatever %}
{{ block.content }}
{% endif %}
{% endfor %}
_blocks/block.md:
---
whatever: true
---
{% page.relative_path %}
Got:
Test page
/_blocks/block.md
Expected:
Test page
test.md
I've been using jekyll for a short time and I'm relying on collections to build my first static portfolio site. So far all my attempts when trying to get the path to the current url simply fails.
In order to achieve the desired result, I've used Jekyll Liquid filters.
Here is how you'd get the expected result you as per your question:
test.md:
---
title: Test page
permalink: /test/
---
Test page
{% for block in site.blocks %}
{% if block.whatever %}
{{ block.content }}
{% endif %}
{% endfor %}
_blocks/block.md:
---
whatever: true
---
{{ page.relative_path | replace:'index.html', '' | remove: '_blocks/' | prepend: site.baseurl }}
Output on Test page
Test page
test.md
Update:
Perhaps the following is not the most straightforward method to get the path to the current url, but by defining relative_path: in the front-matter definitions of a document you'd also get the result you expect, of course this is something required on a per page basis.
---
whatever: true
relative_path: test.md
---
{% page.relative_path %}
So in this very specific case
{% page.relative_path %}
should output
test.md
A Jekyll's doc reminder:
As per Jekyll's doc, when you create a collection it becomes available via the site Liquid variable, pretty much like site.posts and site.pages, so you're able to use the available filters in most cases.
I hope it helps!

Jekyll: output of liquid tags / variables

I try to render something like this:
{% highlight ruby %}
{{ page.url }}
{% endhighlight %}
The Raw tag doesn't have an effect:
{% highlight ruby %}
{% raw %}
{{ page.url }}
{% endraw %}
{% endhighlight %}
Even not when I put this in my plugins folder: https://gist.github.com/phaer/1020852
I have tried this also:
<pre>
{% raw %}
{{page.url}}
{% endraw %}
</pre>
But in all cases the page.url does show up.
I also tried tipp #1 here:
http://truongtx.me/2013/01/09/display-liquid-code-in-jekyll/
To be clear i want to see the literal here.
In fact the real use case is to show some javascript like this:
var disqus_identifier = '{{page.dsq-id}}';
When I use the { entities they are shown as entites and not as brackets.
Only this works, but then my code highlighting is gone:
<pre>
var disqus_identifier = '{{page.dsq-id}&#125';
</pre>
I use jekyll 1.4.2.
Any ideas how i can solve this?
I tried your code in Jekyll 1.2.1 and it works as you've expected it to work.
To uninstall Jekyll 1.4.2 and reinstall Jekyll 1.2.1 run these commands,
gem uninstall jekyll
y
gem install jekyll -v 1.2.1

How to suppress blank line in Jekyll?

I use GitHub Pages for my blog, and am running into a problem with Jekyll. My post.html has a block like this:
{% for testpost in site.posts %}
{% four %}
{% lines of %}
{% processing %}
{% goes here %}
{% endfor %}
The part in the middle doesn't matter. The important part is the end of the line which is outside of the {% %} markup, and is therefore rendered into the html. Since this is in a loop, it's putting about 1000 blank lines into the middle of by HTML page. It doesn't affect the display, but it make a View/Source troublesome.
Any ideas on how to avoid those extra blank lines?
Since Liquid v4 (included in Jekyll from v3.5) there is a Whitespace control, which finally resolved case with blank line, white space, etc.
Link to documentation: https://shopify.github.io/liquid/basics/whitespace/
There's a nice workaround, that I found out in https://github.com/plusjade/jekyll-bootstrap/blob/master/_includes/JB/setup, and which is compatible with github pages.
Just enclose your loop in a capture statement, and assign nil to the resulting var.
{% capture cache %}
{% for p in site.posts %}
do stuff here
{% endfor %}
{% endcapture %}{% assign cache = nil %}
How about
{{ page.content | escape | strip_newlines }}
There is Jekyll plugin that strips the whitespace.
Jekyll plugins by Aucor: Plugins for eg. trimming unwanted
newlines/whitespace and sorting pages by weight attribute.
You can get it directly from its Github repository. So basically you wrap your code with {% strip %}{% endstrip %}. Even if this doesn't suit you needs, you can easily change the ruby script.
For example:
{% strip %}
{% for testpost in site.posts %}
{% four %}
{% lines of %}
{% processing %}
{% goes here %}
{% endfor %}
{% endstrip %}
However, please remember the nature of Jekyll plugins, you can't run them on the Github Pages server.
Quote from Jekyll Doccumentation:
GitHub Pages is powered by Jekyll, however all Pages sites are generated using the --safe option to disable custom plugins for security reasons. Unfortunately, this means your plugins won’t work if you’re deploying to GitHub Pages.
You can still use GitHub Pages to publish your site, but you'll need to convert the site locally and push the generated static files to your GitHub repository instead of the Jekyll source files.
Actually there is a new solution for this problem which works without any plugin.
A Jekyll layout that compresses HTML. At a glance:
removes unnecessary whitespace;
removes optional end tags;
removes optional start tags;
removes comments;
preserves whitespace within <pre>;
GitHub Pages compatible;
ignores development environments;
configurable affected elements;
profile mode;
automatically tested.
http://jch.penibelst.de/
If you - for some reason - do not want to use this here is a nice article, which describes some workarounds:
Compressing Liquid generated code - sylvain durand

Evaluate a liquid "if" statement based on value of liquid filter

I have a custom Liquid filter I use in a Jekyll site,
{{ page.url | git_modified }}
Which generates the modification date from the git log (plugin code here).
Often I may add the additional filter to convert this to a string or XML schema, depending on context, e.g. {{ page.url | git_modified | date_to_string }}. Everything is hunky-dory unless for some reason my git_modified filter fails to return a time object for some post. In that case, I am trying to write a decent fail condition but cannot quite figure this out.
I'd like to just wrap my call in a liquid if statement to check if the variable is defined first:
{% if defined?( {{ page.url | git_modified }} %}
But I don't seem to be able to use Liquid tags ({{) inside Liquid block options ({%, %}). I thought I could get around this with Liquid capture:
{% capture page_modified %}{{ page.url | git_modified }}{% endcapture %}
{% if defined?(page_modified) %}
{{ page.url | git_modified | date_to_string }}
{% endif %}
but said variables do not seem to be available to the if statements. Any suggestions?
try doing it this way:
{% capture page_modified %}
{{ page.url }}
{% endcapture %}
{% if page_modified %}
{{ page.url }}
{% endif %}
If page_modified isn't defined, its value will be nil anyway, so just use the if construct as you would in pure Ruby. I tested here with jekyll 1.0.0.beta2 — jekyll new test, then created a file with the above code — and it worked. :)