配布用テーマならいざ知らず、WordPressに関わるほとんどの人は、特定の案件のためにテーマを開発し、そしてカスタマイズし続けるでしょう。
WordPressサイトの保守を行う上でネックになるのは、デプロイの複雑さです。
ファイルをアップロードするだけでは完結せず、新たに固定ページを投稿する、Advanced Custom Fields でカスタムフィールドを追加する、場合によってはプラグインのインストール、設定を行うなど。
ひとつでも間違えたり漏れたりすると、開発環境通りに動いてくれません。
初回リリース時はDBごと持っていくことができても、運用が始まってしまうとそうはいきません。
また、ソース外の作業が増えてしまうと、Gitなどによるソース管理の意義も半減してしまいます。
そこで、サイトの新規・修正リリース時には、
1. テーマファイルをアップロードし、
2. テーマを見再アクティベートし、
3. パーマリンクの更新ボタンを押す
以外のことは何もしなくて良いように作っています。
まずはプラグイン。
前提として、プラグインは極力使わないことです。
キャッシュやバックアップなど、テーマの機能と直接関係しないものは問題ありませんが、
これがなくてはテーマの機能が成立しない、というようなプラグインは、テーマに組み込んでしまいまうのが良いです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Mytheme { //略 public function init() { //略 //Built-Inプラグインのロード include_once( TEMPLATEPATH . '/lib/acf/acf.php' ); include_once( TEMPLATEPATH . '/lib/acf-repeater/acf-repeater.php' ); //略 } //略 } |
上記のように、プラグインファイルをテーマのサブディレクトリに入れ、
プラグインのメインファイルを include すれば、大抵のプラグインは動きます。
管理画面から更新通知が来ない点は注意が必要です。
私の場合、ほとんどのテーマ開発に Advanced Custom Fields を用いています。
ただし、フィールド設定は管理画面から投稿するのではなく、フック用クラスで register_field() を用いて設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
<?php /** * 投稿タイプ、タクソノミー、カスタムフィールド * リライトルール、テンプレートルールなどの設定を行う * * @category includes / hooks * @package fresale * @author AD5 */ class MT_Setting { public function init() { //略 add_action( 'init', array( $this, 'set_post_types' ) ); add_action( 'init', array( $this, 'set_taxonomies' ) ); add_action( 'init', array( $this, 'set_custom_fields' ) ); //略 } //略 /** * ACTION HOOK : init * Advanced Custom Fieldsを用いてカスタムフィールドを登録 */ public function set_custom_fields() { if(function_exists( "register_field_group" ) ) { register_field_group( array ( 'id' => 'acf_post_type_ebook', 'title' => 'post_type_ebook', 'fields' => array ( array ( 'key' => 'field_post_type_ebook_pdf', 'label' => 'PDFファイル', 'name' => 'pdf', 'type' => 'file', 'required' => 1, 'save_format' => 'url', 'library' => 'all', ), array ( 'key' => 'field_post_type_ebook_thumbnail', 'label' => 'サムネイル画像', 'name' => 'thumbnail', 'type' => 'image', 'save_format' => 'object', 'preview_size' => 'thumbnail', 'library' => 'all', ), array ( 'key' => 'field_post_type_ebook_catchcopy', 'label' => 'キャッチコピー', 'name' => 'catchcopy', 'type' => 'text', 'default_value' => '', 'placeholder' => '', 'prepend' => '', 'append' => '', 'formatting' => 'html', 'maxlength' => '', ), //略 ), 'location' => array ( array ( array ( 'param' => 'post_type', 'operator' => '==', 'value' => 'ebook', 'order_no' => 0, 'group_no' => 0, ), ), ), 'options' => array ( 'position' => 'normal', 'layout' => 'no_box', 'hide_on_screen' => array ( 0 => 'the_content', 1 => 'featured_image', 2 => 'categories', 3 => 'tags', 4 => 'send-trackbacks', ), ), 'menu_order' => 0, ) ); } //略 } } |
こうすれば、デプロイの際に管理画面から細々と設定をいじる必要がありません。
カスタム投稿タイプやカスタムタクソノミーの設定も、プラグインを用いず、フックで行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
/** * ACTION HOOK : init * register_post_type() を実行し、投稿タイプを登録 */ public function set_post_types() { $labels = array( 'name' => 'eBook', 'singular_name' => 'eBook', 'menu_name' => 'eBook', ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => array( 'slug' => 'ebook' ), 'capability_type' => 'post', 'has_archive' => true, 'hierarchical' => false, 'menu_position' => 6, 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ) ); register_post_type( ebook, $args ); //略 } /** * ACTION HOOK : init * register_taxonomy(), register_taxonomy_for_object_type() を実行し、タクソノミーを追加 */ public function set_taxonomies() { register_taxonomy( 'ebook-genre', 'ebook', array( 'label' => 'レポートカテゴリ', 'show_in_quick_edit' => true, 'show_admin_column' => true, 'rewrite' => array( 'slug' => 'ebook/genre' ), 'hierarchical' => true ) ); register_taxonomy_for_object_type( 'ebook-genre', 'ebook' ); //略 } |
さらに、テーマに必須の固定ページ、特にコンテンツを記述せず、専用のページテンプレートを用意して表示を行うようなものは、テーマの有効化時にフックによって投稿するようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
<?php /** * テーマアクティベート時のフック用クラス * * @category includes / hooks * @package fresale * @author AD5 */ class MT_Activate { public function init() { add_action( "init", array( $this, "do_action" ) ); add_action( "mt_theme_activate", array( $this, "insert_pages" ) ); //略 } /** * ACTION HOOK : init * テーマアクティベート時にカスタムアクションを実行 */ public function do_action() { global $pagenow; if( is_admin() && $pagenow == "themes.php" && isset( $_GET["activated"] ) ) { do_action( "mt_theme_activate" ); } } /** * ACTION HOOK : mt_theme_activate (custom) * 必要な固定ページがなければデフォルト値投稿 */ public function insert_pages() { $default_pages = $this->get_default_pages(); $parent_pages = array(); $args = array( 'hierarchical' => 0, 'post_status' => 'publish' ); $exist_pages = get_pages( $args ); foreach ( $exist_pages as $exist_page ) { $key = $exist_page->post_name; if ( array_key_exists( $key, $default_pages ) ) { unset( $default_pages[$key] ); } $parent_pages[$exist_page->post_name] = $exist_page->ID; } if ( $default_pages ) { foreach ( $default_pages as $default_page ) { $default_page['post_status'] = 'publish'; $default_page['post_type'] = 'page'; if ( array_key_exists( 'post_parent', $default_page ) ) { if ( array_key_exists( $default_page['post_parent'], $parent_pages ) ) { $default_page['post_parent'] = $parent_pages[$default_page['post_parent']]; } else { $default_page['post_parent'] = 0; } } $inserted = wp_insert_post( $default_page ); $parent_pages[$default_page['post_name']] = $inserted; } } } public function get_default_pages() { return array( FS_Const::PAGE_INQUIRY => array( 'post_name' => FS_Const::PAGE_INQUIRY, 'post_title' => 'お問合せ', 'post_content' => 'お問合せ' ), FS_Const::PAGE_REGISTER => array( 'post_name' => FS_Const::PAGE_REGISTER, 'post_title' => '会員登録', 'post_content' => 'レポートを投稿したい方は、こちらから会員登録してください。' ), FS_Const::PAGE_SIGNIN => array( 'post_name' => FS_Const::PAGE_SIGNIN, 'post_title' => 'ログイン', 'post_content' => 'ログイン' ), FS_Const::PAGE_SIGNOUT => array( 'post_name' => FS_Const::PAGE_SIGNOUT, 'post_title' => 'ログアウト', 'post_content' => 'ログアウト', 'post_parent' => FS_Const::PAGE_SIGNIN ), FS_Const::PAGE_MYPAGE => array( 'post_name' => FS_Const::PAGE_MYPAGE, 'post_title' => 'マイページ', 'post_content' => 'マイページ', ), FS_Const::PAGE_MYPAGE_PROFILE => array( 'post_name' => FS_Const::PAGE_MYPAGE_PROFILE, 'post_title' => 'プロフィール編集', 'post_content' => 'プロフィール編集', 'post_parent' => FS_Const::PAGE_MYPAGE, ), ); } //略 } |
こうしておけば、基本的に修正デプロイ時は、ファイルをアップロードしてテーマを再有効化するのみで済みます。
(リライトルールに関わる処理を追加・修正した時は、パーマリンクのリフレッシュも行います。)
ソース管理のみで完結するので、非常に構成管理が楽になります。
前提として、ソース内でIDによる投稿やタームの参照はしない、ソースから参照するスラッグは定数化しておくなどの考慮も大切です。