how to pad a string in jekyll? - ruby

Say I'm incrementing an integer like this
{% capture page %}{{ page | plus: '1' }}{% endcapture %}
How could I pad it like this?
{% capture paddedPage %}{{ page | pad '0', 4 }}{% endcapture %}
where 4 is number of padding places, and '0' is the padding string? The end result would look like this: 0001 where the value of page is 1. How might I do this inline or in a filter?
I guess it could be represented like sprintf( '%d4', page ) but obviously this syntax does not work with liquid/jekyll.
I'm growing really disappointed in jekyll/liquid syntax (does not even have native modulus!) That aside, how might I pad a string with leading characters?

Use liquid filter prepend and slice, like this:
{{ page | prepend: '0000' | slice: -4, 4 }}

With Liquid you can do :
{% assign pad = 4 %}
{% assign padStr = '0' %}
{% assign numbers = "1|12|123|1234" | split: "|" %}
{% for number in numbers %}
{% assign strLength = number | size %}
{% assign padLength = pad | minus: strLength %}
{% if padLength > 0 %}
{% assign padded = number %}
{% for position in (1..padLength) %}
{% assign padded = padded | prepend: padStr %}
{% endfor %}
<p>{{ number}} padded to {{ padded }}</p>
{% else %}
<p>{{ number}} no padding needed</p>
{% endif %}
{% endfor %}
Note : Liquid modulus filter is {{ 12 | modulo: 5 }}

Related

Transform Jekyll "reading time" into "page rating calculation"

I want to transform following Jekyll "reading time" calculator
<span class="reading-time">
{% capture words %}
{{ content | number_of_words | minus: 180 }}
{% endcapture %}
{% unless words contains “-” %}
{{ words | plus: 180 | divided_by: 180 |
append: “minutes to read” }}
{% endunless %}
</span>
into "page rating" with the following meta taken from page Front matter using following formula
{{ page.facebook }}
plus
{{ page.instagram }}
multiply
{{ page.age }}
divide
1000 000
multiply {{ content | number_of_words }}
divide
100 =
More details here
This can do the trick :
{% assign number_of_words = content | strip_html | number_of_words %}
{% assign social = page.facebook | plus: page.instagram %}
{% comment %}Two lines for readability, but can be chained on one line{% endcomment %}
{% assign Indexmod = social | times: page.age | divided_by: 1000000.0 %}
{% assign Indexmod = Indexmod | times: number_of_words | divided_by: 100 %}
Note :
the use of strip_html, this avoid counting html as words.
the use of 'divided_by: 1000000.0' to cast result to a Float

Jekyll page rating calculator with meta from Front Mater area

I am editing include/span with the following code pretend to be as "Jekyll page rating calculator with meta from Front Mater area" but it seems like some syntax missing an extra heading/lines to let calculation to display in left bottom round quotes. Now there is no value
See the sampl page
<span class="indexmod">
{% assign number_of_words = content | strip_html | number_of_words %}
{% assign social = page.facebook | plus: page.instagram %}
{% comment %}Two lines for readability, but can be chained on one line{%
endcomment %}
{% assign Indexmod = social | times: page.age | divided_by: 1000000.0 %}
{% assign Indexmod = Indexmod | times: number_of_words | divided_by: 100
%}
{% endunless %}
</span>
There are two reasons why this doesn't work:
The {% endunless %} in this include is missing a matching unless clause. Either add one or remove the endunless line.
The value of Indexmod is not printed. You can do that by adding {{ Indexmod }} after your calculations are done.

if else liquid statement shopify featured image

I want to show the featured image of the product if it has no variants attributed to it, but if it does, I want to show the selected variant image via the product.selected_or_first_available_variant.image object.
However despite numerous attempts, on product pages with no variants I get the no image thumbnail which looks like this: http://cdn.shopify.com/s/assets/no-image-2048-5e88c1b20e087fb7bbe9a3771824e743c244f437e4f8ba93bbf7b11b53f7824c.gif
These are the three approaches I have attempted below:
{% if product.variants.price < 1 %}
{% assign featured_image = product.featured_image | img_url: 'master' %}
{% else %}
{% assign featured_image = product.selected_or_first_available_variant.image | img_url: 'master' %}
{% endif %}
{% if product.variants.price == 0 %}
{% assign featured_image = product.featured_image | img_url: 'master' %}
{% else %}
{% assign featured_image = product.selected_or_first_available_variant.image | img_url: 'master' %}
{% endif %}
{% if product.variants.price == 'null' %}
{% assign featured_image = product.featured_image | img_url: 'master' %}
{% else %}
{% assign featured_image = product.selected_or_first_available_variant.image | img_url: 'master' %}
{% endif %}
None of them work. Why? What do I need to do to get value of no variants?
ALSO: I just tried "undefined" - didn't work either.
{% if product.variants.price == 'undefined' %}...
You can simply use .
{% if product.has_only_default_variant %}
You can see it in action here: product-has_only_default_variant

FInd last matched element using Liquid

I'm working on custom solution for Shopify store and my problem is that I can't manage how to avoid adding ' / ' after the last matched tag in the case statement.
I've tried to use some if statements with a forloop filters with no result.
The last thing on my mind was finding the last matched tag in the loop that will help us avoiding ' / ' after the last element, but unfortunately I can't manage how to do that.
Expected result: Wool/Nylon/Viscose
Here is the part of the code that compares all tags assigned to the product with the list of tags(clothing materials) required for the output.
Considering that product has such tags as Wool, Nylon and Viscose and others, non material.
Example 1
Actual & Expected Result: WoolNylonViscose
{% for tag in product.tags %}
{% case tag %}
{% when 'Viscose' %}
Viscose
{% when 'Wool' %}
Wool
{% when 'Polyamide' %}
Polyamide
{% when 'Nylon' %}
Nylon
{% else %}
{% endcase %}
{% endfor %}
Example 2
Filter forloop.last was used to define the last element of the loop, but the problem is that material tags(Wool, Nylon, Viscose) can be in the middle of the product tag array. Considering product has 10 tags and material tags are spread among the array we will see next result.
Result: ///Wool/Nylon////Viscose//
{% for tag in product.tags %}
{% if forloop.last == true %}
{% case tag %}
{% when 'Viscose' %}
Viscose
{% when 'Wool' %}
Wool
{% when 'Nylon' %}
Nylon
{% else %}
{% endcase %}
{% else %}
{% case tag %}
{% when 'Viscose' %}
Viscose
{% when 'Wool' %}
Wool
{% when 'Nylon' %}
Nylon
{% else %}
{% endcase %}
/
{% endif %}
{% endfor %}
I would appreciate if you could please point on my mistakes and suggest me how can i achieve solution.
This should work:
{% capture tag_string %}{% endcapture %}
{% for tag in product.tags %}
{% if tag == 'Viscose' %}{% capture tag_string %}{{ tag_string }}Viscose/{% endcapture %}
{% elsif tag == 'Wool' %}{% capture tag_string %}{{ tag_string }}Wool/{% endcapture %}
{% elsif tag == 'Polyamide' %}{% capture tag_string %}{{ tag_string }}Polyamide/{% endcapture %}
{% elsif tag == 'Nylon' %}{% capture tag_string %}{{ tag_string }}Nylon/{% endcapture %}
{% endif %}
{% endfor %}
{{ tag_string | split: "" | reverse | join: "" | remove_first: "/" | split: "" | reverse }}
More on string filters: https://help.shopify.com/themes/liquid/filters/string-filters
You can try the following:-
{% for tag in product.tags %}
{% case tag %}
{% when 'Viscose' %}
{{ 'Viscose' | append: '/' }}
{% when 'Wool' %}
{{ 'Wool' | append: '/' }}
{% when 'Polyamide' %}
{{ 'Polyamide' | append: '/' }}
{% when 'Nylon' %}
{{ 'Nylon' }}
{% else %}
{% endcase %}
{% endfor %}

Jekyll custom date

I want use bellow code to display custom date in my Jekyll site
{% assign m = page.date | date: "%-m" %}
{% case m %}
{% when '1' %}Januar
{% when '2' %}Februar
{% when '3' %}März
{% when '4' %}April
{% when '5' %}Mai
{% when '6' %}Juni
{% when '7' %}Juli
{% when '8' %}August
{% when '9' %}September
{% when '10' %}Oktober
{% when '11' %}November
{% when '12' %}Dezember
{% endcase %}
But I don't now where to put it (I tried in post.html but does not work)
I've made a template for this.
This template translate a date in a specific language. Here it's french but feel free to change month and day arrays.
This template can be used in an enumeration of post/page (eg: the index page) or in a post/page template.
When used in an enumeration, you need to pass the date to process
{% for post in site.posts %}
<li>
<span class="post-date">{% include custom_date_full_fr.html date = post.date %}</span>
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
</li>
{% endfor %}
Where used in a page/post template, you just have to include the template, as the page.date will already be available.
{% include custom_date_full_fr.html %}
custom_date_full_fr.html
{% if include.date %}
{% assign processed_date = include.date %}
{% else if page.date %}
{% assign processed_date = page.date %}
{% endif %}
{% comment %}-------- Test if we have a date to process --------{% endcomment %}
{% if processed_date %}
{% assign month = "janvier,février,mars,avril,mai,juin,juillet,août,septembre,octobre,novembre,décembre" | split: "," %}
{% comment %}------ Note : sunday is the first day in this array -------{% endcomment %}
{% assign day = "dimanche,lundi,mardi,mercredi,jeudi,vendredi,samedi" | split: "," %}
{% assign month_index = processed_date | date: "%m" | minus: 1 %}
{%comment%}----------------------------------------------
Here **minus: 0** is a trick to convert day_index from string to integer and then use it as an array index.
----------------------------------------------{%endcomment%}
{% assign day_index = processed_date | date: "%w" | minus: 0 %}
{%comment%}-------- Output the date ----------{%endcomment%}
{{ day[day_index] }} {{ processed_date | date: "%d" }} {{ month[month_index] }} {{ processed_date | date: "%Y" }}
{% endif %}
See here for more info :
Jekyll Date Formatting Examples by Alan W. Smith
Liquid documentation - date filters

Resources