At this point, you have most likely come to learn that, any time your client asks for a “quick update” or a really “simple fix” it’s never actually quick or simple. Sometimes it might seem like it is, but rarely EVER is it actually quick or simple. Sometimes it might even seem quick and simple to you until you get into it and realize it will take way more work than you expected.
Let’s say someone comes to you with this request:
“I have a really quick request I was hoping you could take care of by EOW. I would like to have a bit of randomly generated text show up in a box on my Shopify site, from a list of 5 to 10 phrases that we have set up in a spreadsheet. Can you get to that?”
Doesn’t that seem like a “simple request”? Well even if it may seem simple, it isn’t, because unfortunately, Shopify doesn’t have this as a default function anywhere. Lucky for you, rather than you spending all day messing with code and trying to figure this out by EOW, I’ve got the work-around for you to be done by EOD!
Time to dig into the code...
- Let’s use an example where we add a section that contains a simple block type containing a single text field. First off, we set these up in the page template, like so...
{% schema %}
{
"name": "Random Content",
"blocks": [{
"type": "paragraph",
"name": "Paragraph",
"settings": [{
"type": "text",
"id": "paragraph",
"label": "Paragraph"
}]
}]
}
{% endschema %}
- Next we add 5 blocks, each containing unique text...
- Now that we’ve got the 5 pieces of content added, we add the code that chooses one at random and displays it every time the page loads.
{% assign min = 0 %}
{% assign max = section.blocks.size %}
{% assign diff = max | minus: min %}
{% assign randomNumber = "now" | date: "%N" | modulo: diff | plus: min %}
{% for block in section.blocks %}
{% if forloop.index0 == randomNumber %}
{{ block.settings.paragraph }}
{% endif %}
{% endfor %}
- The way we do this is to generate a random number from 1 to the number of blocks present (5 in this case) and then we display the block with the index of the random number.
- We use the min and max variables to define the lower and upper bounds of the possible random number that we generate. The min variable is always 0 in this case, and the max variable is assigned the value of the number of blocks in the section. The diff variable is the difference from subtracting min from max.
- Where the real magic happens, is the way we create the randomNumber variable. First we get the current time using the “now” keyword. That is then converted to seconds using the date filter. Next we apply the modulo filter to divide the seconds value by the diff value before finally adding the min value, which ensures that we always get a unique value.
- Now that we’ve got our random number generated, the final step is to display the paragraph of text inside the block at the matching index. In order to accomplish this, we loop through the blocks and get the block with the index that matches the randomNumber value. Before we move forward, it is Important to note that we use the forloop.index0 method here because by default Shopify’s loops start with an index of 1, but our min variable is 0, so we need Shopify’s loop to match that. When it finds the block in question, it outputs the paragraph that it has randomly chosen on page load.
- There is one final caveat to mention: Shopify’s cache. While this method works perfectly fine in concept, in reality, because Shopify caches pages, it means that sometimes the randomly generated content is also cached and so therefore this is not 100% truly random every time. This may or may not be a critical issue, depending on your use case. If it is critical that you have a truly random result on every single page load then there is another alternate route that you can take: javascript.
- Instead of performing the random number generation inside the template using liquid code, this method uses javascript and jquery to do it instead. So we change our page template output code to look like this
<ul>
{% for block in section.blocks %}
<li>{{ block.settings.paragraph }}</li>
{% endfor %}
</ul>
- Instead we output all blocks as a list. We then hide them all by default with this CSS.
ul li { display: none; }
- Then we add this javascript to choose which list item to display on page load
var min = 0;
var max = {{ section.blocks.size }} - 1;
var randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
$('ul li').eq(randomNumber).css('display', 'block');
And viola! You’ve got your random number generated, with a choose your own adventure when it comes to code preference. Simple, isn’t it?