I have a simple collection component that lists the products out in a straightforward card grid. Nothing too complicated or special going on so far. However, the client wants the ability to make ad hoc additions to these card grids with “informational cards” that will just contain some text and an image. The issue that I’m running into is that they want to be able to inject one or more of these cards into specific positions in the grid and I’m really not sure how to do this in Liquid. It feels like it should be possible but it’s definitely pushing the limits of my knowledge and experience with Liquid.
Here’s a few more details:
There’s a collection-grid.liquid section file that allows the author to fill out a couple of text fields and choose a collection to display.
This section allows for one or more “information card” blocks, with fields to choose the position of the card in the grid as well as a metaobject that contains all the data for the card.
I’ve already tried appending the block(s) to the end of the grid and reordering via the grid classes that are available. It works fine when there’s only one card but gets a little confusing when there are two or more.
I’ve blown a few hours attempting to figure how to get the positions for the cards and then somehow split the products array in the right places before putting everything back together. This feels like I’m either finding the limits of what Liquid is capable of or I’m taking the wrong approach.
I would greatly appreciate any advice or feedback. Thank you!
This is definitely a bit advanced. Definitely will need to look at the code. Also specify which product you want where, how it is now and what other info client is looking for. So a more visual representation
Hello again, to anyone who finds this in the future and has a similar need here’s a solution that worked for me. You could pretty easily swap out my “info” card concept with whatever your situation calls for.
{% if section.settings.collection != blank %}
{% liquid
# counts and counters
assign product_card_counter = 0
assign info_card_counter = 0
assign total_card_count = section.settings.collection.products_count | plus: section.blocks.size | minus: 1
# get "expected" position from info card block(s) (re: author will not be thinking in zero-based indexing like we do here in the code)
assign info_card_positions = section.blocks | map: 'settings' | map: 'position'
# create new empty array
assign new_info_card_positions = '' | split: ''
for position in info_card_positions
# convert "expected" positions to zero-based indexing
assign new_position = position | minus: 1
# add position to new array
assign new_position = new_position | sort
# merge everything into a new array for use in ui
assign new_info_card_positions = new_info_card_positions | concat: new_position
endfor
%}
<ul class="your-grid-classes-go-here">
{% for index in (0...total_card_count) %}
<li>
{% liquid
if new_info_card_positions contains index
# render info card at "expected" position
render 'info-card', block: section.blocks[info_card_counter]
# increment info_card_counter
assign info_card_counter = info_card_counter | plus: 1
else
# render product card at "expected" position"
render 'product-card', product: section.settings.collection.products[product_card_counter]
# increment product_card_counter
assign product_card_counter = product_card_counter | plus: 1
endif
%}
</li>
{% endfor %}
</ul>
{% endif %}
Thank you for your response! I ended up solving this over the weekend and posted my solution. If you have any feedback I’d still love to hear it - as would any future travelers.