Liquid Filters
mdsh
now has a new feature, inspired by Liquid filters.
The Liquid templating system was created by Shopify and is used in the templating system of Jekyll.
Here's a description of "liquid filters" from the liquid filters documentation:
Filters are simple methods that modify the output of numbers, strings, variables and objects. They are placed within an output tag {{ }} and are denoted by a pipe character |.
As mdsh
is written in shell, and uses mo
as its Mustache library, I've
implemented a rip-off version of liquid filters.
You can use the filters in your .mustache
templates files, and in your .mdsh
source files. You pass the variables through a filter using the pipe symbol |
.
Usage and examples:
1. Template usage
Filtering basic page data (strings):
<h2>{{page_name | uppercase}}</h2>
^ this will output the page title in upper case.
Here is a more advanced example:
<h2>{{page_name | truncate_words 6 ".." | strip_newlines}}</h2>
^ this will truncate to 6 words, and append `..` if truncated, and strip new lines.
These filters also can also be applied to whole sections (if you must!):
{{page_header | strip_html}}
Filtering arrays:
In your templates various places use arrays to iterate over lists, such as recent posts. These lists can also be "filtered", in much the same way as the page data variables described above.
In your templates, normal `arrays` work as iterators, that can also take filters.
For example:
{{#someArray | sort_array desc | limit 3}}
{{. | titlecase}}
{{/someArray}}
Associative arrays also work nicely with the `foreach` iterator:
{{#foreach item in someAssocArray | sort_by "age" "asc" | limit 3}}
Hi {{item.name | titlecase}},
at {{item.address | uppercase | newline_to_br}}
{{/foreach}}
2. Markdown usage
You can even use them in the sub-shells of your `*.mdsh` source files:
< ?bash echo "$something" | replace_all foo bar ;? >
Available filters:
Here is a list of all the filters available:
String filters
Here is the general usage:
{{someString | <filter> [options]}}
Make text upper case:
{{someString | uppercase}}
Make text lower case
{{someString | lowercase}}
Make text title case
{{someString | titlecase}}
Capitalise first-letter of string, lower case the rest
{{someString | capitalise}}
Convert string to slug
{{someString | slugify}}
Convert camel case string to a slug
{{someString | camelcase_to_slug}}
Convert a slug to camel case
{{someString | slug_to_camelcase}}
Remove leading whitepace from (left of string)
{{someString | lstrip}}
Remove trailing whitepace from (right of string)
{{someString | rstrip}}
Remove leading and trailing whitespace
{{someString | strip}}
Remove all HTML tags, keeping the inner content
{{someString | strip_html}}
Strip newline characters from string
{{someString | strip_newlines}}
Replace `<p>` with `<p>`
{{someString | escape_html}}
Replace `<p>` with `<p>`
{{someString | unescape_html}}
Replace newline characters with `<br>` tags
{{someString | newline_to_br}}
Replace `<br>` tags with newline characters
{{someString | br_to_newline}}
Reverse a string
{{someString | reverse}}
Replace first occurance of $1 with $2
{{someString | replace_first 'old' 'new'}}
Replace last occurance of $1 with $2
{{someString | replace_last 'old' 'new'}}
Replace all occurances of $1 with $2
{{someString | replace_all 'old' 'new'}}
Prepend a string with another string
{{someString | prepend 'some other string'}}
Append a string with another string
{{someString | append 'some other string'}}
Truncate string to the given number of characters
{{someString | truncate 20}}
Truncate string to the given number of words.
Optionally pass a string as the second parameter, which will be appended if text was indeed truncated.
{{someString | truncate_words 20 '...'}}
Intelligently guesses the time to read the given string in "Mins"
Optionally, override the default units by giving the desired units name as the second parameter.
{{someString | time_to_read "Minutes"}}
Encode string to URL friendly format
{{someString | urlencode}}
Decode string from URL friendly format
{{someString | urldecode}}
Convert colour values `255 0 0` into `#ff0000`
{{someString | rgb2hex}}
Convert colour values `#ff0000` into `255 0 0`
{{someString | hex2rgb}}
Replace string with its md5 checksum
{{someString | md5}}
Replace string with its sha1 checksum
{{someString | sha1}}
Replace string with its sha256 checksum
{{someString | sha256}}
Replace string with its sha512 checksum
{{someString | sha512}}
Data filters
Convert the given markdown to HTML
{{someString | markdown_to_html}}
Convert the given csv to a markdown table
{{someString | csv_to_markdown}}
Convert the given csv to an HTML table
{{someString | csv_to_html}}
Convert the given csv to JSON
{{someString | csv_to_json}}
Convert the given csv to a single, flat, indexed array
{{someString | csv_to_array}}
Convert csv data into an array of associative arrays. The CSV headers become the arrays keys. It can be used to iterate over and filter CSV data in your templates (see Array filters below).
{{someString | csv_to_arrays}}
Number filters
Sets a minimum value for returned numbers
{{someNumber | at_least 10}}
Sets a maximum value for returned numbers
{{someNumber | at_most 10}}
Limit number to the given number of decimal places
{{someNumber | decimal_places 2}}
Divide input by the given number
{{someNumber | divided_by 2}}
Subtract the given number from the input number
{{someNumber | minus 2}}
Add the given number to the input number
{{someNumber | plus 2}}
Find remainder after division of input and given number
{{someNumber | modulo 3}}
Return the given number in ordinal form (112 => 112th)
{{someNumber | ordinal}}
Convert a float to an int
{{someNumber | to_int}}
Round float down to the nearest integer
{{someNumber | floor}}
Round float up to the nearest integer
{{someNumber | ceil}}
Append a singular (first param) or plural (second param) to a number
{{someNumber | pluralize 'ox' 'oxen'}}
Perform unit conversions. Supported conversions: inches/feet, miles/km, kgs/stones, kgs/lbs, gallons/quarts
{{someNumber | convert miles to km}}
Money filters
Converts number to money format, with currency symbol (locale aware).
Optional: give the currency symbol to override the locale default.
{{someNumber | money £}}
If input is `10`, it will output:
£10.00
Converts number to money format, with currency symbol and name (locale aware)
Optional:
- Give a currency symbol as the first parameter to override locale defaults.
- Give a currency name as the second parameter to override locale defaults.
{{someNumber | money_with_currency £ GBP}}
If input is `10`, it will output:
£10.00 GBP
Converts number to money format, without currency symbol or name.
{{someNumber | money_without_currency}}
Remove ".0*" from end of numbers (and strings).
{{someNumber | without_trailing_zeros}}
Date filters
These filters can be used with the variables `page_created` and `page_modified`, or any others which hold dates in this format: 2019-07-13T23:56:01Z
Re-format a date, where `format` is a named format, GNU date format or 'now':
- `basic` => 09/31/2019
- `basic_uk` => 31/09/2019
- `iso8601` => 2019-90-31
- `to_string` => 09 Nov 2019
- `to_long_string` => 09 November 2019
- `rfc822` => Mon, 09 Nov 2019 13:07:54 -0800
- `"%Y %m %d"` => 2019 09 31
- `"%d %B %Y"` => 31 November 2009
{{page_created | date_format 'basic_uk'}}
{{page_created | date_format "%d %B %Y"}}
Note that `rfc822` has these easier aliases:
- `rss`
- `email`
You can also use `now` to get the current date/time when the page is built:
{{now | date_format rss}}
HTML filters
Return the absolute URL to the given file, starting with http://${blog_domain}${blog_url}.
{{someURL | absolute_url}}
Return a relative URL to the given string, starting with "${blog_url}" (top dir of blog).
{{someURL | relative_url}}
Return a relative path to the given file, appended with a timestamp as a query string, for cache busting purposes. Uses `find` to locate the path to the file (if it exists), else it uses the given string.
{{someURL | asset_url}}
Return a `<a href="..">..</a>` tag, linking to the given string.
Works well with these other filters: `asset_url`, `absolute_url`, `relative_url`.
{{someURL | absolute_url | link_tag "My link title"}}
Return a `<time>` tag, with `datetime` attribute. $1 is required and formats the printed (visible) date. $2 is optional, and formats the `datetime` attribute.
Supports the same options as the `date_format` filter: `basic`, `basic_uk`, `to_string`, `email`, and GNU date format strings like `%d %M %Y %H:%M`.
{{someDate | time_tag basic iso8601}}
Outputs:
<time datetime="2019-07-13">13 July, 2019</time>
Return the given content wrapped inside a <script> tag.
{{someString | script_tag}}
Return the given content wrapped inside a <stylesheet> tag.
{{someString | stylesheet_tag}}
Return the given URL wrapped inside an <img> tag.
Optionally set the alt text using the first parameter.
Works well with `asset_url`.
{{someURL | asset_url | img_tag "My alt text."}}
Array filters
Concatenate two arrays (append one to another).
{{#someArray | concat 'otherArrayName'}}
...
{{/someArray}}
Remove empty items from array.
{{#someArray | compact}}
...
{{/someArray}}
Remove duplicate items from array.
{{#someArray | unique}}
...
{{/someArray}}
Limit total items returned to the given number.
{{#someArray | limit 5}}
...
{{/someArray}}
Exclude all items containing the given string.
{{#someArray | exclude 'foo'}}
...
{{/someArray}}
Exclude the first item containing the given string.
{{#someArray | exclude_first 'foo'}}
...
{{/someArray}}
Exclude the last item containing the given string.
{{#someArray | exclude_last 'foo'}}
...
{{/someArray}}
Exclude all items matching the given string exactly.
{{#someArray | exclude_exact 'foo'}}
...
{{/someArray}}
Convert an array into a string delimeted by the given string.
{{#someArray | join_by ','}}
{{.}}
{{/someArray}}
Sort the array 'asc' or 'desc'.
{{#someArray | sort_array 'asc'}}
...
{{/someArray}}
Sort an array by the given key, either ascending or descending.
{{#foreach item in someAssocArray | sort_by someKey desc}}
...
{{/foreach}}
Keep only the array items matching the given string/expression.
Usage of `where`, with associative arrays (hashes):
{{#foreach item in someAssocArray | where someKey '!=' 'foo'}}
...
{{/foreach}}
{{#foreach item in someAssocArray | where someKey 'contains' 'foo'}}
...
{{/foreach}}
{{#foreach item in someAssocArray | where someKey '!=' 'foo'}}
...
{{/foreach}}
{{#foreach item in someAssocArray | where someKey '=' 'foo'}}
...
{{/foreach}}
{{#foreach item in someAssocArray | where someKey '>=' 20}}
...
{{/foreach}}
{{#foreach item in someAssocArray | where someKey '<' 60}}
...
{{/foreach}}
Usage of `where` With simple (indexed) arrays:
{{#someIndexedArray | where contains "Smith" }}
{{.}}
{{/someIndexedArray}}
{{#someIndexedArray | where ">" 20 }}
{{.}}
{{/someIndexedArray}}
Conclusion
Using these filters, you can do even more with your templates - transform date formats on the page, sanitize names, exclude specific items, re-order content and more.
But be aware that using lots of filters will slow down your pages build times.