shopifyにはかっこいいテンプレートが沢山売っています。
外人さんがバリバリに作り込んだテンプレートは圧巻で、至れり尽くせりです。
shopify テンプレート
https://themes.shopify.com/?locale=ja

写真を入れ替えて商品を登録するだけでWEB SHOP完成じゃね!?
みたいな完成度のテンプレートがいっぱい。
しかしそういう流れには多分なりません。
改造したいというのです。
改造といっても聞いたこともないライブラリを使っていますよ。
デキる外人さんのガチガチのオリジナルscriptです。
テンプレートのソースを睨めっこして理解するだけで、簡単に時間が溶けていきます。
いろんなものがインクルードされていて他の箇所に影響しそう。もう初期状態の最初のプレーンな状態から構築したい。
この記事は、そういう考えに落ち着きました人用の、比較的にカスタムすることが多いなと感じる「スライダー」を設置したいという旨の内容のものになります。
【共有】ソースコード
sectionsで追加作成したliquidファイルにそのまま貼り付けれるように、cssとhtmlとscript、schemaを丸っと記述します。
要件は以下です。
- 使い慣れたswiperスライダー。
- sectionで何個もページ内に仕込めるようにしたい。
- ページネーションとnext/prevのボタンあり。
- 画像の上にタイトルとかリンクを入れたい時も想定したい。
- zoom機能【オプション】
html(sections/slideshow-swiper.liquid)
<!-- /sections/slideshow-swiper.liquid -->
{%- style -%}
#shopify-section-{{ section.id }} {
}
.section-{{ section.id }}-padding {
padding-top: calc({{ section.settings.padding_top }}px * 0.75);
padding-bottom: calc({{ section.settings.padding_bottom }}px * 0.75);
}
.section-{{ section.id }}-margin {
margin-left: calc({{ section.settings.margin_left }}px * 0.75);
margin-right: calc({{ section.settings.margin_right }}px * 0.75);
}
@media screen and (min-width: 750px) {
.section-{{ section.id }}-padding {
padding-top: {{ section.settings.padding_top }}px;
padding-bottom: {{ section.settings.padding_bottom }}px;
}
.section-{{ section.id }}-margin {
margin-left: {{ section.settings.margin_left }}px;
margin-right: {{ section.settings.margin_right }}px;
}
}
@media screen and (max-width: 749px) {
.section-{{ section.id }}-margin {
margin-left: 0px;
margin-right: 0px;
}
}
.swiper-slideshow-info {
height: 100%;
display: flex;
align-items: center;
}
.swiper-slideshow-info .slideshow-box {
max-width: 72.6rem;
}
.swiper-slideshow-info.slideshow__box--top-left {
align-items: flex-start;
justify-content: flex-start;
text-align: start;
}
.swiper-slideshow-info.slideshow__box--top-center {
align-items: flex-start;
justify-content: center;
text-align: center;
}
.swiper-slideshow-info.slideshow__box--top-right {
align-items: flex-start;
justify-content: flex-end;
text-align: end;
}
.swiper-slideshow-info.slideshow__box--middle-left {
align-items: center;
justify-content: flex-start;
text-align: start;
}
.swiper-slideshow-info.slideshow__box--middle-center {
align-items: center;
justify-content: center;
text-align: center;
}
.swiper-slideshow-info.slideshow__box--middle-right {
align-items: center;
justify-content: flex-end;
text-align: end;
}
.swiper-slideshow-info.slideshow__box--bottom-left {
align-items: flex-end;
justify-content: flex-start;
text-align: start;
}
.swiper-slideshow-info.slideshow__box--bottom-center {
align-items: flex-end;
justify-content: center;
text-align: center;
}
.swiper-slideshow-info.slideshow__box--bottom-right {
align-items: flex-end;
justify-content: flex-end;
text-align: end;
}
@media screen and (min-width: 750px) {
#set-{{ section.id }}.container {
margin-inline: auto;
max-width: unset;
position: relative;
}
#set-{{ section.id }} .swiper{
max-width: unset;
height: auto;
opacity: 0;
animation: showSwiper 0.2s ease forwards;
}
@keyframes showSwiper {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#set-{{ section.id }} .swiper-slide {
position: relative;
}
#set-{{ section.id }} .swiper-slide > picture img {
object-fit: contain;
width: 100%;
height: 80svh;
}
#set-{{ section.id }} .swiper-pagination {
text-align: center;
position: relative;
}
#set-{{ section.id }} .swiper-horizontal>.swiper-pagination-bullets, #set-{{ section.id }} .swiper-pagination-bullets.swiper-pagination-horizontal, #set-{{ section.id }} .swiper-pagination-custom, #set-{{ section.id }} .swiper-pagination-fraction {
bottom: -5px;
left: unset;
right: unset;
width: 100% !important;
padding: 0 0;
}
#set-{{ section.id }} .swiper-pagination-bullet {
width: var(--swiper-pagination-bullet-width, var(--swiper-pagination-bullet-size, 8px));
height: var(--swiper-pagination-bullet-height, var(--swiper-pagination-bullet-size, 8px));
background: #000 !important;
}
#set-{{ section.id }} .swiper-button-next, #set-{{ section.id }} .swiper-button-prev {
z-index: 1;
}
#set-{{ section.id }} .swiper-button-next, #set-{{ section.id }} .swiper-rtl .swiper-button-prev {
right: var(--swiper-navigation-sides-offset, -55px);
left: auto;
display: block;
}
#set-{{ section.id }} .swiper-button-prev, #set-{{ section.id }} .swiper-rtl .swiper-button-next {
left: var(--swiper-navigation-sides-offset, -55px);
right: auto;
display: block;
}
#set-{{ section.id }} .swiper-button-next:after, #set-{{ section.id }} .swiper-rtl .swiper-button-prev:after {
content: 'next';
}
#set-{{ section.id }} .swiper-button-prev:after, #set-{{ section.id }} .swiper-rtl .swiper-button-next:after {
content: 'prev';
}
#set-{{ section.id }} .swiper-button-next:after, #set-{{ section.id }} .swiper-button-prev:after {
font-family: swiper-icons;
font-size: var(--swiper-navigation-size);
text-transform: none!important;
letter-spacing: 0;
font-variant: initial;
line-height: 1;
width: 6px;
height: 12px;
color: #000;
}
#set-{{ section.id }} .swiper-button-prev:after {
transform: rotate(0deg);
}
#set-{{ section.id }} .swiper-slideshow-info {
position: absolute;
width: calc(100% - 10%);
height: 100%;
left: 0;
top: 0;
padding: 1.4rem 5%;
}
#set-{{ section.id }} .slideshow-subheading {
margin: 1.2rem 0;
}
#set-{{ section.id }} .slideshow-heading {
margin: 1.2rem 0;
}
#set-{{ section.id }} .slideshow-text {
margin: 1.2rem 0;
}
#set-{{ section.id }} .slideshow-button {
}
#set-{{ section.id }} picture {
display: flex;
}
}
@media screen and (max-width: 749px) {
#set-{{ section.id }}.container {
margin-inline: auto;
max-width: unset;
position: relative;
width: auto;
margin: 0 26px 0;
}
#set-{{ section.id }} .swiper{
max-width: unset;
height: auto;
opacity: 0;
animation: showSwiper 0.2s ease forwards;
}
@keyframes showSwiper {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#set-{{ section.id }} .swiper-slide {
position: relative;
}
#set-{{ section.id }} .swiper-slide > picture img {
object-fit: cover;
width: 100%;
height: auto;
}
#set-{{ section.id }} .swiper-pagination {
text-align: center;
position: relative;
}
#set-{{ section.id }} .swiper-horizontal>.swiper-pagination-bullets, #set-{{ section.id }} .swiper-pagination-bullets.swiper-pagination-horizontal, #set-{{ section.id }} .swiper-pagination-custom, #set-{{ section.id }} .swiper-pagination-fraction {
bottom: -5px;
left: unset;
right: unset;
width: 100% !important;
padding: 0 0;
}
#set-{{ section.id }} .swiper-pagination-bullet {
width: var(--swiper-pagination-bullet-width, var(--swiper-pagination-bullet-size, 5px));
height: var(--swiper-pagination-bullet-height, var(--swiper-pagination-bullet-size, 5px));
background: #000 !important;
}
#set-{{ section.id }} .swiper-button-next, #set-{{ section.id }} .swiper-button-prev {
z-index: 1;
}
#set-{{ section.id }} .swiper-button-next, #set-{{ section.id }} .swiper-rtl .swiper-button-prev {
right: var(--swiper-navigation-sides-offset, -35px);
left: auto;
display: flex;
}
#set-{{ section.id }} .swiper-button-prev, #set-{{ section.id }} .swiper-rtl .swiper-button-next {
left: var(--swiper-navigation-sides-offset, -35px);
right: auto;
display: flex;
}
#set-{{ section.id }} .swiper-button-next:after, #set-{{ section.id }} .swiper-rtl .swiper-button-prev:after {
content: 'next';
}
#set-{{ section.id }} .swiper-button-prev:after, #set-{{ section.id }} .swiper-rtl .swiper-button-next:after {
content: 'prev';
}
#set-{{ section.id }} .swiper-button-next:after, #set-{{ section.id }} .swiper-button-prev:after {
font-family: swiper-icons;
font-size: 16px;
text-transform: none!important;
letter-spacing: 0;
font-variant: initial;
line-height: 1;
width: 6px;
height: 12px;
color: #000;
}
#set-{{ section.id }} .swiper-button-prev:after {
transform: rotate(0deg);
}
#set-{{ section.id }} .swiper-slideshow-info {
width: calc(100% - 10%);
height: 100%;
left: 0;
top: 0;
}
#set-{{ section.id }} .slideshow-subheading {
margin: 1.2rem;
}
#set-{{ section.id }} .slideshow-heading {
margin: 1.2rem;
}
#set-{{ section.id }} .slideshow-text {
margin: 1.2rem;
}
#set-{{ section.id }} .slideshow-button {
margin: 1.2rem;
}
#set-{{ section.id }} picture {
display: flex;
}
}
{% comment %}トップページにだけcss{% endcomment %}
{%- if request.page_type == 'index' -%}
{%- endif -%}
{%- endstyle -%}
<div class="page-width section-{{ section.id }}-padding section-{{ section.id }}-margin">
<div id="set-{{ section.id }}" class="container">
<div class="swiper">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
{% for block in section.blocks %}
<div class="swiper-slide">
<picture class="swiper-zoom-container">
<source srcset="{{ block.settings.image | img_url: 'master' }}" media="(min-width: 1024px)">
<source srcset="{{ block.settings.image | img_url: 'master' }}" media="(min-width: 768px)">
<img src="{{ block.settings.image_mobile | img_url: 'master' }}" alt="スライド {{ forloop.index }}">
</picture>
<div class="swiper-slideshow-info slideshow__box--{{ block.settings.text_box_position }}">
<div class="slideshow-box">
{%- if block.settings.subheading != blank -%}
<h5 class="slideshow-subheading {{ block.settings.subheading_size }}">
{{ block.settings.subheading | escape }}
</h5>
{%- endif -%}
{%- if block.settings.heading != blank -%}
<h2 class="slideshow-heading {{ block.settings.heading_size }}">
{{ block.settings.heading | escape }}
</h2>
{%- endif -%}
{%- if block.settings.text != blank -%}
<div class="slideshow-text {{ block.settings.text_size }}">
{{ block.settings.text | escape }}
</div>
{%- endif -%}
{%- if block.settings.button_label != blank -%}
<div class="slideshow-button">
<a class="button"{% if block.settings.button_link != blank %} href="{{ block.settings.button_link }}"{% else %} role="link" aria-disabled="true"{% endif %}>
{{ block.settings.button_label | escape }}
</a>
</div>
{%- endif -%}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
</div>
<!-- swiper -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css" />
<script src="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js"></script>
<script>
const mySwiper = new Swiper('#set-{{ section.id }} .swiper', {
slidesPerView: 1,
spaceBetween: 0,
loop: true,
zoom: {
maxRatio: 3, // 最大拡大率
},
loopAdditionalSlides: 1,
speed: 1000,
autoplay: {
delay: 50000,
disableOnInteraction: false,
},
pagination: {
el: '#set-{{ section.id }} .swiper-pagination',
clickable: true,
},
navigation: {
nextEl: '#set-{{ section.id }} .swiper-button-next',
prevEl: '#set-{{ section.id }} .swiper-button-prev',
},
on: {
init: function () {
this.slides.forEach((slide, index) => {
const formattedIndex = String(index + 1).padStart(2, '0'); // 01, 02, 03の形式にする
slide.classList.add(`index_${formattedIndex}`);
});
},
},
});
</script>
{% schema %}
{
"name": "t:sections.slideshow-swiper.name",
"tag": "section",
"class": "section",
"max_blocks": 50,
"settings": [
{
"type": "paragraph",
"content": "t:sections.slideshow-swiper.settings.paragraph.content"
},
{
"type": "header",
"content": "t:sections.slideshow-swiper.settings.padding.header.content"
},
{
"type": "range",
"id": "padding_top",
"min": 0,
"max": 100,
"step": 4,
"unit": "t:sections.slideshow-swiper.settings.padding.padding_top.unit",
"label": "t:sections.slideshow-swiper.settings.padding.padding_top.label",
"default": 36
},
{
"type": "range",
"id": "padding_bottom",
"min": 0,
"max": 100,
"step": 4,
"unit": "t:sections.slideshow-swiper.settings.padding.padding_bottom.unit",
"label": "t:sections.slideshow-swiper.settings.padding.padding_bottom.label",
"default": 36
},
{
"type": "range",
"id": "margin_left",
"min": 0,
"max": 100,
"step": 4,
"unit": "t:sections.slideshow-swiper.settings.padding.margin_left.unit",
"label": "t:sections.slideshow-swiper.settings.padding.margin_left.label",
"default": 36
},
{
"type": "range",
"id": "margin_right",
"min": 0,
"max": 100,
"step": 4,
"unit": "t:sections.slideshow-swiper.settings.padding.margin_right.unit",
"label": "t:sections.slideshow-swiper.settings.padding.margin_right.label",
"default": 36
}
],
"blocks": [
{
"type": "image",
"name": "t:sections.slideshow-swiper.blocks.image.name",
"settings": [
{
"type": "image_picker",
"id": "image",
"label": "t:sections.slideshow-swiper.blocks.image.settings.image.label"
},
{
"type": "image_picker",
"id": "image_mobile",
"label": "t:sections.slideshow-swiper.blocks.image.settings.image_mobile.label"
},
{
"type": "select",
"id": "text_box_position",
"options": [
{
"value": "top-left",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text_box_position.options__1.label"
},
{
"value": "top-center",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text_box_position.options__2.label"
},
{
"value": "top-right",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text_box_position.options__3.label"
},
{
"value": "middle-left",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text_box_position.options__4.label"
},
{
"value": "middle-center",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text_box_position.options__5.label"
},
{
"value": "middle-right",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text_box_position.options__6.label"
},
{
"value": "bottom-left",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text_box_position.options__7.label"
},
{
"value": "bottom-center",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text_box_position.options__8.label"
},
{
"value": "bottom-right",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text_box_position.options__9.label"
}
],
"default": "middle-center",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text_box_position.label"
},
{
"type": "text",
"id": "subheading",
"label": "t:sections.slideshow-swiper.blocks.image.settings.subheading.label"
},
{
"type": "text",
"id": "heading",
"default": "Image slide",
"label": "t:sections.slideshow-swiper.blocks.image.settings.heading.label"
},
{
"type": "textarea",
"id": "text",
"default": "Give customers details about the slide image or content on the template.",
"label": "t:sections.slideshow-swiper.blocks.image.settings.text.label"
},
{
"type": "text",
"id": "button_label",
"default": "Button label",
"label": "t:sections.slideshow-swiper.blocks.image.settings.button_label.label",
"info": "t:sections.slideshow-swiper.blocks.image.settings.button_label.info"
},
{
"type": "url",
"id": "button_link",
"label": "t:sections.slideshow-swiper.blocks.image.settings.button_link.label"
}
]
}
],
"presets": [
{
"name": "t:sections.slideshow-swiper.presets.name",
"blocks": [
{
"type": "image"
},
{
"type": "image"
}
]
}
]
}
{% endschema %}
cssが多少不備なところもあると思いますが、自由に変えてください。
【オプション】「zoom」機能
スライダーの画像をダブルタップで拡大してくれるswiperのオプション機能です。
358〜360行目
【オプション】で「zoom」機能を入れています。
必要のない場合は消してください。
※もちろん、
「タイトルとかボタン」を画像の上に配置するとなると、重なる部分でうまく動作がいかなくなるでしょう。
その時はzoomを清く諦めましょう。
zoomしたければ、タイトルとかボタンを清く諦めましょう。
zoomしたら非表示にするとか苦労したいときは、AIに相談しましょう。
※next/prevのarrowアイコン(<>)はフォントです。
なんでswiperなんですか?
みんな大好きだからです。
オフィシャルのデモページでは、いろんなスライダーの表現を確認できます。
swiper デモ
https://swiperjs.com/demos
【共有】jsonコード
管理画面の入力箇所の名前のlabelを決めよう。
入力項目のタイトルなどが日本語になるように、以下のファイルにjsonを追加します。
locales/ja.schema.json
{
"slideshow-swiper": {
"name": "スライドショーswiper",
"settings": {
"paragraph": {
"content": "基本的な画像を使うスライドショーです。"
},
"padding": {
"header": {
"content": "セクションパディング"
},
"padding_top": {
"label": "上パディング",
"unit": "px"
},
"padding_bottom": {
"label": "下パディング",
"unit": "px"
},
"margin_right": {
"label": "右マージン",
"unit": "px"
},
"margin_left": {
"label": "左マージン",
"unit": "px"
}
}
},
"blocks": {
"image": {
"name": "画像スライド",
"settings": {
"image": {
"label": "画像"
},
"image_mobile": {
"label": "モバイル画像"
},
"text_box_position": {
"options__1": {
"label": "左上"
},
"options__2": {
"label": "上・中央"
},
"options__3": {
"label": "右上"
},
"options__4": {
"label": "左・中央"
},
"options__5": {
"label": "上下左右の中央"
},
"options__6": {
"label": "右・中央"
},
"options__7": {
"label": "左下"
},
"options__8": {
"label": "下・中央"
},
"options__9": {
"label": "右下"
},
"label": "デスクトップコンテンツポジション",
"info": "タイトル位置を決めます。"
},
"heading": {
"label": "ヘッディング"
},
"subheading": {
"label": "サブヘディング"
},
"text": {
"label": "詳細"
},
"button_label": {
"label": "ボタンのラベル",
"info": "ボタンを非表示するには空白のラベルにしてください"
},
"button_link": {
"label": "リンクボタン"
}
}
}
},
"presets": {
"name": "スライドショーswiper"
}
}
}
入力項目のタイトルって、何を言ってるんですか?
以下のような箇所(shopifyのCMS)になります。
shopifyにログインして「カスタマイズ」をしてみてください。
「+セクションを追加」する時

作成した「スライドショーswiper」が登場しているのを確認できるでしょう。
セクション要素の設定(スライダーの大枠)

ブロック要素の設定(block要素はスライド枚数も増やせます)

面倒ですが、管理画面をカスタマイズできる感覚で楽しいですね。
※英語の方もやる必要があると思います。その時はlocales/en.default.jsonというファイルがそれなので、同じように英語で仕込みます。
以上、メモになります。
いろいろな方法があると思いますが、諦めてプレーンな状態からスタートさせるのも手だと思いますがいかがでしょうか。
よくあるかも怖い余談話
shopifyでありそうな、怖いお話です。
・仕様的な事柄もデザインXDを見ながらのミーティングで終わり。
・遅れてテンプレートを購入も、デザインとかけ離れている。
さらに以下のようなワードを感じたら要注意です。
・テンプレートの機能は全て活かしつつ改造したい。
・テンプレートのカスタマイズだけなので、4人日(お安く)で可能?
・デザインXDの赤の箇所変更で、あそこトル詰めです。
・これじゃなく、前にどこか別案件でやったアレです。
・わからないことあったら早く聞いてください。
危険ワードです。
言った言わない、仕様も2転3転する可能性が高いかも。
次回のお見積もりは3倍程度、納期も同じく3倍が適当でしょう。
間に合いそうもないと感じたら、早く言っておいた方が良いです。
あなたの作業が的を得ていないのでは。
どうして的を得ない作業をしたのですか?
それに仕様が変わるとか普通なりますか。
何を聞いてたのですか?
ふぇ。。ごめんなさい。
【AI】イラストを描いてもらった
今回の記事のキャッチ画像で使わせてもらいます「Memeplex.app」で作成した画像です。誰でもgoogleアカウントでログインして使えます。
この記事にピッタリなイラストのための考えたリクエストは、「3D電子仮想空間ショッピングモール内を漂いながら買い物を楽しむ女の子」です。
選んだモードは以下の3つです。
・特撮
・サイバーパンク風
・UnrealEngine5風

頭の中で考えてた「こんな感じ」を超えてきます。
女の子、かわいい。
参考サイト置き場
swiper デモ
https://swiperjs.com/demos
shopify テンプレート
https://themes.shopify.com/?locale=ja
wordpress 「サーバーが画像を処理できません」に対処!
https://ineters.com/wordpress/wp-image-upload-error/