Christian
Christian

Reputation: 5521

Dynamically change link target in Jekyll when target does not exist

I need to insert links but check whether a file exists in this language. I want to adjust the link target dynamically during or after build.

Currently, due to the nested structure of the navigation file, a generator plugin creates an index of articles with their properties, e.g. title, path, etc. The information is accessible in includes in site.docs_by_site.

The idea is to correct any missing links to other articles in the page content by passing a partial link to an include file. The link will be passed into a parameter.

I would insert links like this:

{% include link.html path='getting-started/test.md' %}

I though using an include file could work out:

{% if page.lang == 'en' %}
  {% assign full_path = "_" | append: 'en' | append: "/" | append: include.path %}
  {% assign post = site.docs_by_path[full_path] %} 
{% endif %}

{% if page.lang != 'en' %}    
  {% assign full_path = "_" | append: page.lang | append: "/" | append: include.path %}
  {% assign localized_file = site.docs_by_path[full_path] %}

  {% if localized_file %}
    {% assign post = localized_file %}
  {% else %}
    {% assign full_path = "_" | append: 'en' | append: "/" | append: include.path %}
    {% assign post = site.docs_by_path[full_path] %} 
  {% endif %}
{% endif %}

<div>
{% if post[0] == nil %}
  <a href="wrong-link-target">wrong-link-target {{ full_path }} in {{ page.url }}</a>
{% else %}
  <a href="{{ post[0] }}">{{ post[1] }} <sup>in English</sup></a><!-- localize sup using i18n - it: in inglese, es: en inglés, nl: in Engels -->
{% endif %}
</div>

Is it smart and does it make sense at all or do you see any downsides, e.g. performance? I need to check and adjust several thousand links. Can it be implemented better, e.g. using another Jekyll plugin?

I have created a sample repo with code using conditionals, see include file and a sample file.

Bonus question: The include returns the element inside a p tag - any idea how to workaround this?

Upvotes: 0

Views: 139

Answers (1)

Christian
Christian

Reputation: 5521

I'd like to share some code about the custom link tag solution from my comment above.

To get rid of the include which slows down the build a lot, we used such format for links:

{% custom_link this is a link title | path/to/file.md %}

Jekyll tag plugin code example below.

The build_url method (code not included) basically contains the same logic as before to check whether the docs exists and returns an HTML link.

module Jekyll
  class CustomLinkTag < Liquid::Tag
    def initialize(tag_name, options_string, tokens)
      super
      @options = options_string
    end

    def render(context)
      site = context.registers[:site]
      page = context.registers[:page]

      build_url(site, page, @options)
    end
    ...
end

Liquid::Template.register_tag('custom_link ', Jekyll::CustomLinkTag)

Upvotes: 0

Related Questions