Add all elements from a for loop to an array

I need to get an array of future posts and combine that with the latest post.

Here is my code to get future posts:

{%- assign futurePosts = site.posts | where_exp: 'post', ' >= site.time' -%}

Now here is the problem, I cannot do this to get the latest post:

{%- assign latestPost = site.posts | limit: 1 -%}

Instead, I have to get the latest post this way:

{%- assign posts = site.posts -%}
    {%- for post in validPosts limit: 1 -%}
    {%- endfor -%}

Ideally, I would like to take the post and concatenate that into the futurePosts array, but post is now a variable. I know I could manually select the items in post and add them to the futurePosts array, but then that manual effort will mean if my YAML front matter ever changes, I need to update the code.

Is there a way to get the latest post and concatenate that to another array of posts?


1 Like

not sure I understand this - but just to make sure - if you are saying for POST in validposts.. - you could change that to item instead of post - or it could be anything. Pretty sure you know that, just making sure.

You can concatenate in a few ways. I think this may help as I am doing something similar on my site. I have an array of property posts, and want to find the ones that are a certain category and have been updated (have a value in the update front matter) in the past month. I capture a string of HTML as I go through the loop so I can count it all at the end and use that for a CSS class.

Maybe an idea in here can help you out. The concatenation happens in the {% capture construct_html %} part, where I include whatever value {{ construct_html }} had previously and add the new output.

{%- assign construction = | where: "categories", "#WhatAreTheyBuilding" | sort: "date-modified" | reverse -%}
{%- assign lastmonth = "now" | date: '%s' | minus: 2592000 | date: '%Y%m%d' | times:1 -%}
{%- assign construct_count = 0 -%}
{%- assign construct_html = '' -%}
{%- for item in construction -%}
  {% assign itemdate = | date: '%Y%m%d' | times:1 %}
  {% if itemdate > lastmonth %}
    {% if item.update %}
    {% else %}
      {% capture construct_html %}
        {{ construct_html }}
        {% include property-card.html %}
      {% endcapture %}
      {% assign construct_count = construct_count | plus: 1 %}
    {% endif %}
  {% endif %}
{%- endfor -%}
  <h2 class="o__title--sm v-rhythm">#WhatAreTheyBuilding: Under Construction</h2>
  <ul class="taxonomy__list taxonomy__list--vertical taxonomy__list--vertical--{{ construct_count }} u__list__unstyled u__vertical__pb" role="list">
    {{ construct_html }}

@jhogue, thank you for the idea! I think this became too complex a solution, so here is how I ultimately resolved the problem.

I create two for loops to get the data I want to work with and then use the same business logic for each by using an include file. Here are the two items you might see on my page:

To work with future posts:

{%- assign posts = site.posts | where_exp: 'post', ' > site.time' -%}
{%- for post in posts -%}
  {%- include my-liquid-business-logic.html -%}
{%- endfor -%}

To work with the current latest post:

{%- assign posts = site.posts | where_exp: 'post', ' < site.time' -%}
{%- for post in posts limit: 1 offset: 0-%}
  {%- include my-liquid-business-logic.html -%}
{%- endfor -%}

Ideally, Jekyll offers the ability to get the latest post into an array by providing the limit and offset within assign, but at least this method works and is less troublesome than trying to fill an array with a “non-array” :slight_smile:

Thanks again!