12

Quick Tip: How to capture and replace newlines in liquid for Jekyll/GitHub Pages

 3 years ago
source link: https://christianheilmann.com/2020/12/17/quick-tip-how-to-capture-and-replace-newlines-in-liquid-for-jekyll-github-pages/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Quick Tip: How to capture and replace newlines in liquid for Jekyll/GitHub Pages

Thursday, December 17th, 2020 at 1:40 pm

As part of the re-write of The Developer Advocacy Handbook I needed to have blockquotes with different classes.

Fact display in the book

With GitHub Pages markdown you can do that using the > notation:

> **Fact:** There are no bad students or a bad audience --
only bad workshops and talks. Your mood, dedication and
enthusiasm do become those of the audience -- 
if you are not happy, they won\'t be happy.

The problem was that I couldn’t add CSS classes to the blockquote elements so I can show them in different styles. I wanted four of them: example, fact, warning and tip.

The good news is that even without any styling using the strong name should make it obvious. But as there is no text “contains” selector in CSS I couldn’t rely on that to change the blockquote element.

First solution: JavaScript

The first thing I thought was to use JavaScript to apply the classes, which is pretty straight forward:

let bqs = document.querySelectorAll('blockquote');
  bqs.forEach(b => {
  b.className = b.
    querySelector('strong').
      innerText.
        toLowerCase().
          replace(':','');
});

This, however, felt dirty and I wanted to use the system itself to do that task.

Moving to liquid

So I wrote a liquid include to convert the HTML before rendering. In my layout template, this works by replacing the {{ content }} with {% include blockquotes.html html=content %}.

In the blockquotes.html, I thought it’d be easy to do a search and replace. Alas, there is the issue that liquid only does string replacement and doesn’t know any regular expressions.

The HTML generated from the markdown has a line-break in it:

<blockquote>
  <p><strong>Fact:</strong> There are no bad students … </p>
</blockquote>

This is where it didn’t get fun. The replace filter doesn’t allow you to concatenate strings and doesn’t know the concept of n. So, I tried to use the newline_to_br together with strip_newlines filters and then replace the br but it was messy.

Turns out, the main trick was to capture a newline in liquid and assemble the string to replace using that one.

{% capture newline %}
{% endcapture %}
{% capture tip %}<blockquote>{{newline}}  <p><strong>Tip:</strong>{% endcapture%}
{% capture example %}<blockquote>{{newline}}  <p><strong>Example:</strong>{% endcapture%}
{% capture warning %}<blockquote>{{newline}}  <p><strong>Warning:</strong>{% endcapture%}
{% capture fact %}<blockquote>{{newline}}  <p><strong>Fact:</strong>{% endcapture%}
 
{% assign newhtml = include.html | 
  replace: tip, '<blockquote class="tip"><p><strong>Tip:</strong>' |
  replace: example, '<blockquote class="example"><p><strong>Example:</strong>' |
  replace: warning, '<blockquote class="warning"><p><strong>Warning:</strong>' |
  replace: fact, '<blockquote class="fact"><p><strong>Fact:</strong>' 
%}
{{ newhtml }}

This works fine. Seems superfluous, but it is a way. It might be that there is a much simpler way as I am new to this world, having used PHP before the build the old version of the book. Got a better option? Tell me :)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK