cdbk.tokyoのJavaScript周り

WordPressの記事管理と問い合わせ送信処理以外のほとんどをJavaScriptでしているので、その簡単なまとめ。

WordPressをREST APIとBackboneを使ってSPAで導入した時のメモ

JavaScriptの構成(ビルド・コンパイル前)

  • lib (ライブラリなど)
    • Underscore
    • jQuery
    • Backbone (MVxなフレームワーク)
    • Marionette (Backboneを便利にできるフレームワーク)
    • Chart (時折つかうグラフ描画)
    • moment (時間フォーマット計算系)
    • photoswipe (一昔前のlightbox風なモーダル)
  • common (共通Ajaxや簡単なAPI経由の一覧表示など)
  • top (トップページ用ページ処理)
  • contactform (お問い合わせ機能)
  • contactform (お問い合わせページ処理)
  • portfolio (ポートフォリオ用モーダル)
  • instagram (インスタグラムデータ取得連携)
  • post (ブログコンテンツページ処理)
  • wpmain (ブログ機能)
    • wpApplication (ブログ機能アプリケーション)
    • wpController (ブログ機能制御コントローラー)
    • wpLayout (ブログレイアウト)
    • wpPager (ブログページャー機能)
    • wpFooter (ブログカテゴリー・タグ一覧表示機能)
    • wpList (ブログ一覧表示処理)
    • wpPost (ブログ記事表示処理)
    • wpSearch (ブログ検索処理)

雑にまとめると上記のような構成で機能とページ毎で分けるようにしています。
機能面の主体はMarionetteで構成、ライブラリ以外は機能毎にコンパイルしています。

ReactやVueなどは使わず、半人月で仕上げられ、BFFもSSRもなく、Apacheのrewriteで間に合うぐらいのサイズ感です。

日本語はUnicodeエスケープ、開発時のJavaScriptはES2015をベースに行っています。

かっこよく今風のにしようとなんども考えるものの、開発コストやフレームワーク側の方針転換などでぶれたり、そもそもJavaScriptのフレームワークのライフサイクルが2年持つか持たないかぐらいの期間でしかないので、導入はもっとコストを注げる時かなという見方をしています。

その他RSSを対応させたり、API取得時のエラーで表示できないケース対応などを暇を見て対応しています。

直近でこのサイトでやろうとしていること

この数日〜数ヶ月で実装しようとしているもの

  • HTMLのユニコードエスケープ
  • plan / プラン、見積もり額表示のコンテンツ再開
  • コーヒー系のプログラム

プラン・見積もりはパッケージのような形で業務別に分けた上で係数をつけ、画面ごとに割り出すようなロジックで計算できないかを考え中です。
コーヒー系のプログラムはものすごく使いやすいなど明確なメリットが出せれば公開・・・

WordPressをREST APIとBackboneを使ってSPAで導入した時のメモ

要点

以前投稿した 「サイトのブログをWordPressベースのSPAにしてみた」 の内容を整理と カテゴリー・タグ別の一覧表示や検索に対応したので軽く実装できるところまでのまとめメモ。

準備したもの(環境)

  • 既存なサーバー(heteml)
  • WordPress
  • JavaScript(Marionette, Backbone, jQuery, Underscore, moment, ES6+babel)
  • Nodejs(Gulp)
  • MAMP(NodeベースではなくApacheのRewriteなどを使うため)

WordPressのSPAを公開する場合の要は普通の検索結果に載せることができるかどうか?
トップページから何度もクリックしないと行き着かないコンテンツは見てもらえず、不便なのでApacheのRewriteなどでPushStateで変更されたアドレスのコンテンツと同じものを表示させることが大事。

またビルド環境がなくともサーバー上のデータを直接編集して修正対応することや、WordPressをSPAで実装するにあたってどんな問題が起こるかなど把握するために、一旦jQueryベースのMarionette/Backboneで構築した。

軽く実装方法

Gulpでビルドしたものの出力先にMAMPの参照先を設定して、Gulpでビルド+Apacheでブラウジングできる環境を整える。
その上でWordPressはWeb上のものをそのまま使用、クロスドメインのため使用上ページ数、記事数などResponse headerで送られてくるデータが取得できないなどのところはnullを置き換える対応を行うなどして考慮する。そしてES2015へ移行。

アドレス別の役目

https://cdbk.tokyo/post → トップページ
https://cdbk.tokyo/post/(slug) → 記事ページ
https://cdbk.tokyo/post/category/(slug) → カテゴリー別一覧ページ
https://cdbk.tokyo/post/tag/(slug) → タグ別一覧ページ
https://cdbk.tokyo/post/search/(slug) → 検索結果ページ

各ディレクトリ毎の(slug)に当たるところに.htaccessを置いてrewriteの設定を行い、pushStateした際のアドレスに沿うようにAPIへのリクエスト処理を構築する。
また、そのため各記事はpost idではなくslugベースで呼び出すようにし、APIで呼び出すJSONデータはキャッシュさせるような仕様にしている。

アプリケーションのひも付き

Application

  • Controller (データの取得&表示系制御)
  • Layout (レイアウトなどのView)
  • Collection (記事などのView)

API

  • WordPress REST API

ルーティングもMarionetteで一応準備はしているもののブラウザバックボタンを使うことがあったりするので、一旦はBackboneで実装。

よかったところ

初期表示を一度してしまえば、表示速度が速い。
WordPressのテーマ・テンプレートの仕様を考慮せずページを作りこめる。
投稿などをWeb、アプリなどさまざまなところから場所を選ばずできる。
Marionetteベースだとビルド環境に左右されずに作ることができる。

まだつらいところ

キャッシュさせているのでクリアさせるのが難しい。
sitemap.xmlとfeed(ATOM/RSS)がまだ未対応で手動・・・
今後を考えるとJavaScriptの主体をvue/react/nuxt/nextにしてしまうのを早めにやってしまうのがいい。

まとめ

今までWordPressを使うときはテンプレートを頑張って、PHPを駆使してページを作ることが多かったけれど、REST APIを使うことで、かなりフロントより、JavaScriptメインでページやSPAを踏まえたサイト構築を行うことができるようになった。
今回はJavaScript周りをES2015へ少し移行させたり、サーバーをSSL対応のSSDベースのところにして高速化したりと今までできなかったことができてよかった。

次はNuxt?Vue?あたりを使えるようにしてから、導入できればと計画中。


関連リンク

WordPress REST API (Version 2)

WP REST APIでいろいろ取得してみる


https://qiita.com/uto-usui/items/4eb21aec704b888936d0

サイトのブログをWordPressベースのSPAにしてみた

まとめると

gulpとejsベースでブログコンテンツを再開したものの、更新や記事の管理を考えるとWordPressに勝るものはなく、WordPressをSPAで実装したという話。

EJSベースからWordPressベースへ戻す・・・

昨年(2017年)、サイトをリニューアルした際にブログ機能をWordPressからejsにして0から始めてみたものの、今後記事数が数百などになった場合の管理やリニューアルをした時の記事データのあり方を考えると、
やはりCMSやデータベースで管理したほうがいいと思ったことと、WordPressのREST APIがとても使いやすかったので、年末年始で全記事一覧、記事表示を一旦実装したので、記事にまとめてみました。

現状、jQuery + Backbone + Marionetteベースの仕様なので、一旦それを踏襲してWordPress REST Apiを使った画面表示+設計を実用レベルで落としこむ&実装、その後、今時の新しい技術で置き換えるをゴールにしようと思い、一旦はjQueryベースで実装しています。

記事一覧トップと各記事はpushStateでアドレスを変更するようにしているものの、実態はSPAのため、記事ページ上でブラウザの更新ボタンを押すor直接アクセスすると404になるという、SPAでよくある事象はApacheのReWriteで解決することにしました。

Marionette + Backboneの実装など

ページへアクセスした際にアプリケーション(Marionette.Application)、コントローラー(Marionette.Controller)、ルーターを起動して、レイアウトの配置をした後に、APIへアクセスして記事データを取得、表示するようにしているのみで、
こちらから記事内容の変更や削除を行えるアクセスはできないようにしています。

APIの設計の都合上、ページ数などをResponse Headerから取得する必要があるため、WordPress本体は同じサブドメイン上に置く必要があり、また、APIへアクセスするとWordPressの実態があるURLも取得可能なため、完全なAPIのみの表示を行おうとするとWordPressのテーマ上でプロセスの追加・変更が必要になると思います。

Apache側でSPAのPushStateしたアドレスを解決

各記事ページのアドレスを「slug」の文字列にしておき、APIへのアクセスと記事ページアドレスを両方、slugにすることで下記のReWrite設定でまかなうことができるようにしています。

RewriteEngine On
RewriteBase /post/
RewriteRule ^index.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ index.html?$1

その他、今後実装する予定のカテゴリー、タグ、検索結果などの○ページ目などをSEOを考慮して実装する際また大幅に手を加えることになりそうですが、ひとまずはこのままで・・・

今後の課題

現状はGoogle側へ送信しているsitemap.xmlをgulpを使い、ejsをビルドする際に作っているので、それに加え、WordPressのプラグインなどを使って作っているsitemap.xmlをサイトのSPAで実装しているアドレスに置き換えて実装できればSEO面も担保できそう。

表示のレスポンスの速さとアクセスのしやすさを両立したSPAをコーポレートサイトに実装する、そのノウハウを次へ活かしつつ、WordPressのSPA化を視野にサイト構築のバリエーションを増やしていくことでエンジニアリングとデザイン両面で表現の幅を広げていければと考えています。

そして15記事あまりのejsで作った記事ページをWordPress側へコピペする作業を地味に行う必要が・・・

これとは別にNuxt.jsなどを使い、何がどこまでできるか、SEO考慮して普通に実装できるかを試していて、もしうまくいく兆しがあれば、換装していく予定。

WordPressのテーマなどに依存しないサイトデザインや設計をこのサイトで具現化していこうと考えているので、また何か更新した時は記事にしていきます。

何か質問などあれば、問い合わせもしくはSNS経由でコンタクトしてみてください。

WordPress REST APIの導入対応中

ゆくゆくはNuxt.jsやNext.jsのSPAでと考えているものの、まだ技術的な城壁が多少あるので手軽なMarionetteJSを使って、取り急ぎ、EJSベースにしているブログ記事更新をWordPressのREST APIベースの管理にしようと現在対応しています。

大まかな表示ができるようになってきたので、あとはカテゴリーなどの一覧表示や検索、ページング機能を追加することで一旦は過去の記事も観れるようになりそうです。

一応SPAなので更新ボタンを押した際にまた観れるようApacheで設定しています。

2017年便利だったガジェット

今年、手に入れ便利だったガジェット

mophieのバッテリー内蔵型イヤホンケース

ケース内にUSBポートが一つあり、AirPodsやBluetoothイヤホンを充電できるケース。

自分はその中にApple Watchの充電ケーブルを入れていて旅行先や仕事先で充電するときに使っています。
少し大きめのケースなので短いケーブルなどいろいろ入ります。

Bluetoothヘッドホン

いつもインイヤータイプのヘッドホンとBluetoothのオーディオレシーバー(最近だとAT-PHA55BTXB10-BTHA)を使っていたのですが、
防寒や部屋にいるとき完全にワイヤレスで音楽を聴いたりしたいと思い色々調べ、ATH-WS990BTはコードを繋げばハイレゾ対応で、スイッチで切り替えると周りの音も拾える機能があり、決めました。
流石に相当寒くないと通勤中はちょっと暑いですが、すごく便利で重宝しています。音質も自分好みのソリッドベース。

Bluetooth対応スピーカー

今までハーマンのエンカウンターを使っていたのですが、古かったり、アナログのみだったりしたので、手頃なCreativeのBluetooth対応スピーカーに買い替えました。

ちゃんと音楽を聴く時はヘッドホンということが多いので、音質は十分、iPhoneやiPad、MacBookなどとワイヤレスで繋がるのはすごく便利です。

18mm-135mmのPentaxの標準ズームレンズ

万能で広角から望遠までカバーできるレンスで三脚を使うような遠距離を撮影する時以外は、このレンズをつけたままです。

電動歯ブラシ

今まで超音波式のドルツを使っていたのですが、価格とスマートフォンを使ったIoT連携ができるフィリップスの電動歯ブラシが気になり、11月から使っています。

今までの歯ブラシとは別次元の仕上がりで磨き残しがないようにスマートフォンでチェックできるところ、充電のドックがグラスでおしゃれなところも完璧でした。

ブラシ交換が3ヶ月ごとで1本あたり1000円しないぐらいなのでコストパフォーマンスはかなりいいと思います。。

蛇口取り付け型の浄水器

今までブリタのポットタイプを使っていたのですが、水を入れて浄水されるのも待つ時間が勿体無いと思い、蛇口に取り付けるタイプに変更しました。

味は若干劣るものの、そのまま飲めるおいしさで、すぐコーヒーやお茶用の水が確保できるのでペットボトル飲料の消費量が減りました。

VS Codeをインストール

気づかぬ間にATOMより流行っていたVS Code。
導入がATOMと比べても楽だったので使い始めることにしました。

ひとまず、インストールしたプラグイン

.ejs
Atom Keymap
Auto Close Tag
Beautify
Debugger for Java
EditorConfig for VS Code
ESLint
Java Debugger
jshint
Language Support for Java
Node Debug 2
NodeMcu
Prettier – Code formatter
React Native Tools

ATOMなどでもPrettierが優秀でいちいち自分でインデントなどをしなくても綺麗にしてくれるのでオススメです。

ESLintを導入するときは設定→ユーザー設定に"eslint.autoFixOnSave": true,
"eslint.enable": true,
を追加。

GoogleのPageSpeed Insightsの対応をトップページに

GoogleのPageSpeed Insightsの対応をトップページに反映してみました。

ひとまずはトップページのみで、読み込み後の表示時にWebフォントのために透明度を調整したりしているところを綺麗にできれば他のページにも反映したいと考えています。

SNS系のシェアボタンなどを使うために入れている外部ツールのリンク先のJSが非圧縮状態だったりするのでそこの点数分引かれてはいるものの、比較的簡単に対応することができました。

素のHTMLファイルではなく、EJSベースで作成、タスクランナーでコンパイル・ビルドをして圧縮しているので、編集するファイルはネストなどをした状態で保持でき、
普段のコーディングは苦にならない状態です。
今までと大きく変わるのはCSSのリンクをJavaScriptで出力しているところで、YAMLのリストベースでcssとjsを管理していたりするのでそこのコードマネージメントもしっかりして他のページにも対応していきたいところです。

実は、ブログ機能はWordPressを復活させてそこからREST APIで描画させようかと検討中。
そうするとiOSなどのWordPressアプリから編集できるので、そのメリットは取り込みたいな・・・

スパムや不正アクセスとFTPについて

この2年ぐらい、主にWordPressで構築したサイトを中心にスパム、 不正アクセスとサーバー管理者からのメールとクライアントとのやり取りを行う機会が増えてきた。

主要因はWordPress本体やプラグインの脆弱性をついたもので WordPressやプラグインをアップデートすることで、一昔前は収束。
ところが、最近は、侵入時に確実にバックドアを仕掛け、数日〜数ヶ月後にそれを使ってスパムメールを送るプログラムを稼働させたりすることで検知、 発覚といったことが増え、何をすればいいのかそのやり方に手詰まり、学生時代の友人に頼ったりもした。

そして、今のところ対策として一番があるのがFTPアクセス制限。

そのほか、サーバーによってはHTTPのIP制限をしてくださいとアナウンスしているところもあるけれど、 法人の回線からだとアクセスできないことが起こったりするので、現実的な方法はFTPアクセス制限。

ひとつ間違えると自分自身の端末からもアクセスできなくなるので実装するには注意は必要ではあるものの、 サーバー側でブラウザベースのファイル管理システムがあるところなどは比較的簡単に制限をしやすい。

もし、FTPアクセス制限をしても治らない場合は、アクセスできる端末やサーバーそのものにバックドアがある場合があるので、 その場合はサーバー管理者に原因を探ってもらう、サーバーを移転してしまうといった方法が考えられるけれど、 できれば、そうなる前に対処しておきたい。

問い合わせフォームの再開について

お問い合わせフォームの処理をフロントエンドに寄せる

問い合わせフォームの処理の送信するまでのところを全てフロントエンド側のJavaScriptをベースに処理できるものに変更しました。

今までのHTMLベースのボタン押下後の処理をJavaScriptで行うだけでなく、
フォームの描画からJavaScriptでコントロールする方式に変更しています。

フロントエンド側へ寄せるメリット

入力内容のバリデーションパターンなどをフロントで管理させる事で、
サーバーサイドの処理を送信のみに絞り、また質問内容などをフロント側で管理することで、
メンテナンスコストを下げる事ができます。

フロントエンド側へ寄せるデメリット

一番大きなデメリットはAMPへの対応が難しく、送信するデータを全てフロントエンド(ブラウザ)側で
準備する必要があるので改ざんされてしまう可能性は0にできないため、
改ざんを防ぐためのロジックや機能をサーバー側に準備させる必要があります。

実際に導入するにあたり、心がけていたところ

今回はサイトのリニューアルでMarionette/Backboneを本格的に導入して、
HTMLのページ生成などにgulpとejsという少し古いものを使い、
ロジカルなところをできるだけライブラリやプラグインではなく、
自分自身で書いて実装する様にしました。

reactやvueベースでとなるとバックエンドのAPI周りの開発コストが従来の比べれば減るものの、
フレームワーク自体の更新ペースが早く、それに付随してさまざまなものも変化が激しいため、
数ヶ月〜1年以上同じバージョンのものを使い続ける事がセキュリティ面など含めて現実的ではないので、
今回は少し古い技術を使って実装しています。

将来的にはAPI周りがnode.jsベースで実装できるサーバー環境が整えば、vueなどで換装したいと考えています。