Replies: 7 comments 3 replies
-
Array of argumentsI like the idea of exposing render tag arguments as an array inside snippets, a bit like Jinja does with call/macro. If we were to call said array {% snippet tabs %}
{% snippet tab %}
<li>
<a href="#tab-{{ name }}">
Tab {{ value }}
</a>
</li>
{% endsnippet %}
<div>
<ul>
{% for argument in arguments %}
{% render tab, name: argument[0], value: argument[1] %}
{% endfor %}
</ul>
</div>
{% endsnippet %}
{% render "tabs", blog: 'some blog', page: 'some page' %}There is a risk that Changing the render tag to accept positional arguments as well as named/keyword arguments might be useful too, but then we'd need to reserve names for two arrays, like |
Beta Was this translation helpful? Give feedback.
-
|
👋🏻 1. Render currently only supports a string as an input, does this proposal include expanding accepted inputs to variables? Or is the proposal limiting variables to just inline snippet declarations? 2. Use-cases for using parent + nested snippets? Interesting part of the proposal! Do you have any real-world examples in mind of where both the parent and nested outputs would be used? Drawing a lot of similarities to JS module default vs named exports. Could be cool to have a 3. Would the new In the above |
Beta Was this translation helpful? Give feedback.
-
|
I think this is a great idea - but I wonder if {% capture header %}
<h1>{{ title }}</h1>
{% if search %}
<div class="nav-search">
<input type="text" placeholder="Search...">
</div>
{% endif %}
{% endcapture %}
<div class="nav-header">
{{ header | args: title: "Main menu", search: true }}
</div>
<div class="nav-header--mobile">
{{ header | args: title: "Main menu" }}
</div> |
Beta Was this translation helpful? Give feedback.
-
|
I completely missed and only noticed it through it getting merged? #2001 @karreiro the ship may have sail but if there's a time to rename this please consider doing so Now add a {% snippet %} TAG to the mix when talking about snippets. This type of overloading ambiguity in words/concepts adds a lot of friction. |
Beta Was this translation helpful? Give feedback.
-
|
I think the issues on naming come from the common issue of being trapped backwards compatibility while torturing the users of your language with outdated syntax. From my personal expierence, the I think the most pure liquid logic i've written (all inside a single {% liquid %} tag was about 500 lines. mostly because of the need for many diferent predicates (lambdas plz). So for really complex liquid logic, i'd probably end up using seperate files anyways. Yes we need safer scope management, this is 2026, but capture with block scoping isn't really that helpfull for most developers doing complex things with liquid. What I most desperately want, and I think many other devs desperately want, is way to create factories to populate the scope. We have capture for modualizing html output, Liquid developers are used to degenerate mutability, introducing a new tag for better scope controll but keeping capture as is, is like putting a single door in the facebook offices and telling people to respect privacy more. Complex liquid code becomes incredibly verbose, I think we mostly want ways to make it less verbose. So if you're not scared about becoming PHP, give us functions. Though I realize that's a whole can of worms you probably don't want to open. If you want to keep to being a templating language, update existing tags in non destructive ways for better developer ergonomics. Implement the update to render so it accepts variables as arguements like you did in the PR you reverted. Add arguement shorthand for render calls. Somethings might be too destructive to do now, like updating capture for scoped variables, but you can use your strict parsing updates to force people to gradually move away from affecting the scope within capture, so that you can eventually make capture safer. Scare merchants into paying us developers to update their ancient themes like you did with the scss deprecation and the webcore vitals dashboard. Tldr, |
Beta Was this translation helpful? Give feedback.
-
|
How about Just like This feels more consistent to me. Both tag names are actions, neither are trying to describe what the block is, like "this is a snippet". A Scope
Note Adding parameters/arguments to Snippet namespace/register I believe blocks defined with Sticking with |
Beta Was this translation helpful? Give feedback.
-
|
I'm happy with the approach in the OP. There's been ideas that have been passed on over the years related to code reuse. The Shopify team's argument has been that it adds complexity for merchants. Has anything changed on this? (FWIW I've always been against that stance and believe this is a big net benefit) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Author: Shopify
Expected end date: March 21st, 2025
Background
Liquid templates can often become quite verbose, with snippets serving as the primary method for reusing code.
Developers frequently need to choose between creating many separate files in a "snippets" directory or managing large and complex Liquid templates. This dilemma can lead to complicated templates and duplication.
For example, when working on a
product.liquidsection, developers frequently break it down into:snippets/product-header.liquidsnippets/product-accordion.liquidsnippets/product-content.liquidsnippets/product-media-modal.liquidsnippets/product-media.liquidsnippets/product-thumbnail.liquidThis approach can clutter the snippets directory with files that are only relevant to a specific template, making the codebase less cohesive, harder to maintain, and to organize, especially as it grows.
Proposal
We propose introducing inline snippets—a feature that allows developers to define and reuse code within the same file. This eliminates the need for additional snippet files when the code is only relevant within a specific context.
Consider the following
snippets/nav.liquidfile:{% snippet header %} <h1>{{ title }}</h1> {% if search %} <div class="nav-search"> <input type="text" placeholder="Search..."> </div> {% endif %} {% endsnippet %} <div class="nav-header"> {% render header, title: "Main menu", search: true %} </div> <div class="nav-header--mobile"> {% render header, title: "Main menu" %} </div>Nested inline snippets
Inline snippets can also be nested and accessed externally, allowing developers to group related snippets into cohesive modules. Here's the updated
snippets/nav.liquidfile:{% snippet header %} <div class="nav-header"> <h1>{{ title }}</h1> {% if search %} <div class="nav-search"> <input type="text" placeholder="Search..."> </div> {% endif %} </div> {% endsnippet %} {% snippet tabs %} {% snippet tab %} <li> <a href="#tab{{ id }}" {% if active %}class="active"{% endif %}> Tab {{ id }} </a> </li> {% endsnippet %} <div> <ul> {% render tab, id: 1, active: true %} {% render tab, id: 2 %} {% render tab, id: 3 %} </ul> </div> {% endsnippet %} {% render header, title: "Main menu", search: true %} {% render tabs %}The
header,tabs, andtabsnippets are defined within the file. Notice that thetabsnippet is accessed using dot notation since it's nested withintabs:{% render tabs %} {% render tabs.tab, id: 4 %}The
snippets/nav.liquidfile can still be rendered entirely or have only a specific snippet within it rendered (for example,"nav.header"):{% render "nav" %} {% render "nav.header", title: "Sub menu", search: false %}By grouping related snippets under a common namespace, developers can organize related snippets together and reduce the number of files.
Call for suggestions
We welcome any feedback or opinions on this proposal. Please share your thoughts by March 21st, 2025. Your input is valuable as we prepare to begin active development on this initiative.
Beta Was this translation helpful? Give feedback.
All reactions