Search code examples
jekyllliquid

Jekyll/Liquid Relative URL filter breaks links


I'm trying to use relative_url in most of the links of my Jekyll theme, so if someone wants to have this theme working in a subdirectory he can do it. I have a problem with the list of categories of the post, each of which should link to the archive.

In _layouts/post.html I have this code:

{% if site.data.settings.categories.active %}
  {% include categories.html %}
{% endif %}

categories.html has this code:

<div class="categories">
    <span><p>Categories:</p>
    {% if post %}
      {% assign categories = post.categories %}
    {% else %}
      {% assign categories = page.categories %}
    {% endif %}
    {% for category in categories %}
      <a href="{{ "/categories/#{{category | slugify}}" | relative_url}}">{{category}}</a>
      {% unless forloop.last %}&nbsp;{% endunless %} 
    {% endfor %}
  </span>
</div>

Here's the problem:

 <a href="{{ "/categories/#{{category | slugify}}" | relative_url}}">{{category}}</a>

Somehow, this returns the current post url.

<a href="/categories/#{{category | slugify}}">{{category}}</a>

This returns the correct link, but does not work in case the site is in a subdirectory.

Why it returns the post url?


Solution

  • There are multiple problems here.

    First off, Liquid doesn't evaluate nested constructs. Therefore, the following code:

    {{ "/categories/#{{category | slugify}}" | relative_url}}
    

    needs to be rewritten into:

    {% capture url %}/categories/{{ category | slugify }}{% endcapture %}
    {{ url | relative_url }}
    

    Secondly, there is no global post object. Therefore {% if post %} is always going to evaluate to a negative. i.e., it is redundant.