Skip to Content
🎉 探索 Shopify 的无限可能 结构化知识 + 实战案例,持续更新中...
Liquid 开发主题设置配置

主题设置配置

主题设置允许商家通过主题编辑器自定义主题外观和功能,无需编写代码。本指南将详细介绍如何创建完善的主题设置系统。

设置文件结构

1. settings_schema.json 基础结构

[ { "name": "theme_info", "theme_name": "我的主题", "theme_version": "1.0.0", "theme_author": "开发者名称", "theme_documentation_url": "https://docs.example.com", "theme_support_url": "https://support.example.com" }, { "name": "全局颜色", "settings": [ { "type": "header", "content": "主要颜色" }, { "type": "color", "id": "color_primary", "label": "主色调", "default": "#1a1a1a", "info": "用于按钮、链接等主要元素" }, { "type": "color", "id": "color_secondary", "label": "辅助色", "default": "#666666", "info": "用于辅助信息和装饰元素" }, { "type": "color", "id": "color_accent", "label": "强调色", "default": "#ff6b6b", "info": "用于促销、警告等需要突出的元素" } ] }, { "name": "字体设置", "settings": [ { "type": "header", "content": "标题字体" }, { "type": "font_picker", "id": "font_heading", "label": "标题字体", "default": "assistant_n4" }, { "type": "range", "id": "font_heading_scale", "label": "标题字体缩放", "min": 100, "max": 150, "step": 5, "unit": "%", "default": 120 }, { "type": "header", "content": "正文字体" }, { "type": "font_picker", "id": "font_body", "label": "正文字体", "default": "assistant_n4" }, { "type": "range", "id": "font_body_scale", "label": "正文字体缩放", "min": 80, "max": 120, "step": 5, "unit": "%", "default": 100 } ] }, { "name": "布局设置", "settings": [ { "type": "header", "content": "页面宽度" }, { "type": "range", "id": "page_width", "label": "最大页面宽度", "min": 1000, "max": 1600, "step": 50, "unit": "px", "default": 1200 }, { "type": "checkbox", "id": "enable_sticky_header", "label": "启用粘性头部", "default": true }, { "type": "select", "id": "grid_gutter", "label": "网格间距", "options": [ { "value": "small", "label": "小" }, { "value": "medium", "label": "中" }, { "value": "large", "label": "大" } ], "default": "medium" } ] }, { "name": "产品设置", "settings": [ { "type": "header", "content": "产品卡片" }, { "type": "checkbox", "id": "show_vendor", "label": "显示品牌", "default": false }, { "type": "checkbox", "id": "show_secondary_image", "label": "悬停显示第二张图片", "default": true }, { "type": "select", "id": "product_image_ratio", "label": "产品图片比例", "options": [ { "value": "natural", "label": "自然" }, { "value": "square", "label": "正方形" }, { "value": "portrait", "label": "竖向" }, { "value": "landscape", "label": "横向" } ], "default": "natural" }, { "type": "header", "content": "产品页面" }, { "type": "select", "id": "product_gallery_layout", "label": "图片画廊布局", "options": [ { "value": "stacked", "label": "堆叠" }, { "value": "thumbnails_left", "label": "缩略图在左" }, { "value": "thumbnails_bottom", "label": "缩略图在下" } ], "default": "thumbnails_bottom" }, { "type": "checkbox", "id": "enable_image_zoom", "label": "启用图片放大", "default": true } ] }, { "name": "购物车设置", "settings": [ { "type": "header", "content": "购物车行为" }, { "type": "select", "id": "cart_type", "label": "购物车类型", "options": [ { "value": "drawer", "label": "侧边抽屉" }, { "value": "page", "label": "独立页面" }, { "value": "popup", "label": "弹窗" } ], "default": "drawer" }, { "type": "checkbox", "id": "cart_notes_enable", "label": "启用订单备注", "default": true }, { "type": "range", "id": "free_shipping_threshold", "label": "免费配送门槛", "min": 0, "max": 1000, "step": 50, "unit": "¥", "default": 200 } ] }, { "name": "社交媒体", "settings": [ { "type": "header", "content": "社交媒体链接" }, { "type": "url", "id": "social_facebook_link", "label": "Facebook", "info": "https://facebook.com/yourstore" }, { "type": "url", "id": "social_twitter_link", "label": "Twitter", "info": "https://twitter.com/yourstore" }, { "type": "url", "id": "social_instagram_link", "label": "Instagram", "info": "https://instagram.com/yourstore" }, { "type": "url", "id": "social_youtube_link", "label": "YouTube", "info": "https://youtube.com/yourstore" }, { "type": "url", "id": "social_weibo_link", "label": "微博", "info": "https://weibo.com/yourstore" }, { "type": "url", "id": "social_wechat_qr", "label": "微信二维码图片链接" } ] }, { "name": "SEO 设置", "settings": [ { "type": "header", "content": "搜索引擎优化" }, { "type": "image_picker", "id": "favicon", "label": "网站图标", "info": "推荐 32x32px PNG 格式" }, { "type": "image_picker", "id": "social_sharing_image", "label": "社交分享图片", "info": "推荐 1200x630px,用于 Facebook、Twitter 等社交媒体分享" }, { "type": "textarea", "id": "social_sharing_description", "label": "默认分享描述", "info": "当页面没有特定描述时使用" } ] }, { "name": "高级设置", "settings": [ { "type": "header", "content": "分析和跟踪" }, { "type": "text", "id": "google_analytics_id", "label": "Google Analytics ID", "info": "例如: G-XXXXXXXXXX" }, { "type": "text", "id": "facebook_pixel_id", "label": "Facebook Pixel ID" }, { "type": "header", "content": "性能优化" }, { "type": "checkbox", "id": "enable_lazyload", "label": "启用图片懒加载", "default": true }, { "type": "checkbox", "id": "minify_css", "label": "压缩 CSS", "default": false, "info": "可能影响主题编辑器预览" }, { "type": "header", "content": "自定义代码" }, { "type": "textarea", "id": "custom_css", "label": "自定义 CSS", "info": "在此添加自定义样式代码" }, { "type": "textarea", "id": "custom_js", "label": "自定义 JavaScript", "info": "在此添加自定义脚本代码" } ] } ]

2. 设置在模板中的使用

<!-- layout/theme.liquid --> <!DOCTYPE html> <html lang="{{ shop.locale }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- SEO 设置 --> {% if settings.favicon %} <link rel="icon" type="image/png" href="{{ settings.favicon | img_url: '32x32' }}"> {% endif %} <!-- 社交分享 --> <meta property="og:image" content="{{ settings.social_sharing_image | default: shop.brand.logo | img_url: '1200x630' }}"> <meta property="og:description" content="{{ page_description | default: settings.social_sharing_description | default: shop.description }}"> <!-- 字体设置 --> <style> {{ settings.font_heading | font_face: font_display: 'swap' }} {{ settings.font_body | font_face: font_display: 'swap' }} :root { /* 颜色变量 */ --color-primary: {{ settings.color_primary }}; --color-secondary: {{ settings.color_secondary }}; --color-accent: {{ settings.color_accent }}; /* 字体变量 */ --font-heading-family: {{ settings.font_heading.family }}, {{ settings.font_heading.fallback_families }}; --font-body-family: {{ settings.font_body.family }}, {{ settings.font_body.fallback_families }}; --font-heading-scale: {{ settings.font_heading_scale }}%; --font-body-scale: {{ settings.font_body_scale }}%; /* 布局变量 */ --page-width: {{ settings.page_width }}px; --grid-gutter: {% case settings.grid_gutter %} {% when 'small' %}1rem {% when 'large' %}3rem {% else %}2rem {% endcase %}; } body { font-family: var(--font-body-family); font-size: calc(1rem * var(--font-body-scale) / 100); } h1, h2, h3, h4, h5, h6 { font-family: var(--font-heading-family); font-size: calc(1em * var(--font-heading-scale) / 100); } .container { max-width: var(--page-width); margin: 0 auto; padding: 0 var(--grid-gutter); } </style> <!-- 自定义 CSS --> {% if settings.custom_css != blank %} <style>{{ settings.custom_css }}</style> {% endif %} </head> <body class="template-{{ template.name }}"> <!-- 粘性头部 --> <header class="site-header {% if settings.enable_sticky_header %}site-header--sticky{% endif %}"> <!-- 头部内容 --> </header> <main class="main-content" role="main"> {{ content_for_layout }} </main> <footer class="site-footer"> <!-- 社交媒体链接 --> {% if settings.social_facebook_link != blank or settings.social_twitter_link != blank or settings.social_instagram_link != blank %} <div class="social-links"> {% if settings.social_facebook_link != blank %} <a href="{{ settings.social_facebook_link }}" target="_blank" rel="noopener" aria-label="Facebook"> {% render 'icon-facebook' %} </a> {% endif %} {% if settings.social_twitter_link != blank %} <a href="{{ settings.social_twitter_link }}" target="_blank" rel="noopener" aria-label="Twitter"> {% render 'icon-twitter' %} </a> {% endif %} {% if settings.social_instagram_link != blank %} <a href="{{ settings.social_instagram_link }}" target="_blank" rel="noopener" aria-label="Instagram"> {% render 'icon-instagram' %} </a> {% endif %} </div> {% endif %} </footer> <!-- 分析代码 --> {% if settings.google_analytics_id != blank %} <!-- Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id={{ settings.google_analytics_id }}"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '{{ settings.google_analytics_id }}'); </script> {% endif %} {% if settings.facebook_pixel_id != blank %} <!-- Facebook Pixel --> <script> !function(f,b,e,v,n,t,s) {if(f.fbq)return;n=f.fbq=function(){n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)}; if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0]; s.parentNode.insertBefore(t,s)}(window, document,'script', 'https://connect.facebook.net/en_US/fbevents.js'); fbq('init', '{{ settings.facebook_pixel_id }}'); fbq('track', 'PageView'); </script> {% endif %} <!-- 自定义 JavaScript --> {% if settings.custom_js != blank %} <script>{{ settings.custom_js }}</script> {% endif %} </body> </html>

条件设置和依赖关系

1. 动态设置显示

{ "name": "头部设置", "settings": [ { "type": "select", "id": "header_style", "label": "头部样式", "options": [ { "value": "simple", "label": "简洁" }, { "value": "centered", "label": "居中" }, { "value": "drawer", "label": "抽屉式" } ], "default": "simple" }, { "type": "checkbox", "id": "show_search", "label": "显示搜索框", "default": true }, { "type": "select", "id": "search_style", "label": "搜索框样式", "options": [ { "value": "icon", "label": "图标" }, { "value": "input", "label": "输入框" }, { "value": "modal", "label": "模态框" } ], "default": "icon", "info": "需要启用搜索功能" } ] }

2. 在模板中处理条件逻辑

<!-- snippets/header-search.liquid --> {% if settings.show_search %} <div class="header-search header-search--{{ settings.search_style }}"> {% case settings.search_style %} {% when 'icon' %} <button type="button" class="search-toggle" data-search-open> {% render 'icon-search' %} </button> {% when 'input' %} <form action="{{ routes.search_url }}" method="get" class="search-form"> <input type="search" name="q" placeholder="搜索..." class="search-input" value="{{ search.terms | escape }}"> <button type="submit" class="search-submit"> {% render 'icon-search' %} </button> </form> {% when 'modal' %} <button type="button" class="search-modal-toggle" data-search-modal> {% render 'icon-search' %} <span>搜索</span> </button> {% endcase %} </div> {% endif %}

高级设置组合

1. 复杂产品设置

{ "name": "产品集合设置", "settings": [ { "type": "header", "content": "集合页面" }, { "type": "range", "id": "products_per_page", "label": "每页产品数量", "min": 12, "max": 48, "step": 12, "default": 24 }, { "type": "select", "id": "collection_layout", "label": "集合布局", "options": [ { "value": "grid", "label": "网格" }, { "value": "list", "label": "列表" }, { "value": "masonry", "label": "瀑布流" } ], "default": "grid" }, { "type": "range", "id": "grid_columns_desktop", "label": "桌面端列数", "min": 2, "max": 6, "step": 1, "default": 4 }, { "type": "range", "id": "grid_columns_tablet", "label": "平板端列数", "min": 2, "max": 4, "step": 1, "default": 3 }, { "type": "range", "id": "grid_columns_mobile", "label": "移动端列数", "min": 1, "max": 2, "step": 1, "default": 2 }, { "type": "header", "content": "过滤器和排序" }, { "type": "checkbox", "id": "enable_filtering", "label": "启用过滤器", "default": true }, { "type": "checkbox", "id": "enable_sorting", "label": "启用排序", "default": true }, { "type": "checkbox", "id": "enable_search_within_collection", "label": "启用集合内搜索", "default": false } ] }

2. 多语言设置支持

{ "name": "多语言内容", "settings": [ { "type": "header", "content": "欢迎消息" }, { "type": "text", "id": "welcome_message_zh", "label": "欢迎消息 (中文)", "default": "欢迎来到我们的商店!" }, { "type": "text", "id": "welcome_message_en", "label": "欢迎消息 (English)", "default": "Welcome to our store!" }, { "type": "header", "content": "按钮文字" }, { "type": "text", "id": "button_add_to_cart_zh", "label": "添加到购物车按钮 (中文)", "default": "加入购物车" }, { "type": "text", "id": "button_add_to_cart_en", "label": "添加到购物车按钮 (English)", "default": "Add to Cart" } ] }

3. 使用多语言设置

<!-- snippets/localized-text.liquid --> {% comment %} 多语言文本组件 参数: - key: 设置键名前缀 (必需) - fallback: 备用文本 (可选) {% endcomment %} {% assign current_locale = request.locale.iso_code %} {% assign setting_key = key | append: '_' | append: current_locale %} {% assign localized_text = settings[setting_key] %} {% if localized_text != blank %} {{ localized_text }} {% elsif fallback %} {{ fallback }} {% else %} {{ settings[key | append: '_zh'] | default: settings[key | append: '_en'] }} {% endif %}
<!-- 使用示例 --> <h1 class="welcome-message"> {% render 'localized-text', key: 'welcome_message', fallback: '欢迎访问!' %} </h1> <button type="submit" class="btn btn--primary"> {% render 'localized-text', key: 'button_add_to_cart' %} </button>

设置验证和错误处理

1. 前端验证

<!-- assets/theme-settings.js --> <script> class ThemeSettings { constructor() { this.init() } init() { this.validateSettings() this.setupDependencies() } validateSettings() { // 验证必需的设置 const requiredSettings = [ 'color_primary', 'font_heading', 'font_body' ] requiredSettings.forEach(setting => { if (!this.getSetting(setting)) { console.warn(`主题设置缺失: ${setting}`) } }) // 验证颜色格式 const colorSettings = [ 'color_primary', 'color_secondary', 'color_accent' ] colorSettings.forEach(setting => { const color = this.getSetting(setting) if (color && !this.isValidColor(color)) { console.warn(`无效的颜色值: ${setting} = ${color}`) } }) } setupDependencies() { // 根据设置调整其他元素 const headerStyle = this.getSetting('header_style') if (headerStyle === 'drawer') { document.body.classList.add('header-drawer-enabled') } // 动态加载功能 const enableLazyload = this.getSetting('enable_lazyload') if (enableLazyload) { this.loadLazyloadScript() } } getSetting(key) { return window.themeSettings?.[key] } isValidColor(color) { const s = new Option().style s.color = color return s.color !== '' } loadLazyloadScript() { if (!document.querySelector('[data-lazysizes]')) { const script = document.createElement('script') script.src = 'https://cdn.jsdelivr.net/npm/lazysizes@5/lazysizes.min.js' script.dataset.lazysizes = 'true' document.head.appendChild(script) } } } // 暴露设置到全局 window.themeSettings = { color_primary: '{{ settings.color_primary }}', color_secondary: '{{ settings.color_secondary }}', color_accent: '{{ settings.color_accent }}', font_heading: '{{ settings.font_heading.family }}', font_body: '{{ settings.font_body.family }}', header_style: '{{ settings.header_style }}', enable_lazyload: {{ settings.enable_lazyload | json }}, // 添加其他需要在 JavaScript 中使用的设置 } // 初始化主题设置 document.addEventListener('DOMContentLoaded', () => { new ThemeSettings() }) </script>

2. 设置备用值

<!-- snippets/safe-settings.liquid --> {% comment %} 安全设置获取器,提供备用值和验证 {% endcomment %} {% assign safe_color_primary = settings.color_primary | default: '#1a1a1a' %} {% assign safe_color_secondary = settings.color_secondary | default: '#666666' %} {% assign safe_color_accent = settings.color_accent | default: '#ff6b6b' %} {% assign safe_page_width = settings.page_width | default: 1200 %} {% if safe_page_width < 1000 %} {% assign safe_page_width = 1000 %} {% elsif safe_page_width > 1600 %} {% assign safe_page_width = 1600 %} {% endif %} {% assign safe_grid_gutter = settings.grid_gutter | default: 'medium' %} {% unless safe_grid_gutter == 'small' or safe_grid_gutter == 'medium' or safe_grid_gutter == 'large' %} {% assign safe_grid_gutter = 'medium' %} {% endunless %} <!-- 在样式中使用安全值 --> <style> :root { --color-primary: {{ safe_color_primary }}; --color-secondary: {{ safe_color_secondary }}; --color-accent: {{ safe_color_accent }}; --page-width: {{ safe_page_width }}px; --grid-gutter: {% case safe_grid_gutter %} {% when 'small' %}1rem {% when 'large' %}3rem {% else %}2rem {% endcase %}; } </style>

设置迁移和版本控制

1. 设置版本管理

{ "name": "theme_info", "theme_name": "我的主题", "theme_version": "2.1.0", "theme_author": "开发者名称", "theme_documentation_url": "https://docs.example.com", "theme_support_url": "https://support.example.com", "settings": [ { "type": "text", "id": "theme_version_check", "label": "主题版本", "default": "2.1.0", "info": "用于版本检查和设置迁移" } ] }

2. 设置迁移脚本

<!-- assets/settings-migration.liquid --> <script> class SettingsMigration { constructor() { this.currentVersion = '{{ settings.theme_version_check | default: "1.0.0" }}' this.targetVersion = '2.1.0' if (this.needsMigration()) { this.migrate() } } needsMigration() { return this.compareVersions(this.currentVersion, this.targetVersion) < 0 } migrate() { console.log(`迁移主题设置从 ${this.currentVersion} 到 ${this.targetVersion}`) // v1.0.0 到 v2.0.0 的迁移 if (this.compareVersions(this.currentVersion, '2.0.0') < 0) { this.migrateToV2() } // v2.0.0 到 v2.1.0 的迁移 if (this.compareVersions(this.currentVersion, '2.1.0') < 0) { this.migrateToV21() } } migrateToV2() { // 重命名的设置 this.renameSetting('old_color_primary', 'color_primary') this.renameSetting('old_font_size', 'font_body_scale') // 删除废弃的设置 this.removeSetting('deprecated_option') console.log('已迁移到 v2.0.0') } migrateToV21() { // 新的默认值迁移 this.setDefaultIfEmpty('enable_lazyload', true) this.setDefaultIfEmpty('cart_type', 'drawer') console.log('已迁移到 v2.1.0') } compareVersions(v1, v2) { const parts1 = v1.split('.').map(Number) const parts2 = v2.split('.').map(Number) for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) { const part1 = parts1[i] || 0 const part2 = parts2[i] || 0 if (part1 < part2) return -1 if (part1 > part2) return 1 } return 0 } renameSetting(oldKey, newKey) { const oldValue = localStorage.getItem(`theme_setting_${oldKey}`) if (oldValue) { localStorage.setItem(`theme_setting_${newKey}`, oldValue) localStorage.removeItem(`theme_setting_${oldKey}`) } } removeSetting(key) { localStorage.removeItem(`theme_setting_${key}`) } setDefaultIfEmpty(key, defaultValue) { const currentValue = localStorage.getItem(`theme_setting_${key}`) if (!currentValue) { localStorage.setItem(`theme_setting_${key}`, JSON.stringify(defaultValue)) } } } // 执行迁移 new SettingsMigration() </script>

最佳实践总结

1. 设置组织原则

  • 逻辑分组: 将相关设置归类到同一组
  • 清晰命名: 使用描述性的标签和ID
  • 提供帮助: 为复杂设置添加说明信息
  • 合理默认值: 设置适当的默认值
  • 渐进增强: 从基础设置开始,逐步添加高级选项

2. 性能考虑

  • CSS变量: 使用CSS自定义属性管理动态样式
  • 条件加载: 根据设置条件性加载资源
  • 缓存友好: 避免频繁更改会影响缓存的设置

3. 用户体验

  • 即时预览: 确保设置更改能立即在预览中体现
  • 合理限制: 为数值设置适当的最小值和最大值
  • 直观操作: 选择最适合的输入控件类型

通过完善的主题设置系统,您可以创建出既灵活又易用的 Shopify 主题!

下一步学习

掌握主题设置配置后,建议继续学习:

  1. 响应式设计实现 - 移动优先设计
  2. 电商功能实现 - 高级电商功能
  3. 第三方集成 - 外部服务集成
  4. 测试和部署 - 质量保证流程
最后更新时间: