1. 安装开发工具
1.1. 安装 SHOPLINE CLI
在 Windows、macOS 上安装 SHOPLINE CLI,这里提供了 npm 和 yarn 两种安装方法进行安装。
npm install --global @shoplineos/cli
或者
yarn global add @shoplineos/cli
cli使用教程点击
使用教程查看。
1.2. 安装3.0开发插件
VS Code 开发者插件,点击
扩展安装包进行下载安装。详细使用教程点击
使用教程查看。
用户排查主题代码语法中的语法错误。
2. 获取3.0主题代码
2.1. 添加3.0主题
如想在已发布的3.0主题进行开发,可忽略此添加3.0主题步骤。
点击【在线商店】>【店铺设计】>【主题商城】。
选择需要的3.0主题。
添加对应的3.0主题。
添加完成效果:
2.2. 拉取3.0主题代码进行开发
桌面创建空白文件夹
进入该文件夹的终端输入以下命令,登录店铺。
sl login --store 店铺handle.myshopline.com
以下是通过此命令,登录到店铺handle为zhenghaonan的示例:
输入完命令并回车,浏览器自动跳转至登录页面。
登录完成。
再输入以下命令,显示店铺所有的主题代码。
sl theme pull
以下是通过此命令,显示zhenghaonan店铺所有的主题代码的示例:
如您想对已发布的主题进行开发,选择带[live]符号的主题。
按键盘上下健,选择对应的3.0主题,再按回车键即可拉取。
再输入以下命令,进行实时预览开发。
sl theme serve
以下是通过此命令返回的信息:
- 本地预览链接:http://127.0.0.1:8282 此链接指向你的开发主题的链接。此 URL 可以热重新加载对本地文件的更改,或在文件更改时刷新整个页面,允许你使用店铺的数据实时预览更改。无法使用此链接预览结账页。
- SHOPLINE 后台中主题编辑器的链接:Shopline Editor
- 你可以与其他开发人员共享的预览链接:https://zhenghaonan.myshopline.com/?preview=1&themeId=690978b35ad5f3fc52297292&dev_mode=1。
3. 抽离 2.1 主题中定制的组件代码
3.1. 找到 2.1 定制组件代码(含 html / css / js 文件)
3.2. 按 2.1 组件结构拉取代码至文件夹
2.1主题组件代码结构:
assets 包含主题中使用的所有资产,包括 Image、CSS 和 JavaScript 文件。
locales 包含主题的 [locale 文件](https://developer.shopline.com/zh-hans-cn/docs/themes-2-0/architecture/locales/overview),用于提供翻译后的内容。
sections 包含一个主题的所有 [section](https://developer.shopline.com/zh-hans-cn/docs/themes-2-0/architecture/sections/overview) 文件。
snippets 包含 Handlebars HTML 文件,用于托管较小的可重用代码片段。
按照 2.1 组件代码结构,将 2.1 定制组件代码移至对应 2.1 目录。
4. 2.1 定制组件转移至 3.0 主题
2.1 定制组件转为 3.0 组件代码结构
3.0主题组件代码结构:
blocks # 可复用的区块 针对 3.0 组件特性拆分出的公共 block 目录
components # 公共代码片段 与 2.1 主题目录 snippets 作用相同
i18n # 多语言配置文件 与 2.1 主题目录 locales 作用相同
public # 静态资源(图片/CSS/JS/字体)与 2.1 主题目录 assets 作用相同
sections # 页面组件与组件集 与 2.1 主题目录 sections 作用相同
注意:
1、3.0 代码结构中每个 section 为一个文件夹。
2、不再支持 2.1 组件 block 在 section 中直接创建的形式。
3、3.0 主题若 html 有对应 css / js ,均放入同命名文件夹。
按照 3.0 组件代码结构,将 2.1 定制组件代码移至对应 3.0 目录。
按照3.0组件目录搬迁至3.0主题代码中相应的位置。
5. 按照 3.0 语法结构修改组件代码
5.1. 修改引用 CSS / JS 语法及路径
原 2.1 定制组件 case-studies.html 引入示例如下:
{{snippet "stylesheet" href=(asset_url "swiper@11/swiper-bundle.min.css")}}
<script src="{{asset_url 'swiper@11/swiper-bundle.min.js'}}" defer></script>
{{snippet "stylesheet" href=(asset_url " case-studies/ case-studies.css")}}
<script src="{{asset_url ' case-studies/ case-studies.js'}}" defer></script>
{{snippet " section-style" section=section}}
{{snippet " section-common" section=section}}
3.0 组件引用 CSS 格式如下:
{{#component “stylesheet” src="CSS路径 " | asset_url() /}}
3.0 组件引用 JS 格式如下:
{{#component “script” src="JS路径 " | asset_url() /}}
3.0组件引用公共模块格式如下:
{{#component "公共模块的路径 " /}}
按照以上 3.0 组件引用代码格式及 3.0 组件文件目录
将原 2.1 定制组件转化成 3.0 case-studies.html 示例如下:
{{#component "stylesheet" src="component/swiper@11/swiper-bundle.min.css" | asset_url() /}}
{{#component "script" src="component/swiper@11/swiper-bundle.min.js" | asset_url() /}}
{{#component "stylesheet" src="./ case-studies.css" | asset_url() /}}
{{#component "script" src="./ case-studies.js" | asset_url() /}}
{{#component " section-style" /}}
{{#component " section-common/ section-common" /}}
5.2. 修改 2.1 组件代码适配 3.0 主题
5.2.1. 修改 settings 配置项
原 2.1 组件 case-studies.html settings 配置项示例如下:
{{#schema}}
{
"name": "Case Studies",
"settings": [
{
"id": "common_title",
"type": "richtext",
"label": "标题",
"default": "Section Title"
},
{
"id": "common_content",
"type": "richtext",
"label": "内容",
"default": "Section Content"
},
{
"type": "product_picker",
"id": "common_button_add_cart_product",
"label": "商品选择器"
},
{
"type": "color",
"id": "bg_color",
"label": "背景颜色",
"default": "#FFFFFF"
},
],
3.0 控件类型
3.0 编辑器控件类型库
3.0 组件图标
3.0 编辑器组件图标库
3.0 用于修改变量和对象的输出Filter
3.0 Sline filter 同 2.1 主题
Handlebars helpers
3.0 用于定义指示模板执行操作的逻辑Tag
3.0 Sline tag
2.1 语法与 3.0 语法差异
Handlebars & Sline 语法差异对比
注意:
-
发现当前 2.1 组件控件未在 3.0 主题显示时,可在 3.0 编辑器控件类型库 文档中查找最新格式/使用 其他控件代替。
场景如:商品选择器:2.1 中使用 product_picker,在 3.0 中需使用 product,否则无效 。 -
3.0 组件/主题代码中如有语法错误,会导致整块内容不显示。
场景如:当 section 代码中有语法时,该 section 在主题编辑器组件库中不显示。 -
如 2.1 代码中使用 {{#comment}} 注释 {{/comment}} 进行注释,需更换为 {{!-- 注释 --}} 。
-
2.1 Handlebars helpers 需替换成 3.0 Sline filter / 3.0 Sline tag 。
场景如:2.1 主题对一个控件值使用 helpers default
{{default section.settings.bg_color ‘#000’}}
在 3.0 主题需更改写法
{{ section.settings.bg_color.hex | default(“#000”) }}
按照以上 3.0 注意事项及 3.0 相关文档修改 case-studies.html 代码示例如下:
{{#schema}}
{
"name": "Case Studies",
"settings": [
{
"id": "common_title",
"type": "richtext",
"label": "标题",
"default": "Section Title"
},
{
"id": "common_content",
"type": "richtext",
"label": "内容",
"default": "Section Content"
},
{
"type": "product", 将原 2.1 的控件类型product_picker 转化为 3.0 的product
"id": "common_button_add_cart_product",
"label": "商品选择器"
},
{
"type": "color",
"id": "bg_color",
"label": "背景颜色",
"default": "#FFFFFF"
},
],
5.2.2. 修改 block 的创建方式
原 2.1 组件 case-studies.html 添加 blocks 示例如下:
{{#schema}}
{
"name": "Case Studies",
"settings": [
...省略上方相关代码
],
"blocks": [
{
"icon": "normal",
"type": "card",
"name": "卡片",
"settings": [
{
"id": "link",
"type": "url",
"label": "跳转链接"
},
{
"id": "media_image",
"type": "image_picker",
"label": "图片"
},
{
"id": "media_local_video",
"type": "video",
"label": "本地视频"
},
{
"id": "media_external_youtube_video",
"type": "video_url",
"format": "video",
"label": "youtube视频链接",
"placeholder": "https://www.youtube.com/watch?v=V7BEzkRBp_g",
"info": "支持youtube"
},
{
"id": "media_external_video",
"type": "text",
"label": "外部视频链接",
"placeholder": "https://cdn4.fireworktv.com/medias/2025/1/14/1736847602-iqkgazld/watermarked/720/smart_pc.mp4",
"info": "支持firework"
}
]
}
],
根据 3.0 组件特性,目前 3.0 组件不支持区块 block 直接创建 , block 需拆分成私有区块 / 公有区块。
公有区块:可以被任意组件或区块引用的区块,创建目录如下:
3.0主题文件夹
├─ blocks
私有区块:只能被对应组件及对应组件下的私有区块引用,创建目录如下:
3.0主题文件夹
├─ sections
├─ 对应组件文件夹
├─ blocks
根据 2.1 定制组件的需求,在对应文件夹下创建 3.0 对应区块文件。
假设 block 名为:product-card
对应 product-card.html 文件代码如下:
{{#schema}}
{
"icon": "normal",
"type": "card",
"name": "卡片",
"tag": "", tag--外层元素代码:不写tag字段默认div包裹,tag传空值则去除默认父级元素,
传xxx,则父级元素为<xxx></xxx>
"settings": [
{
"id": "link",
"type": "url",
"label": "跳转链接"
},
{
"id": "media_image",
"type": "image", 将原 2.1 的控件类型 image_picker 转化为 3.0 的image
"label": "图片"
},
{
"id": "media_local_video",
"type": "video",
"label": "本地视频"
},
{
"id": "media_external_youtube_video",
"type": "external_video", 将原 2.1 的控件类型 video_url 转化为 3.0 的 external_video
"format": "video",
"label": "youtube视频链接",
"placeholder": "https://www.youtube.com/watch?v=V7BEzkRBp_g",
"info": "支持youtube"
},
{
"id": "media_external_video",
"type": "text",
"label": "外部视频链接",
"placeholder": "https://cdn4.fireworktv.com/medias/2025/1/14/1736847602-iqkgazld/watermarked/720/smart_pc.mp4",
"info": "支持firework"
}
],
"block":[]
}
{{/schema}}
修改对应Section的引用方式:
按照创建的区块,修改 case-studies.html 添加 block 的代码如下:
{{#schema}}
{
"name": "Case Studies",
"settings": [
...省略上方相关代码
],
"blocks":[
{
"type": "$product-card", 如果区块为私有区块,则添加 $ 符号,若是公有区块,则去除 $ 。
"limit": 1 添加该区块的最大数量
}
]
}
{{/schema}}
5.2.3. 修改代码中引用 block 的方式
3.0 渲染当前 Section / Block 子级 Blocks 的方式:
- 仅支持渲染当前 section / block 下的动态 blocks 。
{{#content "blocks" /}}
- 渲染当前 section / block 下的动态 block ,支持往子级 block 传对象值,作用域内会下发 forblock 对象,支持做一些特殊逻辑处理。
{{#blocks}}
{{#block /}}
{{/blocks}}
3.0 Section / Block 传对象值给子级 Blocks 并渲染的方式:
- 传 Section 的控件配置项/特定的值给子级 Blocks 并渲染的格式:
{{#blocks}}
{{#block 自定义传值名称=section.settings.控件id 自定义传值名称=自定义值 /}}
{{/blocks}}
Section 渲染子级 Blocks 时传 title 的配置值及自定义参数 isBigBox 的示例如下:
{{#blocks}}
{{#block title=section.settings.title isBigBox=true /}}
{{/blocks}}
- 传 Block 的控件配置项/特定的值给子级 Blocks 并渲染的格式:
{{#blocks}}
{{#block 自定义传值名称=block.settings.控件id 自定义传值名称=自定义值 /}}
{{/blocks}}
Block 渲染子级 Blocks 时传 richtext 的配置值及自定义参数 isSmallBox 的示例如下:
{{#blocks}}
{{#block text=section.settings.richtext isSmallBox=true /}}
{{/blocks}}
- 传 Section / Block 中定义的变量给子级 Blocks 并渲染的格式:
{{#var 变量名 /}} 定义变量
{{#set 变量名 = 变量值 /}} 赋值变量
{{#blocks}}
{{#block 自定义传值名称=变量名 /}} 使用变量
{{/blocks}}
Section / Block 渲染子级 Blocks 时传定义的变量示例如下:
{{#var isBox /}}
{{#set isBox = true /}}
{{#blocks}}
{{#block isBigBox=isBox /}}
{{/blocks}}
- Section / Block 渲染特定的子级 block 并传参数,可结合 forblock.type 判断子级 block 的类型进行操作。
格式:
{{#blocks}}
{{#if forblock.type == “子级 block 的类型” }}
{{#block 自定义传值名称=变量名 /}}
{{/if}}
{{/blocks}}
Section / Block 渲染特定的子级 block 并传参数示例如下:
{{#blocks}}
{{#if forblock.type == "$product-cart" }} 如果区块为私有区块,则添加 $ 符号,
{{#block text=section.settings.richtext /}} 若是公有区块,则去除 $ 。
{{/if}}
{{/blocks}}
3.0 子级 Block 引用 Section / Block 传参的方式:
格式:
{{ props.自定义传值名称 }}
子级 Block 引用 Section 传参 title 及 isBigBox 的示例如下:
{{ props.title }}
{{ props.isBigBox }}
3.0 Section/Block 拿取子级blocks 的值的方式:
格式:
{{#blocks}}
{{ forblock.settings.子级 block 配置项的控件 Id /}}
{{/blocks}}
Section / Block 显示子级 blocks title 配置项 title 的值示例如下:
{{#blocks}}
{{ forblock.settings.title /}}
{{/blocks}}
获取特定的子级 block 配置参数,可结合 forblock.type 判断子级 block 的类型进行操作。
格式:
{{#var 变量名 /}}
{{#blocks}}
{{#if forblock.type == “子级 block 的类型” }}
{{#set 变量名 = forblock.settings.子级 block 配置项的控件 Id /}}
{{/if}}
{{/blocks}}
Section / Block 获取特定的子级 Block 配置 title 参数示例如下:
{{#var enable_info_layer /}}
{{#blocks}}
{{#if forblock.type == "product-card/info" }}
{{#set enable_info_layer = forblock.settings.title /}}
{{/if}}
{{/blocks}}
原 2.1 组件 case-studies.html 引用 blocks 示例如下:
<div class="case-studies-swiper">
<div class="swiper-wrapper">
{{#for section.blocks as |block|}}
<div class="swiper-slide case-studies-card {{#if (or block.settings.media_image block.settings.media_local_video block.settings.media_external_youtube_video block.settings.media_external_video)}} case-studies-card-with-media{{/if}}">
<div class="case-studies-card-content-title">
{{{block.settings.title}}}
</div>
<div class="case-studies-card-content-avatar-image">
{{snippet "image" data=block.settings.avatar_image}}
</div>
<div class="case-studies-card-content-avatar-content">
<div class="case-studies-card-content-avatar-content-title">
{{{block.settings.avatar_title}}}
</div>
<div class="case-studies-card-content-avatar-content-text">
{{{block.settings.avatar_content}}}
</div>
</div>
</div>
{{/for }}
</div>
</div>
根据上方 Section / Block 与子级 Block 的相关交互方式,以 {{#for section.blocks as |block|}} 为分界线,按照该组件的需求,将 {{#for}} 里面的代码分别添加至创建的对应子级 block,并添加对应的 block 配置项代码。
如:将 .case-studies-card-content-title 拆分成一个私有/公有区块,在对应目前下添加文件 title.html,并粘贴代码及添加对应的配置项。
假设 block 名为:product-card-content
对应 product-card-content.html 文件代码如下:
<div class="swiper-slide case-studies-card {{#if block.settings.media_image || block.settings.media_local_video || block.settings.media_external_youtube_video || block.settings.media_external_video}} case-studies-card-with-media{{/if}}">
⚠️:需关注当前 helper 是否适配 3.0,如 3.0 不再支持 or 。
<div class="case-studies-card-content-title">
{{{block.settings.title}}}
</div>
<div class="case-studies-card-content-avatar-image">
{{snippet "image" data=block.settings.avatar_image}}
</div>
<div class="case-studies-card-content-avatar-content">
<div class="case-studies-card-content-avatar-content-title">
{{{block.settings.avatar_title}}}
</div>
<div class="case-studies-card-content-avatar-content-text">
{{{block.settings.avatar_content}}}
</div>
</div>
</div>
{{#schema}}
{
"icon": "normal",
"type": "card",
"name": "标题",
"tag": "", tag--外层元素代码:不写tag字段默认div包裹,tag传空值则去除默认父级元素,
传xxx,则父级元素为<xxx></xxx>
"settings": [
{
"id": "title",
"type": "richtext",
"label": "标题"
},
...省略相关代码,⚠️:添加时需关注配置项是否适配 3.0 。
],
"block":[]
}
{{/schema}}
添加完,按照 block 显示需求,修改对应的 section 文件。
3.0 组件 case-studies.html 引用 blocks 示例如下:
<div class="case-studies-swiper">
<div class="swiper-wrapper">
{{#blocks }} ⚠️:需关注当前 helper 是否适配 3.0,如 3.0 渲染 block 不支持使用 for 。
{{#if forblock.type == "$product-card-content" }} 如区块为私有区块,则添加 $ 符号
{{#block /}}
{{/if }}
{{/blocks }}
</div>
</div>
{{#schema}}
{
"name": "Case Studies",
"settings": [
...省略上方相关代码
],
"blocks":[
{
"type": "$product-card-content", 如区块为私有区块,则添加 $ 符号,公有区块则去除。
"limit": 1 添加该区块的最大数量
},
...省略上方相关代码
]
}
{{/schema}}
5.2.4. 修改 presets 预设代码
假设 2.1 定制组件在 presets 的代码如下:
"presets": [
{
"category_index": 1,
"category": "t:sections.rich-text.presets.presets__0.category",
"name": "t:sections.rich-text.presets.presets__0.name",
"settings": {
"desktop_content_position": "center",
"color_scheme": "none",
"normal_width": true,
"show_decoration": false,
"padding_top": 60,
"padding_bottom": 60
},
"blocks": [
{
"type": "heading",
"settings": {
"heading": "heading",
"heading_size": "title3"
}
},
{
"type": "text",
"settings": {
"text": "<p>A sentence or two introducing your brand, what you sell, and what makes your brand compelling to customers.</p>"
}
}
]
}
]
:3.0 组件 presets 下的 blocks 支持嵌套,整个组件的层级最多为五层。
3.0 组件 presets 下的 blocks 嵌套代码示例如下:
"presets": [
{
"name": "视频推荐商品", 一层
"settings":{
...省略其他配置代码
},
"blocks": [
{
"type": "$float-video" 二层
},
{
"type": "$collection", 二层
"blocks": [
{
"type": "$product-card", 三层
"blocks": [
{
"type": "$image" 四层
"blocks": [
{
"type": "$title" 五层
}
]
},
{
"type": "$quick_add" 四层
}
]
}
]
}
]
}
]
按照目前 3.0 组件 blocks 的类型,进行修改。
对应的 3.0 组件 presets 代码示例如下:
"presets": [
{
"category_index": 1,
"category": "t:sections.rich-text.presets.presets__0.category",
"name": "t:sections.rich-text.presets.presets__0.name",
"settings": {
...省略其他配置代码
},
"blocks": [
{
"type": "$heading", 如区块为私有区块,则添加 $ 符号,公有区块则去除。
"settings": {
"heading": "heading",
"heading_size": "title3"
},
"blocks":[ 按照组件的新显示需求,将区块进行嵌套
{
"type":"text",
"settings": {
"text": "<p>A sentence or two introducing your brand, what you sell, and what makes your brand compelling to customers.</p>"
}
}
]
}
]
}
]
5.2.5. 将 2.1 组件 locales 多语言文件代码搬迁至 3.0 i18n
假设原定制组件在 locales 目录下 zh-hans-cn.schema 的语料如下:
{
"sections": {
...省略其他语料代码
"main-article": {
"name": "博客文章",
"blocks": {
"select": {
"name": "配图",
"settings": {
"image_height": {
"label": "封面图高度",
"options__0": {
"label": "适应图片"
},
"options__1": {
"label": "小"
},
"options__2": {
"label": "中"
},
"options__3": {
"label": "大"
}
}
}
},
"title": {
"name": "标题",
"settings": {
"blog_show_date": {
"label": "显示日期"
},
"blog_show_author": {
"label": "显示作者"
}
}
},
"share": {
"name": "分享"
},
"content": {
"name": "内容"
}
}
}
},
"settings_schema":{
...省略其他语料的代码
}
}
可直接将对应 json 复制粘贴至 3.0 i18n 目录下的 zh-hans-cn.schema
对应的 3.0 zh-hans-cn.schema 引用 blocks 示例如下:
{
"sections": {
...省略其他语料代码
"main-article": {
"name": "博客文章",
"blocks": {
"select": {
"name": "配图",
"settings": {
"image_height": {
"label": "封面图高度",
"options__0": {
"label": "适应图片"
},
"options__1": {
"label": "小"
},
"options__2": {
"label": "中"
},
"options__3": {
"label": "大"
}
}
}
},
"title": {
"name": "标题",
"settings": {
"blog_show_date": {
"label": "显示日期"
},
"blog_show_author": {
"label": "显示作者"
}
}
},
"share": {
"name": "分享"
},
"content": {
"name": "内容"
}
}
}
},
"settings_schema":{
...省略其他语料的代码
},
"blocks":{
...省略其他语料的代码
}
}
在对应位置,继续使用引用代码即可。
按照以上操作,即可实现将 2.1 主题定制组件搬迁至 3.0 主题。













