Page history Edit this page How do I edit this website?

Pitfalls

This page covers pitfalls to be aware of when writing content for the site.

This site uses Markdown for rich text formatting. It is powerful and friendly, but not a full replacement for raw HTML. Fortunately, you can mix HTML into your Markdown, as long as you are careful!

Mixing Markdown and HTML

You can apply CSS styles to inline HTML elements such as <span>, and any nearby Markdown will still be applied:

Code

Enjoy some
*<span style="color: red">colored</span>
<span style="color: green">text</span>
<span style="color: blue">in italics</span>*!

Result

Enjoy some colored text in italics!

Markdown inside block elements

If you use a block element, Markdown won’t be rendered inside:

Code

<div>
Why isn't *this* in italics?
</div>

Result

Why isn't *this* in italics?

Add markdown=1 to force Markdown rendering inside that element:

Code

<div markdown=1>
Yay, *this* is now in italics!
</div>

Result

Yay, this is now in italics!

Be sure to put a newline before your </div>! Otherwise you will get broken HTML. (Might be a bug in the kramdown renderer?)

To avoid the pitfall with </div> and newlines, you can instead target the parts you want Markdownified using <span markdown=1>:

Code

<div>I like *asterisks*.
They are so <span markdown=1>**pretty**</span>!
Do you like *asterisks* too?</div>

Result

I like *asterisks*. They are so pretty! Do you like *asterisks* too?

Using capture and markdownify

In some scenarios, it is easier to use Liquid’s capture directive to store a block of Markdown into a variable, and then use Jekyll’s markdownify filter to convert it to HTML, so that it can be more easily mixed with other HTML. One such case is with the <details> to create an expandable block of content. Here is an example:

Code

{% capture periodic-table %}
| 1 | H  | Hydrogen  |  1.008 |
| 2 | He | Helium    |  4.003 |
| 3 | Li | Lithium   |  6.938 |
| 4 | Be | Beryllium |  9.102 |
| 5 | B  | Boron     | 10.806 |
| 6 | C  | Carbon    | 12.009 |
| 7 | N  | Nitrogen  | 14.006 |
| 8 | O  | Oxygen    | 15.999 |
| 9 | F  | Fluorine  | 18.998 |
{:.left}
{% endcapture %}
<details><summary>Check out this amazing table!</summary>
{{ periodic-table | markdownify }}
</details>

Result

Check out this amazing table!
1 H Hydrogen 1.008
2 He Helium 4.003
3 Li Lithium 6.938
4 Be Beryllium 9.102
5 B Boron 10.806
6 C Carbon 12.009
7 N Nitrogen 14.006
8 O Oxygen 15.999
9 F Fluorine 18.998

The markdownify filter can be very useful, but watch out: it does not work well for inline elements because it will surround your Markdown expression in <p>...</p> tags, ruining the inline effect:

Code

{% capture question %} Does *Monday* work? {% endcapture %}
<div>I asked: "{{ question | markdownify }}" and she nodded.</div>

Result

I asked: "

Does Monday work?

" and she nodded.

Suppressing Markdown rendering

The markdown attribute can also be used the other way, to suppress Markdown rendering inside an HTML element:

Code

<span markdown=0>
Here are some **asterisks**.
</span>

Result

Here are some **asterisks**.

Conditional expressions

Where conditionals work

Conditional expressions may only be used with if and unless tags! They notably do not work with assign tags. So you cannot write a truthy conditional expression and assign it to variable expecting it to be set as true or false. If you need that, you can write:

{%- if a or b or c -%}
  {%- assign my-boolean-flag = true -%}
{%- else -%}
  {%- assign my-boolean-flag = false -%}
{%- endif -%}

Truthiness and falsiness

In Liquid, the only conditional expressions that evaluate to false are false and nil. Unlike other languages, in Liquid even the empty string ('') and the number zero (0) evaluate to true!

Table of truthy and falsy example expressions
Expression truthiness
"have a cow" true
"" true
0 true
1 true
false false
"false" true
nil false
nil or "" true
nil or "" or "hello" or "goodbye" true
"" or "hello" or "goodbye" true
"hello" or "goodbye" true
nil or "" true
"" or nil true
true or false true
false or true true
true or true true
false or false false
true or nil true
nil or true true
false or nil false
nil or false false
false or nil or true true
nil or false or true true
nil and "" false
"" and nil false
true and false false
false and true false
true and true true
false and false false
true and nil false
nil and true false
false and nil false
nil and false false
false and nil and true false
nil and false and true false

Order of operations

Unlike other languages, the and and or operators in Liquid have the same precedence. And even more surprisingly, Liquid evaluates conditionals from right to left with equal operator precedence.

Here is an example:

Code

{%- if nil and 'me' or 'yes' and 'OK' -%}
  Oh yes I did!
{%- else -%}
  Oh no you didn't!
{%- endif -%}

Result

Oh no you didn’t!

Here is a breakdown of how Liquid is evaluating the above:

nil and ('me' or ('yes' and 'OK'))
nil and ('me' or true)
nil and true
false

The parentheses above are merely for illustration; Liquid does not support parentheses in conditional expressions and your expression will be wrongly evaluated if you try to use them.

In most other languages such as Python or JavaScript, it would be true:

$ js
> console.log(null && 'me' || 'yes' && 'OK' ? 'true' : 'false')
true
$ python
>>> print('true' if None and 'me' or 'yes' and 'OK' else 'false')
true