Shopifyのsnippetsを活用! 独自デザインでブログを表示する【ECサイト制作ビギナー】

Shopifyで作るECサイトで、商品以外のコンテンツを増やす場合、ブログを複数作成して使い分けることが多いです。今回はお知らせに使うブログを作成し、デフォルトテーマとはデザインを変えてブログページ(記事一覧)、トップページからの表示を作ります。

スニペットファイルを活用し、コードを何回も書く手間を省ける方法も使ってみましょう。ここまで出来たら、もうShopifyテーマ制作初心者は卒業です!

制作ストア・今回の目標

Shopifyで架空の和菓子屋『江戸屋』のECサイトを制作する、という想定です。
テーマはShopifyデフォルトテーマ“Dawn”をベースにカスタマイズしています。

詳細は、下記記事を参照してください。

今回の目標は「ブログ一覧ページのカスタマイズ」です。
以下のことができるようになります。

  • Shopifyのブログ機能を用途に合わせて使い分ける
  • トップページの“ブログ記事”のバリエーションができる
  • セクション内で、スニペットを呼び出せるようになる
  • renderタグでスニペットに値を渡し、ページに応じた出力ができる

制作内容の詳細

コンテンツマーケ用に使う“ストーリー”とは別に、事務的な連絡(休業日のお知らせ、出店情報など)を中心としたブログを作ります。

運営者側からすると、ちょっとしたお知らせの記事にまで、画像を見繕ってトリミングして…と、毎回違うサムネイル画像を用意するのは地味に面倒。
かと言って、サムネイル無しでの表示にセクション設定で調整しても、以下のようにしかなりません。これでは、ちょっと見にくいですよね。

投稿日とタイトルをシンプルに表示するように、テーマをカスタマイズします。
完成イメージは、下図のような形です。

また、ブログページ(ブログごとの記事一覧ページ)も、デフォルトテンプレートのレイアウトでは綺麗に見えません。ですので、トップページと同じく、時系列が分かりやすいシンプルなレイアウトで、記事の一覧表示も作ります。

おしらせブログ制作の準備

ブログ(一覧)のページテンプレートを用意

今回のお題だと、ブログ記事はDawnデフォルトのテンプレートのままで良いです。
ブログ(一覧)ページは、デザインに沿って記事一覧を表示する自作セクションが必要です。そのセクションを読み込むために、ページテンプレートも“デフォルト”とは別のファイルを用意しなくてはいけませんね。

ブログページのテンプレートを新規作成しましょう。
コード編集画面で テンプレート の下にある「新しいテンプレートを追加する」をクリック。

ウィンドウで以下のように入力します。
ファイル名は、お好きに設定して頂いても構いません。

  • 作成するテンプレートを選択する:blog
  • ファイル形式:JSON
  • ファイル名:blog.info.json


そのまま、コード編集画面左上のアイコン(閉じる)で、ストアダッシュボードに戻ってください。

ブログ記事を作成する

“おしらせ”に使う、ブログ記事を作成しましょう。

オンラインストア > ブログ記事 から「ブログ記事を追加する」を選択。

下記3つを設定して、保存してください。

  1. タイトル(適当でOK)
  2. コンテンツ(適当でOK)
  3. 公開


保存できたら、メインカラム左上のボタン、もしくはメニューの「ブログ記事」をクリックして一覧に戻ります。

ブログ名/テンプレートを変更する

「ブログを管理する」から、ニュースを開きます。

ニュースブログの設定画面が開きます。
タイトルとテーマテンプレートを変更し、保存してください。

左メニューから「ブログ記事」を開きます。
先程作成した記事のブログ名が変更されていることを確認してください。

記事が増えた時の、以下の表示が確認できるように最低でも2つ以上の記事が必要です。

  • トップページ:「すべて見る」などブログページへのリンク
  • ブログページ:ページネーションの表示

表示確認用に“おしらせ”の記事を追加しておいてください。

Shopifyテーマをカスタマイズする

確認用のブログができたら、テーマのカスタマイズを行っていきましょう。
★マークの付いている、4つのファイルを作成します。

ここからは、コード編集画面をメインに使います。

1.ブログ一覧で使用するセクションの作成

1-1.新規セクションの作成

日付とタイトルを横並びで表示させる、ブログ記事一覧のセクションを作ります。
新しいセクションを追加する からmain-blog-slim.liquidを作成します。

これから作る一覧部分も、表示したい情報はデフォルトとほぼ一緒です。
逐一プロパティ等を調べるのも大変なので、既存のブログ一覧セクション(main-blog.liquid)を活用させてもらいましょう。

main-blog.liquidを開きます。

コードを全選択して、コピー。

作成したmain-blog-slim.liquidにペーストします。
初期状態で書かれているコードは削除してください。
全選択してから、貼り付けをすると上書きで貼り付けられます。

コードを貼り付けたら、schemaのnameを変更します。
分かりやすい名前を設定してください。

ここまでできたら、保存ボタンで上書き保存します。

コードのコピー元main-blog.liquidはこれ以降使いません。
×で閉じておくと分かりやすいです。

1-2.テンプレートファイルを変更

infoテンプレートで使うセクションを、main-blog-slim.liquidにします。

blog.info.jsonで、以下を変更してください。

  • typeの値をmain-blog-slimに変更
  • settingsで使わない3つのプロパティを削除
    • layout
    • show_image
    • image_height


   

変更できたら上書き保存してください。
この先、blog.info.jsonは使用しないので、ファイルは閉じてOKです。

カスタマイズ画面で反映を確認しましょう。

1-3.必要箇所を整理する

新しく作ったセクションmain-blog-slim.liquidは、現段階ではデフォルトの「ブログ記事」の複製。作りたいデザインでは不要な設定が、結構あります。

不要な箇所は削除した方が、デザイン調整もシンプルなコーディングで済みます。どこが要らないか、あったら良いかを考えてみましょう。
今回は、レイアウトとサムネイル表示なし/抜粋と執筆者は表示も可能、という形で作っていきます。

1-4.schemaを整理する

schemaから上の赤線部分を削除します。
settingsはカスタマイズ画面と同じ順番なので、「日付を表示する」のチェックボックスよりも上を全て削除します。

{ } や似たような文言が多くて分かりにくい!
なんて時は、行数の横ので折りたたむと分かりやすいです。

新しく作りたい「抜粋を表示する」のチェックボックス。
ここは、show_authorのオブジェクトをコピペして、idとlabelを打ち替えましょう。

コードを上書き保存して、カスタマイズ画面の表示をチェック。
サイドバーの設定項目が、作りたい形になってたらOKです。

1-5.出力のLiquidを確認

次に、実際の表示、ページにブログ記事の情報を書き出している部分です。
ループの{%- for article in blog.articles -%}が目印になるでしょう。

探してみると、以下のように書かれています。

renderが出てきました。
スニペット(snippets)ディレクトリにある「article-card(article-card.liquid)を使って、この部分を表示する」というイメージです。

renderや、その上のpaginateをはじめて見た方は、下記記事をご確認ください。

2.スニペットファイルを作成する

ブログ記事セクションで使われているのは、article-card.liquid。
ですが、このファイルを変更するとデフォルトのブログテンプレート類にも影響を与えてしまいます。自作セクション以外に影響しないよう、新しくスニペットファイルを作成して、カスタマイズしていきましょう。

2-1.新規スニペットファイルの作成

スニペットディレクトリの中で、一番上にある「新しいスニペットを追加する」をクリック。分かりやすいファイル名を付けて、完了ボタンで作成します。
見本では、セクション名に寄せた article-slimlist.liquid にしました。

デフォルトで使用されているarticle-card.liquidを開きます。

以下の2つを article-slimlist.liquid にコピー&ペーストしてください。

  • {% endcomment %} のすぐ下にあるif文
  • 2つめの<div class="card__content">からファイル末尾まで

2つ</div>が余分なので、削除します。
こちらも、行数の横ので折りたたむと分かりやすいです。

ここまで出来たら、インデントを整えて保存してください。
article-card.liquidは閉じて良いです。

2-2.render部分を変更する

スニペットファイル article-slimlist.liquidがざっくりと出来たので、セクションファイルの方を変更して表示させてみましょう。

main-blog-slim.liquidで、renderの後のファイル名を変更します。

ファイルを上書き保存して、表示を確認しましょう。
記事のタイトルや投稿日が表示されていればOKです。

2-3.コードを整理する

article-slimlist.liquidには、まだ使わない部分があります。
そのままでも問題なく使えますが、見た目を調整する際に分かりにくいですよね。
わかりやすさ優先で、少し整理します。

article-slimlist.liquidでは、後ろの方にある2箇所を削除します。
下図で青くハイライトした部分です。

  • <div class="article-card__footer">から閉じる</div>まで
  • {%- if show_badge -%}から閉じる{%- endif -%}まで

article-slimlist.liquid

main-blog-slim.liquidの方は、renderのパラメーターを変更します。
抜粋はカスタマイズ画面からのチェックで表示・非表示が変わるようにします。

  • media_height、media_aspect_ratio、show_imageの3行を削除
  • show_excerptの値を変更

main-blog-slim.liquid

   

ついでに、上3行のCSSもコメントアウトか削除しておきましょう。
テーマのカスタマイズ画面で、チェックボックスと表示が連動するか確認します。

2-4.HTMLとCSS部分を作る

ここまでの調整で、表示に必要な“パーツ”になるコードは揃いました。
あとは、デザインに合わせて、HTMLとCSSを書いていくだけです。

  • セクションファイル(main-blog-slim.liquid):記事リンク全体のラッパー
  • スニペットファイル (article-slimlist.liquid):1つの記事のブロック

blog-articles__xxxやcard__xxxクラスは使わず、自作クラスに切り替えます。divタグなどのタグも、デザインに合わせて足し引き・変更します。

main-blog-slim.liquid(出力部分)

{%- paginate blog.articles by 6 -%}
  <div class="main-blog page-width section-{{ section.id }}-padding">
    <h1 class="title--primary">{{ blog.title | escape }}</h1>
    <ul class="list-style-none">
      {%- for article in blog.articles -%}
        <li class="textlist-2col articles">
          {%- render 'article-slimlist',
            article: article,
            show_date: section.settings.show_date,
            show_author: section.settings.show_author,
            show_excerpt: section.settings.show_desc 
          -%}
        </li>
      {%- endfor -%}
    </ul>

    {%- if paginate.pages > 1 -%}
      {%- render 'pagination', paginate: paginate -%}
    {%- endif -%}
  </div>
{%- endpaginate -%}

スニペットの方は {%- if show_xxx %} ~ {%- endif -%}までが1つの固まり、と考えて扱うと書きやすいです。

article-slimlist.liquid

{%- if article and article != empty -%}

  {%- if show_date -%}
    <p class="col2list_heading">
      {{ article.published_at | time_tag: format: 'date' }}
    </p>
  {%- endif -%}

  <div class="col2list_text">
    <h3 class="card__heading{% if show_excerpt %} h2{% endif %}">
      <a href="{{ article.url }}" class="full-unstyled-link">
        {{ article.title | truncate: 50 | escape }}
      </a>
    </h3>

    {%- if show_excerpt -%}
      {%- if article.excerpt.size > 0 or article.content.size > 0 -%}
        <p class="col2list_text_excerpt">
          {%- if article.excerpt.size > 0 -%}
            {{ article.excerpt | strip_html | truncatewords: 30 }}
          {%- else -%}
            {{ article.content | strip_html | truncatewords: 30 }}
          {%- endif -%}
        </p>
      {%- endif -%}
    {%- endif -%}
    {%- if show_author -%}
      <p class="right">{{ article.author }}</p>
    {%- endif -%}
  </div>

{%- endif -%}

CSSクラスは下記記事で、メタフィールドの表示に作成したものを一部活用しています。

今回追加した部分は、コメントアウト「Blog - slim」以下です。

edoya.css

.col2list{
  padding: 1.25rem 0;
  border-top: 1px #bbb solid;
}
.col2list:last-child{
  border-bottom: 1px #bbb solid;
}

/* 画面幅 750px以上の場合
/======================= */
@media screen and (min-width: 750px) {
  .col2list {
    display: flex;
  }
  .col2list_heading{
    flex: 0 0 25%;
  }
  .col2list_text{
    flex: 1;
  }
}
/* =============================================
/ Blog - slim
/============================================ */
.list-style-none{
  list-style: none;
  padding-left: initial;
}

.col2list_text_excerpt{
  font-size: 1.4rem;
}

/* 画面幅 750px以上の場合
/======================= */
@media screen and (min-width: 750px) {
  .col2list.articles {
    padding: 3rem 1.5rem;
    align-items: baseline;
  }

  .articles .col2list_heading{
    flex-basis: 10em;
  }
}

3.ブログページを確認

ブログページ(infoテンプレート)の表示を確認してみましょう。

デフォルトの日付+記事タイトル表示。

抜粋や執筆者を表示した場合、スマホ幅での表示。

一通り、崩れがないか見え方を確認してください。
ページネーションはセクションファイル(main-blog-slim.liquid)の 「by」の数字を変えると確認しやすいです。

これでブログ一覧ページの作成は完了です。
調整したい箇所があれば、CSSなどを更新してください。

4.ホームページからの表示

では、最後にホームページからのブログ表示を行います。
ホームページで使われている「ブログ記事」のセクションも、ブログページ(デフォルトブログ)の「ブログ記事」とやることは、ほぼ一緒ですね

今回も、新しいセクションを複製して作る > 調整する 方法で進めます。
完成したセクションファイルのコード全体は本記事ページ下部で公開しています。

4-1.セクションの新規作成

ホームページでブログ記事を表示しているセクションは featured-blog.liquid です。
このカスタマイズ版として「featured-blog-slim.liquid」を作成します。

featured-blog.liquidを開いて、{%- endstyle -%}の下からファイル末尾までをコピー。

新しく作ったfeatured-blog-slim.liquidに貼り付けます。

元ファイルの featured-blog.liquid は使わないので、×で閉じてください。

featured-blog-slim.liquidの、schema内にある“presets”を変更します。

  • name:ブログ記事(テキストのみ)
  • settings > blog :info

ここまで出来たら、一旦保存します。

4-2.settingsを調整する

カスタマイズ画面からの調整可能な項目(settings)を調整します。
変更箇所は下記の4つです。

  1. デスクトップの列数……使わないので削除する
  2. 記事のサムネイルを表示…使わないので削除する
  3. 執筆者を表示するの下に「抜粋文を表示する」のチェックを作る
  4. 記事の最大表示数を4から6に変更

デスクトップの列数はfeatured-blog-slim.liquid、settings内の「"id": "columns_desktop"」のオブジェクトが該当します。まるっと削除しましょう。

次に、記事のサムネイルを表示のチェックボックス。
こちらは「"id": "show_image"」のオブジェクトです。
同様に{ から },までを削除します。

「抜粋文を表示する」のチェックボックス追加。
これは、ブログページ用に作ったセクション(main-blog-slim.liquid)からコピー・アンド・ペーストしましょう。idが"show_desc"のオブジェクトです。

最後に、記事の最大表示数を4から6に変更。
idが"post_limit"のオブジェクトの、maxの値を書き換えればOKです。

保存ボタンで、上書き保存します。

4-3.renderタグを調整する

featured-blog-slim.liquidでの記事表示を、ブログ一覧と同じく作成したスニペット「article-slimlist.liquid」を使う形に変更します。

{% render 'article-card' ...という記述を見つけましょう。
検索機能を使うと、探しやすいです。

  • Win:Ctrl + F
  • Mac:command + F

呼び出すスニペットをarticle-cardから、article-slimlistに変更します。
下図では見やすいように、カンマ毎に改行も加えました。

renderのパラメーターを変更します。
使用しないサムネイル関係のパラメーターを削除し、抜粋文はsettingsの選択によって表示するかを決める形です。ブログページの時とほぼ同じですね。

  • mediaaspectratio と show_imageの2行を削除
  • show_excerptの値は、settingsの値に書き換える

【調整後】

保存して、表示を確認してみましょう。
カスタマイズ画面のホームページから、セクションを追加 を選択。
「ブログ記事(テキストのみ)」を挿入し、触ってみましょう。

settings(サイトバーでのセクション設定)との連動は上手く行っています。
あとはHTML/CSSクラスなどを整理すれば良さそうですね。

4-4. 出力部分のコードを整理

ブログ記事が横並びに表示されているのは、先程変更した{% render 'article-slimlist' ...を囲うulタグ、liタグのクラスが影響しています。

一旦、ulタグとliタグの属性を全て削除。
ulタグに「list-style-none」クラス、liタグには「col2list articles」クラスを書き加えます。
main-blog-slim.liquidとクラスを揃えるイメージです。

   

下記の2箇所を削除してください。

  • <ul>タグの上にある<slider-component ... の行
  • </ul>タグの下の{%- if posts_exceed_limit -%}から</slider-component>まで


   

保存して、表示を確認してください。

イメージ通りの表示になっていたら、ホームページ用セクション完成です!
セクション見出しや表示件数は、お好きに設定してください。

更にカスタマイズするなら…

ホームページ用セクション

ホームページで使うブログ記事セクション(featured-blog-slim.liquid)。
必要最低限の設定はできましたが、触れていない部分もありますね。

カスタマイズした{% render 'article-slimlist' ...よりも下の記述は、すべてを表示するボタン、記事が1つもないブログを選択した時のサンプル表示になっています。


記事が1つもない時のサンプル表示を実際のレイアウトに合わせたい時は、オレンジ色の線で囲った部分をカスタマイズすると出来ます。

コード上部、assignタグの下あたりには、セクション全体を囲うdiv、セクション見出しの設定です。スマホ幅だと見出し横に表示される「すべてを表示する」もこちらに書かれています。

セクション全体を囲うdivは、元の横並び表示(スマホ幅では横スライド表示)を整えるためのクラスが設定されています。
必要ないものは無くすとスッキリします。

ここまでのカスタマイズを行ったfeatured-blog-slim.liquidは、以下のようになりました。

{%- style -%}
  .section-{{ section.id }}-padding {
    padding-top: {{ section.settings.padding_top | times: 0.75 | round: 0 }}px;
    padding-bottom: {{ section.settings.padding_bottom | times: 0.75 | round: 0 }}px;
  }

  @media screen and (min-width: 750px) {
    .section-{{ section.id }}-padding {
      padding-top: {{ section.settings.padding_top }}px;
      padding-bottom: {{ section.settings.padding_bottom }}px;
    }
  }
{%- endstyle -%}

{%- liquid
  assign posts_displayed = section.settings.blog.articles_count
  if section.settings.post_limit <= section.settings.blog.articles_count
    assign posts_exceed_limit = true
    assign posts_displayed = section.settings.post_limit
  endif
-%}
<div class="blog color-{{ section.settings.color_scheme }} gradient{% if section.settings.heading == blank %} no-heading{% endif %}">
  <div class="page-width section-{{ section.id }}-padding">
    {%- unless section.settings.heading == blank -%}
      <div class="title-wrapper-with-link title-wrapper--no-top-margin">
        <h2 id="SectionHeading-{{ section.id }}" class="blog__title {{ section.settings.heading_size }}">{{ section.settings.heading | escape }}</h2>

        {%- if section.settings.blog != blank and section.settings.show_view_all and section.settings.post_limit < section.settings.blog.articles_count -%}
          <a href="{{ section.settings.blog.url }}"
            class="link underlined-link large-up-hide"
          >
            {{ 'sections.featured_blog.view_all' | t }}
          </a>
        {%- endif -%}
      </div>
    {%- endunless -%}
    {%- if section.settings.blog != blank and section.settings.blog.articles_count > 0 -%}
      <ul class="list-style-none">
        {%- for article in section.settings.blog.articles limit: section.settings.post_limit -%}
          <li class="col2list articles">
            {% render 'article-slimlist',
              blog: section.settings.blog,
              article: article,
              show_date: section.settings.show_date,
              show_author: section.settings.show_author,
              show_excerpt: section.settings.show_desc 
            %}
          </li>
        {%- endfor -%}
      </ul>

      {%- if section.settings.show_view_all and section.settings.post_limit < section.settings.blog.articles_count -%}
        <div class="blog__view-all center small-hide medium-hide">
          <a href="{{ section.settings.blog.url }}" id="ViewAll-{{ section.id }}" class="blog__button button" aria-labelledby="ViewAll-{{ section.id }} SectionHeading-{{ section.id }}">
            {{ 'sections.featured_blog.view_all' | t }}
          </a>
        </div>
      {%- endif -%}
    {%- else -%}
      <ul class="list-style-none">
        <li class="col2list articles">
          <p class="col2list_heading">
            ブログ投稿日
          </p>
          <div class="col2list_text">
            <h3 class="card__heading{% if show_excerpt %} h2{% endif %}">
               {{ 'sections.featured_blog.onboarding_title' | t }}
            </h3>
            <p class="col2list_text_excerpt">
              このブログにはまだ記事がありません。<br>
              抜粋を表示を選択すると、この場所に記事の抜粋が表示されます。
            </p>
            <p class="right">ブログ執筆者名</p>
          </div>
        </li>
      </ul>
    {%- endif -%}
  </div>
</div>

{% schema %}
{
  "name": "t:sections.featured-blog.name",
  "tag": "section",
  "class": "section",
  "settings": [
    {
      "type": "text",
      "id": "heading",
      "default": "Blog posts",
      "label": "t:sections.featured-blog.settings.heading.label"
    },
    {
      "type": "select",
      "id": "heading_size",
      "options": [
        {
          "value": "h2",
          "label": "t:sections.all.heading_size.options__1.label"
        },
        {
          "value": "h1",
          "label": "t:sections.all.heading_size.options__2.label"
        },
        {
          "value": "h0",
          "label": "t:sections.all.heading_size.options__3.label"
        }
      ],
      "default": "h1",
      "label": "t:sections.all.heading_size.label"
    },
    {
      "type": "blog",
      "id": "blog",
      "label": "t:sections.featured-blog.settings.blog.label"
    },
    {
      "type": "range",
      "id": "post_limit",
      "min": 2,
      "max": 6,
      "step": 1,
      "default": 3,
      "label": "t:sections.featured-blog.settings.post_limit.label"
    },
    {
      "type": "select",
      "id": "color_scheme",
      "options": [
        {
          "value": "accent-1",
          "label": "t:sections.all.colors.accent_1.label"
        },
        {
          "value": "accent-2",
          "label": "t:sections.all.colors.accent_2.label"
        },
        {
          "value": "background-1",
          "label": "t:sections.all.colors.background_1.label"
        },
        {
          "value": "background-2",
          "label": "t:sections.all.colors.background_2.label"
        },
        {
          "value": "inverse",
          "label": "t:sections.all.colors.inverse.label"
        }
      ],
      "default": "background-1",
      "label": "t:sections.all.colors.label",
      "info": "t:sections.all.colors.has_cards_info"
    },
    {
      "type": "checkbox",
      "id": "show_date",
      "default": true,
      "label": "t:sections.featured-blog.settings.show_date.label"
    },
    {
      "type": "checkbox",
      "id": "show_author",
      "default": false,
      "label": "t:sections.featured-blog.settings.show_author.label"
    },
    {
      "type": "checkbox",
      "id": "show_desc",
      "default": false,
      "label": "抜粋文を表示する"
    },
    {
      "type": "checkbox",
      "id": "show_view_all",
      "default": true,
      "label": "t:sections.featured-blog.settings.show_view_all.label"
    },
    {
      "type": "header",
      "content": "t:sections.all.padding.section_padding_heading"
    },
    {
      "type": "range",
      "id": "padding_top",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_top",
      "default": 36
    },
    {
      "type": "range",
      "id": "padding_bottom",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_bottom",
      "default": 36
    }
  ],
  "presets": [
    {
      "name": "ブログ記事(テキストのみ)",
      "settings": {
        "blog": "info"
      }
    }
  ]
}
{% endschema %}

投稿日時を8桁で表示する

縦並びで投稿日時を表示すると、月・日の桁数の違いで、少しズレが生じます。

しっくり来ない……という時は、日時表示の方法を変えると揃えられます。
article-slimlist.liquidにある、article.published_atの部分を変更してみましょう。

article-slimlist.liquid

{{ article.published_at | time_tag: format: 'date' }}

   

article-slimlist.liquid

 {{ article.published_at | time_tag: '%Y%m%d' }}

time_tagやdateフィルターは、Rubyのstrftimeメソッドを使ってフォーマットが出来ます。上記で書き換えたのもstrftimeメソッドの記述。

「ここに来てRubyの勉強も?!」と思った方、大丈夫です。
strftime reference and sandboxというサイトでは、よく使われるものが一覧で見られます。英語ですが、感覚的にわかるサイトなので、使わせていただきましょう。
http://www.strfti.me/

まずは無料で14講座から始めましょう!

ハイクオリティな14講座/98レッスンが受け放題。
募集人数には制限があります。サインアップはお早めに。
無料申し込み期限
4月28日まで

募集 人数
100名 (残りわずか)

こちらもオススメ

×