Shopify / Shopify/liquid

New Object Feature brainstorm

Open
#1,237 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Ruby
Stars
11.9k
Forks
1.5k
Avg merge
17h 55m
Merged PRs (30d)
3

Description

So quick rant and proposal followed by use cases and reasoning. I would like to propose a new feature I am going to refer to as "masks" for liquid objects.

What is a mask? A mask is a object modifier that takes a liquid object and returns a new masked one only using passed values and globals. The idea is to be able to create new attributes/modify existing ones for objects in a consistent, predictable, and repeatable manner. An example of this would be

mask product_with_avg_price:

     {{old_object}}
     {% assign new_object = {} %} #no idea what the correct syntax is here
     {{assign counter = 0}}
     {{assign pricing = 0 }}
     {for price in old_object.variants.variant.price}
          {counter = counter | plus 1}
          {pricing = pricing | plus price}
     {end for}
     {%assign return_object.avg_price = pricing | divide_by : counter %}
     {% return_pointer = new_object %}

products.liquid:

     {% mask "product_with_avg_price", old_object = product, return_pointer = new_object_pointer %} 

     {{new_object_pointer.avg_price}}

This would allow us to encapsulate website wide object logic into the objects themselves instead of into externally referenced snippets and render functions. Further this would cut down on the number of local variables in the template and snippet sections as the ones used to calculate values would be moved into the mask scope and could be discarded after calculation. I believe the masks could also be cached with a high hit rate and may help speed up page load if we where to restrict them to global scoped variables only. Most importantly this greatly increase developers flexibility within platforms using liquid. Being able to create new object scopes allows for a wide variety of applications without having to expose to much to external parties.

A few uses cases from our own code base in shopify. Product status, Product compare at price, Collection filter options, Custom Json objects, ect.

Product status and compare at price are values that need to be calculated for each product and are used anytime a product is shown on our site. Being able to ensure the same value we calculate at the homepage is the values we calculate at the collection page would be extremely helpful and creates enforceable consistency.

Now technically we can emulate some of this behavior right now with render but it would require a lot of reworking our snippets to make them load from product view down. As well as force us to either needlessly calculate values, have ugly if else statements to pass caller references to ensure we only calculate what we need to each time, or separate the calculations into different render snippets. Being able to mask our objects would be much more easily transferable to most liquid code as it would simply require you to replace the template and snippet file references. You would not even need to remove old calculations allowing for users to test the feature out in a piecemeal fashion.

Anyway let me know what yall think. I read a fair amount of the codebase here but I do not write in ruby so if I am missing some implementation details that would make this impossible or not very efficient I apologize. Really just looking for feedback and if this is something that seems interesting to do.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The issue names Liquid objects, masks, render, and snippets but no source files or tests. Start by examining the existing render and snippet behavior, then define the mask syntax, scoping, and caching requirements; done would require an agreed design and tests for the behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
ruby
Domain
web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.