Liquid开发之Shopify自定义section

3,384 阅读4分钟

新增section组件

sections目录下新建名为my-carousel.liquid文件 新增有两种方式:

  • 可通过本地开发直接新建,编辑完的section需要deploy发布对应的主题代码库上,可通过命令行 theme deploy sections/my-carousel.liquid部署该新建的section;
  • 通过shopify端,Online Store --> Theme --> Actions --> edit code, 然后在sections目录,点击 Add a new section来新建,这种方式新增的section有以下默认代码片段,接着通过命令行 theme download sections/my-carousel.liquid来同步代码到本地开发环境:
{% schema %}
{
    "name": "Section name",
    "settings": []
}
{% endschema %}
{% stylesheet %}
{% endstylesheet %}
{% javascript %}
{% endjavascript %}

section组件开发步骤拆解

  1. 编写html结构;
  2. 编写js逻辑;
  3. 编写css样式;
  4. 编写schema配置,将section的内容可配置化;
    下面以一个图片轮播组件作为例子来说明开发步骤,其功能需求:
  • 图片轮播的数量可配置;
  • 点击图片可以跳转指定的link;
  • link类型分为3种:商品详情页商品列表页自定义link

编写section的html结构

编写sections/my-mobi-carousel.liquidhtml结构,代码如下:

<div class="carousel-section>
    <section class="swiper-container">
        <div class="swiper-wrapper">
            <a href="#">
                <div class="swiper-slide">
                    <img src="#" alt="" />
                </div>
            </a>
        </div>
    </section>
</div>

编写section的js逻辑

编写sections/my-carousel.liquidjs逻辑,这里我采用了第三方swiper库,这里以Swiper 2.x版本作为示例,注意不同的Swiper版本使用会有一定的差异,所以其所依赖的文件有3个,分别是jquery.jsswiper.min.jsswiper.min.css,其中jquery.js可以在layout上面引入,其他2个文件分别放在assets目录下:

<!doctype html>
<html class="suports-no-js" lang="{{ shop.locale }}">
    <head>
        <meta charset="UTF-8">
        <title>
            {{ shop.name }}
        </title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1">
        {{ content_for-header }}
        <!-- 自定义的carousel.liquid section需要jq依赖库,故在加载其前引入 -->
        {{ 'jquery-1.11.0.min.js' | assets_url | script_tag }}
    </head>
    <body>
        <!-- 这里必须引入,不然page.activity.liquid配置的aection不能正常显示对应的配置 -->
        {{ content_for_layout }}
    </body>
</html>

然后sections/my-carousel.liquid文件,代码修改为如下:

{{ 'swiper.min.css' | asset_url | stylesheet_tag }}
<div class="carousel-section>
    <section class="swiper-container">
        <div class="swiper-wrapper">
            <a href="#">
                <div class="swiper-slide">
                    <img src="#" alt="" />
                </div>
            </a>
        </div>
        <!-- Add Pagination -->
        <div class="swiper-pagination"></div>
    </section>
</div>

<script src="{{ 'swiper.min.js' | asset_url }}"></script>
<script>
$(function(){
    var swiprt = new Swiper('.swiper-container', {
        pagination: {
            el: '.swiper-pagination'
        },
    });
});
</script>

编写section的css样式

编写sections/my-carousel.liquidcss样式文件assets/my-carousel.scss,代码如下:

.carousel-section {
    margin: 50px auto;
    .swiper-container {
        width: 100%;
        height: 100%;
    }
    .swiper-slide {
        display: flex;
        justify-content: center;
        align-items: center;
        overflow: hidden;
        max-height: 200px;
        border-radius: 15px;
        text-align: center;
        font-size: 18px;
        background: #fff;
    }
    .swiper-slide img {
        display: block;
        width: 100%;
        min-height: 170px;
    }
}

然后在sections/my-carousel.liquid文件引入assets/my-carousel.scss,(一定要注意是'my-carousel.scss.css'而不是'my-carousel.scss'),这里shopify服务器会自动将scss文件编译成css文件,修改后的sections/my-carousel.liquid代码如下:

{{ 'swiper.min.css' | asset_url | stylesheet_tag }}
{{ 'my-carousel.scss.css' | asset_url | stylesheet_tag }}
<div class="carousel-section>
    <section class="swiper-container">
        <div class="swiper-wrapper">
            <a href="#">
                <div class="swiper-slide">
                    <img src="#" alt="" />
                </div>
            </a>
        </div>
        <!-- Add Pagination -->
        <div class="swiper-pagination"></div>
    </section>
</div>

<script src="{{ 'swiper.min.js' | asset_url }}"></script>
<script>
$(function(){
    var swiprt = new Swiper('.swiper-container', {
        pagination: {
            el: '.swiper-pagination'
        },
    });
});
</script>

编写section的schema部分

最后编写sections/my-carousel.liquidschema setting部分,将section的内容可配置化。

  • section schema 配置具体说明可以查看这里
  • 同时settingspresets配置项需要着重理解和运用,settings配置详情可查看这里。 由官方文档得知,settings分为Basic setting typesSpecialized input setting types。 如果我们希望在shopify管理后台侧的home pageAdd sections界面下找到自己自定义的section,则需要设置presets对应的参数,这里的my-carousel.liquidpresets配置如下:
"presets": [
    {
        "name": "Carousel",
        "category": "My Sections",
        "blocks": []
    }
]

配置完成后,在Add sections界面展示的效果如下图所示:

微信图片_20220305161358.png

微信图片_20220305161402.png

sections/my-carousel.liquidschema根据需求一一对应添加,

  • 图片轮播的数量可配置,则需要blocks属性;
  • 添加图片,则是需要typeimage_picker
  • link类型分为3种:
  1. 商品详情页,则需要配置对应的typeproduct
  2. 商品列表页,则需要配置对应的typecollection
  3. 自定义link,则需要配置对应的typeurl; 其代码如下:
{% schema %}
    {
        "name": "Activity-section-carousel",
        "max_blocks": 10,
        "settings": [
            {
                "type": "checkbox",
                "id": "carousel_autoplay",
                "label": "Auto rotate between slides",
                "default": true
            },
            {
                "type": "range",
                "id": "carousel_autoplay_speed",
                "label": "Change slides every",
                "min": 4,
                "max": 10,
                "unit": "s",
                "step": 1,
                "default": 6
            }
        ],
        "blocks": [
            {
                "type": "image",
                "name": "Slide",
                "settings": [
                    {
                        "type": "image_picker",
                        "id": "image",
                        "label": "Image"
                    },
                    {
                        "type": "radio",
                        "id": "link_type",
                        "label": "Link Type",
                        "options": [
                            {"value": "product", "label": "product"},
                            {"value": "collection", "label": "collection"},
                            {"value": "other", "lable": "other"}
                        ]
                    },
                    {
                        "type": "product",
                        "id": "link_product",
                        "label": "link to product detail",
                        "info": "if you choose 'Link Type' as 'product', you should set it"
                    },
                    {
                        "type": "collection",
                        "id": "link_collection",
                        "label": "link to product collection",
                        "info": "if you choose 'Link Type' as 'collection', you should set it"
                    },
                    {
                        "type": "url",
                        "id": "link_other",
                        "label": "link to other page",
                        "info": "if you choose 'Link Type' as 'other', you should set it"
                    }
                ]
            }
        ],
        "presets": [
            {
                "name": "Carousel",
                "category": "My Sections",
                "blocks": []
            }
        ]
    }
{% endschema %}

然后修改sections/my-carousel.liquid文件的html代码,最终完整代码如下:

{{ 'swiper.min.css' | asset_url | stylesheet_tag }}
{{ 'my-carousel.scss.css' | asset_url | stylesheet_tag }}
<div class="carousel-section>
    <section class="swiper-container">
        <div class="swiper-wrapper">
            {% for block in section.blocks %}
                {% if block.settings.image == blank %}
                    {{ 'lifestyle-1' | placeholder_svg_tag: 'placeholder-svg' }}
                {% else %}
                    {% if block.settings.link_type == 'product' and block.settings.link_product.url != blank %}
                        <a href="{{ block.settings.link_product.url }}">
                            <div class="swiper-slide">
                                {% assign img_url = block.settings.image | img_url: '1024x1024' %}
                                <img src="{{ img_url }} alt="" />
                            </div>
                        </a>
                    {% elsif block.settings.link_type == 'collection' and block.settings.link_collection.url != blank %}
                        <a href="{{ block.settings.link_collection.url }}">
                            <div class="swiper-slide">
                                {% assign img_url = block.settings.image | img_url: '1024x1024' %}
                                <img src="{{ img_url }} alt="" />
                            </div>
                        </a>
                    {% elsif block.settings.link_type == 'other' and block.settings.link_other.url != blank %}
                        <a href="{{ block.settings.link_other.url }}">
                            <div class="swiper-slide">
                                {% assign img_url = block.settings.image | img_url: '1024x1024' %}
                                <img src="{{ img_url }} alt="" />
                            </div>
                        </a>
                    {% else %}
                        <div class="swiper-slide">
                            {% assign img_url = block.settings.image | img_url: '1024x1024' %}
                            <img src="{{ img_url }} alt="" />
                        </div>
                     {% endif %}
                 {% endif %}
             {% endfor %}
        </div>
        <!-- Add Pagination -->
        <div class="swiper-pagination"></div>
    </section>
</div>

<script src="{{ 'swiper.min.js' | asset_url }}"></script>
<script>
$(function(){
    var swiprt = new Swiper('.swiper-container', {
        pagination: {
            el: '.swiper-pagination'
        },
    });
});
</script>

{% schema %}
    {
        "name": "Activity-section-carousel",
        "max_blocks": 10,
        "settings": [
            {
                "type": "checkbox",
                "id": "carousel_autoplay",
                "label": "Auto rotate between slides",
                "default": true
            },
            {
                "type": "range",
                "id": "carousel_autoplay_speed",
                "label": "Change slides every",
                "min": 4,
                "max": 10,
                "unit": "s",
                "step": 1,
                "default": 6
            }
        ],
        "blocks": [
            {
                "type": "image",
                "name": "Slide",
                "settings": [
                    {
                        "type": "image_picker",
                        "id": "image",
                        "label": "Image"
                    },
                    {
                        "type": "radio",
                        "id": "link_type",
                        "label": "Link Type",
                        "options": [
                            {"value": "product", "label": "product"},
                            {"value": "collection", "label": "collection"},
                            {"value": "other", "lable": "other"}
                        ]
                    },
                    {
                        "type": "product",
                        "id": "link_product",
                        "label": "link to product detail",
                        "info": "if you choose 'Link Type' as 'product', you should set it"
                    },
                    {
                        "type": "collection",
                        "id": "link_collection",
                        "label": "link to product collection",
                        "info": "if you choose 'Link Type' as 'collection', you should set it"
                    },
                    {
                        "type": "url",
                        "id": "link_other",
                        "label": "link to other page",
                        "info": "if you choose 'Link Type' as 'other', you should set it"
                    }
                ]
            }
        ],
        "presets": [
            {
                "name": "Carousel",
                "category": "My Sections",
                "blocks": []
            }
        ]
    }
{% endschema %}