jtk

WordPress に Vue.js を スモールスタートで入れてみる その3

とあるサイトでVue.jsで作っていて、公開してからもろもろやったことまとめ その3
今回はACFオプションページのリピーターフィールドについて

f:id:jotaki:20190212100544p:plain

ACF オプションページ リピーターフィールドの取得・出力

カスタムフィールドは、

  • sample_field(繰り返しフィールド)
    • sample_field_title(テキスト)
    • sample_field_text(テキストエリア)

https://siteUrl.com/wp-json/acf/v3/options/options/ では

{
  "acf":{
    "sample_field":[
      {
        "sample_field_title":"title01-title01-title01",
        "sample_field_text":"text01-text01-text01"
      },
      {
        "sample_field_title":"title02-title02-title02",
        "sample_field_text":"text02-text02-text02"
      },
      // ...
    ]
  }
}

のようにAPIが吐かれる。そのうえで sampleField.vue(親) から sampleFieldBlock.vue(子) に props でオブジェクトを渡して、子コンポーネントで出力

sampleField.vue

<template>
  <sample-field-block:option="option">
  </sample-field-block>
</template>

<script>
import { API_OPTION_URL } from './../variable'
import axios from 'axios';
import SampleFieldBlock from './../component/sampleFieldBlock';

export default {
  components: {
    SampleFieldBlock
  },
  data() {
    return {
      option: {}
    }
  },
  mounted() {
    axios
      .get(`${API_OPTION_URL}`)
      .then((response) => {
        this.option = response.data.acf;
      })
  }
};
</script>

sampleFieldBlock.vue

<template>
  <section v-if="option.sample_field">
    <h1>Title</h1>
      <section v-for="(group,index) in option.sample_field" :key="index">
        <h2>{{group.sample_field_title}}</h2>
        <div>
          <p>{{group.sample_field_text}}</p>
        </div>
      </section>
  </section>
</template>

<script>
export default {
  props: {
    option: Object
  }
};
</script>

WordPress に Vue.js を スモールスタートで入れてみる その2

とあるサイトでVue.jsで作っていて、公開してからもろもろやったことまとめ その2

f:id:jotaki:20190212100544p:plain

基本構造 WordPress の各テンプレートファイルからVue.jsを呼び込む

トップページの場合、 homeGallery.vue には Vue ( <template><script> ) を書いていく感じ。

▼ app.js

import Vue from 'vue'

// import文を使ってSassファイルを読み込む。(これがないと.scss => .cssへコンパイルされない)
import './../scss/app.scss';

// Variable
import {
  APP_ID
} from './variable';

// Vue Component
import HomeGallery from './component/homeGallery';

// Home
window.renderHome = function () {
  new Vue({
    el: `#${APP_ID}`,
    components: {
      HomeGallery
    }
  });
}

▼ front-page.php

<?php get_header(); ?>
  <home-gallery></home-gallery>
<?php get_footer(); ?>

▼ footer.php

<script type='text/javascript' src='/_assets/js/bundle.js'></script>
<?php if ( is_front_page() ) : ?>
  <!-- トップページ -->
  <script>
    document.addEventListener('DOMContentLoaded', function() {
      renderHome()
    })
  </script>
<?php endif; ?>

定数用の.jsファイル

js/variable.js では定数の管理を行って各.vueにexportする

const APP_ID = `app`;

// サイト情報
const SITE_INFO = {
  name: 'siteName',
  url: `https://siteUrl.com`
}

// APIのベースURL
const API_POST_URL = `${SITE_INFO.url}/wp-json/wp/v2`;
const API_OPTION_URL = `${SITE_INFO.url}/wp-json/acf/v3/options/options/`;

export {
  APP_ID,
  SITE_INFO,
  API_POST_URL,
  API_OPTION_URL
};

全体構成編、ちょっと長くなったのでここまで。
次回はもう少し細かい内容になる予定です。

WordPress に Vue.js を スモールスタートで入れてみる その1

とあるサイトでVue.jsで作っていて、公開してからもろもろやったことをまとめようと思ったのですが、年内公開も怪しくなってきたので今の段階でメモしておこうとおもいます。

f:id:jotaki:20190212100544p:plain

概要

WordPress を使った既存サイトがあり、リニューアル版は WordPress を残しつつ、REST API と Vue.js 使って組めるところは組んでみようというたくらみでした。
Vue.js を実案件で勉強したかったのが大きな理由で、残りは高速化など自分で触ってみてどこまでできるかを知りたかったためです。

WordPress と Vue.js と組み合わせ方

設計段階でどの箇所にVue入れるかもそうですが、そもそもの入れ方が分からなかったので色々なGitHubリポジトリをみました。

みてみてると、

的なふたつがあるようでした(表現合っているかわかりませんが)
参考: Vue.js と WordPress の 付き合い方について考えてみた - Qiita

SPA方式

index.php<div id="app"></div> だけ用意して、ルーティングはVue Routerなどを使って書いていく方法

スタンドアロン方式

front-page/page/archive/single.php など、各ページテーマテンプレートファイルは用意しつつ、箇所箇所でVue.jsを使う(Axios経由でAPI取得=>出力)方法

これもどこかのリポジトリを参考にした気がするのですが失念してしまいました..
ただ色々記事みたり触ってみて、スモールスタートで小規模なところから使っていくやり方が良いと思い今回はこちらを採用しました。

ファイル構成

今回webpackを使って、リポジトリ内のファイル構造的には

.
├── node_modules
├── package.json
├── webpack.config.js
│
├── src
│   ├── js
│   │   ├── app.js
│   │   ├── variable.js
│   │   ├── page
│   │   │   └── *.vue
│   │   └── component
│   │   │   └── *.vue
│   │   └── function
│   │       └── *.vue
│   └── scss
│       ├── app.scss
│       ├── foundation
│       │   └── _*.scss
│       ├── layout
│       │   └── _*.scss
│       └── object
│           └── _*.scss
│
└── themes
    ├── _assets
    │   ├── img
    │   │   └── *.jpg
    │   ├── js
    │   │   └── bundle.js
    │   └── css
    │       └── app.css
    ├── _inc
    │   └── *.php
    ├── functions.php
    ├── header.php
    ├── footer.php
    ├── index.php
    └── ...

になりました。
src/ 内の app.jsscss/ 内の app.scss
テンプレートいじる必要があるときは themes/ 内の *.php を直接いじる

webpack 設定

展開する

const TerserPlugin            = require('terser-webpack-plugin');
const MiniCssExtractPlugin    = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const VueLoaderPlugin         = require('vue-loader/lib/plugin');

// [定数] webpack の出力オプションを指定します
// 'production' か 'development' を指定
const MODE = 'production';

// ソースマップの利用有無 production or development (productionのときはソースマップを利用しない)
const enabledSourceMap = (MODE === 'production');

module.exports = {
  name: "app",
  externals: {
    Vue: "Vue"
  },
  // モード値を production に設定すると最適化された状態で、
  // development に設定するとソースマップ有効でJSファイルが出力される
  mode: MODE,
  // メインとなるJavaScriptファイル(エントリーポイント)
  entry: {
    "app": './src/js/app.js'
  },
  // ファイルの出力設定
  output: {
    // 出力ファイルのディレクトリ名
    path: `${__dirname}/themes/_assets/js`,
    // 出力ファイル名
    filename: 'bundle.js'
  },
  // CSS minify と sourceMap の出力のための設定
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
        sourceMap: true,
      }),
      new OptimizeCSSAssetsPlugin({
        cssProcessorOptions: {
          map: {
            inline: false,
            annotation: true,
          }
        }
      })
    ]
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: [
          {
            // Babel を利用する
            loader: 'vue-loader',
          }
        ]
      },
      {
        // .js の場合
        test: /\.js$/,
        use: [
          {
            // Babel を利用する
            loader: 'babel-loader',
            // Babel のオプションを指定する
            options: {
              presets: [
                // プリセットを指定することで、ES2018 を ES5 に変換
                '@babel/preset-env'
              ]
            }
          }
        ]
      },
      // Sassファイルの読み込みとコンパイル
      {
        test: /\.scss/, // 対象となるファイルの拡張子
        use:
          [
            // CSSファイルを書き出すオプションを有効にする
            {
              loader: MiniCssExtractPlugin.loader,
            },
            // CSSをバンドルするための機能
            {
              loader: 'css-loader',
              options: {
                // オプションでCSS内のurl()メソッドの取り込みを禁止する
                url: false,
                // ソースマップの利用有無
                sourceMap: enabledSourceMap,

                // 0 => no loaders (default);
                // 1 => postcss-loader;
                // 2 => postcss-loader, sass-loader
                importLoaders: 2
              }
            },
            {
              loader: 'sass-loader',
              options: {
                // ソースマップの利用有無
                sourceMap: enabledSourceMap,
              }
            }
          ]
      }
    ]
  },
  // 完全ビルドされたVue.jsを読み込むように変更
  // ref: https://aloerina01.github.io/blog/2017-03-08-1
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['*', '.js', '.vue', '.json']
  },
  plugins: [
    // CSSファイルを外だしにするプラグイン
    new MiniCssExtractPlugin({
      // ファイル名を設定します(output.path から見た階層)
      filename: './../css/app.css',
    }),
    // Vue loader プラグイン
    new VueLoaderPlugin()
  ]
};

こんな感じで開発環境は完了
次回は .vue でやったこと中心に書いていきます。

【読書メモ】インタフェースデザインのお約束 ―優れたUXを実現するための101のルール

インタフェースデザインのお約束 ―優れたUXを実現するための101のルール

インタフェースデザインのお約束 ―優れたUXを実現するための101のルール

本屋に寄って見つけた インタフェースデザインのお約束 ―優れたUXを実現するための101のルール を読みました。
オライリー系のインタフェース関連本は インタフェースデザインの心理学 以来でしたが、形式は似ているものの内容は新しく共感することも多い本でした。

概要・ポイント

タイトルの通り、101個のデザインについての筆者の考えが掲載されています。

  • 文字と言葉
  • アイコンやボタン
  • UI部品
  • フォーム
  • ナビゲーションとユーザージャーニー
  • ユーザーへの情報提示
  • アクセシビリティ

の各章がありその中で例えば、

  • 009 用語は製品内で統一せよ
  • 034 リンクはリンクらしい体裁にせよ
  • 069 ハンバーガーメニューなんて使うな
  • 079 検索結果は関連度の高い順に表示せよ
  • 094 UIデザインではベストプラクティスの採用は盗用にはならない

のような指針が101個書かれています。
英語のタイトルが 101 UX PRINCIPLES ~A definitive design guide~ なので101の指針、原則が載っているような感じですね。

201〜208までは訳者によって日本(語)特有の指針もあとがきとしてあります。
オライリー公式にPDFでもありました。
https://www.oreilly.co.jp/pub/9784873118949/yakusha-atogaki.pdf

作者のWill GrantさんはイギリスのUI/UX専門家とのこと
まえがきに

「これには賛成できない」と思えるルールもあるかもしれないが、それはそれでかまわない。なにしろこれは私が自説を披露する本なのだ。とはいえ、ときにはそのような意見の相違が、これまで良しとしてきた考え方の見直しに、ひいてはユーザーのゴールを達成するより良い方法の模索につながる可能性もあり得る。

とあり決してこの101個の指針をその通り飲み込めといっているわけではないそうです。
そのうえで、 001 あなたもUXのプロになれる では

UXデザインに必須の基本スキルは共感力客観性だ。

という内容があります。このふたつは度々出てくるキーワードで 012 常に「顧客は生身の人間」を念頭に置いた表現を でも

...
「自分たちが作っている製品」という見方を一時捨てて、顧客の目になって見直してみる能力が大事、ということだ。これはユーザビリティの高いソフトウェアを構築するには欠かせない能力であり、面倒でもやってみる価値は十分にある。

とあくまでユーザーファーストで開発しようというスタンスで全ての指針が同じ方向を向いていると感じました。

ポイント

  • 「ユーザーにとって」分かりやすく アイコン、色情報にはラベルをつけるなど
  • ユーザーはやりたい作業(Jobs To Be Done)をこなすために製品を使う。その上でユーザーが主導権や裁量権を握っていることが大事。
  • 車輪の再発明をしなくてよい。デフォルトのコントロール、既存のUIからベストプラクティスを拝借して使う。

良かった点

  • 1項目1ページ〜2ページほどなので合間時間でも読みやすい。
  • 語り口がかしこまってないので頭に入りやすい。
  • 本のサイズがちょうどよく小さいサイズ。(インタフェースデザインの心理学 は大きかったので)
  • 間口が広い内容なので ディレクター/デザイナー/フロントエンドエンジニア だれでも興味深い内容になっている(おすすめしやすい)

惜しかった点

特になし。

まとめ

チームみんなで読んでそれぞれの考えの方向性をまとめれると感覚的なコミュニケーションロスが少なくなるのかなと感じました。
どの場面でもこの通りにするのは難しいこともあるかもしれないですが。
ともあれ、今年読んだ本の中で一番共感もでき面白い内容の本でした。

本のサポートページもあり、読者から意見(新しいルール)も募集しているみたいです。
インタフェースデザインのお約束 —— 優れたUXを実現するための101のルール サポートページ — マーリンアームズ株式会社

2019年11月 振り返り

結果

ブログ

目標:月 12 回(週 3 回)更新
結果:月 5 回 更新

読書

目標:月 1 冊
結果:月 1 冊

反省点など

11月中に読んだUI GRAPHICSと、次のを読んでいるので読書週間は少しずつ回復
ブログを書くネタがないわけではないですが、日頃からネタ帳作っておかないとなと思った

来月に向けて

Vueのサイトは残り調整くらい。年末までには公開できそう
使った技術的なことをブログに書き起こすのと、今年全体の振り返りや来年に向けても考えたい

Shifter をさわってみた

f:id:jotaki:20191122165357p:plain

WordPress の静的ホスティングサービス Shifter を検証で触ったのでメモしておきます。
今回採用には至らず、無料プランで試した範囲の内容です。

概要

WordPress の静的ホスティングサービスってなんだろと思ってましたがざっくり Shifter の特長として認識したのは

  • 静的HTMLで書き出される(.php動的されない)
    • CloudFront での配信
  • 管理画面は常時稼働(アクセス)されず、編集が必要なときのみ稼働

の2点が大きいかなと

それを受けての大きいメリットは、

ということ

デメリットとしては、

  • 有料(無料プランもありますが)
  • 即時反映できない(数分生成が必要)
  • 管理画面が2段階(Shifter管理画面 => WordPress管理画面)

ですかね。
あまり裏側のこと分かっていないので目立つ部分だけですが。

やりたかったこと・できなかったこと

既存で動いている・運用している WordPress サイトを Shifter を使って静的HTML配信。

これに関して、自身の調査前の認識と違う所がShifter触ってみるとありました。
大枠の流れや仕組みを図にまとめたのはこちら。

f:id:jotaki:20191124124447p:plain

一番大枠の部分ですが、
既存のWordPress環境にShifter環境(機能)を追加する、ではなく
既存のWordPress環境を新規のShifter環境に移行する、必要があることです。
サーバーレス/マネージドホスティングと謳っているので、そういうことなのねという感じでした。

既存 => Shifter環境への移行

公式 で移行の際は All-in-One WP Migration を推奨しており、これでやってみるとコンテンツからテーマまで移行できました。

Shifter環境ではおすすめできないプラグイン

プラグインに関しても動作が出来ない可能性が高いものは 公式 にのっています。

Shifter環境では動かない機能

いくつかのブログにも載っている通り動的生成される要素や機能は再現が難しいです。

  • 検索
  • お問い合わせフォーム

など。
ただこれに関しては未検証ですがShifter側が公式で代替の方法を作っている

あと今回はパーマリンク周りで全部 Custom Permalinks を使っていて、 /.html などにしていましたがそれが /.html/ になってしまうとか細かい所で調整や妥協が必要そうなところがでてきてしまいました。

Shifter側のサーバーは触れない

WordPressサーバーへFTPクライアントなど経由で接続できない(はず)なので、img/css/js などのアセット類はルートではなくテーマフォルダ内に置く必要があったりする。

テーマは手動で管理画面のテーマページからアップするか GitHubリポジトリとの連携 もできるみたい

.htaccess的な設定も直接触れなかったり、/wp-content/ 以下もアクセスができないので、例えばプラグイン一気に移行して、WPのバージョンやphpが既存と新環境(最新版)が合ってなかったりしてプラグイン有効化して止まると管理画面が真っ白状態になってしまったこともありました。(サポートに問い合わせれば解決かな)
その時はこれも未検証ですが ローカル環境つくって やるのが正解っぽい感じです。

まとめ・今後

上記で挙げた、移行に際しての懸念やもう少し要検証の要素があったこと、
Shifter管理画面 => WordPress管理画面 => 編集 => html生成 => デプロイ のフローを複数人で運用していくことが今は難しそうなどもあり、今回は見送りになりました。

ただ最初にあげたメリットをどこかで生かしてWordPressサイト作りたいと思うときも出てくると思うので、そのときにまた検証からはじめて使ってみたいと思っています。

参考:

【読書メモ】UI GRAPHICS 成功事例と思想から学ぶ、これからのインターフェイスデザインとUX

【新版】UI GRAPHICS 成功事例と思想から学ぶ、これからのインターフェイスデザインとUX

【新版】UI GRAPHICS 成功事例と思想から学ぶ、これからのインターフェイスデザインとUX

  • 作者: 安藤剛,水野勝仁,萩原俊矢,ドミニク・チェン,菅俊一,鹿野護,有馬トモユキ,渡邊恵太,須齋佑紀/津?将氏,庄野祐輔,藤田夏海,塚田有那,増川草介??栂木一徳
  • 出版社/メーカー: ビー・エヌ・エヌ新社
  • 発売日: 2018/10/19
  • メディア: 単行本
  • この商品を含むブログを見る

UI関連の本で以前から欲しい物リストに入っていた UI GRAPHICS 成功事例と思想から学ぶ、これからのインターフェイスデザインとUX を読みました。

概要・ポイント

事例では、

  • Intuitive
  • Minimal & Clean
  • Analog & Comfortable
  • Illustration & Infographic
  • Micro Interaction
  • Onboading Illustration
  • Internet of Things

の各テーマの事例がいくつか画面キャプチャありで掲載されています。
主にアプリのUIについてで、Webに派生しているものはほんのわずか紹介がある形。

ページ数的にこの事例がこの本のメインなんじゃないかと思っていたのですが、事例の合間に描き下ろしのコラムが10個ほどあります。
興味深かったのは、、いくつかピックアップしようと思いましたが全部ですね。

  • Apple が目指す「流れるインターフェイス」 | 安藤剛
  • 思考とジェスチャーとのあいだの微細なインタラクションがマインドをつくる | 水野勝仁
  • 個人的なインタラクション | 萩原俊矢
  • ユーザーのウェルビーイングのためのUI/UX | ドミニク・チェン
  • 導線としての制約を作る | 菅俊一
  • 動きとUI デザイン | 鹿野護
  • 話法について | 有馬トモユキ
  • UI の外在化とメタハードウェア | 渡邊恵太
  • 世界観への期待を創るUI デザインとエクスペリエンサビリティを向上するUX | 須齋佑紀/津﨑将氏

UIの変遷的な話の基礎部分から、それぞれの観点で捉えるUIについて語られるといった感じでしょうか。
特に近年のUIについてはフラットデザインで理解が止まっていたので Fluid Interface のこと、その潮流に伴う思考の変化など勉強になりました。

あとは個人的にUX寄りですがウェルビーイングについては初めて触れる観点でいろいろな世界があるなあと感じました。

巻末の再録は、

が特に興味深かったです。

良かった点

  • 事例が新しい、印刷がきれい
  • コラムが充実

惜しかった点

特になし。
ほんのサイズがちょい大きいくらいです(けど事例見せるためと思うのでしょうがないかなと)

まとめ

ぱっと本屋で立ち読みして事例目当てで買いましたが、どちらかというとコラムが面白かったです。