shopify theme (一)

365 阅读26分钟

(1). 添加预设分区——模块的名字

image.png

image.png

(2). 模块名字

image.png

image.png

(3). a 标签为空时,

role="link" 用于表示该元素充当一个链接,尽管它可能不是一个实际的 <a> 标签。aria-disabled="true" 表示该链接是不可交互的,即用户无法点击它。结合使用这两个属性,可以确保即使该元素不能实际点击,它依然被辅助技术识别为一个链接并显示为禁用状态。

<a role="link" aria-disabled="true" class="slide-image">

image.png

image.png

(4). 配置 config 里的 settings_data.json 和 settings_schema.json

enable_lazyload 举例: image.png

image.png

image.png

image.png

image.png

(5). forloop 对象的属性

1. forloop.index: 当前循环的索引(从1开始)

image.png

2. forloop.index0: 当前循环的索引(从0开始)

image.png

3. forloop.rindex: 从循环结束到当前迭代的位置(从1开始),即反向顺序排序

image.png

4. forloop.rindex0: 从循环结束到当前迭代的位置(从0开始),即反向顺序排序

image.png

image.png

5. forloop.first: 布尔值,指示当前循环是否是第一次迭代。第一个循环的 forloop.firsttrue,其余的为 false

image.png

image.png

6. forloop.last: 布尔值,指示当前循环是否是最后一次迭代。最后一个循环的 forloop.lasttrue,其余的为 false

image.png

7. forloop.length 循环中的总迭代次数

image.png

8. forloop.parentloop 在内部循环中访问外部循环的属性

image.png

9. {%- for i in (1..section.blocks.size) -%}

  • 表示从 1 到 section.blocks.size 的所有整数;

  • section.blocks.size 是一个属性,通常是指当前 section(页面模块)的 blocks(区块)数组的大小,也就是这个部分的区块数量;

  • 如果 section.blocks.size 是 5,那么 i 会从 1 循环到 5。

10. 下一模块 section.blocks[forloop.index0 | plus: 1] 和上一模块section.blocks[forloop.index0 | minus: 1]

{%- liquid
  assign previous_block_index = forloop.index0 | minus: 1
  assign next_block_index = forloop.index0 | plus: 1
  assign previous_block = section.blocks[previous_block_index]
  assign next_block = section.blocks[next_block_index]
 -%}
  • forloop.index0:这个变量表示当前循环的索引(从 0 开始)。例如,在第一次循环中,它的值是 0,第二次是 1,以此类推。

  • assign previous_block_index = forloop.index0 | minus: 1:这行代码将当前索引减 1,得出前一个块的索引。

  • assign next_block_index = forloop.index0 | plus: 1:这行代码将当前索引加 1,得出下一个块的索引。

  • assign previous_block = section.blocks[previous_block_index] :这行代码通过前一个块的索引从 section.blocks 中获取前一个块的内容。

  • assign next_block = section.blocks[next_block_index] :这行代码通过下一个块的索引从 section.blocks 中获取下一个块的内容。

① 下一模块 section.blocks[forloop.index0 | plus: 1]

image.png

image.png

② 上一模块section.blocks[forloop.index0 | minus: 1]

image.png

image.png

image.png

image.png

(6). video/youtube

{% if block.settings.style_video == 'youtube' %}
    {%- liquid
        assign autoplay_youtube = 0
      if forloop.first and section.settings.auto_playvideo
        assign autoplay_youtube = 1
      endif
    -%}
    <div data-video-youtube class="item slide-youtube embed-responsive item-video" id="slide-{{ block.id }}">
        <div class="fluid-width-video-wrapper">
            <iframe class="youtube-player{% if block.settings.video_link_mb != blank %} slide-pc{% endif %}" id="player_{{ block.id }}" width="100%" height="100%" data-video-id="{{ block.settings.video_link }}" src="https://www.youtube.com/embed/{{ block.settings.video_link }}?enablejsapi=1&rel=0&autoplay={{ autoplay_youtube }}&mute=1" frameborder="0" allowfullscreen=""></iframe>
            {%- if block.settings.video_link_mb != blank -%}
                <iframe class="youtube-player slide-mobile" id="player_mb_{{ block.id }}" width="100%" height="100%" data-video-id="{{ block.settings.video_link_mb }}" src="https://www.youtube.com/embed/{{ block.settings.video_link_mb }}?enablejsapi=1&rel=0&autoplay={{ autoplay_youtube }}&mute=1" frameborder="0" allowfullscreen=""></iframe>
            {%- endif -%}
        </div>
    </div>
{% else %}
    <div data-video-mp4 class="item slide-video item-video" id="slide-{{ block.id }}">
        <div class="fluid-width-video-wrapper">
            <video class="video{% if block.settings.video_mp4_link_mb != blank %} slide-pc{% endif %}" muted playsinline preload="none" autoplay loop><source type="video/mp4" src="{{ block.settings.video_mp4_link }}"></video>
            {%- if block.settings.video_mp4_link_mb != blank -%}
                <video class="video slide-mobile" muted playsinline preload="none" autoplay loop><source type="video/mp4" src="{{ block.settings.video_mp4_link_mb }}"></video>
            {%- endif -%}
        </div>
    </div>
{% endif %}

(7). settings 的 "type": "header"

"settings": [ 
    { 
    "type": "header",
    "content": "Background", 
    "info": "颜色设置" 
    } 
]
  • type: "header"`

    • 这表示该设置项的类型是 header,通常 header 类型的设置项是用来作为分隔标题或说明,帮助用户理解接下来的设置项。
    • 在这个例子中,header 是用来显示一个区块标题: "Background"
  • content: "Background"`

    • 这是该设置项的实际内容,显示给用户的标题文本。在这种情况下,标题是  "Background" ,表示接下来的设置与背景有关。
  • info: " 这是一段描述信息,向用户解释如何使用该设置

image.png

image.png

(8). settings 的 "type": "paragraph"

image.png

"settings": [ 
    { 
    "type": "paragraph",
    "content": "Video-显示一段文本,通常用于页面设置或自定义设置区域中的说明文字。"
    } 
]
  • 类型paragraph
  • 内容content 定义了要显示的文本内容。

paragraph 类型用于显示一段纯文本,通常用于帮助说明或为设置提供描述。它不会创建一个可交互的控件或输入框,只是单纯地显示一段文本,通常用于页面设置或自定义设置区域中的说明文字。

示例使用场景

  • 显示一段关于视频内容的描述或说明:

    • "在此部分添加您的视频设置"
    • "这里可以设置视频的大小或布局"

(9). 预设 presets

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

(10)assign

第一种:①

{%- assign slideshow_id = 'slideshow-' | append: section.id -%}

<div id="{{slideshow_id}}">aaa</div>

页面渲染: image.png

  • {%--%} :这些是 Liquid 模板的标记,分别表示去除空格的开始和结束。{%- 会去除前面的空格,-%} 会去除后面的空格。

  • assignassign 是 Liquid 中用来创建和赋值变量的指令。在这个例子中,它创建了一个名为 slideshow_id 的变量,并将一个值赋给它。

  • 'slideshow-' :这是一个字符串,包含了字面上的文本 slideshow-

  • appendappend 是一个 Liquid 字符串操作函数,它会将右侧的值追加到左侧的字符串中。在这个例子中,'slideshow-' 后面会追加一个 section.id 的值。

  • section.id:这是一个变量或对象的属性,通常表示当前部分(section)的 ID。在 Shopify 中,section.id 是自动提供的,表示该部分的唯一标识符。

因此,整体意思是:创建一个新的变量 slideshow_id,它的值是 'slideshow-' 字符串加上当前 section.id 的值。

这段代码的作用是动态生成一个基于 section.id 的唯一标识符,通常用于为页面中的每个幻灯片(或其他部分)创建唯一的 ID。

image.png

image.png

image.png

第二种:② allow_false: true

{%- assign full_width = full_width | default: section.settings.full_width, allow_false: true -%}

image.png

image.png

image.png

为什么需要 allow_false: true

一般情况下,false 在 Liquid 中已经被认为是有效值,不会被跳过。但是,allow_false: true 显式地让你控制这个行为。它确保即使你提供了 false,这个值仍然会被接受并赋给变量,而不会像某些情况下那样被认为是“空值”而跳过。

总结: allow_false: true 的作用是确保 false 被视为有效值,不会被误认为是“假值”并跳过赋值。对于大多数情况,它并不会改变 false 的处理方式,因为 false 默认就是一个有效的值。但如果你的代码中可能有逻辑依赖于这种明确声明,使用 allow_false: true 可以确保一致性

(11)unless

  • {% unless ... %}{% endunless %} :这是一种条件判断语法,和 if 语句相反,unless 表示“除非”。它会在条件 不成立 时执行代码块。例如,如果条件是 falsenil,代码块中的内容会被执行。

  • section.settings.full_width:这是访问 section.settings 中的 full_width 设置项,通常是一个布尔值(truefalse),这个设置项的值通常来自于主题配置。

综合起来:

  • 这段代码的意思是:

    • 如果 section.settings.full_width 的值为 false 或没有设置(即 nil),  就输出 slideshow--boxed
    • 如果 section.settings.full_width 的值为 true,那么什么都不输出。

image.png

(12)capture

{%- capture %}{%- endcapture -%} 标签用于捕获一段内容,并将其存储在一个变量中。这个标签通常用于将一段 HTML 或字符串内容存储到一个变量里,以便在模板的其他地方重复使用。

-   `capture` 标签:开始捕获一段内容并赋值给指定的变量(`variable_name`)。
-   `endcapture` 标签:结束捕获过程。

{%- capture variable_name -%}
  <!-- 要捕获的内容 -->
{%- endcapture -%}

image.png

image.png

举例 3: image.png

等同以下代码:

{% assign style = style | default: settings.button_style %}

{% capture class_attribute %}
  button
  {% if size != blank and size != 'base' %} button--{{ size }}{% endif %}
  {% if style == 'outline' %} button--outline{% endif %}
  {% if secondary and disabled != true %} button--secondary{% endif %}
  {% if subdued and background == blank and text_color == blank %} button--subdued{% endif %}
  {% if stretch %} w-full{% endif %}
{% endcapture %}

image.png

(13)strip_newlines

{% if class_attribute != blank %}class="{{ class_attribute | strip_newlines | strip }}"{% endif %}

{{ style_attribute | strip_newlines | strip }}:去除 style_attribute 中的换行符和前后空格,然后将其作为样式应用到 HTML 标签。

strip_newlines

  • 这个过滤器会去除字符串中的所有换行符(\n)和回车符(\r)。
  • 例如,如果一个字符串中有多行内容,使用 strip_newlines 后,字符串中的换行符会被删除,字符串变成单行。

image.png

image.png

(14) image

{%- capture sizes -%}{% if section.settings.full_width %}100vw{% else %}min({{ settings.page_width }}px, 100vw){% endif %}{%- endcapture -%}
{%- capture loading_strategy -%}{% if forloop.first %}eager{% else %}lazy{% endif %}{%- endcapture -%}
{%- capture fetch_priority -%}{% if forloop.first %}high{% else %}low{% endif %}{%- endcapture -%}

<picture>
  {%- if block.settings.mobile_image != blank -%}
    <source
      media="(max-width: 699px)"
      srcset="{{ block.settings.mobile_image | image_url: width: '400x' }} 400w, {{ block.settings.mobile_image | image_url: width: '600x' }} 600w, {{ block.settings.mobile_image | image_url: width: '800x' }} 800w, {{ block.settings.mobile_image | image_url: width: '1000x' }} 1000w, {{ block.settings.mobile_image | image_url: width: '1200x' }} 1200w"
      width="{{ block.settings.mobile_image.width }}"
      height="{{ block.settings.mobile_image.height }}"
    >
  {%- endif -%}

  {{- block.settings.image | image_url: width: block.settings.image.width | image_tag: loading: loading_strategy, fetchpriority: fetch_priority, sizes: sizes, widths: '200,300,400,500,600,700,800,900,1000,1200,1400,1600,1800,2000,2200,2400,2600,2800,3000,3200' -}}
</picture>

image.png

1. source

<source
    media="(max-width: 699px)"
    
    srcset="{{ block.settings.mobile_image | image_url: width: '400x' }} 400w, 
            {{ block.settings.mobile_image | image_url: width: '600x' }} 600w, 
            {{ block.settings.mobile_image | image_url: width: '800x' }} 800w,
            {{ block.settings.mobile_image | image_url: width: '1000x' }} 1000w,
            {{ block.settings.mobile_image | image_url: width: '1200x' }} 1200w"
            
    width="{{ block.settings.mobile_image.width }}"
    height="{{ block.settings.mobile_image.height }}"
>
  • media="(max-width: 699px)" 当屏幕宽度小于或等于699px时,才会应用这个<source>标签(适用于手机或小屏设备)

  • srcset是一个HTML属性,它用于在不同的屏幕宽度或分辨率下,提供多个图像资源。浏览器会根据设备的屏幕宽度和分辨率,选择一个最适合的图像进行加载,避免加载不必要的高分辨率图像,提升性能。

  • {{ block.settings.mobile_image | image_url: width: '400x' }} 400w:生成宽度为400像素的图像URL。 w 后缀:表示每个图像的宽度(例如:400w 表示图像宽度为 400px)。浏览器会根据视口的大小和设备像素比(DPR)来选择最适合的图像。

  • 已经设置了media="(max-width: 699px)",为什么还要800,1000,1200的宽度?

即使你使用了 media="(max-width: 699px)" 来针对小屏幕设备设置样式,设备的屏幕密度和分辨率差异仍然可能导致图像需要不同的分辨率。为了在各种设备上保持良好的显示效果,提供多个尺寸的图像能够让浏览器做出更智能的选择,保证图像清晰并优化性能。

2. schema 中定义了图像,但没有直接定义 width 和 height

Liquid 会自动提取该图像的实际宽度 (width) 和高度 (height),并将它们作为 HTML 属性渲染出来。

width="{{ block.settings.mobile_image.width }}"

height="{{ block.settings.mobile_image.height }}"

{ 
    "type": "image", 
    "id": "mobile_image", 
    "label": "Mobile Image" 
}

3. image_tag

{%- capture sizes -%}{% if section.settings.full_width %}100vw{% else %}min({{ settings.page_width }}px, 100vw){% endif %}{%- endcapture -%}

{%- capture loading_strategy -%}{% if forloop.first %}eager{% else %}lazy{% endif %}{%- endcapture -%}

{%- capture fetch_priority -%}{% if forloop.first %}high{% else %}low{% endif %}{%- endcapture -%}

 {{- block.settings.image | image_url: width: block.settings.image.width | image_tag: loading: loading_strategy, fetchpriority: fetch_priority, sizes: sizes, widths: '200,300,400,500,600,700,800,900,1000,1200,1400,1600,1800,2000,2200,2400,2600,2800,3000,3200' -}}
  • image_tag 会生成图像的 <img> 标签

  • loading: loading_strategy:这是图像懒加载的设置。loading 的属性有: ① : eager:默认行为,告诉浏览器当处理 <img> 标签时立即加载图片。② :lazy:推迟图片加载直到浏览器认为其需要立即加载时才去加载;例如,如果用户正在往下滚动页面,值为 lazy 会导致图片仅在马上要出现在 可视视口中时开始加载。

  • fetchpriority: fetch_priority: 该属性允许开发人员发出信号,表明在加载过程的早期获取特定图像对用户体验的影响或多或少,而不是浏览器在分配内部优先级时可以合理推断的影响。fetchpriorityg 的属性有: ① : high : 相对于具有相同内部优先级的其他图像,以高优先级获取图像。② :low : 相对于具有相同内部优先级的其他图像,以较低的优先级获取图像。③ : auto : 不要为 fetch 优先级设置用户首选项。 这是默认设置。 如果未设置任何值或设置了无效值,则使用它。

  • sizes: sizessizes 是一个属性,用来定义图像显示时可用的不同大小。这个属性通常用于响应式图像,告诉浏览器在哪些条件下使用哪个尺寸的图像。sizes 可能会基于不同的视口宽度进行变化。

  • widths:'200,300,400,500,600,700,800,900,1000,1200,1400,1600,1800,2000,2200,2400,2600,2800,3000,3200': 定义了图像的不同尺寸宽度。它提供了一个逗号分隔的宽度列表(单位是像素),告诉浏览器可以根据不同的视口宽度选择最佳的图像尺寸来显示。

(15)cycleplaceholder_svg_tag

{%- capture placeholder_image -%}{% cycle 'placeholder': 'lifestyle-1', 'lifestyle-2' %}{%- endcapture -%}
{{- placeholder_image | placeholder_svg_tag: 'placeholder' | replace: '<svg', '<svg preserveAspectRatio="xMinYMin slice"' -}}

1. cycle

这行代码使用了 capture 标签来创建一个名为 placeholder_image 的变量,并通过 cycle 标签给它赋值。

  • capture:这个标签会捕获包含的内容,并将其存储到一个变量中。在这个例子里,placeholder_image 就是存储占位符图像名称的变量。
  • cycle:这个标签循环地选择一组值。它会根据上下文中的循环次数选择对应的值。这里,它循环使用 'placeholder''lifestyle-1''lifestyle-2'。每次调用时,cycle 会根据顺序返回这些值之一,作用类似于循环的“选择器”。

最终,placeholder_image 变量将会获得 'placeholder', 'lifestyle-1''lifestyle-2' 其中之一,具体值取决于调用时的循环次数或上下文。

2. placeholder_svg_tag

这一行则是输出并处理刚才存储在 placeholder_image 变量中的内容。

  • placeholder_image:这是从 capture 标签中得到的值,可能是 'placeholder''lifestyle-1', 或 'lifestyle-2'
  • placeholder_svg_tag: 'placeholder':这个是一个自定义的 Liquid 过滤器(placeholder_svg_tag),它的作用是生成一个占位符图像的 SVG 标签。'placeholder' 是传递给过滤器的参数,告诉过滤器它需要为 'placeholder' 占位符图像生成一个 SVG 标签。
  • replace: '<svg', '<svg preserveAspectRatio="xMinYMin slice"':这是一个 replace 过滤器,用来替换生成的 SVG 标签中的部分内容。它将 <svg 替换为 <svg preserveAspectRatio="xMinYMin slice"。这意味着,SVG 图像将具有 preserveAspectRatio="xMinYMin slice" 属性,这个属性是为了确保图像在缩放时保留其宽高比例,并使图像尽可能填满其容器。

(16) render

1. 传参

① 第一种 class

<span>{% render 'icon-close', class: 'ml-2 w-5' %}</span>

在 icon-close.liquid 中接收并使用 class 参数:

image.png

② 第二种: width 'chevron-right' 传递字符串

{%- render 'icon' with 'chevron-right' -%}
  • render:这是 Shopify Liquid 模板中的一个标签,用来在当前模板中 引入并渲染 其他模板文件(例如部分文件)。在这里,它引用了一个名为 icon 的部分模板。

  • 'icon' :这是指向一个部分模板的名称,通常这是一个文件名,代表一个可重用的组件或部分。在 Shopify 中,部分模板通常存放在 sections 或 snippets 文件夹中。

  • with 'chevron-right' :这是向 icon 部分模板传递的参数。传递的 'chevron-right' 是一个字符串,通常表示要显示的图标类型或图标的名称。在这个例子中,它可能是指向右箭头的图标(也就是 chevron-right)。

  • {%- 和 -%} :这对符号表示“去除空格”,它会去掉标签前后的空格,使代码更加紧凑。

icon 这个文件 怎么接收参数'chevron-right'??

{%- assign icon_name = icon -%} <!-- 接收传入的参数并将其赋值给变量 icon_name --> 
<!-- 这里你可以根据 icon_name 渲染不同的图标 --> 
{% if icon_name == 'chevron-right' %} 
    <svg><!-- 右箭头 SVG 图标代码 --></svg> 
    {% elsif icon_name == 'chevron-left' %} 
        <svg><!-- 左箭头 SVG 图标代码 --></svg> 
    {% else %} 
        <span>未知图标</span> 
{% endif %}

image.png

③ 第三种:strip过滤器用于去除变量值两端的多余空格

class="{{ class | strip }}"

  • 将 class 变量的值赋给 HTML 标签的 class 属性
  • strip 过滤器用于去除 class 变量值两端的多余空格。比如,若 class 的值是 " text-center ",使用 strip 后会变为 "text-center",避免额外的空格影响 CSS 类。

style="{{ style | strip }}"

  • 将 style 变量的值赋给 HTML 标签的 style 属性
  • strip 过滤器会移除 style 变量值两端的空格。

image.png

image.png

image.png

image.png

④ 第四种:父文件 没有 直接传值

image.png

image.png

image.png

image.png

⑤ 第五种: 父文件 直接传值

image.png

(17)escape

{{ block.settings.subheading | escape }}
  • escape 是一个 Liquid 过滤器,它的作用是对文本进行 HTML 转义。
  • 如果 block.settings.subheading 包含了 HTML 标签或特殊字符(如 <>&" 等),这些字符会被转换成对应的 HTML 实体,从而避免 XSS(跨站脚本攻击)等安全问题,确保文本安全地嵌入到 HTML 中。

假设 block.settings.subheading 的值为:<div>Welcome</div>

  • 如果没有使用 escape,渲染的结果可能是:<div>Welcome</div>。这意味着浏览器会将 <div>Welcome</div> 作为 HTML 标签进行解析,从而产生一个实际的 div 元素。

  • 使用 escape 过滤器后,渲染结果将是:&lt;div&gt;Welcome&lt;/div&gt;。这时,<div> 被转义为 &lt;div&gt;,从而在页面上显示为纯文本,而不会被当作 HTML 标签解析。

(18){{ 'general.accessibility.next' | t }}

  • 'general.accessibility.next':这是一个字符串,通常是一个翻译键。它指的是一个被存储在语言文件中的翻译项。翻译键(如 general.accessibility.next)对应于某个具体的翻译值,可以是“下一步”,“下一项”等,取决于你所使用的语言和具体的翻译文件。

  • | t:这是 Liquid 中的过滤器,t 代表 translate翻译)。它将翻译键 'general.accessibility.next' 映射到实际的翻译文本。

这段代码的作用是根据当前选择的语言环境,获取翻译键 'general.accessibility.next' 对应的翻译文本,并将其渲染到页面上。举个例子,如果你的商店语言是中文,翻译键 'general.accessibility.next' 可能会被翻译为“下一步”或“下一个”。

image.png

举例:

{%- for item in collection.items -%} 
    <a href="#item-{{ item.id }}"> 
    {{ 'general.accessibility.go_to_item' | t: index: forloop.index }} </a>
{%- endfor -%}

image.png

如果 collection.items 中有 3 个项目,渲染出的文本会是:

  • Go to item 1
  • Go to item 2
  • Go to item 3

(19)case when

{%- case section.settings.controls_type -%}
  {%- when 'filled_arrows', 'outline_arrows' -%}
  • Liquid 模板语言 中的 case 语句,类似于其他编程语言中的 switch 语句。case 用来对某个变量的值进行判断,并根据不同的值执行不同的代码块。

    • case 语句用于根据 section.settings.controls_type 的值来决定执行哪一部分代码。
    • 当 section.settings.controls_type 的值为 'filled_arrows' 或 'outline_arrows' 时,Liquid 会执行 when 后面的代码块。
  • section.settings.controls_type 的值是 'filled_arrows' 'outline_arrows' 时,执行接下来的代码块。在这里,when 后面的两个值 'filled_arrows''outline_arrows'通过逗号分隔的,表示如果变量值匹配这两个中的任何一个,都会执行相应的代码

(20)default

{{ section.blocks.first.settings.background_gradient 
    | default: section.blocks.first.settings.background 
    | default: section.settings.background_gradient 
    | default: section.settings.background 
}};
  • section.blocks.first.settings.background_gradient:首先检查 section.blocks.first 中的 settings 是否包含 background_gradient。如果有,使用该值。

  • default: section.blocks.first.settings.background:如果 background_gradient 没有值(或者是空值),那么使用 section.blocks.first.settings.background 的值作为默认值。

  • default: section.settings.background_gradient:如果 background 也没有值,接着会使用 section.settings.background_gradient 作为默认值。

  • default: section.settings.background:最后,如果上述所有值都没有,使用 section.settings.background 作为默认值。

(21)shopify_attributes

shopify_attributes 是 Shopify 提供的一个特殊属性,用来生成与该 block 相关的 HTML 属性。它通常包括了该 block 的配置和其他动态生成的属性。例如,shopify_attributes 可能包括一些由 Shopify 系统根据 block 的设置自动生成的属性,如 class, id, 或 data-* 属性。

{%- for block in section.blocks -%}
  <div role="group" {{ block.shopify_attributes }}></div>
{% endfor %}

image.png

image.png

(22)role

HTML 中的 role 属性用于定义元素的功能或目的,role 属性用来帮助定义元素的语义和用途,特别是对于辅助技术(例如屏幕阅读器)来说非常重要。它有助于让页面的内容对所有用户更易于访问,尤其是对那些依赖辅助技术的用户。

这通常用于无障碍访问,帮助屏幕阅读器理解相关的内容。

image.png

(23)divided_by

{{ block.settings.overlay_opacity | divided_by: 100.0 }}

  • block.settings.overlay_opacity 表示获取 block 对象中的 settings 下的 overlay_opacity 属性,通常是一个数字,表示不透明度,范围一般在 0 到 100 之间。

  • divided_by: 100.0 是一个过滤器(或操作符),意味着将 overlay_opacity 除以 100。通常这是为了将百分比转化为小数值,因为 CSS 中的透明度(opacity)通常是一个介于 0 和 1 之间的小数值。例如,如果 overlay_opacity 为 50,除以 100 后会得到 0.5,表示透明度为 50%。

image.png

(24)md5

{%- assign background_hash = background_gradient | md5 | split: '' -%}
  1. background_gradient

    这是一个变量,存储了背景渐变的值(例如可能是一个色彩渐变的字符串)。

  2. | md5

    • md5 是一个哈希函数,用于将输入的字符串(在这个案例中是 background_gradient 的值)转换成一个 MD5 哈希值。MD5 哈希值通常是一个固定长度的 32 位十六进制字符串,表示原始数据的“指纹”。

    • 这意味着无论 background_gradient 的值有多长或复杂,最终输出的将始终是一个32个字符长的字符串。

  3. | split: ''

    • split 是一个用于将字符串分割成数组的函数。传入的参数 '' 表示按字符分割字符串,即将 MD5 哈希值中的每个字符作为一个独立的数组元素。

    • 例如,如果 background_gradient 被哈希成了 5d41402abc4b2a76b9719d911017c592(这只是一个示例,实际的 MD5 值会不同),那么 split: '' 会将这个字符串分解成一个字符数组:

      ['5', 'd', '4', '1', '4', '0', '2', 'a', 'b', 'c', '4', 'b', '2', 'a', '7', '6', 'b', '9', '7', '1', '9', 'd', '9', '1', '1', '0', '1', '7', 'c', '5', '9', '2']
      
  4. assign background_hash

    • assign 是用来将一个值赋给一个变量。在这行代码中,最终的字符数组(经过 MD5 哈希和分割操作)将被赋给 background_hash 变量。

image.png

(25)timesprepend

{%- assign background_numeric_hash = 0 -%}

{%- for item in background_hash -%}
  {%- assign background_numeric_hash = item | times: 1 | prepend: background_numeric_hash -%}
{%- endfor -%}
  • assign:再次使用 assign 操作符,这次它将更新 background_numeric_hash 的值。

  • item | times: 1item 是当前遍历到的 background_hash 中的元素。通过 times: 1,它会将 item 乘以 1,实际上这种做法不会改变 item 的值,可能是想确保 item 被转化为数值型(如果可能的话)。如果 item 是数字或可以转化为数字的字符串(如 '3'),它就会转换为数字;否则会被转换为 NaN 或 0

  • prepend: background_numeric_hashprepend 是一个字符串操作,它会将 background_numeric_hash 当前的值放到 item 前面。即,background_numeric_hash 的当前值会添加到 item 的前面。举个例子,如果 background_numeric_hash 当前值为 '123',而 item 是 '4',执行 prepend 后的结果是 '1234'

image.png

(26)'now' | date: '%N'

{%- assign block_margin_collapsing = true -%}
{%- if block_margin_collapsing == true -%}
  {%- assign background_numeric_hash = 'now' | date: '%N' -%}
{%- endif -%}
  • 'now' | date: '%N'

    • 'now':这是一个字符串,表示当前时间(Liquid 自动将 'now' 作为当前时间的标识)。
    • date: '%N' :这是一个日期格式化过滤器,它将 now 转换成一个特定格式的字符串。'%N' 是 Liquid 中的日期格式符号,它返回当前时间的纳秒部分。
    • 例如,如果当前时间是 2025-03-03 08:52:41.123456789,那么 '%N' 会返回 123456789,也就是纳秒部分的数字

image.png

image.png

(27)split

image.png

image.png

// 从一个 `linear-gradient` 字符串中提取出颜色值,并对其进行拆分和处理
{%- assign gradient_first_stop = background_gradient | split: 'rgba(' | last | split: ')' | first | remove: ',' | split: ' ' -%}

linear-gradient(180deg,rgba(196,102,238,1),rgba(82,218,236,1) 100%) 作为示例来分析每个部分的功能

image.png

代码示例: image.png

(28)handle

handle 是 Liquid 中的一个过滤器。过滤器用于修改变量的值,通常用于处理字符串。handle 过滤器将变量中的值转换为一种可以用于 URL 或 CSS 类名的格式,通常会将字符串中的空格替换为短横线 (-),并将字母转换为小写。

image.png

image.png

image.png

image.png

(29)自定义数据

案例1:

在setting 里创建数据: image.png

image.png

image.png

在product里输入数据: image.png

在代码里进行相关逻辑操作 image.png

案例2:

image.png

image.png

image.png

————————————————————————————————————

以上配置成功,下面进行使用:

image.png

image.png

image.png

————————————————————————————————————

到了这里的产品颜色配置,其实没有真正的关联到产品:

image.png

下面进行 颜色 关联到产品:

image.png

image.png

image.png

这里涉及到代码对应参数是 swatch

image.png

image.png

image.png

(30)at_most

(max-width: 1200px) calc(100vw / {{ 3 | at_most: section.settings.products_per_row_desktop }} - 64px)
  • 这部分设置了针对最大宽度为 1200px(通常是平板或较小桌面设备)的媒体查询。

    • 100vw / 3 计算的是宽度除以 3,这意味着默认情况下在这些设备上每行显示 3 个产品。
    • | at_most 是一个 Liquid 过滤器,它返回较小的值,即 3 和 section.settings.products_per_row_desktop 之间的较小值。这是为了防止设置值大于 3。
    • - 64px 是为了调整间距,使每个产品有合适的间距。

image.png

(31)section

文档地址:shopify.dev/docs/api/li…

    {%- liquid
      assign main_media_loading_strategy = nil

      if section.index > 3 or position > 3
        assign main_media_loading_strategy = 'lazy'
      endif
    -%}

image.png

image.png

image.png

(32)product

文档地址:shopify.dev/docs/api/li…

① product.featured_media

image.png

image.png

image.png

image.png

image.png

product.media[product.featured_media.position]

image.png

product.available

image.png

image.png

product.variants

案例1:

{%- if product.variants.size == 1 -%}
  • product.variants 是一个数组,包含当前产品的所有变体(如不同的颜色、尺寸等)。variants.size 返回该数组的大小,也就是产品变体的数量。此条件判断的是:当前产品是否只有 1 个变体

  • 举个例子:如果该产品只有一种尺寸或颜色(即只有一个变体),则该条件为 true

案例2: image.png

**[  {    "id": 1,    "title": "Red - Small",    "price": 19.99,    "option1": "Red",    "option2": "Small"  },  {    "id": 2,    "title": "Red - Medium",    "price": 19.99,    "option1": "Red",    "option2": "Medium"  },  {    "id": 3,    "title": "Red - Large",    "price": 19.99,    "option1": "Red",    "option2": "Large"  },  {    "id": 4,    "title": "Blue - Small",    "price": 19.99,    "option1": "Blue",    "option2": "Small"  },  {    "id": 5,    "title": "Blue - Medium",    "price": 19.99,    "option1": "Blue",    "option2": "Medium"  },  {    "id": 6,    "title": "Blue - Large",    "price": 19.99,    "option1": "Blue",    "option2": "Large"  }]
**

案例3: image.png

案例4: image.png

product.selling_plan_groups

image.png

image.png

image.png

product.selected_or_first_available_variant

如果用户没有明确选择变体,或者没有选择的情况下,selected_or_first_available_variant 会返回商品的第一个可用变体。这个变体通常是系统自动选择的第一个可用选项,比如商品列表中的第一个尺码或颜色。

第一个:variant.compare_at_pricevariant.price

{%- assign variant = variant | default: product.selected_or_first_available_variant -%}

image.png

image.png

image.png

image.png

image.png

image.png

第二个:product.selected_or_first_available_variantproduct.featured_media 的区别

image.png

image.png

vendor

文档地址:shopify.dev/docs/api/st…

image.png

过滤器 url_for_vendor image.png

⑧ product.compare_at_price ,product.price 和 variant.compare_at_price,variant.price 这4个的区别是什么

1. product.price

  • 定义:这是整个 产品 的 标准售价,即产品的正常销售价格(不考虑任何折扣或促销)。
  • 适用场景product.price 用于表示产品本身的价格。如果你有一个多变体的产品,这个价格是产品的默认价格(通常是第一个变体的价格)。
  • 注意:如果你直接使用 product.price,它不会考虑变体的价格差异。即使产品有多个变体,每个变体的价格可能不同,但 product.price 始终是默认变体(通常是第一个变体)的价格。

2. product.compare_at_price

  • 定义:这是整个 产品 的 原价(也叫“划线价”或“建议零售价”),通常用于显示一个较高的参考价格,以便让顾客看到当前的价格折扣。
  • 适用场景product.compare_at_price 用于显示折扣后的价格对比。当产品的 compare_at_price 大于 price 时,Shopify 会显示一个价格折扣,并展示原价(compare_at_price)和现价(price)。
  • 注意:如果所有变体的 compare_at_price 都设置了,那么该属性显示的值通常是第一个变体的 compare_at_price

3. variant.price

  • 定义:这是每个 变体 的 售价,即特定变体的实际销售价格。
  • 适用场景:如果产品有多个变体,variant.price 显示的是当前选择变体的实际售价。例如,如果有不同颜色或尺寸的变体,它们的价格可能会有所不同。
  • 注意variant.price 是针对单个变体的,不是整个产品的价格。

4. variant.compare_at_price

  • 定义:这是每个 变体 的 原价(划线价),通常用于与 variant.price 进行比较,显示折扣信息。
  • 适用场景:与 variant.price 类似,variant.compare_at_price 用于展示原价,帮助顾客了解当前价格的折扣幅度。如果变体的 compare_at_price 大于其 price,Shopify 会展示该变体的折扣信息。
  • 注意variant.compare_at_price 是特定于变体的,而不是产品的。

image.png

options_by_name

image.png

image.png

(A) product.options_by_name.values

{%- assign color_label_list = 'general.label.color' | t | replace: ', ', ',' | downcase | split: ',' -%}
  • assign 是 Liquid 中用来创建和赋值变量的指令。在这一行,color_label_list 被赋值为一系列颜色标签的列表。
  • 'general.label.color' | t:这里,'general.label.color' 是一个翻译键,它会被翻译成当前商店所选语言中的“颜色”这个词。例如,在英语中,它会被翻译为 "color"。t 是 Liquid 中的翻译过滤器,用来获取语言文件中的翻译内容。
  • replace: ', ', ',':这个过滤器将翻译得到的字符串中的所有 ', ' (逗号和空格)替换成 ','(仅逗号)。这样做是为了去掉多余的空格,确保分隔符只有逗号。
  • downcase:将整个字符串转换为小写字母。比如“Color”会被转换为“color”。
  • split: ',':将翻译结果按逗号进行拆分,生成一个数组。假设翻译结果是 "red, green, blue",经过这一操作之后,color_label_list 将变成 ["red", "green", "blue"]

{{ product.options_by_name[color_label] }}

  • product.options_by_name 是一个包含所有产品选项的对象。通过 product.options_by_name[color_label],你可以访问当前 color_label 对应的产品选项。如果该选项存在,它将返回该选项的值(如颜色选项)。

image.png

image.png

(B) product.options_by_name.values.size

案例1: image.png

案例2: image.png

//这段代码用于从语言文件中获取与产品可用颜色数量相关的翻译文本,

//并根据实际的颜色数量进行动态插入,确保无论是中文还是英文,都会根据用户的语言环境输出正确的内容。

{{- 'product.general.available_colors_count' | t: count: product_option.values.size -}}

(aa)'product.general.available_colors_count'

  • 这是一个 字符串,通常代表一个翻译键。Shopify 支持多语言,翻译键可以在 locales 文件夹中的 .json 文件中定义。这些翻译文件存储了不同语言的翻译内容。
  • 'product.general.available_colors_count' 这个翻译键,通常用来表示“可用颜色数量”的文本,可能会有不同的语言版本。

(bb)| t: count: product_option.values.size

  • | t 是一个 Liquid 过滤器,用于对指定的翻译键进行翻译。它将根据当前语言环境的设置从语言文件中获取翻译文本。

  • count: product_option.values.size 是一个 参数,它将 product_option.values.size 的值传递给翻译模板中的 count 变量。

  • product_option.values.size 获取产品选项(如颜色)的数量。在 Shopify 产品页面中,product_option 可能代表产品的一个选项(如颜色、大小等),values 是该选项的具体值(如红色、蓝色等),size 是该选项的值的数量。

(C)product.options_by_name[Color].product_option 与 product.options_by_name[Color].values.product_option_value

product_option:

image.png

image.png

product_option_value 这是个数组:

product.options_by_name[Color] .values. product_option_value

image.png

image.png

(D)position:

image.png

(33) form

product

    {% form 'product', product %}
      form_content
    {% endform %}

image.png转存失败,建议直接上传图片文件

image.png转存失败,建议直接上传图片文件

案例1: image.png转存失败,建议直接上传图片文件