Shopifyでセクションを自作する
最近必死でShopifyの開発を行っているので、その内容をまとめます!
セクションとは

画像左側の「ヘッダー」「テキストオーバーレイ…」などがセクションと呼ばれるもので、ページの各パーツのことです
どんなものを作成するか

Shopifyに登録されたブログの最新記事を表示させるものを作ります
利用する画像をアップする

左下の設定 > ファイル > ファイルをアップロード
からファイルをアップすることができます

画像をアップロードすると、URLを取得できます
sectionファイルを作成する
次にsectionファイルを作成してきます。Shopifyのコード編集画面まで行くと、「Sections」というフォルダがあり、各セクションの.liquidファイルがこの中に入っています。「新しいsectionを追加する」をクリックしてファイルを新規作成します。

liquidファイル
<div class="tl_container page-width">
{%- assign blog_1 = blogs[section.settings.blog_1] -%}
{%- assign blog_2 = blogs[section.settings.blog_2] -%}
{%- assign blog_3 = blogs[section.settings.blog_3] -%}
{%- assign blog_4 = blogs[section.settings.blog_4] -%}
{%- assign blog_5 = blogs[section.settings.blog_5] -%}
<ul class="tl_list">
<li><a href="#A" class="a ON">{{ blog_1.title }}</a></li>
<li><a href="#B" class="b">{{ blog_2.title }}</a></li>
<li><a href="#C" class=c>{{ blog_3.title }}</a></li>
<li><a href="#D" class=d>{{ blog_4.title }}</a></li>
<li><a href="#E" class=e>{{ blog_5.title }}</a></li>
</ul>
<section id="A" class="tl_section a">
{% for article1 in blog_1.articles limit: 1 %}
<div class="blog-sction-column">
<h2>{{ article1.title }}</h2>
<p>{{ article1.content }}</p>
<button class="blog-detail" onclick="location.href='{{ article1.url }}'">ブログをもっと見る</button>
</div>
<div class="blog-sction-column">
<img src="https://cdn.shopify.com/s/files/1/0277/3614/6018/files/2788204_s.jpg?v=1608208421" />
</div>
<div class="blog-sction-column">
<img src="https://cdn.shopify.com/s/files/1/0277/3614/6018/files/949796_s.jpg?v=1608208420" />
</div>
{% endfor %}
</section>
<section id="B" class="tl_section b">
{% for article2 in blog_2.articles limit: 1 %}
<div class="blog-sction-column">
<h2>{{ article2.title }}</h2>
<p>{{ article2.content }}</p>
<button class="blog-detail" onclick="location.href='{{ article2.url }}'">ブログをもっと見る</button>
</div>
<div class="blog-sction-column">
<img src="https://cdn.shopify.com/s/files/1/0277/3614/6018/files/2788204_s.jpg?v=1608208421" />
</div>
<div class="blog-sction-column">
<img src="https://cdn.shopify.com/s/files/1/0277/3614/6018/files/949796_s.jpg?v=1608208420" />
</div>
{% endfor %}
</section>
<section id=C class="tl_section c">
{% for article3 in blog_3.articles limit: 1 %}
<div class="blog-sction-column">
<h2>{{ article3.title }}</h2>
<p>{{ article3.content }}</p>
<button class="blog-detail" onclick="location.href='{{ article3.url }}'">ブログをもっと見る</button>
</div>
<div class="blog-sction-column">
<img src="https://cdn.shopify.com/s/files/1/0277/3614/6018/files/2788204_s.jpg?v=1608208421" />
</div>
<div class="blog-sction-column">
<img src="https://cdn.shopify.com/s/files/1/0277/3614/6018/files/949796_s.jpg?v=1608208420" />
</div>
{% endfor %}
</section>
<section id=D class="tl_section d">
{% for article4 in blog_4.articles limit: 1 %}
<div class="blog-sction-column">
<h2>{{ article4.title }}</h2>
<p>{{ article4.content }}</p>
<button class="blog-detail" onclick="location.href='{{ article4.url }}'">ブログをもっと見る</button>
</div>
<div class="blog-sction-column">
<img src="https://cdn.shopify.com/s/files/1/0277/3614/6018/files/2788204_s.jpg?v=1608208421" />
</div>
<div class="blog-sction-column">
<img src="https://cdn.shopify.com/s/files/1/0277/3614/6018/files/949796_s.jpg?v=1608208420" />
</div>
{% endfor %}
</section>
<section id=E class="tl_section e">
{% for article5 in blog_5.articles limit: 1 %}
<div class="blog-sction-column">
<h2>{{ article5.title }}</h2>
<p>{{ article5.content }}</p>
<button class="blog-detail" onclick="location.href='{{ article5.url }}'">ブログをもっと見る</button>
</div>
<div class="blog-sction-column">
<img src="https://cdn.shopify.com/s/files/1/0277/3614/6018/files/2788204_s.jpg?v=1608208421" />
</div>
<div class="blog-sction-column">
<img src="https://cdn.shopify.com/s/files/1/0277/3614/6018/files/949796_s.jpg?v=1608208420" />
</div>
{% endfor %}
</section>
</div>
{% schema %}
{
"name": {
"ja": "ブログタブ",
"en": "blog tab"
},
"settings": [
{
"id": "blog_1",
"type": "blog",
"label": {
"en": "Blog 1",
"ja": "ブログ 1"
}
},
{
"id": "blog_2",
"type": "blog",
"label": {
"en": "Blog 2",
"ja": "ブログ 2"
}
},
{
"id": "blog_3",
"type": "blog",
"label": {
"en": "Blog 3",
"ja": "ブログ 3"
}
},
{
"id": "blog_4",
"type": "blog",
"label": {
"en": "Blog 4",
"ja": "ブログ 4"
}
},
{
"id": "blog_5",
"type": "blog",
"label": {
"en": "Blog 5",
"ja": "ブログ 5"
}
}
],
"presets": [
{
"name": {
"en": "Blog tab",
"ja": "ブログタブ"
},
"category": {
"en": "Blog",
"ja": "ブログ"
}
}
]
}
{% endschema %}
{% stylesheet %}
.tl_container {
margin: 0 auto;
}
.tl_list {
display: flex;
padding: 0;
margin: 0;
align-items: center;
justify-content: left;
list-style: none;
}
.tl_list li {
margin: 0;
width: 33.3333%;
text-align: center;
border-radius: 4px 4px 0 0;
}
.tl_list a {
color: #000000;
padding: 1rem 0.5rem;
display: block;
border: none;
text-decoration: none;
text-shadow: none;
}
.tl_list a:hover,
.tl_list a:focus {
text-shadow: none;
}
.tl_list a {
border-bottom:solid #E3E3E3;
}
.tl_list a[aria-selected="true"] {
border-bottom:solid #FDCF50;
}
/* White focus ring - so you can see when it's focussed (not required) */
.tl_section h2:focus {
outline: none;
}
/* Section styling (optional) */
.tl_section {
padding: 1rem 0;
min-height: 8rem;
/* border-radius: 0 0 4px 4px; */
text-shadow: none;
/* overflow: hidden; */
display: flex;
flex-wrap: wrap;
}
.tl_section h2 {
margin-top: 1rem;
}
.tl_section .blog-sction-column {
/* width: 30%;
float: left; */
padding: 0 10px;
flex: 0 0 33.3333%;
max-width: 33.3333%; /* IE11バグ対応 */
position: relative;
}
@media (max-width: 800px) {
.tl_section .blog-detail {
flex: 0 0 100%;
max-width: 100%; /* IE11バグ対応 */
}
}
.tl_section .blog-sction-column img {
height: 350px;
object-fit: cover;
}
.tl_section .blog-detail {
background-color: #DEDEDE;
border: none;
height: 50px;
padding: 0 50px;
border-radius: 25px;
position: absolute;
bottom: 10px;
}
/*
Section styling (required)
Removes hidden sections from the keychain.
Only used when JavaScript is available.
*/
[role="tabpanel"][aria-hidden="true"] {
display: none;
}
{% endstylesheet %}
{% javascript %}
var accessibleTabs6 = (function () {
"use strict";
var d = document;
var tabListClass;
var onClass;
var hoverableClass;
var setTabsOff = function (tabList) {
var i = tabList.tabs.length;
while (i--) {
setTab(tabList.tabs[i], false);
}
};
var setTab = function (tab, switchOn) {
if (tab && tab.panelId) {
d.getElementById(tab.panelId).setAttribute("aria-hidden", !switchOn);
tab.setAttribute("aria-selected", switchOn);
tab.setAttribute("tabindex", switchOn ? "0" : "-1");
}
};
var _activateTab = function (e) {
var tab = e.target;
if (e.preventDefault) {
e.preventDefault();
setTabsOff(tab.tabList);
setTab(tab, true);
d.getElementById(tab.panelId).children[0].focus();
}
};
var _keypressed = function (e) {
var tab = e.target;
var newNo = -1;
var tabs = tab.tabList.tabs;
var maxNo = tabs.length - 1;
if (e.keyCode === 37 || e.keyCode === 38) { // left / up arrow
newNo = (tab.no === 0) ? maxNo : tab.no - 1;
}
if (e.keyCode === 39 || e.keyCode === 40) { // right arrow / down arrow
newNo = (tab.no === maxNo) ? 0 : tab.no + 1;
}
if (newNo > -1) {
setTabsOff(tab.tabList);
setTab(tabs[newNo], true);
tabs[newNo].focus();
}
};
var _tabHovered = function (e) {
var a = e.target;
var useHover = a.tabList.classList.contains(hoverableClass);
if (useHover) {
_activateTab(e);
}
};
var _events = function (tab) {
tab.addEventListener("click", _activateTab, false);
tab.addEventListener("keydown", _keypressed, false);
tab.addEventListener("mouseover", _tabHovered, false);
};
var _initialiseAriaAttributes = function (tab) {
var tabPanel = d.getElementById(tab.panelId);
tab.parentNode.setAttribute("role", "presentation");
tab.setAttribute("role", "tab");
tab.setAttribute("aria-controls", tab.panelId);
tabPanel.setAttribute("role", "tabpanel");
tabPanel.setAttribute("aria-labelledby", tab.id);
// Make first <section> object keyboard focussable
// Preferably a heading
// Tabindex=0 to work both forwards and backwards through the keychain
tabPanel.children[0].setAttribute("tabindex", "0");
};
var _setUpConfig = function (cfg) {
tabListClass = cfg.tabListClass || "tl_list";
onClass = cfg.onClass || "ON";
hoverableClass = cfg.hoverableClass || "tl-hoverable";
};
var _setUpTab = function (tab, panelId, count) {
tab.no = count;
tab.id = "tab-" + panelId;
tab.panelId = panelId;
_initialiseAriaAttributes(tab);
_events(tab);
};
var _initialiseTabList = function (tabList) {
var defaultTab = 0;
var panelId;
var tabPanel;
var i;
if (tabList) {
tabList.setAttribute("role", "tablist");
tabList.tabs = tabList.getElementsByTagName("a");
i = tabList.tabs.length;
while (i--) {
tabList.tabs[i].tabList = tabList;
panelId = tabList.tabs[i].href.slice(tabList.tabs[i].href.lastIndexOf("#") + 1);
tabPanel = d.getElementById(panelId);
if (tabPanel) {
_setUpTab(tabList.tabs[i], panelId, i);
if (tabList.tabs[i].classList.contains(onClass)) {
defaultTab = i;
// onClass only used to declare intial state, so remove from DOM
tabList.tabs[i].classList.remove(onClass);
d.getElementById(panelId).classList.remove(onClass);
}
}
}
setTabsOff(tabList);
if (tabList.tabs[defaultTab] && tabList.tabs[defaultTab].panelId) {
setTab(tabList.tabs[defaultTab], true);
}
}
};
var _isMustardCut = function (e) {
// check browser feature support (IE10+)
return (
(typeof d.querySelectorAll === "function") &&
d.addEventListener &&
!!d.documentElement.classList // IE10+
);
};
var init = function (cfg) {
var tabLists;
var i;
if (_isMustardCut()) {
_setUpConfig(cfg);
tabLists = d.getElementsByClassName(tabListClass);
i = tabLists.length;
while (i--) {
_initialiseTabList(tabLists[i]);
}
}
};
return {
init: init
};
}());
accessibleTabs6.init({
tabListClass : "tl_list", // default, may omit
onClass : "ON", // default, may omit
hoverableClass : "tl-hoverable" // default, may omit
});
{% endjavascript %}・ファイルの前半部分
HTMLのコード
・{% schema %} 〜{% endschema %}で囲まれた部分
設定項目を定義しています。
まず、管理画面上で利用できるようにしたいため、以下を設定してください
"presets": [
{
"name": {
"en": "Blog tab",
"ja": "ブログタブ"
},
"category": {
"en": "Blog",
"ja": "ブログ"
}
}
]
そうするとこのように編集画面上から利用できるようになります。
今回はShopify内のブログを選択できるようにしたかったため、↓のような項目を5つ用意しています
{
"id": "blog_1",
"type": "blog",
"label": {
"en": "Blog 1",
"ja": "ブログ 1"
}
},
そうすると、sectionの設定からブログを選択できるようになります
選択したブログはliquidファイル上部のHTMLで
{%- assign blog_1 = blogs[section.settings.blog_1] -%}このように記述すると、blog_1という名前で扱えるようになります。
取り出したblog objectの使い方はShopifyのdevelopersサイトから確認できます
・{% stylesheet %}〜{% endstylesheet %}
・{% javascript %}〜{% endjavascript %}
こちらはそれぞれ、cssとJavaScriptを定義できます
以上のように設定すると、このようにsectionを作成することができます!

おわり