タグ: WordPressマルチサイト

  • WordPressのマルチサイト案件で、子テーマを使って効率よくカスタマイズする。

    この間、WordPressのマルチサイトモードで、8サイトくらいあるサイトを作りました。

    一つのサイトですが、更新コンテンツがとにかく大量にあっりました。
    そのコンテンツがカスタムフィールドばりばり使ったり、デザインがいろいろ違っていたり、求められる機能がいろいろ違ったりしていて、カスタム投稿やタクソノミーでは、開発しづらいし運用も大変だろうな・・・・ということで、マルチサイトで子テーマを6つくらい作りました。そのときのやったこと、やれば良かったことなどなど。

    そもそも子テーマとは

    子テーマ – WordPress Codex 日本語版

    要は、あるテーマを元にしてそのテーマを一部だけ改変したようなテーマを作成できる機能です。ただ、読み込み順は子テーマ→親テーマとなるので、子テーマに足りないものを親テーマから保管する機能と言ったほうが正確かも知れません。
    継承って言い方をしていますが、プログラミングにおけるクラスの継承とは全く別物なので注意が必要です。

    なので、get_header()とかを子テーマで、書いた場合、子テーマ内のheader.phpを探しにいって、なかった場合、親テーマのheader.phpが呼ばれます。
    また、子テーマにarchive.php、親テーマにcategory.phpがある場合は、カテゴリーページにアクセスしたら親テーマのcategory.phpが呼ばれるようです。まぁ、そうじゃないと、index.phpを作ったら全部のテンプレートを上書きってことになってしまいますもんね。

    子テーマの作成

    子テーマとしてテーマを作成するためには、style.cssの最初のテーマ用コメントに Template: 親テーマのディレクトリ名とするだけです。また、子テーマの場合、index.phpが無くても大丈夫です。
    [css]
    /*
    Theme Name: 子テーマ
    Template: parent
    */
    [/css]

    また、子テーマの子テーマ、孫テーマみたいなのは作成できません。1世代までです。

    子テーマ、親テーマで値が変わる関数や、定数

    正直全部は説明できませんが、とりあえず、

    • bloginfo(“stylesheet_directory’”)/bloginfo(“template_directory’”)
    • get_stylesheet_directory()/get_template_directory()
    • get_stylesheet_directory_uri()/get_template_directory_uri()
    • STYLESHEETPATH/TEMPLATEPATH

    の値は変わります。
    stylesheet・・・シリーズは子テーマ、templateシリーズは親テーマの情報を返します。
    なので、テーマ内で使う画像やCSS等、共通のリソースは親テーマに突っ込んでおく&なるべくtemplateシリーズでの記述ををお勧めします。

    また、is_child_theme()という関数もあるようです。

    functions.php

    functions.phpだけは存在すれば読み込まれない、という挙動ではなく、子テーマのfunctions.php→親テーマのfunctions.phpの順で両方読み込まれます。カスタム投稿・タクソノミーの設定は、子テーマのfunctions.phpに記述するといいかもしれません。

    また、

    子テーマのfunctions.php で同名の関数があれば、子テーマの関数が使用されます。

    という記述が日本語版Codexにありますが、これは、ちょっと言葉足らずで、そのまま同名の関数を書くと、「Cannot redeclare」のエラーを吐いてしまいます。なので、親テーマに再定義可能な関数を作る場合は

    [php]
    if ( ! function_exists( ‘parent_function’ ) ) {
    function parent_function() {
    // 処理内容
    }
    }
    [/php]

    としてあげる必要があります。英語版のCodexにはここら辺のこともちゃんと書いてあります。Child Themes « WordPress Codex

    また、テーマで使う変数も保護しないと上書きされてしまうのでここら辺は注意が必要です。変数の上書きはエラーにならないので、定数にしておく等の工夫が必要です。

    テーマの構造の設計における注意

    ちゃんと使いこなせば、いろいろ便利な機能ですが、ちゃんと設計しないと、「別々にテーマを作った方が、楽だった」になんてことになりかねない機能でもあります。
    なので、いくつか注意事項、というより現時点で僕が気を使っているルールです。

    親テーマを実際に使用するテーマにしない

    一番最初にマルチサイト+子テーマでサイトを作ったときに、親テーマを親サイト(ルートサイト)に設定していたために、死ぬほど苦労した結果、子テーマをやめた。なんて失敗もありました。

    親サイトはトップページなど、再利用性が低いものが入ることが多いですし、front-page.phpや、home.phpなど、テンプレートの読み込み順の優先度が高いものを使うことも多いです。これを子テーマ側でいちいち作成するのはとても面倒。無駄。これだけは絶対やってはいけないです。

    また、親テーマを実際に利用していると、「このサイトではカテゴリーも月別アーカイブも全部一緒でいいのに・・・・」みたいなことが発生し易いです。
    なので、親テーマに置くのは、ほんとに共通で使い回す部分だけ&テンプレートの読み込み順が低いもの例えば、

    1. header.php/footer.php等のモジュール系
    2. archive.php
    3. index.php
    4. テーマ内で使い回したい関数、ヘルパー等のライブラリ

    等に留めましょう。

    親テーマのfunctions.phpの肥大化を避ける

    別に子テーマを使ったりしなくてもという話でもあるんですが、マルチサイトは基本的に大きな案件にならないと使わないとは思いますが、そうなってくると、どんどん全部で使い回すようなカスタマイズが、functions.phpに蓄積していきます。

    ただ、管理画面のカスタマイズなど、テーマとの関連性が薄いもの、すべてのサイトで活用するものはfunctions.phpではなく、プラグインにして極力テーマの見通しを良くしましょう。カスタム投稿タイプ等は冗長になりがちなので、プラグインで関数を作るなりクラスを作り、それをテーマで使い回す等が便利だと思います。

    その他やっておいた方が、いいかもと思うこと。

    body_classにサイト名を出力


    をプラグインとかfunctions.phpに書いておくと、site-hogeみたいなクラスを吐くので便利かもしれません。特にテーマを識別する手段が無いので。。

    blog_idに依存しない

    特にテーマを別環境で作っているときは気をつけたいのですが、現在のサイトを識別する手段が、グローバル変数の$blog_idくらいしか無かったと思います。ただ、テーマにIDを直書きするのはメンテナンス性を欠くので、get_id_from_blogname( “hoge” )とかで、パスで指定する方が設定とテーマの分離ができて良いのかなと思います。

    前回の記事でもそんなとき使えるものを書きました。

    https://torounit.com/blog/2013/04/25/1514/

    WordPressのマルチサイト機能3.0からMUと統合されたまだまだ新しい機能です。対応していないプラグインもあります。僕のリリースしているCustom Post Type Permalinksもちゃんと対応できておりません(汗)
    またカスタム投稿との棲み分けとかも考えないといけない部分があります。

    ただ、ちゃんと使いこなせれば、更新コンテンツが多い、ユーザーが多い案件等でもかなり使い易い構築ができるんじゃないかな・・・と思っています。

  • WordPressのマルチサイトでブログパスでswitch_to_blogする。

    最近マルチサイト案件が多かったりするのですが、各ブログを横断してリンクをつないだりみたいなことをたくさんやりました。
    扱うサイトも多く、ブログを削除して作り直して・・・みたいなことが結構あったのですが、そのときに当然blog_idもかわってしまいます。(まぁそりゃそうだよね)

    で、マルチサイトの肝になるところといえば、switch_to_blog でブログを切り替えてあーだこーだすることだとは思うのですが、これが、

    [php]
    switch_to_blog(1);
    [/php]

    みたいな感じで、変更先のブログのIDを指定せねばならないのです。これがちょっと使い勝手が悪いし、テーマを見たときにどこのブログに変わったのか、よくわかりません。

    という訳でソースを眺めていたら、get_id_from_blogname( $slug )といういかにもな関数がありました。

    example.com/hoge/ もしくは hoge.example.com

    という子サイトがあった場合、
    [php]
    get_id_from_blogname( "hoge" );
    [/php]
    とすると、blog_idを教えてくれるので、

    [php]
    switch_to_blog( get_id_from_blogname( "hoge" ) );
    [/php]

    といった感じで、サイトパスで切り替えることができます。こっちの方が解り易いですね。テーマだけ別環境で開発といった場合でもちょっとは反映作業などもスムーズになるのではないでしょうか。

    まぁ、案件も終盤になった頃に見つけたのですがね・・・・

    マルチサイトは発展途上なイメージですが、ちゃんと使うと結構いろいろなことができそう!

  • WordPressのマルチサイトでブログが追加されたときに、フロントページ・投稿ページを自動追加する

    「WordPressのマルチサイトを使ったWEBサービスを作る」なんてコトを最近ちょこちょこやっているのですが、そのときに専用のページをこさえたりしたいなんて、ことがありまして。

    フロントページ機能を自動的に有効化したかったのですが、調べてみたらそんなに難しくなさそうだったので作ってみました。
    別に関数一つなんだからクラスにする必要ないんじゃないかとは思いますが、そこはご愛敬です。

    wpmu_new_blogというアクションフックがブログの新規作成時に実行されるらしいです。しかも結構色々と変数を渡してくれるみたいです。
    WordPressのネットワークで新規サイト作成時のAction Hook探し | ちいさな創々

    なので、それにフックして、wp_insert_postで、ページを作成して、それをupdate_optionで設定する、という意外に単純な作りで実現できます。

    BUddyPressなんかで活用活用したい!