WordPressをサーバH2Oで動かす (WordPressアプリケーションサーバとしてのH2O)

常時SSL とプロトコル HTTP/2 に対応するため、サーバ環境を新しくしてウェブサイトを移行しました。
新しい試みとしてサーバ構成を CentOS7 + PHP7 + MariaDB + H2O + WordPress にしてみました。

次世代の HTTPサーバ H2O を中心に速い WordPress を目指してサーバを構築。

今回 WordPress を HTTPサーバ H2O でどのように動かせばいいのか見てみたいと思います。

HTTPサーバ H2O とは

H2O は、プロトコル HTTP/2 に最適化されたウェブサーバです。

ここ数年でセキュリティ面で SSL が必須になりつつあり、ネット環境も新しい通信規約 (プロトコル) が求められている時代に最適なウェブサーバのひとつになっていくのだろうと注目していました。

H2O の開発は、2014年から元DNAの @kazuho さんが中心にオープンソースとして進められています。Perl を使っている方はウェブアプリを作るときに Server::Starter でお世話になっているのでは。ボクもいつもお世話になっています。
Server::Starter は、H2O のバックグラウンドにも使われていて start_server が動いているのが見て取れます。こういうところにも使われているのかとほんと感心しますね。

HTTP/2 時代を見据えているだけあってサーバの性能もベンチマークを見るとレスポンスが Apache や Nginx より速い。
他にも H2O の技術要素に注目したいものがたくさんあるのですが、詳しく知りたい方は、公式サイトやスライドも上がっているのでそちらを見ていただければと思います。

WordPress をサーバ H2O で動かす

2015年6月に FastCGI機能を実装したバージョン 1.3.0 がリリースされて、PHP が動くようになりました。
サーバ H2O で WordPress を動かすには、2 つの方法があります。

ひとつめは、WordPress を PHP-FPM や HHVM で管理。Nginx で従来やっている馴染みのあるやり方をそのまま踏襲。H2O も fastcgi.connect でホストに繋げてレスポンスを返してくれる。

今回採用したもう一個の方は、H2O 自体で管理する方法。
fastcgi.spawn で起動してH2Oの下で PHP のプロセスを管理してくれます。
PHP-FPM や HHVM をインストールしてコンフィグの設定起動、運用の手間がなくなります。

今回の試みとして思っていたことで、
WordPress とかPHPアプリを動かすアプリケーションサーバとしてH2Oは、最適なんじゃないかなぁと。

実際 H2O の下に php-cgi が動いているのが見て取れます。

WordPress を動かすサーバ設定 (/etc/h2o/h2o.conf) もYAML書式でシンプルに書けます。

以下これだけでWordPressが動きます。

paths:
  "/":
    file.dir: /path/to/wordpress
    redirect:
      url: /index.php/
      internal: YES
      status: 307
    file.custom-handler:
      extension: .php
      fastcgi.spawn: "PHP_FCGI_CHILDREN=10 exec /usr/bin/php-cgi"

実にシンプル。YAMLでわかりやすいのがいいですね。(本番運用には、自動更新やダッシュボードへのアクセスのところでもう少し手を入れる必要があるのですが。)

で今回の試したサーバ設定は、

  • 常時SSL
  • www にURL正規化
  • http から https にリダイレクト
  • WordPress ツールバーからダッシュボード (www.example.com/wp-admin/) へアクセス
  • WordPressの自動更新ができるように
  • FastCGI のスループットチューニング
  • 他もろもろ

で以下のような本番運用サーバ設定 (/etc/h2o/h2o.conf) になりました。

user: nobody
 
listen:
  port: 80
listen:
  port: 443
  ssl:
    certificate-file: /path/to/fullchain.pem
    key-file: /path/to/privkey.pem
 
hosts:
  "localhost":
    paths:
      "/":
      redirect:
        status: 301
        url: https://www.example.com/
 
  "www.example.com:80":
    paths:
    "/":
      redirect: https://www.example.com/
  "www.example.com:443":
    paths:
      "/":
        file.dir: /var/www/wordpress
        redirect:
          url: /index.php/
          internal: YES
          status: 307
 
file.index: [ 'index.php', 'index.html' ]
 
file.custom-handler:
  extension: .php
  fastcgi.spawn:
    command: "PHP_FCGI_CHILDREN=10 exec /usr/bin/php-cgi"
    user: example
  fastcgi.timeout.keepalive: 10000
 
access-log: "| exec sudo rotatelogs /var/log/h2o/access.log.%Y%m%d 86400"
error-log:  "| exec sudo rotatelogs /var/log/h2o/error.log.%Y%m%d 86400"
 
pid-file: /var/run/h2o/h2o.pid
http1-upgrade-to-http2: ON
http2-reprioritize-blocking-assets: ON

WordPressを動かすH2Oサーバ設定のポイント

WordPress ツールバーからダッシュボード (www.example.com/wp-admin/) へアクセス

通常の設定では、WordPress ツールバーからダッシュボード (www.example.com/wp-admin/) へアクセスは、トップページを返してしまいます。

ダッシュボードにアクセスできるように file.index で index.php を追加して www.example.com/wp-admin/ で www.example.com/wp-admin/index.php にアクセスするようにしました。

WordPressの自動更新ができるように

H2O はデフォルトで nobody の下で動きます。
H2Oの管理下にある PHP も nobody で動きます。
WordPressの自動更新は、WordPressのファイル所有者の下でPHPが動かないと自動更新が働きません。
fastcgi.spawn には、どのユーザ user で動かすか指定できるので、WordPressのファイル所有者を指定して動かします。

FastCGI のスループットチューニング

fastcgi.spawn での PHP への接続は、デフォルトでは1回限りの接続です。これだとWordPressが動くたびにコネクションが発生します。
fastcgi.timeout.keepalive で Keep-Aliveを 10 秒に指定。一定時間 FastCGI の接続を継続させてスループットを改善してみました。

まだまだキャッシュ周りやいろいろチューニングができそうなので、運営しつつ試してみたいと思います。

参考サイト

ブログを Movable Type から WordPress に移行

Movable Type から WordPress に移行したときの備忘録です。

このブログは、PSGI Plack 環境の Movable Type で運営してきました。
今回 WordPress の移行をどこまでできるか、開発環境でいろいろ試してみました。移行前に考えたのは...

  • コンテンツマネジメントシステム (CMS) は同じでサーバ間の移行は経験があるけど、CMS 間の違いの移行はやったことがない。
  • Movable Type はバージョン 5
  • CMS 間で形式が違うデータをどうやって WordPress に移行するのか。
  • どの程度コンテンツデータに手を入れる必要があるのか。
  • パーマネントリンクの URL は、すでに登録されている検索インデックスに影響を与えないようできるだけ維持したい。

まずは、データの移行

Movable Type のブログデータのエクスポート。
「ツール > 記事のエクスポート」からエクスポートしてテキスト形式のファイル (export-xxx.txt) をダウンロードします。

開発環境に構築していた WordPress にそのエクスポートファイルをインポートします。
「ツール > インポート」にある Movable Type と TypePad で「今すぐインストール」をクリックするとインポーターがインストールされます。インストールが完了して「インポーターの実行」をクリックすると、インポーター画面に移動。
実際は裏でプラグイン「Movable Type・TypePad インポートツール」をインストールして有効化されています。
移行が済んだら無効化しましょう。

インポーター画面では、
エクスポートファイルを選択する方法と、
エクスポートファイルを mt-export.txt に変えて /wp-content/ ディレクトリに直接アップロードする方法の
2 つのやり方があります。

今回は、エクスポートファイルのデータサイズが大きくないので、ファイルを選択する方で。

ダウンロードしたエクスポートファイルを選択して「ファイルをアップロードしてインポート」ボタンを押すと、
新しくユーザを作るか、今いるユーザに投稿者を割り当てて「実行」をします。

いたってスムーズにデータの移行ができました。

どこまでデータが移行できたか

タグは移行できなかった。タグはほとんど使っていないので問題ないけれど。
やる場合はプラグインに手を入れる必要がある。
画像がメディアライブラリに入ってくれたら嬉しかったけど。
エクスポートファイルとの対応付けの難しさ、
エクスポートしたデータを変更してしまうデータ保全から無理もない感じで。
実装が難しそう。

あとは問題ない。投稿もコメントもちゃんと入っている。

コンテンツデータに手を入れるとすれば、画像の張り替え。
いままでの画像フォルダを残しておけば、そのまま引き継がれる。
特段手を入れる必要は無いけれど。
今回は画像数が少ないので、メディアライブラリで管理することに。
コンテンツデータは画像のところだけ手を入れた。

パーマネントリンクのURLをどう維持するか

一番考えて調整が難しかったのがパーマネントリンクの引き継ぎ。
パーマリンクの構造は、Movable Type のテンプレートで設定していたアーカイブマッピングに依存してしまう。

ブログ記事のアーカイブパスは、archives/%e.html
%e は、6 桁のエントリー ID、桁数が 6 桁に満たないとき、0 で埋めて表示される。

ブログ記事リストでは
カテゴリが %c/index.html
月別は %y%m/index.html
とパーマリンクの構造を設定していた。

WordPress に設定するパーマリンク設定として、
ブログ記事は Movable Type から完璧に引き継ぎ。
これは記事が検索されることを考えると譲れないところ。
ただし、今後はパーマリンクを変更できるようにしたい。

カテゴリやアーカイブは、
プラグイン「Custom Permalinks」でカテゴリ、タグを個別にパーマリンクの設定ができるので、対応できる。
けれど、今後の運営のことも考えて WordPress のパーマリンクの構造に変更することにした。

ということで、パーマリンク設定のカスタム構造は、
投稿のスラッグを 6 桁のエントリー ID でヒモ付けて
パーマリンク設定のデフォルトの選択にはない以下の通りに設定した。

/archives/%postname%.html

記事のスラッグを 6 桁のエントリー ID に変える作業をやった。

これでいままでのパーマリンクを引き継ぎつつ、
今後はパーマリンクを自分でつけられるようにしてみました。

Blue-Green Deployment で無事に移行完了

あとは、メニューを作ったり、必要なプラグインを入れたりしてレイアウトを整えた。
本番環境のサーバーに新しい DocumentRoot を作って WordPress を入れてそこに WordMove で同期。
サーバーの設定を前のブログの DocumentRoot から 新しい方の DocumentRoot に向けて振り替え。
サーバーを再起動すると、WordPress ブログの運営が始まりました。
Blue-Green Deployment 的にデプロイを進めてみました。

ウェブサイトの移行は?

まだ試していない。ウェブサイトの移行も試してみたい。
普通はホームページのリニューアルを考えるものが大半だと思うので、正式なやり方がない。
そもそもCMS間でサイトの捉え方が違う。
Movable Type は、今までのサイト設計のようにフォルダーを作ってウェブサイトの設計ができるけれど、
WordPress は、固定ページを作ってそこに親子関係を作っていく設計をするので、
そこをエクスポートデータでどう吸収できるかがサイト移行の肝のような気がする。

ウェブエンジニア、プログラマのためのプログラミング開発環境「VAP」をリリースしました

プログラミング開発環境 Vagrant Ansible Programming languages (VAP) を作りました。

VAP は日常的にプログラミングするウェブエンジニア、プログラマのための Ansible playbooks です。Vagrant でプログラミング開発環境を立ち上げて、プログラミングをしてプロダクトを作ったり、ソフトウェアの技術課題の検証やバグ・不具合の検証ができます。

エンジニアにとって開発環境の構築に時間がかかる手間を減らしていきたい、社内で開発環境を整えるツールとして活用できます。

VAP の特長は、3つ。

  • 様々な組み合わせのサーバとデータベース構成で構築
  • Ruby, PHP, Perl, Python などプログラミング言語をバージョンを指定してインストール
  • Develop & Deploy ツールのインストール

以前 2014年12月に WordPressサイトを開発する WordPress開発環境 Vagrant Ansible WordPress (VAW) を作ってリリースしました。VAW はアップデートを続け、いろいろなノウハウを蓄積してきました。VAP は、そのコンセプトをベースに開発環境を素早く立ち上げてアイデアを試して、終わればその開発環境を捨てるという試行錯誤ができる環境を目指してみました。

今後もサポートするプログラミング言語を増やしたり、Develop & Deploy ツールの充実をしていきたいと思います。

以下、GitHub にある VAP の readme-ja.md です。(updated: version 0.1.2 - 2016.09.12)

続きを読む "ウェブエンジニア、プログラマのためのプログラミング開発環境「VAP」をリリースしました"

CSS Flexbox のグリッドレイアウトがつくれる Sass Mixin ライブラリ「Flexbox Grid Mixins」をつくりました

スタイルシートの Flexbox を使ってグリッドレイアウトが生成できる Sass Mixin「Flexbox Grid Mixins」をリリースしました。

グリッドを自由自在につくりたい

どういうものかというと、以下のサンプルのような HTML と Sass があると、サクッとグリッドの CSS をつくってくれます。

HTML

<div class="grid">
<div class="grid__col-3">
  3
</div>
<div class="grid__col-9">
  9
</div>
</div>

Sass

@import 'node_modules/flexbox-grid-mixins/sass/flexbox-grid-mixins';
 
$default-grid-gutter: 2%;
 
.grid {
  @include grid($gutter: $default-grid-gutter);
 
  > .grid__col-3 {
    @include grid-col($col: 3, $gutter: $default-grid-gutter);
  }
  > .grid__col-9 {
    @include grid-col($col: 9, $gutter: $default-grid-gutter);
  }
}

CSS

.grid {
  box-sizing: border-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-flow: row nowrap;
  -ms-flex-flow: row nowrap;
  flex-flow: row nowrap;
  margin: 0 -1%;
}
 
.grid > .grid__col-3 {
  box-sizing: border-box;
  -webkit-flex: 0 0 23%;
  -ms-flex: 0 0 23%;
  flex: 0 0 23%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-9 {
  box-sizing: border-box;
  -webkit-flex: 0 0 73%;
  -ms-flex: 0 0 73%;
  flex: 0 0 73%;
  margin: 0 1% 2%;
}

グリッドシステムも作れます

ほんの数行の Sass コードでグリッドシステムがつくれます。

よく使われる 12 カラムのグリッドシステムはデフォルトでつくれることはもちろん。カラム数のオプションを指定すれば、いくつのカラム数のグリッドシステムも自由自在につくれます。

HTML

<div class="grid">
<div class="grid__col-12">
    12
</div>
</div>
 
<div class="grid">
<div class="grid__col-1">
    1
</div>
<div class="grid__col-11">
    11
</div>
</div>
 
<div class="grid">
<div class="grid__col-2">
    2
</div>
<div class="grid__col-10">
    10
</div>
</div>
 
<div class="grid">
<div class="grid__col-3">
    3
</div>
<div class="grid__col-9">
    9
</div>
</div>
 
<div class="grid">
<div class="grid__col-4">
    4
</div>
<div class="grid__col-8">
    8
</div>
</div>
 
<div class="grid">
<div class="grid__col-5">
    5
</div>
<div class="grid__col-7">
    7
</div>
</div>
 
<div class="grid">
<div class="grid__col-6">
    6
</div>
<div class="grid__col-6">
    6
</div>
</div>

Sass

@import 'node_modules/flexbox-grid-mixins/sass/flexbox-grid-mixins';
 
$default-grid-columns: 12;
$default-grid-gutter: 2%;
 
.grid {
    @include grid($gutter: $default-grid-gutter);
 
    @for $i from 1 through $default-grid-columns {
        > .grid__col-#{$i} {
            @include grid-col($col: $i, $grid-columns: $default-grid-columns, $gutter: $default-grid-gutter);
        }
    }
}

CSS

.grid {
  box-sizing: border-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-flow: row nowrap;
  -ms-flex-flow: row nowrap;
  flex-flow: row nowrap;
  margin: 0 -1%;
}
 
.grid > .grid__col-1 {
  box-sizing: border-box;
  -webkit-flex: 0 0 6.33333%;
  -ms-flex: 0 0 6.33333%;
  flex: 0 0 6.33333%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-2 {
  box-sizing: border-box;
  -webkit-flex: 0 0 14.66667%;
  -ms-flex: 0 0 14.66667%;
  flex: 0 0 14.66667%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-3 {
  box-sizing: border-box;
  -webkit-flex: 0 0 23%;
  -ms-flex: 0 0 23%;
  flex: 0 0 23%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-4 {
  box-sizing: border-box;
  -webkit-flex: 0 0 31.33333%;
  -ms-flex: 0 0 31.33333%;
  flex: 0 0 31.33333%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-5 {
  box-sizing: border-box;
  -webkit-flex: 0 0 39.66667%;
  -ms-flex: 0 0 39.66667%;
  flex: 0 0 39.66667%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-6 {
  box-sizing: border-box;
  -webkit-flex: 0 0 48%;
  -ms-flex: 0 0 48%;
  flex: 0 0 48%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-7 {
  box-sizing: border-box;
  -webkit-flex: 0 0 56.33333%;
  -ms-flex: 0 0 56.33333%;
  flex: 0 0 56.33333%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-8 {
  box-sizing: border-box;
  -webkit-flex: 0 0 64.66667%;
  -ms-flex: 0 0 64.66667%;
  flex: 0 0 64.66667%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-9 {
  box-sizing: border-box;
  -webkit-flex: 0 0 73%;
  -ms-flex: 0 0 73%;
  flex: 0 0 73%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-10 {
  box-sizing: border-box;
  -webkit-flex: 0 0 81.33333%;
  -ms-flex: 0 0 81.33333%;
  flex: 0 0 81.33333%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-11 {
  box-sizing: border-box;
  -webkit-flex: 0 0 89.66667%;
  -ms-flex: 0 0 89.66667%;
  flex: 0 0 89.66667%;
  margin: 0 1% 2%;
}
 
.grid > .grid__col-12 {
  box-sizing: border-box;
  -webkit-flex: 0 0 98%;
  -ms-flex: 0 0 98%;
  flex: 0 0 98%;
  margin: 0 1% 2%;
}

オプションでさらに自由自在なグリッドに

Sass Mixin「Flexbox Grid Mixins」には、たくさんのオプション (引数) が用意されています。くわしくは、Mixins リファレンスを読んでもらえればと思いますが。グリッドのカラム数やカラム周りのマージン指定の他、flexbox のプロパティ、事前に用意したカラム (プリセットカラム) が生成できたり。サンプルページもありますので、参考に一度ご覧ください。いろんなレイアウトが組めると思います。

作った理由。なぜフレームワークではなくライブラリなのか

Sass Mixin ライブラリ「Flexbox Grid Mixins」を作った理由は、3つあります。

まず自由自在なグリッドレイアウトを作りたいと思ったこと。CSSフレームワークでは、12 カラムのグリッドシステムが定番でそれを元に作っていくのですが。もっとシンプルに、作りたいグリッドを作りたいカラム数でその場で柔軟に作っていきたい。

次にフロントエンド開発環境。昨今ウェブアプリの開発環境で起こっていることがフロントエンド開発環境に波及していること。一例を挙げると、Node.js とそのパッケージ管理 npm のもと、package.json で依存関係を解決することで、プロジェクトのポータビリティが向上したことが挙げられます。また gulp や grunt などのタスクライナーで自動化、効率化が図られています。スタイルシートも Sass などプリプロセッサを通じて生成することが多くなりました。

最後にCSSフレームワーク。はじめ開発者向けに作られた Bootstrap はバージョンを繰り返し、フルスタックで様々なプロジェクトに導入されるようになりました。さらに多種多様なCSSフレームワークがたくさん作られています。フレームワークを導入すると、便利に効率的な開発ができます。しかし、フレームワークを導入することは融通さを犠牲にすることもあり、バランスを取るのが難しくなります。とくにスタイルシートは最終的に静的ファイルに生成するため、事前に様々なことを想定していろいろなものを詰め込んでしまいます。次第に複雑さが増し柔軟性がなくなっていきます。それは同時にプロジェクトにも柔軟性がなくなることを意味します。フレームワークの次が求められています。

そしてフレームワークの先へ...

これからのフロントエンド開発を考えるに、いかに柔軟性をもちつつ、開発ができる環境を整えるかが重要になってきます。プロジェクトの中でパッケージ管理を行い、必要な機能や部品だけをライブラリという形で取り込み、Sass などプリプロセッサで組み合わせて使っていくコンポーメントベースに向かっていくのではないか。と仮説を立ててみました。これも昨今のウェブアプリの開発環境と同じ方向に向かうのでは。フレームワークとは言えないほど薄っぺらいフレームワークを利用してウェブサイトを開発していく未来に。

という未来を見据え、実現に一歩近づきつつ、Sass Mixin ライブラリ「Flexbox Grid Mixins」が産まれました。

個人的にはこれをなんとかしたい。class属性の嵐

フレームワークを使ったり、OOCSS をもとに実装すると、HTML の class属性 にいっぱい値を記述しがちです。ボクもよくやりがち。

CSS の設計で構造と見た目の分離をした分、HTMLの方にしわ寄せがいって、気づいたら構造と見た目の class属性、状態の class属性でいっぱいになってしまいます。

必要最小限の記述でシンプルな解決を目指しつつ、Sass Mixin「Flexbox Grid Mixins」を作ったところもあります。

サンプルを作ってみた感想

flexbox ベースのグリッドは、ブラウザのサポート状況から float ベースのグリッドから次第に採用が増えたり、移行されたりすると思います。現状は flexbox のだいたいは使えるが、ブラウザの実装によっては細かいところでまだまだ不十分なところがありますね。これからもいろいろ改良をしていきたいと思います。

ということで

是非 Sass Mixin「Flexbox Grid Mixins」を使ってウェブサイトを設計したり、グリッドシステムを作ったりしてみてくださいね。

Flexbox Grid Mixins

Flexbox Grid Mixins is Sass Mixins library to help you write well-structured, readable, maintainable, component-based grid using Flexbox (CSS Flexible Box Layout Module).

Flexbox Grid Mixins documentation: https://thingsym.github.io/flexbox-grid-mixins/

Mixins Reference and Example

GitHub: https://github.com/thingsym/flexbox-grid-mixins

License

The MIT License (MIT)

WordPressプラグイン「Custom Post Type Widgets」に Search Widget を追加しました

カスタム投稿タイプで活用できるデフォルトウィジェット WordPressプラグイン「Custom Post Type Widgets」をアップデートしました。

今回のアップデートでは、新たに Search Widget を追加しました。

投稿、固定ページ、カスタム投稿タイプで絞り込み検索ができます。

また、Search Widget と Comments Widget には Custom Post Type すべてを対象にできるようにしてみました。

開発裏話

今回いろいろ手を入れて、ウィジェット独自にキャッシュ機能があったのを削除したり、全面的にリファクタリングをして、コード数もざっくり減らすことが出来ました。

一番悩んだことは、Search Widget は GitHub でプルリクをいただいたのですが、うまく機能しなかったこと。
書いたプラグインがダメではなく WordPress 本体の方。個別ページだけの検索絞り込みができない。

ググってもあまり分からず、WordPressで検索の絞り込みノウハウが書いてあるブログ記事を見てもなぜか投稿ページだけの絞り込みに関してはたくさんあるが、ページに関してはほとんどなかったり。

ということでソースコード (wp-includes/post.php) を読むと、個別ページを作成する register_post_type には、publicly_queryable に false が設定されており、フロントエンドで post_type クエリが実行できないようになっています。(なぜそうなっているのか開発フォーラムを見ても経緯がよく分からなかったのですが...)

実際、?post_type=page でアクセスしても post_type が破棄されて (unset)、裏で revision以外すべてのタイプ (any) が検索対象になったりします。

個別ページだけの検索絞り込みをするために対処したことは、検索ページが表示される時に、pre_get_posts にフックして破棄された post_type を再度追加してみました。

他のアプローチとしては、register_post_type で登録されたものを変更してもいいのではと思ったのですが、そもそも register_post_type を実行途中で変えていいのか、検索時だけなので影響範囲を考えるとこれでいいのではないかと。
また、register_post_type の変更方法がわからないというのもあります... 誰かどういうアプローチがあるのか教えてください。

おかげさまで

WordPressプラグイン「Custom Post Type Widgets」は2015年1月にリリースして一年あまり。海外の開発者に反応が良く、プルリクをいただいたり、段々使われるプラグインに育ちつつあります。カスタム投稿タイプを使ったテーマ開発に是非使ってみてくださいね。

ダウンロード & インストール

WordPress の公式プラグインページ

ライセンス

GNU General Public License v2.0 (GPLv2) licenses

開発

GitHub

最近の投稿

カテゴリー

アーカイブ