<!-- AUTO-GENERATED — do not edit directly. Edit src/data/raw-api-instructions/{api}.md in shopify-dev-tools, then run: npm run generate_agent_skills (outputs to distributed-agent-skills/) -->
name: shopify-liquid description: "Liquid est un langage de templating open-source créé par Shopify. C'est la base des thèmes Shopify et il est utilisé pour charger du contenu dynamique sur les vitrines. Keywords: liquid, theme, shopify-theme, liquid-component, liquid-block, liquid-section, liquid-snippet, liquid-schemas, shopify-theme-schemas" compatibility: Claude Code, Claude Desktop, Cursor metadata: author: Shopify
Votre tâche
Vous êtes un développeur expérimenté de thèmes Shopify. Implémentez les demandes des utilisateurs en générant des composants de thème qui sont conformes aux « Principes clés » et à l'« Architecture du thème ».
Architecture du thème
Principes clés : concentrez-vous sur la génération de snippets, blocks et sections ; les utilisateurs peuvent créer des templates à l'aide de l'éditeur de thème
Structure de répertoires
.
├── assets # Stocke les ressources statiques (CSS, JS, images, polices, etc.)
├── blocks # Composants réutilisables, imbriquables et personnalisables
├── config # Paramètres globaux du thème et options de personnalisation
├── layout # Wrappers de niveau supérieur pour les pages (modèles de layout)
├── locales # Fichiers de traduction pour l'internationalisation du thème
├── sections # Composants de page modulaires pleine largeur
├── snippets # Fragments de code Liquid réutilisables ou fragments HTML
└── templates # Templates combinant sections et blocks pour définir les structures de page
sections
- Les sections sont des fichiers
.liquidqui vous permettent de créer des modules réutilisables pouvant être personnalisés par les commerçants - Les sections peuvent inclure des blocks qui permettent aux commerçants d'ajouter, de supprimer et de réorganiser le contenu dans une section
- Les sections sont rendues personnalisables en incluant la balise
{% schema %}requise qui expose les paramètres dans l'éditeur de thème via un objet JSON. Validez cet objet JSON en utilisant le schéma JSONschemas/section.json - Exemples de sections : bannières héros, grilles de produits, témoignages, collections en vedette
blocks
- Les blocks sont des fichiers
.liquidqui vous permettent de créer de petits composants réutilisables pouvant être personnalisés par les commerçants (ils n'ont pas besoin de s'adapter à la largeur complète de la page) - Les blocks sont idéaux pour la logique qui doit être réutilisée et également modifiée dans l'éditeur de thème par les commerçants
- Les blocks peuvent inclure d'autres blocks imbriqués qui permettent aux commerçants d'ajouter, de supprimer et de réorganiser le contenu dans un block aussi
- Les blocks sont rendus personnalisables en incluant la balise
{% schema %}requise qui expose les paramètres dans l'éditeur de thème via un objet JSON. Validez cet objet JSON en utilisant le schéma JSONschemas/theme_block.json - Les blocks doivent avoir la balise
{% doc %}en tant qu'en-tête si vous les rendez directement/statiquement dans un autre fichier via{% content_for 'block', id: '42', type: 'block_name' %} - Exemples de blocks : témoignages individuels, diapositives dans un carrousel, éléments de fonctionnalité
snippets
- Les snippets sont des fragments de code réutilisables rendus dans les fichiers blocks, sections et layouts via la balise
render - Les snippets sont idéaux pour la logique qui doit être réutilisée mais pas directement modifiée dans l'éditeur de thème par les commerçants
- Les snippets acceptent des paramètres lors du rendu pour un comportement dynamique
- Les snippets doivent avoir la balise
{% doc %}en tant qu'en-tête - Exemples de sections : boutons, balises meta, variables CSS et éléments de formulaire
layout
- Définit la structure HTML globale du site, y compris
<head>et<body>, et enveloppe d'autres templates pour fournir un cadre cohérent - Contient des éléments globaux répétés comme la navigation, le tiroir du panier, le pied de page, et inclut généralement des ressources CSS/JS et des balises meta
- Doit inclure
{{ content_for_header }}pour injecter les scripts Shopify dans le<head>et{{ content_for_layout }}pour rendre le contenu de la page
config
config/settings_schema.jsonest un fichier JSON qui définit le schéma des paramètres globaux du thème. Validez la forme de ce fichier JSON en utilisant le schéma JSONschemas/theme_settings.jsonconfig/settings_data.jsonest un fichier JSON qui contient les données pour les paramètres définis parconfig/settings_schema.json
assets
- Contient des fichiers statiques comme CSS, JavaScript et images, y compris les ressources compilées et optimisées, référencées dans les templates via le filtre
asset_url - Conservez-y uniquement
critical.csset les fichiers statiques nécessaires pour chaque page, sinon préférez l'utilisation des balises{% stylesheet %}et{% javascript %}
locales
- Stocke les fichiers de traduction organisés par code de langue (par exemple,
en.default.json,fr.json) pour localiser tout le contenu de thème visible par l'utilisateur et les chaînes d'éditeur - Active la prise en charge multilingue en fournissant des traductions accessibles via des filtres comme
{{ 'key' | t }}en Liquid pour une internationalisation appropriée - Validez les fichiers JSON
localesen utilisant le schéma JSONschemas/translations.json
templates
- Fichier JSON qui définit la structure, l'ordre et les sections et blocks qui apparaissent sur chaque type de page, permettant aux commerçants de personnaliser les mises en page sans modifications de code
CSS & JavaScript
- Écrivez CSS et JavaScript par composants en utilisant les balises
{% stylesheet %}et{% javascript %} - Remarque :
{% stylesheet %}et{% javascript %}ne sont supportées que danssnippets/,blocks/etsections/
LiquidDoc
Les snippets et blocks (quand les blocks sont rendus statiquement) doivent inclure l'en-tête LiquidDoc qui documente l'objectif du fichier et les paramètres requis. Exemple :
{% doc %}
Renders a responsive image that might be wrapped in a link.
@param {image} image - The image to be rendered
@param {string} [url] - An optional destination URL for the image
@example
{% render 'image', image: product.featured_image %}
{% enddoc %}
<a href="{{ url | default: '#' }}">{{ image | image_url: width: 200, height: 200 | image_tag }}</a>
La balise {% schema %} sur les blocks et sections
Principes clés : suivez les « Bonnes pratiques » et « Validez le contenu de {% schema %} en utilisant des schémas JSON**
Bonnes pratiques
Lors de la définition de la balise {% schema %} sur les sections et blocks, suivez ces lignes directrices pour utiliser les valeurs :
Paramètres de propriété unique : Pour les paramètres qui correspondent à une seule propriété CSS, utilisez les variables CSS :
<div class="collection" style="--gap: {{ block.settings.gap }}px">
Example
</div>
{% stylesheet %}
.collection {
gap: var(--gap);
}
{% endstylesheet %}
{% schema %}
{
"settings": [{
"type": "range",
"label": "gap",
"id": "gap",
"min": 0,
"max": 100,
"unit": "px",
"default": 0,
}]
}
{% endschema %}
Paramètres de propriétés multiples : Pour les paramètres qui contrôlent plusieurs propriétés CSS, utilisez les classes CSS :
<div class="collection {{ block.settings.layout }}">
Example
</div>
{% stylesheet %}
.collection--full-width {
/* multiple styles */
}
.collection--narrow {
/* multiple styles */
}
{% endstylesheet %}
{% schema %}
{
"settings": [{
"type": "select",
"id": "layout",
"label": "layout",
"values": [
{ "value": "collection--full-width", "label": "t:options.full" },
{ "value": "collection--narrow", "label": "t:options.narrow" }
]
}]
}
{% endschema %}
Mises en page mobiles
Si vous avez besoin de créer une mise en page mobile et que vous voulez que le commerçant puisse sélectionner une ou deux colonnes, utilisez une entrée select :
{% schema %}
{
"type": "select",
"id": "columns_mobile",
"label": "Columns on mobile",
"options": [
{ "value": 1, "label": "1" },
{ "value": "2", "label": "2" }
]
}
{% endschema %}
Liquid
Délimiteurs Liquid
{{ ... }}: Sortie – imprime une valeur.{{- ... -}}: Sortie, supprime les espaces autour de la valeur.{% ... %}: Balise logique/contrôle (if, for, assign, etc.), n'imprime rien, pas de suppression d'espaces.{%- ... -%}: Balise logique/contrôle, supprime les espaces autour de la balise.
Conseil :
Ajouter un tiret (-) après {%/{{ ou avant %}/}} supprime les espaces ou sauts de ligne à côté de la balise.
Exemples :
{{- product.title -}}→ imprime la valeur, supprime les espaces ou lignes environnantes.{%- if available -%}In stock{%- endif -%}→ logique, supprime les espaces/lignes supplémentaires.
Opérateurs Liquid
Opérateurs de comparaison :
- ==
- !=
-
- <
-
=
- <=
Opérateurs logiques :
orandcontains- vérifie si une chaîne contient une sous-chaîne, ou si un tableau contient une chaîne
Balises de comparaison et de comparaison
Principes de condition clés :
- Pour la simplicité, TOUJOURS utiliser des conditions
ifimbriquées quand la logique nécessite plus d'un opérateur logique - Les parenthèses ne sont pas supportées en Liquid
- Les conditionnelles ternaires ne sont pas supportées en Liquid, utilisez toujours
{% if cond %}
Exemple de comparaison basique :
{% if product.title == "Awesome Shoes" %}
These shoes are awesome!
{% endif %}
Conditions multiples :
{% if product.type == "Shirt" or product.type == "Shoes" %}
This is a shirt or a pair of shoes.
{% endif %}
Utilisation de Contains :
- Pour les chaînes :
{% if product.title contains "Pack" %} - Pour les tableaux :
{% if product.tags contains "Hello" %} - Remarque :
containsfonctionne uniquement avec les chaînes, pas les objets dans les tableaux
{% elsif %} (utilisé uniquement à l'intérieur de if/unless)
{% if a %}
...
{% elsif b %}
...
{% endif %}
{% unless %}
{% unless condition %}
...
{% endunless %}
{% case %}
{% case variable %}
{% when 'a' %}
a
{% when 'b' %}
b
{% else %}
other
{% endcase %}
{% else %} (utilisé à l'intérieur de if, unless, case ou for)
{% if product.available %}
In stock
{% else %}
Sold out
{% endif %}
ou à l'intérieur d'une boucle for :
{% for item in collection.products %}
{{ item.title }}
{% else %}
No products found.
{% endfor %}
Variables et balises de variables
{% assign my_variable = 'value' %}
{% capture my_variable %}
Contents of variable
{% endcapture %}
{% increment counter %}
{% decrement counter %}
Filtres Liquid
Vous pouvez enchaîner des filtres en Liquid, en passant le résultat d'un filtre comme entrée au suivant.
Voir ces filtres :
upcase:{{ string | upcase }}retourne une chaînesplit:{{ string | split: string }}retourne un tableau (comme on peut le remarquer dans la doc,splitreçoit une chaîne comme argument)last:{{ array | last }}retourne non typé
Chaque filtre peut passer sa valeur de retour au filtre suivant tant que les types correspondent.
Par exemple, upcase retourne une chaîne, qui est une entrée appropriée pour split, qui produit ensuite un tableau pour que last l'utilise.
Voici comment les filtres sont exécutés étape par étape pour finalement retourner "WORLD" :
{{ "hello world" | upcase | split: " " | last }}
- Premièrement,
"hello world"est converti en majuscules :"HELLO WORLD", qui est une chaîne - Ensuite,
splitpeut agir sur les chaînes, donc il divise la valeur par un espace en un tableau :["HELLO", "WORLD"] - Enfin, le filtre
lastfonctionne avec un tableau, donc"WORLD"est retourné
Tableau
compact:{{ array | compact }}retournearrayconcat:{{ array | concat: array }}retournearrayfind:{{ array | find: string, string }}retournenon typéfind_index:{{ array | find_index: string, string }}retournenumberfirst:{{ array | first }}retournenon typéhas:{{ array | has: string, string }}retournebooleanjoin:{{ array | join }}retournestringlast:{{ array | last }}retournenon typémap:{{ array | map: string }}retournearrayreject:{{ array | reject: string, string }}retournearrayreverse:{{ array | reverse }}retournearraysize:{{ variable | size }}retournenumbersort:{{ array | sort }}retournearraysort_natural:{{ array | sort_natural }}retournearraysum:{{ array | sum }}retournenumberuniq:{{ array | uniq }}retournearraywhere:{{ array | where: string, string }}retournearray
Panier
item_count_for_variant:{{ cart | item_count_for_variant: {variant_id} }}retournenumberline_items_for:{{ cart | line_items_for: object }}retournearray
Collection
link_to_type:{{ string | link_to_type }}retournestringlink_to_vendor:{{ string | link_to_vendor }}retournestringsort_by:{{ string | sort_by: string }}retournestringurl_for_type:{{ string | url_for_type }}retournestringurl_for_vendor:{{ string | url_for_vendor }}retournestringwithin:{{ string | within: collection }}retournestringhighlight_active_tag:{{ string | highlight_active_tag }}retournestring
Couleur
brightness_difference:{{ string | brightness_difference: string }}retournenumbercolor_brightness:{{ string | color_brightness }}retournenumbercolor_contrast:{{ string | color_contrast: string }}retournenumbercolor_darken:{{ string | color_darken: number }}retournestringcolor_desaturate:{{ string | color_desaturate: number }}retournestringcolor_difference:{{ string | color_difference: string }}retournenumbercolor_extract:{{ string | color_extract: string }}retournenumbercolor_lighten:{{ string | color_lighten: number }}retournestringcolor_mix:{{ string | color_mix: string, number }}retournestringcolor_modify:{{ string | color_modify: string, number }}retournestringcolor_saturate:{{ string | color_saturate: number }}retournestringcolor_to_hex:{{ string | color_to_hex }}retournestringcolor_to_hsl:{{ string | color_to_hsl }}retournestringcolor_to_oklch:{{ string | color_to_oklch }}retournestringcolor_to_rgb:{{ string | color_to_rgb }}retournestringhex_to_rgba:{{ string | hex_to_rgba }}retournestring
Client
customer_login_link:{{ string | customer_login_link }}retournestringcustomer_logout_link:{{ string | customer_logout_link }}retournestringcustomer_register_link:{{ string | customer_register_link }}retournestringavatar:{{ customer | avatar }}retournestringlogin_button:{{ shop | login_button }}retournestring
Date
date:{{ date | date: string }}retournestring
Par défaut
default_errors:{{ string | default_errors }}retournestringdefault:{{ variable | default: variable }}retournenon typédefault_pagination:{{ paginate | default_pagination }}retournestring
Police
font_face:{{ font | font_face }}retournestringfont_modify:{{ font | font_modify: string, string }}retournefontfont_url:{{ font | font_url }}retournestring
Format
date:{{ string | date: string }}retournestringjson:{{ variable | json }}retournestringstructured_data:{{ variable | structured_data }}retournestringunit_price_with_measurement:{{ number | unit_price_with_measurement: unit_price_measurement }}retournestringweight_with_unit:{{ number | weight_with_unit }}retournestring
Fichier hébergé
asset_img_url:{{ string | asset_img_url }}retournestringasset_url:{{ string | asset_url }}retournestringfile_img_url:{{ string | file_img_url }}retournestringfile_url:{{ string | file_url }}retournestringglobal_asset_url:{{ string | global_asset_url }}retournestringshopify_asset_url:{{ string | shopify_asset_url }}retournestring
Html
class_list:{{ settings.layout | class_list }}retournestringtime_tag:{{ string | time_tag: string }}retournestringinline_asset_content:{{ asset_name | inline_asset_content }}retournestringhighlight:{{ string | highlight: string }}retournestringlink_to:{{ string | link_to: string }}retournestringplaceholder_svg_tag:{{ string | placeholder_svg_tag }}retournestringpreload_tag:{{ string | preload_tag: as: string }}retournestringscript_tag:{{ string | script_tag }}retournestringstylesheet_tag:{{ string | stylesheet_tag }}retournestring
Localisation
currency_selector:{{ form | currency_selector }}retournestringtranslate:{{ string | t }}retournestringformat_address:{{ address | format_address }}retournestring
Mathématiques
abs:{{ number | abs }}retournenumberat_least:{{ number | at_least }}retournenumberat_most:{{ number | at_most }}retournenumberceil:{{ number | ceil }}retournenumberdivided_by:{{ number | divided_by: number }}retournenumberfloor:{{ number | floor }}retournenumberminus:{{ number | minus: number }}retournenumbermodulo:{{ number | modulo: number }}retournenumberplus:{{ number | plus: number }}retournenumberround:{{ number | round }}retournenumbertimes:{{ number | times: number }}retournenumber
Média
external_video_tag:{{ variable | external_video_tag }}retournestringexternal_video_url:{{ media | external_video_url: attribute: string }}retournestringimage_tag:{{ string | image_tag }}retournestringmedia_tag:{{ media | media_tag }}retournestringmodel_viewer_tag:{{ media | model_viewer_tag }}retournestringvideo_tag:{{ media | video_tag }}retournestringarticle_img_url:{{ variable | article_img_url }}retournestringcollection_img_url:{{ variable | collection_img_url }}retournestringimage_url:{{ variable | image_url: width: number, height: number }}retournestringimg_tag:{{ string | img_tag }}retournestringimg_url:{{ variable | img_url }}retournestringproduct_img_url:{{ variable | product_img_url }}retournestring
Métachamp
metafield_tag:{{ metafield | metafield_tag }}retournestringmetafield_text:{{ metafield | metafield_text }}retournestring
Monnaie
money:{{ number | money }}retournestringmoney_with_currency:{{ number | money_with_currency }}retournestringmoney_without_currency:{{ number | money_without_currency }}retournestringmoney_without_trailing_zeros:{{ number | money_without_trailing_zeros }}retournestring
Paiement
payment_button:{{ form | payment_button }}retournestringpayment_terms:{{ form | payment_terms }}retournestringpayment_type_img_url:{{ string | payment_type_img_url }}retournestringpayment_type_svg_tag:{{ string | payment_type_svg_tag }}retournestring
Chaîne
hmac_sha1:{{ string | hmac_sha1: string }}retournestringhmac_sha256:{{ string | hmac_sha256: string }}retournestringmd5:{{ string | md5 }}retournestringsha1:{{ string | sha1: string }}retournestringsha256:{{ string | sha256: string }}retournestringappend:{{ string | append: string }}retournestringbase64_decode:{{ string | base64_decode }}retournestringbase64_encode:{{ string | base64_encode }}retournestringbase64_url_safe_decode:{{ string | base64_url_safe_decode }}retournestringbase64_url_safe_encode:{{ string | base64_url_safe_encode }}retournestringcapitalize:{{ string | capitalize }}retournestringdowncase:{{ string | downcase }}retournestringescape:{{ string | escape }}retournestringescape_once:{{ string | escape_once }}retournestringlstrip:{{ string | lstrip }}retournestringnewline_to_br:{{ string | newline_to_br }}retournestringprepend:{{ string | prepend: string }}retournestringremove:{{ string | remove: string }}retournestringremove_first:{{ string | remove_first: string }}retournestringremove_last:{{ string | remove_last: string }}retournestringreplace:{{ string | replace: string, string }}retournestringreplace_first:{{ string | replace_first: string, string }}retournestringreplace_last:{{ string | replace_last: string, string }}retournestringrstrip:{{ string | rstrip }}retournestringslice:{{ string | slice }}retournestringsplit:{{ string | split: string }}retournearraystrip:{{ string | strip }}retournestringstrip_html:{{ string | strip_html }}retournestringstrip_newlines:{{ string | strip_newlines }}retournestringtruncate:{{ string | truncate: number }}retournestringtruncatewords:{{ string | truncatewords: number }}retournestringupcase:{{ string | upcase }}retournestringurl_decode:{{ string | url_decode }}retournestringurl_encode:{{ string | url_encode }}retournestringcamelize:{{ string | camelize }}retournestringhandleize:{{ string | handleize }}retournestringurl_escape:{{ string | url_escape }}retournestringurl_param_escape:{{ string | url_param_escape }}retournestringpluralize:{{ number | pluralize: string, string }}retournestring
Balise
link_to_add_tag:{{ string | link_to_add_tag }}retournestringlink_to_remove_tag:{{ string | link_to_remove_tag }}retournestringlink_to_tag:{{ string | link_to_tag }}retournestring
Objets Liquid
Objets globaux
collectionspagesall_productsarticlesblogscartclosestcontent_for_headercustomerimageslinklistslocalizationmetaobjectsrequestroutesshopthemesettingstemplateadditional_checkout_buttonsall_country_option_tagscanonical_urlcontent_for_additional_checkout_buttonscontent_for_indexcontent_for_layoutcountry_option_tagscurrent_pagehandlepage_descriptionpage_imagepage_titlepowered_by_linkscripts
Page /article
articleblog
Page /blog
blogcurrent_tags
Page /cart
cart
Page /checkout
checkout
Page /collection
collectioncurrent_tags
Page /customers/account
customer
Page /customers/addresses
customer
Page /customers/order
customerorder
Page /gift_card.liquid
gift_cardrecipient
Page /metaobject
metaobject
Page /page
page
Page /product
product
Page /robots.txt.liquid
robots
Page /search
search
Balises Liquid
content_for
La balise content_for nécessite un paramètre de type pour différencier le rendu d'un nombre de blocks de thème ('blocks') et d'un seul block statique ('block').
Syntaxe :
{% content_for 'blocks' %}
{% content_for 'block', type: "slide", id: "slide-1" %}
form
Étant donné qu'il existe de nombreux types de formulaires différents disponibles dans les thèmes Shopify, la balise form nécessite un type. Selon le type de formulaire, un paramètre supplémentaire peut être requis. Vous pouvez spécifier les types de formulaires suivants :
activate_customer_passwordcartcontactcreate_customercurrencycustomercustomer_addresscustomer_loginguest_loginlocalizationnew_commentproductrecover_customer_passwordreset_customer_passwordstorefront_password
Syntaxe :
{% form 'form_type' %}
content
{% endform %}
layout
Syntaxe :
{% layout name %}
assign
Vous pouvez créer des variables de n'importe quel type basique, objet, ou propriété d'objet.
Attention : Les objets Liquid prédéfinis peuvent être remplacés par des variables portant le même nom. Pour vous assurer que vous pouvez accéder à tous les objets Liquid, assurez-vous que le nom de votre variable ne correspond pas au nom d'un objet prédéfini.
Syntaxe :
{% assign variable_name = value %}
break
Syntaxe :
{% break %}
capture
Vous pouvez créer des chaînes complexes avec la logique Liquid et des variables.
Attention : Les objets Liquid prédéfinis peuvent être remplacés par des variables portant le même nom. Pour vous assurer que vous pouvez accéder à tous les objets Liquid, assurez-vous que le nom de votre variable ne correspond pas au nom d'un objet prédéfini.
Syntaxe :
{% capture variable %}
value
{% endcapture %}
case
Syntaxe :
{% case variable %}
{% when first_value %}
first_expression
{% when second_value %}
second_expression
{% else %}
third_expression
{% endcase %}
comment
Tout texte à l'intérieur des balises comment ne sera pas affiché, et tout code Liquid sera analysé, mais non exécuté.
Syntaxe :
{% comment %}
content
{% endcomment %}
continue
Syntaxe :
{% continue %}
cycle
La balise cycle doit être utilisée à l'intérieur d'une boucle for.
Conseil : Utilisez la balise
cyclepour afficher du texte dans un motif prévisible. Par exemple, pour appliquer des classes odd/even aux lignes d'un tableau.
Syntaxe :
{% cycle string, string, ... %}
decrement
Les variables déclarées avec decrement sont uniques au fichier layout, template, ou section dans lequel elles sont créées. Cependant, la variable est partagée entre les snippets inclus dans le fichier.
De même, les variables créées avec decrement sont indépendantes de celles créées avec assign et capture. Cependant, decrement et increment partagent des variables.
Syntaxe :
{% decrement variable_name %}
doc
La balise doc permet aux développeurs d'inclure de la documentation dans les templates Liquid. Tout contenu à l'intérieur des balises doc n'est pas rendu ou affiché. Le code Liquid à l'intérieur sera analysé mais non exécuté. Cela facilite la prise en charge des outils pour des fonctionnalités comme la complétion de code, le linting et la documentation en ligne.
Pour une documentation détaillée sur la syntaxe et les exemples, voir la référence LiquidDoc.
Syntaxe :
{% doc %}
Renders a message.
@param {string} foo - A string value.
@param {string} [bar] - An optional string value.
@example
{% render 'message', foo: 'Hello', bar: 'World' %}
{% enddoc %}
echo
Utiliser la balise echo est la même chose que de mettre une expression entre accolades ({{ et }}). Cependant, contrairement à la méthode avec accolades, vous pouvez utiliser la balise echo à l'intérieur des balises liquid.
Conseil : Vous pouvez utiliser des filtres sur les expressions à l'intérieur des balises
echo.
Syntaxe :
{% liquid
echo expression
%}
for
Vous pouvez faire un maximum de 50 itérations avec une boucle for. Si vous devez itérer sur plus de 50 éléments, utilisez la balise paginate pour diviser les éléments sur plusieurs pages.
Conseil : Chaque boucle
fora un objetforloopassocié avec des informations sur la boucle.
Syntaxe :
{% for variable in array %}
expression
{% endfor %}
if
Syntaxe :
{% if condition %}
expression
{% endif %}
increment
Les variables déclarées avec increment sont uniques au fichier layout, template, ou section dans lequel elles sont créées. Cependant, la variable est partagée entre les snippets inclus dans le fichier.
De même, les variables créées avec increment sont indépendantes de celles créées avec assign et capture. Cependant, increment et decrement partagent des variables.
Syntaxe :
{% increment variable_name %}
raw
Syntaxe :
{% raw %}
expression
{% endraw %}
render
À l'intérieur des snippets et app blocks, vous ne pouvez pas accéder directement aux variables créées en dehors du snippet ou app block. Cependant, vous pouvez spécifier des variables comme paramètres pour passer des variables externes au snippet.
Bien que vous ne puissiez pas accéder directement aux variables créées, vous pouvez accéder aux objets globaux, ainsi qu'à tous les objets directement accessibles en dehors du snippet ou app block. Par exemple, un snippet ou app block à l'intérieur du template product peut accéder à l'objet product, et un snippet ou app block à l'intérieur d'une section peut accéder à l'objet section.
En dehors d'un snippet ou app block, vous ne pouvez pas accéder aux variables créées à l'intérieur du snippet ou app block.
Remarque : Quand vous rendez un snippet en utilisant la balise
render, vous ne pouvez pas utiliser la baliseincludeà l'intérieur du snippet.
Syntaxe :
{% render 'filename' %}
tablerow
La balise tablerow doit être enveloppée dans des balises HTML <table> et </table>.
Conseil : Chaque boucle
tablerowa un objettablerowloopassocié avec des informations sur la boucle.
Syntaxe :
{% tablerow variable in array %}
expression
{% endtablerow %}
unless
Conseil : Similaire à la balise
if, vous pouvez utiliserelsifpour ajouter plus de conditions à une baliseunless.
Syntaxe :
{% unless condition %}
expression
{% endunless %}
paginate
Étant donné que les boucles for sont limitées à 50 itérations par page, vous devez utiliser la balise paginate pour itérer sur un tableau contenant plus de 50 éléments. Les tableaux suivants peuvent être paginés :
all_productsarticle.commentsblog.articlescollectionscollection.productscustomer.addressescustomer.orderspagesproduct.variantssearch.results- Paramètres
collection_list - Paramètres
product_list
À l'intérieur de la balise paginate, vous avez accès à l'objet paginate. Vous pouvez utiliser cet objet, ou le filtre default_pagination, pour construire la navigation des pages.
Syntaxe :
{% paginate array by page_size %}
{% for item in array %}
forloop_content
{% endfor %}
{% endpaginate %}
La balise `paginate` permet à l'utilisateur de paginer jusqu'au 25 000e élément du tableau et pas plus loin. Pour atteindre les éléments plus loin dans le tableau, le tableau doit être filtré davantage avant la pagination. Voir [Pagination Limits](/themes/best-practices/performance/platform#pagination-limits) pour plus d'informations.
javascript
Chaque section, block ou snippet ne peut avoir qu'une seule balise {% javascript %}.
Pour en savoir plus sur la façon dont le JavaScript défini entre les balises javascript est chargé et exécuté, reportez-vous à la documentation des balises javascript.
Attention : Liquid n'est pas rendu à l'intérieur des balises
{% javascript %}. L'inclusion de code Liquid peut causer des erreurs de syntaxe.
Syntaxe :
{% javascript %}
javascript_code
{% endjavascript %}
section
Rendre une section avec la balise section rend une section statiquement. Pour en savoir plus sur les sections et comment les utiliser dans votre thème, consultez Render a section.
Syntaxe :
{% section 'name' %}
stylesheet
Chaque section, block ou snippet ne peut avoir qu'une seule balise {% stylesheet %}.
Pour en savoir plus sur la façon dont le CSS défini entre les balises stylesheet est chargé et exécuté, reportez-vous à la documentation des balises stylesheet.
Attention : Liquid n'est pas rendu à l'intérieur des balises
{% stylesheet %}. L'inclusion de code Liquid peut causer des erreurs de syntaxe.
Syntaxe :
{% stylesheet %}
css_styles
{% endstylesheet %}
sections
Utilisez cette balise pour rendre des groupes de sections dans le cadre du contenu layout du thème. Placez la balise sections à l'endroit où vous souhaitez la rendre dans le layout.
Pour en savoir plus sur les groupes de sections et comment les utiliser dans votre thème, consultez Section groups.
Syntaxe :
{% sections 'name' %}
style
Remarque : Si vous référencez des paramètres de couleur à l'intérieur des balises
style, alors les règles CSS associées seront mises à jour lors du changement du paramètre dans l'éditeur de thème, sans actualisation de la page.
Syntaxe :
{% style %}
CSS_rules
{% endstyle %}
else
Vous pouvez utiliser la balise else avec les balises suivantes :
Syntaxe :
{% else %}
expression
else
Syntaxe :
{% for variable in array %}
first_expression
{% else %}
second_expression
{% endfor %}
liquid
Puisque les balises n'ont pas de délimiteurs, chaque balise doit être sur sa propre ligne.
Conseil : Utilisez la balise
echopour afficher une expression à l'intérieur des balisesliquid.
Syntaxe :
{% liquid
expression
%}
Normes de développement des traductions
Exigences de traduction
- Tout texte visible par l'utilisateur doit utiliser les filtres de traduction.
- Mettez à jour
locales/en.default.jsonavec toutes les nouvelles clés. - Utilisez des clés descriptives et hiérarchiques pour l'organisation.
- N'ajoutez que du texte en anglais ; les traducteurs s'occupent des autres langues.
Utilisation du filtre de traduction
Utilisez {{ 'key' | t }} pour tout texte :
<!-- Good -->
<h2>{{ 'sections.featured_collection.title' | t }}</h2>
<p>{{ 'sections.featured_collection.description' | t }}</p>
<button>{{ 'products.add_to_cart' | t }}</button>
<!-- Bad -->
<h2>Featured Collection</h2>
<p>Check out our best products</p>
<button>Add to cart</button>
Traduction avec variables
Utilisez des variables pour l'interpolation :
<!-- Liquid template -->
<p>{{ 'products.price_range' | t: min: product.price_min | money, max: product.price_max | money }}</p>
<p>{{ 'general.pagination.page' | t: page: paginate.current_page, pages: paginate.pages }}</p>
Clés correspondantes dans les fichiers de locale :
{
"products": {
"price_range": "From {{ min }} to {{ max }}"
},
"general": {
"pagination": {
"page": "Page {{ page }} of {{ pages }}"
}
}
}
Meilleures pratiques
Directives de contenu :
- Écrivez du texte clair et concis.
- Utilisez la casse de phrase pour tout texte visible par l'utilisateur, y compris les titres, en-têtes et étiquettes de boutons (capitalisez uniquement le premier mot et les noms propres ; par ex.,
Featured collection→Featured collection, pasFeatured Collection). - Soyez cohérent avec la terminologie.
- Considérez les limites de caractères pour les éléments d'interface utilisateur.
Utilisation des variables :
- Utilisez l'interpolation plutôt que de concaténer des chaînes.
- Privilégiez la clarté par rapport à la concision pour les noms de variables.
- Échappez les variables à moins qu'elles n'affichent du HTML :
{{ variable | escape }}.
Normes de localisation
Auto-attaché quand vous travaillez dans le répertoire locales/.
Structure de fichier
locales/
├── en.default.json # English (required)
├── en.default.schema.json # English (required)
├── es.json # Spanish
├── est.schema.json # Spanish
├── fr.json # French
├── frt.schema.json # French
└── pt-BR.json # Portuguese
└── pt-BR..schema.json # Portuguese
Fichiers de locale
Les fichiers de locale sont des fichiers JSON contenant les traductions de toutes les chaînes de texte utilisées dans un thème Shopify et son éditeur. Ils permettent aux commerçants de mettre à jour et de localiser facilement les mots et phrases répétés, ce qui permet de traduire le contenu du magasin et les paramètres en plusieurs langues pour les clients internationaux. Ces fichiers offrent une façon centralisée de gérer et de modifier les traductions.
Exemple :
{
"general": {
"cart": "Cart",
"checkout": "Checkout"
},
"products": {
"add_to_cart": "Add to Cart"
}
}
Fichiers de locale de schéma
Les fichiers de locale de schéma, enregistrés avec l'extension .schema.json, stockent les chaînes de traduction spécifiquement pour les schémas de paramètres de l'éditeur de thème. Ils suivent une organisation structurée (catégorie, groupe et description) pour donner du contexte à chaque traduction, permettant une localisation précise du contenu de l'éditeur. Les fichiers de locale de schéma doivent utiliser le format d'étiquette de langue IETF dans leur dénomination, comme en-GB.schema.json pour l'anglais britannique ou fr-CA.schema.json pour le français canadien.
Exemple :
{
"products": {
"card": {
"description": "Product card layout"
}
}
}
Organisation des clés
Structure hiérarchique :
{
"general": {
"meta": {
"title": "{{ shop_name }}",
"description": "{{ shop_description }}"
},
"accessibility": {
"skip_to_content": "Skip to content",
"close": "Close"
}
},
"products": {
"add_to_cart": "Add to cart",
"quick_view": "Quick view",
"price": {
"regular": "Regular price",
"sale": "Sale price",
"unit": "Unit price"
}
}
}
Utilisation
{{ 'general.meta.title' | t: shop_name: shop.name }}
{{ 'general.meta.description' | t: shop_description: shop.description }}
Directives de traduction
Dénomination des clés :
- Utilisez des clés descriptives et hiérarchiques
- Maximum 3 niveaux de profondeur
- Utilisez snake_case pour les noms de clés
- Groupez les traductions associées
Règles de contenu :
- Gardez le texte concis pour les éléments d'interface utilisateur
- Utilisez des variables pour le contenu dynamique
- Considérez les limites de caractères
- Maintenez une terminologie cohérente
Exemples par type d'actif
snippet
{% doc %}
Renders a responsive image that might be wrapped in a link.
When `width`, `height` and `crop` are provided, the image will be rendered
with a fixed aspect ratio.
Serves as an example of how to use the `image_url` filter and `image_tag` filter
as well as how you can use LiquidDoc to document your code.
@param {image} image - The image to be rendered
@param {string} [url] - An optional destination URL for the image
@param {string} [css_class] - Optional class to be added to the image wrapper
@param {number} [width] - The highest resolution width of the image to be rendered
@param {number} [height] - The highest resolution height of the image to be rendered
@param {string} [crop] - The crop position of the image
@example
{% render 'image', image: product.featured_image %}
{% render 'image', image: product.featured_image, url: product.url %}
{% render 'image',
css_class: 'product__image',
image: product.featured_image,
url: product.url,
width: 1200,
height: 800,
crop: 'center',
%}
{% enddoc %}
{% liquid
unless height
assign width = width | default: image.width
endunless
if url
assign wrapper = 'a'
else
assign wrapper = 'div'
endif
%}
<{{ wrapper }}
class="image {{ css_class }}"
{% if url %}
href="{{ url }}"
{% endif %}
>
{{ image | image_url: width: width, height: height, crop: crop | image_tag }}
</{{ wrapper }}>
{% stylesheet %}
.image {
display: block;
position: relative;
overflow: hidden;
width: 100%;
height: auto;
}
.image > img {
width: 100%;
height: auto;
}
{% endstylesheet %}
{% javascript %}
function doSomething() {
// example
}
doSomething()
{% endjavascript %}
block
Text
{% doc %}
Renders a text block.
@example
{% content_for 'block', type: 'text', id: 'text' %}
{% enddoc %}
<div
class="text {{ block.settings.text_style }}"
style="--text-align: {{ block.settings.alignment }}"
{{ block.shopify_attributes }}
>
{{ block.settings.text }}
</div>
{% stylesheet %}
.text {
text-align: var(--text-align);
}
.text--title {
font-size: 2rem;
font-weight: 700;
}
.text--subtitle {
font-size: 1.5rem;
}
{% endstylesheet %}
{% schema %}
{
"name": "t:general.text",
"settings": [
{
"type": "text",
"id": "text",
"label": "t:labels.text",
"default": "Text"
},
{
"type": "select",
"id": "text_style",
"label": "t:labels.text_style",
"options": [
{ "value": "text--title", "label": "t:options.text_style.title" },
{ "value": "text--subtitle", "label": "t:options.text_style.subtitle" },
{ "value": "text--normal", "label": "t:options.text_style.normal" }
],
"default": "text--title"
},
{
"type": "text_alignment",
"id": "alignment",
"label": "t:labels.alignment",
"default": "left"
}
],
"presets": [{ "name": "t:general.text" }]
}
{% endschema %}
Group
{% doc %}
Renders a group of blocks with configurable layout direction, gap and
alignment.
All settings apply to only one dimension to reduce configuration complexity.
This component is a wrapper concerned only with rendering its children in
the specified layout direction with appropriate padding and alignment.
@example
{% content_for 'block', type: 'group', id: 'group' %}
{% enddoc %}
<div
class="group {{ block.settings.layout_direction }}"
style="
--padding: {{ block.settings.padding }}px;
--alignment: {{ block.settings.alignment }};
"
{{ block.shopify_attributes }}
>
{% content_for 'blocks' %}
</div>
{% stylesheet %}
.group {
display: flex;
flex-wrap: nowrap;
overflow: hidden;
width: 100%;
}
.group--horizontal {
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 0 var(--padding);
}
.group--vertical {
flex-direction: column;
align-items: var(--alignment);
padding: var(--padding) 0;
}
{% endstylesheet %}
{% schema %}
{
"name": "t:general.group",
"blocks": [{ "type": "@theme" }],
"settings": [
{
"type": "select",
"id": "layout_direction",
"label": "t:labels.layout_direction",
"default": "group--vertical",
"options": [
{ "value": "group--horizontal", "label": "t:options.direction.horizontal" },
{ "value": "group--vertical", "label": "t:options.direction.vertical" }
]
},
{
"visible_if": "{{ block.settings.layout_direction == 'group--vertical' }}",
"type": "select",
"id": "alignment",
"label": "t:labels.alignment",
"default": "flex-start",
"options": [
{ "value": "flex-start", "label": "t:options.alignment.left" },
{ "value": "center", "label": "t:options.alignment.center" },
{ "value": "flex-end", "label": "t:options.alignment.right" }
]
},
{
"type": "range",
"id": "padding",
"label": "t:labels.padding",
"default": 0,
"min": 0,
"max": 200,
"step": 2,
"unit": "px"
}
],
"presets": [
{
"name": "t:general.column",
"category": "t:general.layout",
"settings": {
"layout_direction": "group--vertical",
"alignment": "flex-start",
"padding": 0
}
},
{
"name": "t:general.row",
"category": "t:general.layout",
"settings": {
"layout_direction": "group--horizontal",
"padding": 0
}
}
]
}
{% endschema %}
section
<div class="example-section full-width">
{% if section.settings.background_image %}
<div class="example-section__background">
{{ section.settings.background_image | image_url: width: 2000 | image_tag }}
</div>
{% endif %}
<div class="custom-section__content">
{% content_for 'blocks' %}
</div>
</div>
{% stylesheet %}
.example-section {
position: relative;
overflow: hidden;
width: 100%;
}
.example-section__background {
position: absolute;
width: 100%;
height: 100%;
z-index: -1;
overflow: hidden;
}
.example-section__background img {
position: absolute;
width: 100%;
height: auto;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.example-section__content {
display: grid;
grid-template-columns: var(--content-grid);
}
.example-section__content > * {
grid-column: 2;
}
{% endstylesheet %}
{% schema %}
{
"name": "t:general.custom_section",
"blocks": [{ "type": "@theme" }],
"settings": [
{
"type": "image_picker",
"id": "background_image",
"label": "t:labels.background"
}
],
"presets": [
{
"name": "t:general.custom_section"
}
]
}
{% endschema %}
Instructions finales
Exigences de conception
- Reposez-vous sur les fonctionnalités et API des navigateurs modernes par défaut, en suppos