Liquid: Can I get a random element from an Array?

后端 未结 6 935
甜味超标
甜味超标 2021-02-13 10:49

I\'m trying to pick a random element from an array -- is this possible using Liquid/Jekyll?

I can create an array -- and access a given index ... but is there a way to \

相关标签:
6条回答
  • 2021-02-13 11:07

    You may be able to do that just in Liquid, but it could less of generic solution like the one provided by @Brendan. According to this article, you can generate a random liquid number between min & max. So simply:

    • Assign the min to 0 and max to your array's length.
    • Loop over the array till you find your random number and pick you element.

    Here is an example, get your random array index:

    {% assign min = 0 %}
    {% assign max = prefix.size %}
    {% assign diff = max | minus: min %}
    {% assign randomNumber = "now" | date: "%N" | modulo: diff | plus: min %}
    

    Then find your random value:

    {{ prefix[randomNumber] }}
    
    0 讨论(0)
  • 2021-02-13 11:27

    Liquid doesn't have a filter for picking a random element from an array or an integer interval.

    If you want Jekyll to do that, you would have to create an extension to add that liquid filter.

    However, I must point out that doing so would pick a random element every time the page is generated, but not every time the page is viewed.

    If you want to get different random values every time you visit a page, your best option is using javascript and letting the client pick a random value. You can use liquid to generate the relevant javascript though.

    0 讨论(0)
  • 2021-02-13 11:28

    You could adapt Liquid::Drop and whitelist Ruby's sample method.

    See https://github.com/Shopify/liquid/blob/master/lib/liquid/drop.rb#L69:

    You would need to change:

    blacklist -= [:sort, :count, :first, :min, :max, :include?]
    

    to:

    blacklist -= [:sort, :count, :first, :min, :max, :include?, :sample]
    

    Next you could just use:

    {{ some_liquid_array.sample }}   
    
    0 讨论(0)
  • 2021-02-13 11:29

    Without using a plugin (which might be a requirement if you are using github pages for example) and don't want the choice to be set only at build/rebuild time.

    This uses collections as it's data source and some feature flags set in the page front matter.

    {% if page.announcements %}
        <script>
            // homepage callout
            var taglines=[ 
             {% for txt in site.announcements %} 
               {{ txt.content | markdownify | jsonify | append: "," }}
            {% endfor %}
            ]
            var selection = document.querySelector('#tagline') !== null;
            if(selection) {
                document.querySelector('#tagline').innerHTML = taglines[ Math.floor(Math.random()*taglines.length) ];
            }
         </script>
    {% endif %}
    

    I use markdownify to process the content, jsonify to make it JavaScript safe and then append a comma to make my array.

    The Javascript then populates one randomly at page load.

    Add collection to config.yml

    collections:
       announcements:
    

    Add flag to page

    ---
    layout: home
    title: 
    slider: true
    announcements: true    
    ---
    

    collection content item (test.md)

    ---    
    published: true
    ---
    
    This is a test post
    
    0 讨论(0)
  • 2021-02-13 11:31

    The 2018 answer is

    {% assign prefix = page.prefix | sample: 2 %}
    {{ prefix[0] }}
    

    As the OP asked about Jekyll, this can be found at: https://jekyllrb.com/docs/templates/

    0 讨论(0)
  • 2021-02-13 11:33

    You can create a plugin to get a random element. Something like this:

    module Jekyll
      module RandomFilter
        # Use sample to get a random value from an array
        #
        # input - The Array to sample.
        #
        # Examples
        #
        #   random([1, 2, 3, 4, 5])
        #   # => ([2])
        #
        # Returns a randomly-selected item out of an array.
        def random(input)
          input.sample(1)
        end
      end
    end
    
    Liquid::Template.register_filter(Jekyll::RandomFilter)
    

    Then do something like this in your template to implement:

    {% assign myArray = '1|2|3|4|5 | split: '|' %}
    {% assign myNumber = myArray | random %}
    
    0 讨论(0)
提交回复
热议问题