Shopifyのページのつくりが知りたいな
このような疑問をお持ちではないでしょうか?
私もShopifyはどうやってページが成り立っているのか知りませんでしたのでまとめてみました。
shopifyのページの成り立ち
- 親ファイルはlayout/theme.liquid
- ヘッダーはlayout/theme.liquidでレンダリング
- メインもlayout/theme.liquidでレンダリング
- フッターもlayout/theme.liquidでレンダリング
親ファイルはlayout/theme.liquid
Shopifyの親ファイルはlayout/theme.liquidになります。
このファイルに各要素をレンダリングして表示させています。
ヘッダーはlayout/theme.liquidでレンダリング
今回ヘッダーの中には「トップバー」と「ナビバー」があります。

「トップバー」(黒い部分)と「ナビバー」それぞれをsnippetsとして作成します。
作成したsnippetsは後から紹介しますようにlayout/theme.liquidでレンダリングして表示します。
「トップバー」(黒い部分)のsnippetsをつくる
<div class="top-bar">
<div class="container-fluid">
<div class="row d-flex align-items-center">
<div class="col-lg-6 hidden-lg-down text-col">
<ul class="list-inline">
<li class="list-inline-item"><i class="icon-telephone"></i>{{settings.topbar_tel}}</li>
<li class="list-inline-item">{{settings.topbar_message}}</li>
</ul>
</div>
<div class="col-lg-6 d-flex justify-content-end">
<!-- Language Dropdown-->
<div class="dropdown show"><a id="langsDropdown" href="https://example.com" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="dropdown-toggle"><img src="img/united-kingdom.svg" alt="english">English</a>
<div aria-labelledby="langsDropdown" class="dropdown-menu dropdown-menu-right"><a href="#" class="dropdown-item"><img src="img/germany.svg" alt="german">German</a><a href="#" class="dropdown-item"> <img src="img/france.svg" alt="french">French</a></div>
</div>
<!-- Currency Dropdown-->
<div class="dropdown show"><a id="currencyDropdown" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="dropdown-toggle">USD</a>
<div aria-labelledby="currencyDropdown" class="dropdown-menu dropdown-menu-right"><a href="#" class="dropdown-item">EUR</a><a href="#" class="dropdown-item"> GBP</a></div>
</div>
</div>
</div>
</div>
</div>
「ナビバー」のsnippetsをつくる
<nav class="navbar navbar-expand-lg">
<div class="search-area">
<div class="search-area-inner d-flex align-items-center justify-content-center">
<div class="close-btn"><i class="icon-close"></i></div>
<form action="#">
<div class="form-group">
<input type="search" name="search" id="search" placeholder="What are you looking for?">
<button type="submit" class="submit"><i class="icon-search"></i></button>
</div>
</form>
</div>
</div>
<div class="container-fluid">
<!-- Navbar Header --><a href="index.html" class="navbar-brand"><img src="{{ settings.header_logo | img_url: '2048x' }}" alt="..."></a>
<button type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler navbar-toggler-right"><i class="fa fa-bars"></i></button>
<!-- Navbar Collapse -->
<div id="navbarCollapse" class="collapse navbar-collapse">
<ul class="navbar-nav mx-auto">
<li class="nav-item dropdown"><a id="navbarHomeLink" href="index.html" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link active">Home<i class="fa fa-angle-down"></i></a>
<ul aria-labelledby="navbarDropdownHomeLink" class="dropdown-menu">
<li><a href="index.html" class="dropdown-item">Classic Home</a></li>
<li><a href="index2.html" class="dropdown-item">Parallax sections</a></li>
<li><a href="index3.html" class="dropdown-item">Video background </a></li>
</ul>
</li>
<li class="nav-item"><a href="category.html" class="nav-link">Shop</a>
</li>
<!-- Megamenu-->
<li class="nav-item dropdown menu-large"><a href="#" data-toggle="dropdown" class="nav-link">Template<i class="fa fa-angle-down"></i></a>
<div class="dropdown-menu megamenu">
<div class="row">
<div class="col-lg-9">
<div class="row">
<div class="col-lg-3"><strong class="text-uppercase">Home</strong>
<ul class="list-unstyled">
<li><a href="index.html">Classic homepage</a></li>
<li><a href="index2.html">Parallax sections <span class="badge badge-success ml-2">New</span></a></li>
<li><a href="index3.html">Video background <span class="badge badge-success ml-2">New</span></a></li>
</ul><strong class="text-uppercase">Shop</strong>
<ul class="list-unstyled">
<li><a href="category.html">Category - left sidebar</a></li>
<li><a href="category-right.html">Category - right sidebar</a></li>
<li><a href="category-full.html">Category - full width</a></li>
<li><a href="category-masonry.html">Category - Masonry layout <span class="badge badge-success ml-2">New</span> </a></li>
<li><a href="detail.html">Product detail</a></li>
</ul>
</div>
<div class="col-lg-3"><strong class="text-uppercase">Order process</strong>
<ul class="list-unstyled">
<li><a href="cart.html">Shopping cart</a></li>
<li><a href="checkout1.html">Checkout 1 - Address</a></li>
<li><a href="checkout2.html">Checkout 2 - Delivery</a></li>
<li><a href="checkout3.html">Checkout 3 - Payment</a></li>
<li><a href="checkout4.html">Checkout 4 - Review </a></li>
<li><a href="checkout5.html">Checkout 5 - Confirmation </a></li>
</ul><strong class="text-uppercase">Blog</strong>
<ul class="list-unstyled">
<li><a href="blog.html">Blog</a></li>
<li><a href="post.html">Post </a></li>
</ul>
</div>
<div class="col-lg-3"><strong class="text-uppercase">Pages</strong>
<ul class="list-unstyled">
<li><a href="contact.html">Contact</a></li>
<li><a href="about.html">About us</a></li>
<li><a href="text.html">Text page</a></li>
<li><a href="faq.html">FAQ <span class="badge badge-success ml-2">New</span></a></li>
<li><a href="coming-soon.html">Coming soon <span class="badge badge-success ml-2">New</span></a></li>
<li><a href="404.html">Error 404</a></li>
<li><a href="500.html">Error 500</a></li>
</ul>
</div>
<div class="col-lg-3"><strong class="text-uppercase">Customer</strong>
<ul class="list-unstyled">
<li><a href="customer-login.html">Login/sign up</a></li>
<li><a href="customer-orders.html">Orders</a></li>
<li><a href="customer-order.html">Order detail</a></li>
<li><a href="customer-addresses.html">Addresses</a></li>
<li><a href="customer-account.html">Profile</a></li>
</ul>
</div>
</div>
<div class="row services-block">
<div class="col-xl-3 col-lg-6 d-flex">
<div class="item d-flex align-items-center">
<div class="icon"><i class="icon-truck text-primary"></i></div>
<div class="text"><span class="text-uppercase">Free shipping & return</span><small>Free Shipping over $300</small></div>
</div>
</div>
<div class="col-xl-3 col-lg-6 d-flex">
<div class="item d-flex align-items-center">
<div class="icon"><i class="icon-coin text-primary"></i></div>
<div class="text"><span class="text-uppercase">Money back guarantee</span><small>30 Days Money Back</small></div>
</div>
</div>
<div class="col-xl-3 col-lg-6 d-flex">
<div class="item d-flex align-items-center">
<div class="icon"><i class="icon-headphones text-primary"></i></div>
<div class="text"><span class="text-uppercase">020-800-456-747</span><small>24/7 Available Support</small></div>
</div>
</div>
<div class="col-xl-3 col-lg-6 d-flex">
<div class="item d-flex align-items-center">
<div class="icon"><i class="icon-secure-shield text-primary"></i></div>
<div class="text"><span class="text-uppercase">Secure Payment</span><small>Secure Payment</small></div>
</div>
</div>
</div>
</div>
<div class="col-lg-3 text-center product-col hidden-lg-down"><a href="detail.html" class="product-image"><img src="img/shirt.png" alt="..." class="img-fluid"></a>
<h6 class="text-uppercase product-heading"><a href="detail.html">Lose Oversized Shirt</a></h6>
<ul class="rate list-inline">
<li class="list-inline-item"><i class="fa fa-star-o text-primary"></i></li>
<li class="list-inline-item"><i class="fa fa-star-o text-primary"></i></li>
<li class="list-inline-item"><i class="fa fa-star-o text-primary"></i></li>
<li class="list-inline-item"><i class="fa fa-star-o text-primary"></i></li>
<li class="list-inline-item"><i class="fa fa-star-o text-primary"></i></li>
</ul><strong class="price text-primary">$65.00</strong><a href="#" class="btn btn-template wide">Add to cart</a>
</div>
</div>
</div>
</li>
<!-- /Megamenu end-->
<!-- Multi level dropdown -->
<li class="nav-item dropdown"><a id="navbarDropdownMenuLink" href="http://example.com" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link">Dropdown<i class="fa fa-angle-down"></i></a>
<ul aria-labelledby="navbarDropdownMenuLink" class="dropdown-menu">
<li><a href="#" class="dropdown-item">Action</a></li>
<li><a href="#" class="dropdown-item">Another action</a></li>
<li class="dropdown-submenu"><a id="navbarDropdownMenuLink2" href="http://example.com" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link">Dropdown link<i class="fa fa-angle-down"></i></a>
<ul aria-labelledby="navbarDropdownMenuLink2" class="dropdown-menu">
<li><a href="#" class="dropdown-item">Action</a></li>
<li class="dropdown-submenu"><a id="navbarDropdownMenuLink3" href="http://example.com" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link">
Another action<i class="fa fa-angle-down"></i></a>
<ul aria-labelledby="navbarDropdownMenuLink3" class="dropdown-menu">
<li><a href="#" class="dropdown-item">Action</a></li>
<li><a href="#" class="dropdown-item">Action</a></li>
<li><a href="#" class="dropdown-item">Action</a></li>
<li><a href="#" class="dropdown-item">Action</a></li>
</ul>
</li>
<li><a href="#" class="dropdown-item">Something else here</a></li>
</ul>
</li>
</ul>
</li>
<!-- Multi level dropdown end-->
<li class="nav-item"><a href="blog.html" class="nav-link">Blog </a>
</li>
<li class="nav-item"><a href="contact.html" class="nav-link">Contact</a>
</li>
</ul>
<div class="right-col d-flex align-items-lg-center flex-column flex-lg-row">
<!-- Search Button-->
<div class="search"><i class="icon-search"></i></div>
<!-- User Not Logged - link to login page-->
<div class="user"> <a id="userdetails" href="customer-login.html" class="user-link"><i class="icon-profile"> </i></a></div>
<!-- Cart Dropdown-->
<div class="cart dropdown show"><a id="cartdetails" href="https://example.com" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="dropdown-toggle"><i class="icon-cart"></i>
<div class="cart-no">1</div></a><a href="cart.html" class="text-primary view-cart">View Cart</a>
<div aria-labelledby="cartdetails" class="dropdown-menu">
<!-- cart item-->
<div class="dropdown-item cart-product">
<div class="d-flex align-items-center">
<div class="img"><img src="img/hoodie-man-1.png" alt="..." class="img-fluid"></div>
<div class="details d-flex justify-content-between">
<div class="text"> <a href="#"><strong>Heather Gray Hoodie</strong></a><small>Quantity: 1 </small><span class="price">$75.00 </span></div><a href="#" class="delete"><i class="fa fa-trash-o"></i></a>
</div>
</div>
</div>
<!-- total price-->
<div class="dropdown-item total-price d-flex justify-content-between"><span>Total</span><strong class="text-primary">$75.00</strong></div>
<!-- call to actions-->
<div class="dropdown-item CTA d-flex"><a href="cart.html" class="btn btn-template wide">View Cart</a><a href="checkout1.html" class="btn btn-template wide">Checkout</a></div>
</div>
</div>
</div>
</div>
</div>
</nav>
layout/theme.liquidでレンダリング
2つのsnippetsができたらそれらを親ファイルであるlayout/theme.liquidでレンダリングして表示させます。
<!doctype html>
<html>
<head>
<title>{{ page_title }}</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="{{ page_description | escape }}">
<link rel="canonical" href="{{ canonical_url }}">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;700&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
{{ content_for_header }} <!-- Header hook for plugins -->
{{ 'application.css' | asset_url | stylesheet_tag }}
{{ 'bootstrap.min.css' | asset_url | stylesheet_tag }}
{{ 'font-awesome.min.css' | asset_url | stylesheet_tag }}
{{ 'bootstrap-select.min.css' | asset_url | stylesheet_tag }}
{{ 'custom-fonticons.css' | asset_url | stylesheet_tag }}
{{ 'owl.carousel.css' | asset_url | stylesheet_tag }}
{{ 'owl.theme.default.css' | asset_url | stylesheet_tag }}
{{ 'style.default.css' | asset_url | stylesheet_tag }}
{{ 'application.js' | asset_url | script_tag }}
</head>
<body>
<header class="header">
<!-- トップバー -->
{% render 'topbar' %}
<!-- ナビバー -->
{% render 'navbar' %}
</header>
{% for link in linklists.main-menu.links %}
{% assign child_list_handle = link.title | handleize %}
{% if linklists[child_list_handle].links != blank %}
<a href="{{ link.url }}">{{ link.title }}</a>
[{% for childlink in linklists[child_list_handle].links %}
<a href="{{ childlink.url }}">{{ childlink.title | escape }}</a>
{% endfor %}]
{% else %}
<a href="{{ link.url }}">{{ link.title }}</a>
{% endif %}
{% endfor %}
<a href="/cart">cart</a>
{% if shop.customer_accounts_enabled %}
{% if customer %}
<a href="/account">account</a>
{{ 'log out' | customer_logout_link }}
{% else %}
{{ 'log in ' | customer_login_link }}
{{ 'register' | customer_register_link }}
{% endif %}
{% endif %}
<main role="main">
{{ content_for_layout }}
</main>
{{ 'jquery.min.js' | asset_url | script_tag }}
{{ 'bootstrap.bundle.min.js' | asset_url | script_tag }}
{{ 'jquery.cookie.js' | asset_url | script_tag }}
{{ 'owl.carousel.min.js' | asset_url | script_tag }}
{{ 'owl.carousel2.thumbs.min.js' | asset_url | script_tag }}
{{ 'bootstrap-select.min.js' | asset_url | script_tag }}
{{ 'front.js' | asset_url | script_tag }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
</body>
</html>
26行目から31行目でレンダリングしてheaderとして表示させているのがわかると思います。
メインもlayout/theme.liquidでレンダリング
上のコードでmainは57行目から59行目でレンダリングされています。
{{ content_for_layout }}としてレンダリングしていますが、具体的には
templates/index.liquidを指します。
templates/index.liquidの中身
{% section 'hero' %}
上記のようにtemplates/index.liquidには、hero sectionsがレンダリングされています。
Sectionsとは?
大まかに言うと、sections(セクション)はマーチャントがカスタマイズできるShopifyテーマのモジュール型コンポーネントです。セクションには、商品ページの基本要素やスライドショーのコンポーネントなど、Shopifyストアの特定エリア用のコンテンツと設定が含まれます。
簡単にまとめるとページを構成している部品の集まり(ブロック)の一つ
hero sectionsの中身
<section class="hero hero-home no-padding">
<!-- Hero Slider-->
<div class="owl-carousel owl-theme hero-slider">
<div style="background-image: url({{section.settings.slider_image | img_url: 'master'}});" class="item d-flex align-items-center has-pattern">
<div class="container">
<div class="row">
<div class="col-lg-6">
<h1>Hub</h1>
<ul class="lead">
<li><strong>Bootstrap 4 E-commerce</strong> template</li>
<li><strong>24</strong> pages, <strong>6</strong> colour variants</li>
<li><strong>SCSS</strong> sources </li>
<li>frequent & <strong>free updates</strong></li>
</ul><a href="#" class="btn btn-template wide shop-now">Shop Now<i class="icon-bag"> </i></a>
</div>
</div>
</div>
</div>
<div style="background: url(img/hero-bg-2.jpg);" class="item d-flex align-items-center">
<div class="container">
<div class="row">
<div class="col-lg-6 text-white">
<h1>Labore et dolore magna aliqua</h1>
<p class="lead">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p><a href="#" class="btn btn-template wide shop-now">Shop Now<i class="icon-bag"> </i></a>
</div>
</div>
</div>
</div>
<div style="background: url(img/hero-bg-3.jpg);" class="item d-flex align-items-center">
<div class="container">
<div class="row">
<div class="col-lg-6 text-white">
<h1>Sed do eiusmod tempor</h1>
<p class="lead">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p><a href="#" class="btn btn-template wide shop-now">Shop Now<i class="icon-bag"> </i></a>
</div>
</div>
</div>
</div>
</div>
</section>
{% schema %}
{
"name": "スライダー",
"settings": [
{
"id": "slider_image",
"type": "image_picker",
"label": "Slider Image"
}
]
}
{% endschema %}
内容は
画像スライダーです、上記のままではスライダーとしては機能しません(他ファイルでjqueryが動いている)。今回は内容がスライダーでしたが、商品のカテゴリ一覧であったり、ブランド紹介の内容だったり、いろいろな内容で構いません。