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

#はじめに

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

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



#fontオブジェクト

fontオブジェクトの概要について[ドキュメント](https://shopify.dev/docs/themes/liquid/reference/objects/font)からの引用です。

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

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

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




##font.baseline_raito

`font.baseline_ratio`は、**emボックス内のベースラインの位置を返します**。ベースラインとは、底面から測った値です。ベースラインの比率については、 [Plumber SASS documentation](https://jamonserrano.github.io/plumber-sass/baselines/)を参照してください。
ベースラインの比率はフォントごとに決まっています。

```.liquid:Input
{{ settings.heading_font.baseline_ratio }}
```

```.liquid:Output
0.091
```



##font.fallback_families

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

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

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

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

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

```.liquid:Input
{{ settings.heading_font.fallback_families }}
```

```.liquid:Output
sans-serif
```
上記の例では、`schema`の`heading_font`という`id`で指定されているフォントのフォールバックフォントを返しています。



##font.family

`font.family`は**フォントの名前を返します**。

```.liquid:Input
{{ settings.heading_font.family }}
```

```.liquid:Output
"Neue Haas Unica"
```

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




##font.style

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

```.liquid:Input
{{ settings.heading_font.style }}
```

```.liquid:Output
normal
```

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



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

```.liquid:Input
{{ settings.heading_font.weight }}
```

```.liquid:Output
400
```

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



##font.variants

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

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



#forloopオブジェクト

`forloop`オブジェクトの概要について[ドキュメント](https://shopify.dev/docs/themes/liquid/reference/objects/for-loops)からの引用です。

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

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



##forloop.first

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

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

```.liquid:Output
First UnReact!
最初のループではありません
最初のループではありません
最初のループではありません
```

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



##forloop.index

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

```.liquid:Input
{% for product in collections.unreact.products %}
    {{ forloop.index }}
{% else %}
    // no products in your UnReact collection
{% endfor %}
```

```.liquid:Output
1 2 3 4 
```

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



##forloop.index0

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

```.liquid:Input
{% for product in collections.unreact.products %}
  {{ forloop.index0 }}
{% endfor %}
```

```.liquid:Output
0 1 2 3
```

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



##forloop.last

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

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

```.liquid:Output
最後のループではありません
最後のループではありません
最後のループではありません
Last UnReact!
```

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



##forloop.length

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

```.liquid: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 %}
```

```.liquid:Output
UnReactコレクションは4商品を含んでいます:
齊藤
西川
福本
和田
```

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



##forloop.rindex

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

```.liquid:Input
{% for product in collections.unreact.products %}
    {{ forloop.rindex }}
{% endfor %}
```

```.liquid:Output
4 3 2 1
```

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



##forloop.rindex0

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

```.liquid:Input
{% for product in collections.unreact.products %}
    {{ forloop.rindex0 }}
{% endfor %}
```

```.liquid:Output
3 2 1 0
```

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



#formオブジェクト

`form`オブジェクトの概要について[ドキュメント](https://shopify.dev/docs/themes/liquid/reference/objects/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`: 具体的なエラーを提供できない場合に使用される、一般的なエラー

```.liquid:Input
{% for error in form.errors %}
  {{ error }}
{% endfor %}
```

```.liquid:Output
<!-- ユーザーが名前フィールドを空欄にしていた場合 -->
author
```

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

```.liquid:Input
{% if form.errors %}
  {{ form.errors | default_errors }}
{% endif %}
```

```.liquid:Output
Please enter a valid email address.
```


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

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

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

```.liquid: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>
```

```.liquid: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`を返します。
アドレスフォーム以外のすべてのフォームはこのプロパティを設定します。アドレスフォームは常に正常に送信されます。

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

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



##form.province

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

```.liquid:Input
{{ form.city }}, {{ form.province }}
```

```.liquid:Output
Kitakyusyu-shi Nishi-ku, Fukuoka
```


##form.set_as_default_checkbox

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

```..liquid:Input
{{ form.set_as_default_checkbox }}
```

```.liquid: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 機能を実現することができます。

https://coming-soon.reterior.jp/

https://apps.shopify.com/shopify-application-314?locale=ja&surface_detail=%E3%83%AA%E3%83%86%E3%83%AA%E3%82%A2&surface_inter_position=1&surface_intra_position=1&surface_type=search