17
Help us understand the problem. What are the problem?

posted at

updated at

Organization

【Shopify】liquidのオブジェクトについてまとめてみた (font, forloop, form)

はじめに

この記事では、Liquidオブジェクトについて日本語訳したものです。

fontからformまでまとめていきます。

fontオブジェクト

fontオブジェクトの概要についてドキュメントからの引用です。

fontオブジェクトは、font_pickerの設定にアクセスするために使用されます。これはグローバルsettingsオブジェクトを介してアクセスできます。

font_pickerとは、Shopifyのセクションでフォントを選択することができる機能のことです。fontオブジェクトでは、そのfont_pickerの設定にアクセスすることができます。

それでは、それぞれの属性についてみていきましょう。

font.baseline_raito

font.baseline_ratioは、emボックス内のベースラインの位置を返します。ベースラインとは、底面から測った値です。ベースラインの比率については、 Plumber SASS documentationを参照してください。
ベースラインの比率はフォントごとに決まっています。

Input
{{ settings.heading_font.baseline_ratio }}
Output
0.091

font.fallback_families

font.fallback_familiesは、フォールバックフォントのフォントファミリーを返します

フォールバックフォントとは、指定されたフォントがデバイスにインストールされていない時に代替で適用されるフォントのことです。
例えば、以下のようなCSSを書いたとします。

h1 {
  font-family: 'ヒラギノ角ゴシック','Hiragino Sans', sans-serif;
}

ヒラギノ角ゴシックは、MacやiPhoneといったApple製品にはデフォルトでインストールされているのでそれらのデバイスでは正常に表示されます。一方、ヒラギノ角ゴシックがインストールされていないWindows製品やAndroid端末では、表示することができないので、代替としてsans-serifが適用されます。

Shopifyのfont_pickerでは、さまざまなフォントを選択することができますが、言語によってはそのフォントを適用することができない場合があります(特に日本語フォントの場合は顕著です。)。その際は、serifsans-serifが代替フォントとして使われます。

Input
{{ settings.heading_font.fallback_families }}
Output
sans-serif

上記の例では、schemaheading_fontというidで指定されているフォントのフォールバックフォントを返しています。

font.family

font.familyフォントの名前を返します

Input
{{ settings.heading_font.family }}
Output
"Neue Haas Unica"

このように選択されているフォント名が出力されました。

font.style

font.styleは、選択したフォントスタイルを返します

Input
{{ settings.heading_font.style }}
Output
normal

他にもitalicなどを返します。

font.weight

font.weightは、選択したフォントウェイトを返します

Input
{{ settings.heading_font.weight }}
Output
400

数値以外にも、boldなども返します。

font.variants

font.variantsは、フォントのファミリー内のすべてのバリアントを返します。それぞれのバリアントは、fontオブジェクトでもあります。

{% for variant in settings.heading_font.variants %}
    {{ variant.family }}
{% endfor %}

forloopオブジェクト

forloopオブジェクトの概要についてドキュメントからの引用です。

forloopオブジェクトには、その親for loopの属性が含まれます。

そのためforloopオブジェクトはforタグの中でしか使うことができません。

forloop.first

forloop.firstは、forループの最初の繰り返しであればtrueを返します。最初の繰り返し出ない場合はfalseを返します。

Input
{% for product in collections.unreact.products %}
    {% if forloop.first == true %}
        First UnReact!
    {% else %}
        最初のループではありません
    {% endif %}
{% endfor %}
Output
First UnReact!
最初のループではありません
最初のループではありません
最初のループではありません

上記の例では、最初のループでのみFirst UnReact!を返すという分岐を書いています。forloop.firstは、booleanを返すので、主に条件式に使われています。

forloop.index

forloop.indexは、forループの現在のインデックス番号1から順にを返します

Input
{% for product in collections.unreact.products %}
    {{ forloop.index }}
{% else %}
    // no products in your UnReact collection
{% endfor %}
Output
1 2 3 4 

このように、インデックス番号が1から出力されます。0ではない点に注意しましょう。

forloop.index0

forloop.index0は、forループの現在のインデックス番号0から順にを返します。先程のforloop.indexは、インデックス番号を1から返していました。

Input
{% for product in collections.unreact.products %}
  {{ forloop.index0 }}
{% endfor %}
Output
0 1 2 3

このようにインデックス番号0から出力されます。

forloop.last

forloop.lastは、forループの最後の繰り返しであればtrueを返します。最後の繰り返しでない場合は falseを返します

Input
{% for product in collections.unreact.products %}
    {% if forloop.last == true %}
        Last UnReact!
    {% else %}
        最後のループではありません
    {% endif %}
{% endfor %}
Output
最後のループではありません
最後のループではありません
最後のループではありません
Last UnReact!

使い方はforloop.firstとほとんど同じです。最後のループでのみLast UnReact!と返しています。

forloop.length

forloop.lengthは、ループの繰り返し回数を返します

Input
<!-- if collections.unreact.products contains 4 products -->
{% for product in collections.unreact.products %}
  {% if forloop.first %}
  <p>UnReactコレクションは {{ forloop.length }} 商品を含んでいます:</p>
  {% endif %}
  <p>{{ product.title }}</p>
{% endfor %}
Output
UnReactコレクションは4商品を含んでいます:
齊藤
西川
福本
和田

このようにforループの中で、イテレーションの回数を出力することができています。

forloop.rindex

forloop.rindexは、forloop.indexの順番を逆にして返します

Input
{% for product in collections.unreact.products %}
    {{ forloop.rindex }}
{% endfor %}
Output
4 3 2 1

このように、インデックス番号が大きい方から順に返ってきます。forloop.indexの逆なので、1が最後になります。

forloop.rindex0

forloop.rindex0は、forloop.index0の順番を逆にして返します

Input
{% for product in collections.unreact.products %}
    {{ forloop.rindex0 }}
{% endfor %}
Output
3 2 1 0

forloop.index0の逆なので、0が最後になります。

formオブジェクト

formオブジェクトの概要についてドキュメントからの引用です。

フォームオブジェクトはフォームタグ内で使用されます。親フォームの属性が含まれます。

forloopオブジェクトと同様に、formオブジェクトは、formタグの中でしかアクセスすることができないオブジェクトになります。

それでは、それぞれのオブジェクトについて見ていきます。

form.address1

form.address1は、アドレスに関連付けられた最初のアドレス行を返します。addressパラメータを持つformタグ専用です。
'address1'は、日本の住所における町名や番地にあたります。

form.address2

form.address2は、アドレスに関連付けられた2番目のアドレス行が存在する場合、それを返します。addressパラメータを持つformタグ専用です。
'address2'は、日本の住所におけるマンション名や部屋番号にあたります。

form.author

form.authorは、ブログ記事コメントの著者名を返します。articleパラメータをもつformタグ専用です。

form.body

form.bodyは、ブログ記事コメントの内容を返します。articleパラメータをもつformタグ専用です。

form.city

form.cityは、アドレスに関連づけられた都市を返します。addressパラメータを持つformタグ専用です。
日本の住所における市区町村にあたります。

form.company

form.companyは、アドレスに関連する会社名が存在する場合にその会社名を返します。addressパラメータを持つformタグ専用です。

form.country

form.countryは、アドレスに関連付けられた国名を返します。addressパラメータを持つformタグ専用です。

form.email

form.emailは、ブログ記事コメントの作者のメールアドレスを返します。articleパラメータをもつformタグ専用です。

form.errors

form.errorsは、フォームが正常に送信されなかった場合に、文字列の配列を返します。返される文字列は、フォームのタイプに必要なフィールドによって異なります。

返される値は以下の通りです。
- author: ブログコメントのような名前が必須であるフィールド用
- body: お問い合わせフォームなどのメッセージのテキストコンテンツ用
- email: メールアドレスが必須であるフィールド用
- password: パスワードが必須であるフィールド用
- form: 具体的なエラーを提供できない場合に使用される、一般的なエラー

Input
{% for error in form.errors %}
  {{ error }}
{% endfor %}
Output
<!-- ユーザーが名前フィールドを空欄にしていた場合 -->
author

配列をループすることなくデフォルトのエラーメッセージを出力するために form.errorsdefault_errorsフィルタを適用することができます。

Input
{% if form.errors %}
  {{ form.errors | default_errors }}
{% endif %}
Output
Please enter a valid email address.

フォームメッセージと翻訳されたフィールド

form.messages配列とform.translates_fields配列をループすることで、返されたform.errorsオブジェクトに関する情報を得ることができます。
form.errorserrorオブジェクトをキーとして使用することで、どちらかの配列の特定の配列の要素をターゲットにすることができます。

messages配列はform.errorsの値の翻訳されたエラーメッセージを持っています。
translated_field配列は、form.errorsの値の翻訳されたフィールド名を持っています。

Input
<ul>
  {% for field in form.errors %}
    <li>
      {% if field == 'form' %}
        {{ form.errors.messages[field] }}
      {% else %}
        {{ form.errors.translated_fields[field] }} - {{ form.errors.messages[field] }}
      {% endif %}
    </li>
  {% endfor %}
</ul>
Output
<ul>
  <li>We have sent an email, please click the link included to verify your email address.</li>
  <li>Password - Please enter a valid password.</li>
</ul>

form.first_name

form.first_nameは、アドレスに関連づけられたファーストネーム(名)を返しますaddressパラメータを持つformタグ専用です。

form.id

form.idは、フォームのid(一意の識別子)を返します。

form.last_name

form.last_nameは、アドレスに関連づけられたラストネーム(姓)を返しますaddressパラメータを持つformタグ専用です。

form.password_needed

customer_loginパラメータを持つフォームタグにのみ使用されます。form.password_need属性は常にtrueを返します。

form.phone

from.phoneは、アドレスに関連づけられた電話番号が存在する場合、その電話番号を返しますaddressパラメータを持つformタグ専用です。

form.posted_successfully?

form.posted_successfully?は、**フォームが正常に送信された場合はtrue、 フォームにエラーが含まれていた場合はfalseを返します。
アドレスフォーム以外のすべてのフォームはこのプロパティを設定します。アドレスフォームは常に正常に送信されます。

{% if form.posted_successfully? %}
    コメントは正常に送信されました
{% else %}
    {{ form.errors | default_errors }}
{% endif %}

このように、フォームが正常に送信されればコメントは正常に送信されました、何かしらのエラーが起きればそのエラーメッセージを返すような実装をすることができます。

form.province

form.provinceは、アドレスに関連づけられている都道府県・州を返しますaddressパラメータを持つformタグ専用です。

Input
{{ form.city }}, {{ form.province }}
Output
Kitakyusyu-shi Nishi-ku, Fukuoka

form.set_as_default_checkbox

form.set_as_default_checkboxは、現在のフォームを顧客のデフォルトアドレスとして送信できるHTMLチェックボックスをレンダリングします。addressパラメータを持つformタグ専用です。

Input
{{ form.set_as_default_checkbox }}
Output
<input type="checkbox" id="address_default_address_12345678" name="address[default]" value="1">

form.zip

form.zipは、アドレスに関連づけられた郵便番号を返します。addressパラメータを持つformタグ専用です。

終わりに

今回の記事はここまでになります。
お疲れ様でした。

Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
17
Help us understand the problem. What are the problem?