Not Wiz Grimoire https://not-wiz.net Everyone is a beginner at first. Wed, 19 Feb 2020 15:40:07 +0000 ja hourly 1 https://wordpress.org/?v=5.3.2 https://not-wiz.net/wp-content/uploads/2020/02/cropped-site-icon-32x32.png Not Wiz Grimoire https://not-wiz.net 32 32 ブロックスタイルをPHPで作ろう https://not-wiz.net/articles/wordpress/add-php-block-style/ Wed, 19 Feb 2020 15:00:58 +0000 https://not-wiz.net/?p=257 本記事は、 WordPress 5.3 以降で可能になった PHP でブロックのスタイルを追加する方法について解説します。

ブロックのスタイルについて

ブロックには、スタイルと言った仕組みがあります。ブロックのスタイルを変更することで、要素の見た目をボタン1つで簡単に変更することを可能にします。

例えば、当ウェブサイトでは図のように「見出し」ブロックに独自の矢印風スタイルを追加しています。そうすることで新しいブロックなどを追加しなくても、ウェブサイトに合わせたデザインの統一感を表現可能です。

現在、ブロックスタイルのカスタマイズはPHPでも可能

ブロックエディターのカスタマイズには、従来の WordPress の開発で使用される PHP 以外(例えば React などのメタ言語)の知識が必要となります。
WordPress 5.3 以降では、React などのメタ言語を使用せず、PHP とCSSのみでもブロックのスタイルを設定可能になりました。その結果、PHP言語を主に取り扱うウェブ制作企業やウェブデザイナーの方でもメタ言語を意識せず、簡単にブロックのスタイルを制作可能な状態になりました。

実際にブロックスタイルを割り当てる前に

まず、スタイルを割り当てるために、標準ブロックの名前やなどを整理する必要があります。次の一覧を参考にしてください。括弧内はブロックの name になります。

標準ブロックの一覧

一覧の対応バージョンについて

WordPress 5.3 で確認しています。

一般ブロック

  • 段落( core/paragraph
  • 見出し( core/heading
  • リスト( core/list
  • 引用( core/quote
  • 画像( core/image
  • ファイル( core/file
  • ギャラリー( core/gallery
  • 音声( core/audio
  • カバー( core/cover
  • 動画( core/video

フォーマット

  • カスタムHTML( core/html
  • 表( core/table
  • ソースコード( core/code
  • クラシック( core/freeform
  • 整形済み( core/preformatted
  • プルクオート( core/pullquote
  • 詩( core/verse

レイアウト要素

  • 続きを読む( core/more
  • グループ( core/group
  • カラム( core/columns
  • ボタン( core/button
  • メディアと文章( core/media-text
  • 改ページ( core/nextpage
  • 区切り( core/separator
  • スペーサー( core/spacer

ウィジェット

  • ショートコード( core/shortcode
  • アーカイブ( core/archives
  • カレンダー( core/calendar
  • カテゴリー( core/categories
  • 最新のコメント( core/latest-comments
  • 最新の記事( core/latest-posts
  • RSS( core/rss
  • 検索( core/search
  • タグクラウド( core/tag-cloud

埋め込み

  • 埋め込み( core/embed
  • Twitter( core-embed/twitter
  • Youtube( core-embed/youtube
  • Facebook( core-embed/facebook
  • Instagram( core-embed/instagram
  • WordPress( core-embed/wordpress
  • SoundCloud( core-embed/soundcloud
  • Spotify( core-embed/spotify
  • Flickr( core-embed/flickr
  • Vimeo( core-embed/vimeo
  • Animoto( core-embed/animoto
  • Cloudup( core-embed/cloudup
  • CollegeHumor( core-embed/collegehumor
  • Dailymotion( core-embed/dailymotion
  • Funny or Die( core-embed/funnyordie
  • Hulu( core-embed/hulu
  • Imgur( core-embed/imgur
  • Issuu( core-embed/issuu
  • Kickstarter( core-embed/kickstarter
  • Meetup.com( core-embed/meetup-com
  • Mixcloud( core-embed/mixcloud
  • Photobucket( core-embed/photobucket
  • Polldaddy( core-embed/polldaddy
  • Reddit( core-embed/reddit
  • ReverbNation( core-embed/reverbnation
  • Screencast( core-embed/screencast
  • Scribd( core-embed/scribd
  • Slideshare( core-embed/slideshare
  • SmugMug( core-embed/smugmug
  • Speaker Deck( core-embed/speaker-deck
  • TED( core-embed/ted
  • Tumblr( core-embed/tumblr
  • VideoPress( core-embed/videopress
  • WordPress.tv( core-embed/wordpress-tv
  • Amazon Kindle( core-embed/amazon-kindle

ブロックスタイルを追加しよう

サンプルコードのダウンロード

ケミ

今回の記事ではサンプルコードを用意しています。ここからの記事解説は、ダウンロードされたファイルのコードを見ながらご覧ください。

サンプルコードの内容

今回の記事では、サンプルとして「見出し」ブロックに幾つかのスタイルを追加することを行います。

サンプルコードの構成

block-style-sample

block-style-sample.php

editor-style.css

front-style.css

コードの解説

init にフックを追加

まず、init に対してフック追加を行います。

add_action( 'init', 'add_block_style' );
ケミ

フックの実行タイミングに問題があると、ブロックのスタイルは正しくブロックエディターに登録されません。ほとんどの場合、 ブロックのinit に対してフック追加を行うのが推奨されているようです。

コールバックをしている add_block_style 関数について

function add_block_style() {
	if ( is_admin() ) {
		editor_block_style();
	} else {
		front_block_style();
	}
}
ケミ

フックで実行される add_block_style 関数では、管理画面時、つまり、ブロックエディター時には editor_block_style 関数を実行し、それ以外は front_block_style 関数を実行するようにしています。

ブロックエディター側のスタイル追加処理について

function editor_block_style() {
	wp_register_style(
		'block_style_sample_editor',
		plugin_dir_url( __FILE__ ) . 'editor-style.css',
		[],
		filemtime( plugin_dir_path( __FILE__ ) . 'editor-style.css' )
	);
	register_block_style(
		'core/heading',
		[
			'name' => 'arrow',
			'label' => '矢印',
			'style_handle' => 'block_style_sample_editor',
		]
	);
	register_block_style(
		'core/heading',
		[
			'name' => 'speech',
			'label' => '吹き出し',
			'style_handle' => 'block_style_sample_editor',
		]
	);
	register_block_style(
		'core/heading',
		[
			'name' => 'stripe',
			'label' => 'ストライプ',
			'style_handle' => 'block_style_sample_editor',
		]
	);
}
ケミ

ブロックエディターの画面でスタイルを反映するため、editor_block_style 関数では wp_register_style 関数で ブロックエディター内で読ませる CSS ファイルを登録する形にします。注意点は wp_enqueue_style 関数ではないことです。

ケミ

そして、register_block_style 関数が今回の最大のポイントです。この関数には、第1引数に「ブロックの name」、第2引数に「スタイルを示す連想配列」を記述します。この関数の詳しいリファレンスは次を参照してください。

register_block_style – WordPress私的マニュアル
ケミ

「スタイルを示す連想配列」の name の値に記述した文字列は、実際のCSSのクラス名では .is-style- をプレフィックスとして付与されます。
label の値に記述した文字列は、ブロックのスタイルを選択する際に表示されるラベル名になります。

style_handle の値に記述した文字列は、wp_register_style 関数で事前に登録していた CSS のハンドル名を割り当てます。

今回は「矢印」「吹き出し」「ストライプ」の3種類を追加するサンプルなので register_block_style 関数を3回使用し、それぞれのスタイルを追加しています。

ブロックエディター側のスタイルについて

ケミ

ここで editor-style.css を一度見てみましょう。

.editor-styles-wrapper div[data-type="core/heading"] h1.rich-text.is-style-arrow,
ケミ

ブロックエディター内では .editor-styles-wrapper と言う大きなクラス要素の中に各ブロックが div タグで囲まれて存在する仕様になっています。そのため、 .editor-styles-wrapper div[data-type= ブロックの name ] でスタイルを当てるブロックに対する切り分け指定が可能です。また、h1 タグの要素の中には、実際の画面とは異なり、見出しの文字入力をするための .rich-text の要素が含まれています。基本的に入力要素がある場合は .rich-text 要素に対してスタイルを当てるようにすれば良いでしょう。

ブロックエディターとフロント画面では一部のスタイルが変化すると言うことを覚えておいてください。

フロント画面側のスタイル追加について

function front_block_style() {
	wp_enqueue_style(
		'block_style_sample_front',
		plugin_dir_url( __FILE__ ) . 'front-style.css',
		[],
		filemtime( plugin_dir_path( __FILE__ ) . 'front-style.css' )
	);
}
ケミ

実際の画面でスタイルを反映するために、front_block_style 関数では wp_enqueue_style 関数で front-style.css を読み込むようにしています。この CSS では、実際の画面には .rich-text などのクラス要素はありませんので h1h2 タグに対してスタイルを当てるようにしています。

補足

備考

サンプル内のブロックのスタイルは、サルワカの「CSSのコピペだけ!おしゃれな見出しのデザイン例まとめ68選」 を参考にさせていただきました。

]]>
MW WP Form のスタイルの基礎 – MW WP Form カスタマイズ https://not-wiz.net/articles/mwf/mwf-style-first/ Tue, 11 Feb 2020 04:33:02 +0000 https://not-wiz.net/?p=254 MW WP Form では、入力、確認、完了の3つの表示状態があります。本記事は、表示状態によるスタイルや、フォーム別のスタイルについて変更方法などを解説します。

MW WP Form のフォームの id と class について

最初に、MW WP Form のフォームは次のような div タグによって囲われています。

<div id="mw_wp_form_mw-wp-form-**" class="mw_wp_form mw_wp_form_****">

id の仕様

テネーブル

mw_wp_form_mw-wp-form-** の最後の ** となっている部分は、フォームID が記載されています。例えば、フォームIDが 1 であれば、div タグの id は、mw_wp_form_mw-wp-form-1 となります。この id によってフォーム別のスタイルを別々に付与させることができます。

class の仕様

ルミェール

classmw_wp_form は、MW WP Form のすべてのフォームで付与されるよ。

テネーブル

mw_wp_form_**** の部分の **** の部分は、表示状態によって異なります。詳しくは、次の項をご参照ください。

フォームの表示状態による class の変化

MW WP Form では

  • 入力時、mw_wp_form_inputclass の付与
  • 確認時、mw_wp_form_confirmclass の付与
  • 完了時、mw_wp_form_completeclass の付与

となります。

テネーブル

先程の mw_wp_form_**** の部分の **** の部分は 入力時では mw_wp_form_input となると言うことですね。

表示状態に合わせて表示を変更するスタイルの例

次のようにスタイルを記述することで、フォームの表示状態に合わせて要素の表示も変更できます。

.適当なクラス名 {
    display: none;
}

/* 入力時のみ、適当なクラス名が付与されている HTML要素を表示 */
.mw_wp_form_input > .適当なクラス名 {
    display: block;
}

最後に

ケミ

制作現場では、お問い合わせフォームに、入力などのステップを表示したいと言うケースをよく依頼されます。そう言った場合でも、本記事で解説している通り、MW WP Formの idclass の仕様に合わせてスタイルを適用すれば、ステップ表示も可能です。

]]>
グラフ・チャート描画ブロックが豊富「Planet Charts」を試したよ – WordPress プラグインレビュー https://not-wiz.net/articles/wordpress/try-plugin-planet-charts/ Tue, 11 Feb 2020 03:45:13 +0000 https://not-wiz.net/?p=252 時々、ウェブサイト制作案件でもグラフやチャートを表示させたいと言う要望をお客様からいただきます。
本記事では、グラフやチャートを簡単に表示できるブロックが豊富な WordPress プラグイン「Planet Charts」を試してみました。

ライセンスはもちろん 100%GPL とのこと

ケミ

envato market の codecanyon と言うサービスで販売されているけど、ライセンスは 100%GPL。開発者の方にも確認したけど、プラグイン自体のライセンスは WordPress コミュニティが推奨する 100%GPL を守っているんだって。

100% GPL のプラグインと言うことなので、当ウェブサイトは本プラグインを紹介することにしました。

どんなプラグインなの?

ケミ

Planet Charts はブロックでグラフを作るためのプラグイン。

ブロックエディターの設定部分で設定をしていく形で、グラフを視覚的に作れる便利なブロックがいっぱい用意されています。

ブロックエディター用のプラグインなので、もちろんクラシックエディターでは役に立ちません。

グラフの種類は、とにかく豊富!

本記事の執筆時点の Planet Chart 1.8.0 では

  • pie
  • doughnut
  • column
  • stacked column
  • bar
  • stacked bar
  • line
  • smooth line
  • stepped line
  • area
  • stacked area
  • stacked stepped area
  • radar

と言う種類のグラフが対応されているみたいです。順番に見ていきましょう。

ケミ

グラフのカラーは用意されている何パターンかを選んでいます。カラーバリエーションもかなり豊富です。

pie

ケミ

テレビなどでお馴染みのパイチャート。値と表示されている割合がよく誤魔化されていることでもお馴染み。こちらは、正しい割合でエリア表示されます(笑)

doughnut

column

stacked column

bar

stacked bar

line

ケミ

プレゼン資料でもよく見かける折れ線チャート。値を右肩上がりにしたいってよく言われるやつですね。

smooth line

stepped line

area

stacked area

stacked stepped area

ケミ

積み上げ段エリアチャートは、最後の値が解りにくいと言うデメリットもあって、日本の企業のプレゼン資料ではあまり取り入れることも少ないと言われてますね。

radar

ケミ

診断サイトとかでよく見かけるレーザーチャート。これもブロックで作れるのは嬉しいですね。要望したら対応をしてくれました。

ブロックの使い方は?

  1. [ 一般ブロック ] カテゴリーから [ Planet Charts ] ブロックを選択してブロックエディター上にブロックを追加します。
  2. [ Data ] と書かれた設定パネルから [ Chart type ] で各グラフの種類を選択します。
  3. [ Add Item ] ボタンを押して、各データの値を入力します。
  4. その他のパネルから、グラフのタイトルやデータの説明を表示するかなどを選択してグラフを彩ってください。
ケミ

プラグインはすべて英語表示ですが、グラフに表示する文字列は日本語も正しく使えます。

最後に

Planet Chartsは、ブロックを使ってグラフを表示したいと言った方には最適なプラグインです。

4.5
ケミ

有料のプラグインですが、購入して良かったと思います。

]]>
よくある問題のまとめ記事 – Snow Monkey カスタマイズ https://not-wiz.net/articles/snow-monkey/faq-customize/ Mon, 10 Feb 2020 09:23:23 +0000 https://not-wiz.net/?p=250 本記事は、Snow Monkey のカスタマイズでよくある問題を随時更新していきます。

Helper クラスが見つからない

Snow Monkey 公式サポートフォーラムなどの古いカスタマイズ情報を確認してみると、Helper::get_template_part と言った \Framework\ を略して記述されている場合があります。しかし、そのまま記述をして動作させると「Helper クラスが見つからない」と言うエラーで表示されるケースがあります。
この Helper クラスは、Snow Monkey v5以降であれば Framework と言うクラス内に実装されていますので、エラーとなる場合は Helper::\Framework\Helper:: に変更して確認してみてください。

ルミェール

または、PHPで use \Framework\Helper; を使用して Helper のまま記述するのも可能だよ。

]]>
文字列置換を行うための正規表現と DOM パーサー – Snow Monkey カスタマイズ https://not-wiz.net/articles/snow-monkey/dom-parser/ Mon, 10 Feb 2020 08:08:48 +0000 https://not-wiz.net/?p=244 本記事は、Snow Monkey カスタマイズを行う際のDOM パーサーのことを書いています。

最初に

Snow Monkey のテーマをカスタマイズする際に、HTML 記述を置換する場合は、正規表現で文字列置換をすることが多いです。しかし、正規表現で正しく置換することが苦労する場合もあるでしょう。

Snow Monkey のテーマをカスタマイズする際の 置換するHTML 記述の中に </div> タグがいくつも記述されていたり、変更したい箇所のDOMを正規表現で正しく置換することが難しい場合はどのようにすれば良いでしょうか?

文字列置換には、DOM パーサーを使う選択もある

その為、PHPライブラリを使用し、置換前の $htmlDOM Parser などを用いて判定する手法を行う方が、楽に実装できる場合があります。

しかし、テーマカスタマイズに対して、そのような DOM パーサーなどのHTML文法を解析する重い処理をする PHPライブラリを使うのは、ページ全体の表示速度の低下につながることでしょう。可能な限り、そう言った思い処理を行う PHPライブラリは使用せずに、標準の PHP で用意されている関数をそのまま用いて実装する方が良いでしょう。

Snow Monkey のカスタマイズでも、DOMパースをしてみる

PHPライブラリを使用せず、Snow Monkey のカスタマイズで DOMパースを行う場合、PHPの標準関数である DOM 関数を使用して DOMパースを行うのが、ページの表示速度をあまり落とさないので良いと考えています。
その DOM 関数を使用した HTML 文字列置換の基礎を解説します。

ここでは、DOM 関数の説明は簡易的なものに留めます。DOM 関数の詳細については下記のページをご参照ください。

Document Object Model – php.net

試しに \Framework\Helper::get_template_part 関数を使用してテンプレートパーツを取得し、特定のdiv要素の削除を行なってみましょう。

add_filter( 'snow_monkey_template_part_render', 'sm_template_part_render', 10, 4 );

function sm_template_part_render( $html, $slug, $name, $vars ) {
	if ( 'template-parts/common/profile-box' === $slug ) {
		$domDocument = new DOMDocument();
		@$domDocument->loadHTML( $html );
		$xPath = new DOMXPath( $domDocument );
		foreach ( $xPath->query( '//a[@class="wp-profile-box__archives-btn"]' ) as $node ) {
			$node->nodeValue = null;
		}
		$html = $domDocument->saveHTML();
	}
	return $html;
}

上記のように記述後、確認してみてください。「この記事を書いた人」の「記事一覧」のリンクが、表示されなく(削除)なるでしょう。
PHP の DOMDocument 関数や DOMXPath 関数を使用し、class="wp-profile-box__archives-btn" がある a タグ の DOMNode を削除したからです。

テネーブル

このように </a> などの閉じタグが複数入る可能性のあるテンプレートパーツでは DOM 関数を使用してその DOMNode だけを削除する方法を使うことで、安全にリンクを取り除くことも可能です。

ルミェール

正規表現で </a> までを置換しようとすると別の</a>までを対象にして変なリンクになっちゃうこともある。そんな時に DOM パースを使うと簡単にできるね!

最後に

ケミ

PHP 標準の DOM 関数は、情報も少なく慣れていない場合には難しいでしょう。「慣れていないけど、どうしてもDOM操作をしたい」と言う方は、若干のページ表示速度の低下を考えた上で PHPライブラリも試しに使ってみるのが良いでしょう。PHP Simple HTML DOM Parser と言った PHPライブラリは、HTML構文解析が非常に遅いのでオススメできませんが、Goutte と言った PHPライブラリであれば、PHP標準の DOM 関数を内部で使用しています。

そちらは、やり方次第で速度の低下を許容範囲内にできる場合もあります。

お試しください。

]]>
Not Wiz Grimoire を全面リニューアルしました https://not-wiz.net/articles/news/not-wiz-grimoire-renewal/ Mon, 10 Feb 2020 05:57:11 +0000 https://not-wiz.net/?p=245 Not Wiz Grimoire を本格的に全面リニューアルしたお知らせです。

過去の記事すべてに大幅な加筆修正・誤字脱字修正をしました

過去の記事やページをすべて加筆修正し、現時点の Snow Monkey v9 に合わせたサンプルコードにも書き換えました。

ケミ

その記事数は合計で約30。テキスト量は、リニューアル前の 2.4 倍です。

また、ポッドキャストやスライドで行った記事は加筆をして標準の記事にしています。

各ページ・記事のURLを変更しました

今後のウェブサイト運営方針の変更のため、リニューアルに合わせて、各ページ・記事のURLも変更しています。

キャラクターを追加・性格などの調整もしました

今までキャラクターをきちんと分けていなかった部分を大幅に修正し、新しくキャラクターを追加しています。
今後、もっとわかりやすく台詞量も増やしていく予定です。

今後ともよろしくお願いします

他に大きく変更もしているのですが、今後ともよろしくお願いいたします。

]]>
WordPress のカスタムテーブルでデータの取得や更新をする https://not-wiz.net/articles/wordpress/custom-table-002/ Thu, 06 Feb 2020 15:00:46 +0000 https://not-wiz.net/?p=178 WordPress のカスタムテーブルに関する基礎」の記事で、テーブルを新規生成・削除する基礎について解説しました。本記事では、新規生成したテーブルのデータを操作する方法について解説します。

今回の記事を読まれる前に

ケミ

本記事内で使用されているカスタムテーブルの新規生成や、データベース操作についての wpdb クラスなどについて「WordPress のカスタムテーブルに関する基礎」の記事で解説を行っています。本記事を読まれる前に、そちらの記事を先にお読みいただければ、理解が深まるかもしれません。

サンプルコードについて

解説したソースコード全体を動作するかたちで記述しているファイルは、記事の最後からダウンロードできるようにしています。動作確認される場合は、そちらをダウンロードしてご確認ください。

カスタムテーブル内にデータを追加・更新してみよう

ブリエ

カスタムテーブルを新規生成した時は、wpdbクラスを使用したし、削除にはその query 関数を使ったんだっけ。データを作成や更新する場合もwpdbクラスの query 関数を使うのかな?

テネーブル

そうですね。wpdb クラスの query 関数で SQL構文をクエリ操作する形で、INSERT(データ追加)やUPDATE(データ更新)を行う形でもテーブル内にデータを追加・更新が可能です。しかし、今回はそれらは使わずに replace 関数と言う関数を使用する方法で解説します。

ブリエ

replace って置き換えると言う意味ですよね?データを置き換えるんですか?

テネーブル

はい。replace 関数は、指定されたデータがある場合にデータの置き換え(更新)を行います。しかし、もともとデータが無い場合は、無いデータを置き換えると言う行為をしますので、データの作成となります。

そのことは、WordPress Codex の下記のウェブページにも記載されています。

行のReplace – WordPress Codex
ルミェール

実際のコードを見ていこう。

// wpdb クラスをグローバル宣言
global $wpdb;
// テーブル名の設定
$table_name = $wpdb->prefix . 'customtable_sample';
// オプションの名前
$option_name = 'test';
// オプションの値
$option_value = maybe_serialize( 'データの値です' );
// replace 関数の実行
$result = $wpdb->replace(
	$table_name,
	[
		'option_name'  => $option_name,
		'option_value' => $option_value,
	],
	[
		'%s',
		'%s',
	]
);
テネーブル

replace 関数の第1引数として、データを操作する対象のテーブル名を指定します。

次の第2引数では、データを追加・更新するカラム名と値を設定します。

maybe_serialize 関数は、データのシリアル化が必要な場合にデータをシリアル化する関数です。PHPの配列などの値はそのままデータベースで保存できませんので、シリアル化をする形で、データベースで保存できる値に変更しているのです。

最後の第3引数は、値のフォーマット書式の指定となります。書式の値は以下の通りになります。

フォーマットで使える書式の値は:
%s – 文字列

%d – 整数(全部が数字)

%f – 浮動小数点数

参考ウェブサイト:WordPress Codexより引用
テネーブル

今回の値はシリアル化も行っておりますので、シリアル化した後の文字列型がフォーマット書式となります。その為、%s を指定しています。

ルミェール

ほとんど行わないけど、第1引数のテーブル名の指定は、カスタムテーブルだけではなく、WordPress 標準のテーブルを対象にもできるよ。ほとんど行わない理由は、WordPress 標準のテーブルの場合には、そのテーブル内のデータを安全に操作するための専用の関数が用意されているから。データを直接自由に操作するのは危険だものね!

insert や update は不要?

ブリエ

何故、insert 関数や update 関数を使わないんですか?

テネーブル

今回のような正しく一意性を持つデータのみを格納しているテーブルであれば、他に重複するデータが存在しません。そのことから replace 関数であっても他のデータが置換されない為です。

今回のテーブルでは option_name は一意となるカラム名ですので、option_name には同じ値が保存(データが重複)される事は、ありませんよね。そう言った場合は replace 関数を使う事も可能なのです。

しかし、設定するデータが重複する構造のデータであれば、replace 関数では指定した値に該当するすべてのデータが置換されてしまいます。その為、そう言ったケースでは insert 関数や update 関数を正しく使う必要があります。もし、複雑なテーブル構造を使用する場合は replace 関数を使用せずにトランザクション制御を行った上で insert 関数や update 関数を使用した方が良いでしょう。

ルミェール

今回は、トランザクション制御や、insert 関数、update 関数の説明は割愛するよ。

動作の確認をしてみよう

ブリエ

この処理の実行だけを行っても、データベースにデータが生成されてるのが確認できました。また、値を変更して実行してみると実際に変更された値が保存されるようになっていますね!

テーブル内のデータを取得してみよう

テネーブル

テーブル内のデータを取得する関数として、wpdb クラスには get_row 関数や get_results 関数が用意されています。一意性のデータであれば、データは1つしか存在しません。今回の場合であれば該当していますので、1つのデータを取得するget_row関数で取得が可能です。

global $wpdb;
// テーブル名の設定
$_table_name = $wpdb->prefix . 'customtable_sample';
// $option_nameの値を設定
$option_name = 'test';
// SQLクエリ文字列の設定
$query = $wpdb->prepare(
	"
		SELECT *
		FROM  %s
		WHERE option_name = %s
	",
	$_table_name,
	$_option_name
);
// get_row 関数の実行を行い、$option_row に結果を設定
$option_row = $wpdb->get_row( $query, ARRAY_A );
テネーブル

データを取得する為には SELECT と言った SQL 構文を使用して SQL クエリ文字列の記述を行います。しかし、そのまま記述を行うと脆弱性対策ができません。その為、wpdb クラスの prepare 関数によって SQL インジェクションといった脆弱性対策を行いましょう。prepare 関数の書き方については詳細を割愛しますが、dbDelta 関数のような制約があると思ってください。「SELECT 文を1カラム1行で記述し、変数をフォーマット書式の値で設定するという形」と覚えておけば良いです。

ルミェール

データが取得できない場合は null が返却され、取得できた場合は第2引数に ARRAY_A を設定している場合は連想配列でデータが返却されるよ。$option_row['option_value'] のように各カラムの値が扱えるんだ。

テーブル内のデータを削除してみよう

テネーブル

テーブル内データを削除するにはwpdbクラスの query 関数を使って DELETE と言った SQL 構文でクエリ操作するのも良いですが、安全にデータを削除する為に削除専用に用意された delete 関数があります。

global $wpdb;
// テーブル名の設定
$table_name = $wpdb->prefix . 'customtable_sample';
// $option_name の値を設定
$option_name = 'test';
// delete関数の実行
$result = $wpdb->delete(
	$table_name,
	[
		'option_name' => $option_name
	],
	[
		'%s'
	]
);
テネーブル

この delete 関数は、指定した条件に一致するデータをすべて削除されますのでご注意ください。引数については replace 関数の指定方法とほぼ変わりませんので、そちらをご覧ください。

ルミェール

重要なデータが消えてしまう可能性もあるので、解らない場合には WordPress が標準で用意しているテーブル名などは指定しないようにしてね!

ブリエ

正しく動作ができるとデータが削除され $result に削除された行の数値を返却されますね。エラーが発生した場合は false の値を返却されます。

サンプルコードのダウンロード

ケミ

解説したサンプルコードを実際にプラグインで動作するようにしているファイルです。勉強される時以外にはプラグインを有効化していたとしても意味ありませんので、勉強後はアンインストールと削除を忘れないようにしてください。

まとめ

ケミ

本記事も長くなりました。割愛していたinsert関数、update関数や、トランザクション制御についての解説は、別の記事で解説することにします。また、get_results関数を使用して複数のデータを処理する方法なども別の記事で解説するようにします。(現在、執筆中ですので気長にお待ちください)

]]>
カスタム投稿のページテンプレートについて – Snow Monkey カスタマイズ https://not-wiz.net/articles/snow-monkey/custom-page-template/ Thu, 06 Feb 2020 15:00:38 +0000 https://not-wiz.net/?p=191 本記事は、カスタム投稿タイプのページテンプレートについて解説をします。

本記事の対応バージョンについて

本記事の対応バージョン

本記事は Snow Monkey v9.0 に対応しています。
( Snow Monkey v9 で動作を確認しています)

本記事のテーマ

Snow Monkey v6 以降では、プラグインでカスタムページテンプレートを追加できるようになっています。それと同様に、カスタム投稿タイプのテンプレートも簡単にプラグインで追加設定する事が可能になりました。

カスタム投稿タイプのテンプレート設定をプラグインで

snow_monkey_template_part_root_hierarchy フィルターフックを使用することで、プラグインだけでカスタム投稿タイプでもテンプレートを正しく追加して設定する方法を解説します。

カスタム投稿タイプとは?

カスタム投稿タイプは自分で作れる新しい投稿タイプです。

WordPress Codex 日本語版 – 投稿タイプ

と、WordPress Codex には記載されています。

ルミェール

WordPress が標準で用意している投稿タイプと別に、プラグインなどで独自に追加した投稿タイプが、カスタム投稿タイプって事だね!

WordPress が標準デフォルトで用意している投稿タイプには、主に5つあります。

WordPress にはデフォルトで5つの主要な投稿タイプがあります。ユーザーが使えるものと内部で使われるものです:
– 投稿 (投稿タイプ: ‘post‘)
– 固定ページ (投稿タイプ: ‘page‘)
– 添付ファイル (投稿タイプ: ‘attachment‘)
– リビジョン (投稿タイプ: ‘revision‘)
– ナビゲーションメニュー (投稿タイプ: ‘nav_menu_item‘)

WordPress Codex 日本語版 – デフォルトの投稿タイプ

と、WordPress Codex には記載されています。

カスタム投稿タイプを使う理由とは?

自分で新しい投稿タイプを作りたい時とは、どう言う時でしょうか?

いくつかのケースを紹介します。

通常の記事と別にしたい場合に使う

例えば、専門用語を紹介する用語集を作りたいとしましょう。
WordPress 標準の投稿を使って行う場合であれば、通常の記事と用語集が混ざってしまう問題が起こるでしょう。

また、用語集では、記事の「カテゴリー」や「タグ」ではなく、その代わりに「品詞」「名詞」「動詞」「副詞」「形容詞」と言った分類で分ける辞書のような構成にしたいかもしれません。標準の記事の構成では難しい仕様もあるでしょう。

ルミェール

標準で用意されている「カテゴリー」「タグ」などの要素を「タクソノミー」って言うんだ。「カスタム投稿タイプ」は「カテゴリー」「タグ」などの要素は標準で用意されず、「タクソノミー」を自分で設定しないと何も設定されないよ。

テネーブル

上記の用語集の例であれば、「分類」と言うタクソノミーで、「品詞」「名詞」「動詞」「副詞」「形容詞」と言った値を登録すると言った感じですね。

カスタム投稿タイプの追加方法について

カスタム投稿タイプの追加方法には、register_post_type 関数を用いて自身で記述を行うか、Custom Post Type UI と言ったカスタム投稿タイプを設定できるプラグインなどが存在します。

register_post_type 関数を使用して自身でプラグインを記述する場合や、Custom Post Type UI と言ったプラグインを使用して設定を行うなどは、WordPress のリファレンスやプラグインの配布ページに詳しい説明があります。そちらを参考にして各自で設定をしてください。本記事では詳細解説を割愛します。

register_post_type関数 – WordPress Codex 日本語版
Custom Post Type UIプラグイン – WordPress.org公式プラグインディレクトリ

カスタム投稿タイプのテンプレートもプラグインで追加設定しよう

カスタム投稿タイプを設定出来たでしょうか?
しかし、それらの設定をしても、まだカスタム投稿タイプには足りない設定があると思われます。その1つは [投稿の属性] パネルに存在する [テンプレート] でしょう。

投稿の属性に表示されるテンプレート要素

このままの状態では、カスタム投稿タイプの投稿にはテンプレートの設定が存在しない為、レイアウトがデフォルトテンプレートの状態でしか表示できません。

カスタマイザーで、カスタム投稿タイプであっても「投稿」と「固定ページ」のビューテンプレートを選択できるようになっていますが、それ以外のテンプレートを選択したい場合もあるはずです。

Snow Monkey v6以降であれば、カスタムページテンプレートをプラグインで設定できるように対応されており、それと同様の手順を My Snow Monkey プラグインで設定を行えば、カスタムページテンプレートを選択できるようになりました。これを使用してカスタム投稿でもページテンプレートを設定してみましょう。

ルミェール

プラグインでカスタムページテンプレートを設定できるようになったのは Snow Monkey v6 以降の大きな変更の1つだね!

Snow Monkey の標準のページテンプレートをカスタム投稿タイプでも使用する方法

まずは、 My Snow Monkey プラグインに、プラグインのテンプレートパーツのルートディレクトリを作成し、snow_monkey_template_part_root_hierarchy フックで設定を行いましょう。
(※ すでに設定をされている場合は必要ありません)

Snow Monkey 公式ウェブサイトの「カスタムページテンプレートの追加方法」の記事では、ファイルの記述をコピーして使用されているのですが、カスタム投稿タイプでも標準のページテンプレートとして使用する場合、テーマにある同一のページテンプレートファイルを読むように調整してあげる方が良いかもしれません。そのようにしてみましょう。

ルミェール

処理を上書きすると、テーマがアップデートされた時や、投稿されている記事のテンプレートにも影響が出ちゃう。カスタム投稿タイプにも Snow Monkey の投稿テンプレートはテーマのアップデートに気にせずに使いたいよね。

現在の Snow Monkey で用意されている標準のページテンプレートは、次のように7つあります。

Template Name編集画面で表示されるテンプレート名ファイル名 / 選択された際の値
Landing pageランディングページpage-templates/blank.php
Left sidebar左サイドバーpage-templates/left-sidebar.php
Full widthフル幅page-templates/one-column-full.php
One column ( slim width )1カラム ( スリム幅 )page-templates/one-column-slim.php
One column1カラムpage-templates/one-column.php
Right sidebar右サイドバーpage-templates/right-sidebar.php
Landing page ( slim width )ランディングページ(スリム幅)page-templates/blank-slim.php
(Snow Monkey v7以降に追加されています)

テーマ標準と同様のレイアウトを使用するのに必要なことは

  • 7つのページテンプレートを同じファイル名で配置にすること
  • Template Name
  • Template Post Type
  • 後述の記述

です。

ワンポイントアドバイス

テーマ標準で用意された7つのページテンプレートのファイル名と同一のファイル名でページテンプレートを生成した場合は、そのファイルの処理が上書きされて適用されます。
その為、既存の投稿のテンプレートに対しても影響が出てしまいますので、テーマと同じテンプレートのファイル名を使用しないようにするか、テーマと同様のレイアウトを使用したいのであれば、後述のようにテーマファイルを読込むようにする処理を設定しておくと良いでしょう。

<?php
/**
 * Template Name: 自由に付けられます
 * Template Post Type: 追加したいカスタム投稿タイプの name
 *
 */
$base_name = pathinfo( __FILE__, PATHINFO_BASENAME );
include( get_stylesheet_directory() . '/page-templates/' . $base_name );

Template Name は、テーマテンプレートと同一の名前にする必要はありません。
Template Post Type は、追加したいカスタム投稿タイプのみでも適用されるようです。

例えば、ランディングページ用のページテンプレート( page-templates/blank.php )を glossary (用語集)と言うカスタム投稿タイプでも使用したい場合は、プラグインのテンプレートルートディレクトリ上で page-templates/blank.php を生成し

<?php
/**
 * Template Name: ランディングページ
 * Template Post Type: glossary
 *
 */
$base_name = pathinfo( __FILE__, PATHINFO_BASENAME );
include( get_stylesheet_directory() . '/page-templates/' . $base_name );

と記述します。

テネーブル

上記のように記述することで、テーマの page-templates ディレクトリにある同一ファイルを include(読込み) しますので、テーマのページテンプレートに記載された処理が実行されます。

テーマがアップデートされた場合でもアップデートされたテーマのページテンプレートを読込んで処理を反映しますので、上書きなどの問題を受けません。

同様に、left-sidebar.php である場合は Template Name: 左サイドバー と変更し、 page-templates/left-sidebar.php と言う名前でファイルを新規生成します。

標準で用意されている7つのタイプのテンプレートに関しては、次のように7つのファイルを用意し、上記のようにテーマディレクトリのページテンプレートを読込む記述の方法で使用すれば、テーマのアップデート時にもテーマのアップデートされたページテンプレートで対応されます。

my-snow-monkey(プラグインルートディレクトリ)

my-snow-monkey.php

template-root(プラグインのテンプレートルートディレクトリ)

page-templates

blank.php

blank-slim.php

left-sidebar.php

one-column-full.php

one-column-slim.php

one-column.php

right-sidebar.php

テーマ標準のページテンプレートは、プラグインで上書き非推奨

Snow Monkey で用意された7つのページテンプレートは、投稿や固定ページの表示にも使用されていますので、変更を行った場合は、それらの投稿や固定ページの表示全体にも影響を及ぼしてしまいます。

Snow Monkey では snow_monkey_template_part_root_hierarchy フックで設定されたテンプレートルートディレクトリに配置された page-templates ディレクトリを、ページテンプレートディレクトリとして上書きした形で読込みますが、Template Post Type は、すべてのルートディレクトリを参照するようなので、同じファイル名の場合は Template Post Type が適用されていなくても優先度が高いファイルの処理で上書き実行されるようです。WordPress の仕様のようですね。

テネーブル

Template Post Typepost(投稿)、page(固定ページ)の記述が無くても、同一ファイル名の場合、優先度が高いファイルの処理が適用されるようなのです。

その為、テーマと同じ7つのページテンプレートのファイル名でテンプレートを作成した場合は、上書きした処理結果で表示されてしまいますので、使用するにあたっても、上記で紹介したようにテーマのページテンプレートを include で読込みするような形でのみ使用が良いと思われます。

テネーブル

もしカスタムページテンプレートを独自で追加したい場合は、テーマで用意されている7つのページテンプレートのファイル名と重複しないオリジナルのファイル名とオリジナルのTemplate Nameを使用するのを推奨します。

最後に

本来の WordPress では、子テーマを使用しないと難しいカスタム投稿のページテンプレートなどと言った仕様を Snow Monkey ではプラグインでも行えるようにしていることからも、プラグインの方では上書きが推奨できないなどの部分もあります。

しかし、子テーマを作らずにプラグインで可能なので、カスタム投稿に合わせたデザインのページテンプレートを同一のプラグインで配布できるのは非常に魅力があると思います。興味のある方は、そういうことにも挑戦してみてください。

]]>
ヘッダーの位置設定に合わせたサイト内コンテンツのスタイルの変更方法 https://not-wiz.net/articles/snow-monkey/head-position-contents/ Thu, 06 Feb 2020 15:00:12 +0000 https://not-wiz.net/?p=203 Snow Monkey では、ヘッダー位置を変更した際に、設定によっては想像しているデザインと異なった形で表示されてしまう場合があります。本記事は、ヘッダー位置に合わせた要素のカスタマイズ方法をまとめました。

本記事の対応バージョンについて

本記事の対応バージョンについて

WordPressテーマ「Snow Monkey v9 以降」のみ対応しています。

Snow Monkey v9 で確認しています。

v9以前からの変更に伴う注意

ブリエ

なぜ、Snow Monkey v9 以降のみ対応なんでしょうか?それより前のバージョンでは出来なかったの?

テネーブル

そうじゃなくて、Snow Monkey v9 でヘッダーに大きな変更があったの。前のバージョンでは data 属性の data-l-header-type にスタイルを当てて行っていたの。でも、変更に伴ってカスタマイズ方法も変更されたんです。Snow Monkey公式では、次の通り書かれています。

ヘッダーの data 属性に対して CSS を適用している場合は、Snow Monkey v9 にアップデートすると CSS が適用されなくなるのでご注意ください。なるべく .l-header に対して CSS をあてるように変更してください。

Snow Monkey 公式より引用
テネーブル

なので、data-l-header-type でスタイルを当てて行うv9より前のカスタマイズをしていた場合は、.l-header に対してCSSをあてる変更が必要です。

ルミェール

Snow Monkey v9より前のバージョンでは、ヘッダーの設定は今のように多分類化されていなかったんだ。v9以降にヘッダーの調整が多くされて、スタイルも大きく変更されたよ。

ヘッダーの種類について

テネーブル

Snow Monkey v9 からのヘッダーの種類は、分類が多くなりました。[ヘッダー位置] は .l-header--ヘッダー位置-sm で書かれ、 [PC用ヘッダー位置] は .l-header--ヘッダー位置-lg と言うスタイルに分かれるようになっています。

例えば、ヘッダー位置を [オーバーレイ]、 PC用ヘッダー位置を [上部固定] にした場合のヘッダーの HTML は、次のように記述されます。

<header class="l-header l-header--overlay-sm l-header--sticky-lg" role="banner">
ブリエ

[ヘッダー位置] の設定は、スマートフォンやタブレット端末で見える時の設定ってことですか?

テネーブル

そうですね。Snow Monkey は主にスマートフォンを基本としたモバイルファーストのテーマと言われています。Snow Monkey v9 以降では、スマートフォンやタブレット端末の時と、PC の解像度でヘッダー位置の見え方も異なる設定ができるように対応されたんですね。その為に多くのスタイルが変更されています。

ルミェール

[ヘッダー位置] と [PC用ヘッダー位置] の設定は、カスタマイザーの [デザイン] > [ヘッダー] の中にあるよ。

カスタマイザーについては、別記事「カスタマイザーをカスタマイズするための基礎 – Snow Monkey カスタマイズ」にも解説があります。

ヘッダー位置の各スタイル記述について

上部固定

テネーブル

sticky と言う記述が付与されます。
ヘッダー位置なら .l-header--sticky-sm に、PC用ヘッダー位置なら .l-header--sticky-lg と言うスタイルクラスになります。

オーバレイ(上部固定)

テネーブル

sticky-overlay と言う記述が付与されます。
ヘッダー位置なら .l-header--sticky-overlay-sm に、PC用ヘッダー位置なら .l-header--sticky-overlay-lg と言うスタイルクラスになります。

オーバーレイ(上部固定 / スクロール時背景白)

テネーブル

sticky-overlay-colored と言う記述が付与されます。
ヘッダー位置なら .l-header--sticky-overlay-colored-sm に、PC用ヘッダー位置なら .l-header--sticky-overlay-colored-lg と言うスタイルクラスになります。

オーバレイ

テネーブル

overlay と言う記述が付与されます。
ヘッダー位置なら .l-header--overlay-sm に、PC用ヘッダー位置なら .l-header--overlay-lg と言うスタイルクラスになります。

ノーマル

ルミェール

ノーマルの場合はスタイルが付かないよ。何も設定されていない場合も、このノーマルが設定される。標準(デフォルト)ってことだね。

ヘッダー位置に合わせたコンテンツスタイルの変更方法

ブリエ

オーバーレイメニューの時にメニューとコンテンツが重なりすぎちゃった。コンテンツ開始位置をズラすと、オーバーレイ以外の時に余白が気になっちゃうかな…。

テネーブル

そう言う場合は、オーバーレイの時だけコンテンツの開始位置を少しずらしたいなどの場合には、ヘッダー位置に合わせてコンテンツスタイルを変更すれば解決するんじゃないでしょうか?

ブリエ

ヘッダー位置に合わせてコンテンツスタイルを変更?

テネーブル

そうです。オーバーレイの時のみにスタイルを掛けたい場合であれば、次のような感じでどうでしょうか?

.l-header--overlay-sm+.l-contents {
  /* ヘッダー位置がオーバーレイ時のコンテンツに掛かるスタイル */
}
ブリエ

おぉー。できました。このスタイルってどう言うことなんですか?

テネーブル

スタイルシートの + を使って、 .l-header--overlay-sm に隣接している .l-contents に対してスタイルを適用させてるんです。それによってヘッダー位置がオーバーレイ時のコンテンツのみに適用できるスタイルとなります。

セレクタを + で区切ると、同じ階層にある要素同士で、 ある要素の直後に隣接している要素を対象にスタイルを適用することができます。

スタイルシートリファレンス – 隣接セレクタ
ルミェール

同様に .l-header--sticky-sm.l-header--sticky-overlay-colored-lg などヘッダー位置に合わせたクラス名でスタイルを記述すると、そのヘッダー位置の時のコンテンツのみにスタイルを当てられるよ。ヘッダースタイルに応じてコンテンツの雰囲気を変えてみよう!

補足(フックを使う別の方法)

ケミ

ヘッダーの位置 や PC用ヘッダーの位置 は、テーマ設定値( theme_mod )の1つとなっています。なので、フィルターフックの get_theme_mod で取得も可能なんです。ヘッダー位置は header-position 、PC用ヘッダー位置は header-position-lg と言う設定名です。取得した値に応じて、読み込むスクリプトを変更することでも、ヘッダー位置の設定に応じてコンテンツのスタイルなどを変更可能です。余計な記述を常に読み込まない分、そっちの方がページ表示が軽くなる場合もありますね。使い分けてみてください。

]]>
Snow Monkey をカスタマイズするためにも、フックについて覚えよう https://not-wiz.net/articles/wordpress/what-is-hook/ Thu, 06 Feb 2020 06:52:42 +0000 https://not-wiz.net/?p=150 本記事では、WordPress の基礎仕様の1つ「フック」について、簡単な基礎を解説します。

最初に

WordPressのカスタマイズ、または Snow Monkey をカスタマイズを何も解らずにやってみると、何から理解すれば良いのか解らない為に、難しいと感じて挫折する場合もあるかもしれません。しかし、それは WordPress に存在する、「フック」と言う基礎の仕組みについて理解をしていないからかもしれません。

フックってなんだろう?

小学館のデジタル大辞泉では、「フック」の意味を次のように公開されています。

フック【hook】

1. 鉤 (かぎ) 。鉤形の留め金。衣服の合わせ目を留める金具。
2. 物を引っ掛けるための器具。鉤。

出典:デジタル大辞泉(小学館)

本記事で取り扱う WordPress の「フック」という用語は、2番目の意味に由来しています。

WordPress は、基礎となる多くの特定の処理が実行される時に対応しているフックに仕掛けられた処理(コールバック関数)を呼び出すと言った柔軟な設計をされているウェブシステムでもあります。WordPress の場合は、 「物を引っ掛ける = 特定の処理に処理を引っ掛ける」と言う意味合いでフックと言う用語を使われています。

ケミ

WordPress のフックとは、WordPress 本来の特定の処理とは別に、特定の処理をした時に、引っ掛けた処理を呼び出す仕組みと言う感じです。

Snow Monkey テーマでも、様々なフックが用意されています。例えば、テンプレートの読み込み処理には snow_monkey_get_template_part_<slug>snow_monkey_template_part_render と言ったフックが定義されています。

少し、次に図を用意してみました。

ケミ

WordPress本来の処理で各テンプレートを読み込まれた時に、Snow Monkey テーマでは snow_monkey_get_template_part_<slug> と定義されているフックの処理をします。また、各テンプレートの表示結果を出力する時には snow_monkey_template_part_render と定義されているフックの処理をします。

テネーブル

上の図のようにフックを使うことで、WordPress 本来の処理の結果を、フックで指定した別の処理の結果に変更することができるのです。

フックを使うと可能なこと一例

例えば…

  • 検索フォームを表示する時に実行されるフックに追加して、検索ボックスの下に検索条件を表示する
  • 時間表示をする時のフックに追加して、時間のフォーマットを和暦に書き換える
  • お問い合わせフォームの入力チェック処理内に用意されているフックに追加して、入力間違いのエラー表示を変更する

こんな風に、様々な処理を行う時に用意されているフックに追加することで、特定の箇所の表示や条件を思いのままに変更することが可能なのです。

ケミ

フックで追加するのは、関数。つまり、処理の集合体です。ここではフックで追加している関数を、コールバック関数と呼ぶことにします。

テネーブル

例えば、WordPress の標準では検索フォームを表示する場合に、get_search_form と定義されているフック名があります。その get_search_form に対して「検索条件の選択フォームを表示する」と言うコールバック関数を指定して追加することで、検索フォームを表示する処理が実行された時に「検索条件の選択フォームを表示する」と言ったコールバック関数も同時に実行されます。その仕組みによって「Not Wiz Search Criteria」では、検索フォームに検索条件のフォームを追加しています。

ルミェール

コールバック関数と言うのは、プログラマの方やゲームを改造した事のある方であれば、サブルーチン、または処理トリガー、パラサイトルーチンのアタッチコールと言う仕組みをイメージすれば解りやすいかも?少し仕組みは違うけど、ニュアンスは一緒な感じ。

フックの種類は2つ!

WordPressワードプレス のフックには、アクションフックフィルターフックと呼ばれる2種類が存在します。

アクションフック

WordPress が動作を行う特定の処理に対して、アクションフックが定義されている場合は、定義に対して登録を行っているコールバック関数も同時に処理されます。アクションフックの場合は return で値を返却しません。大抵のケースでは、追加でフック内の処理結果を表示させたりすると言った使い方をされます。

フィルターフック

WordPress が動作を行う特定の処理に対して、フィルターフックが定義されている場合は、定義に対して登録を行っているコールバック関数も同時に処理されます。フィルターフックの場合は、return で値を返却できます。場合によって、コールバック関数の return で返却された値が本来の処理の値の代わりとして使用されます。

フックの追加方法

テネーブル

フック処理を追加すると言うのは、特定の処理が実行された時に実行されるコールバック関数を仕掛けると言うことです。

アクションフックの場合の追加方法

テネーブル

add_action 関数を使用します。

詳しい説明は後述しますが、まずはコードをご確認ください。

add_action(
  <追加を行うフック定義名>,
  <フックを処理するコールバック関数名>,
  <追加する優先度(デフォルトは10 / 省略可能)>,
  <特定処理から渡される引数の数(デフォルトは1 / 省略可能)>
);

function <フックを処理するコールバック関数名> ( <特定処理から渡される引数> ) {
  <コールバック関数の処理>
}

フィルターフックの場合の追加方法

ルミェール

add_filter 関数を使用するよ。

詳しい説明は後述するので、まずはコードを確認してね。

add_filter(
  <追加を行うフック定義名>,
  <フックを処理するコールバック関数名>,
  <追加する優先度(デフォルトは10 / デフォルトの場合は省略可能)>,
  <特定処理から渡される引数の数(デフォルトは1 / デフォルトの場合は省略可能)>
);

function <フックを処理するコールバック関数名> ( <特定処理から渡される引数> ) {
  <コールバック関数の処理>
  return <返却値>;
}

それぞれの追加に関する説明

追加を行うフック定義名には、特定の処理が実行された時に実行されるフックの定義名を記述します。上記にも記載していましたが、WordPress の標準では検索フォームを表示する場合に、get_search_form と定義されているフック名があります。get_search_form を定義名で記述した場合は、検索フォームを表示する場合に実行されるフックを追加となります。

フックを処理するコールバック関数名は、実際の処理を行うコールバック関数の関数名を記述します。もし、クラス内の関数を使用したい場合には array( クラスのインスタンス変数, 'コールバック関数の関数名' ) と言ったように配列で記述することで使用可能です。

フックを追加する優先度は、それぞれのフック定義の特定の処理が実行された時に対して、数値を大きい方が先に実行される処理として登録されます。デフォルトや省略時には 10 で登録されます。
アクションフックでは、別に登録されるフックより先に実行したい場合は優先度の数値を大きくし、別に登録されるフックより後に実行したい場合は優先度の数値を小さくして使用します。
フィルターフックでは、最初に実行されたフック処理の値のみが使用される場合もある為、優先度の数値を大きくすればするほど、実行される順序が先となる可能性が高くなる事から優先度を 9999(またはPHP_INT_MAX)などの最大数値を使用することで、強制的にそのフックの返却値で実行させると言ったことも可能です。
アクションフックやフィルターフックに関わらず、中には一番優先度が高いフック処理のみしか動作しない場合もあります。その際には、実行される順序を別に登録されるフックより優先的に動作させる為にも、優先度を比較的に高い数値で設定して追加されていることが多いです。

特定処理から渡される引数の数は、各フックの定義で決まっている特定処理から渡される引数の数を数値で記述します。例えば、admin_bar_menu と言うフック定義では管理バーの項目の参照配列が渡されるようになっています。その場合は引数は1つなので 1 と記述します。またはデフォルトや省略時には 1 で登録されますので、その場合であれば省略しても問題ありません。

コールバック関数の関数は、関数名を追加する際に記述する関数名で記述し、引数も特定処理から渡される引数としてください。また、フィルターフックの場合には値を返却する必要があります。その場合も仕様が決まっています。WordPress の標準のフックであれば、詳しい仕様は WordPress のフック一覧などに載っています。

アクションフック一覧 – WordPress Codex 日本語版
フィルターフック一覧 – WordPress Codex 日本語版

フックの削除方法

追加されているフック処理は、削除することも可能です。
特定の時には追加したフック処理を処理したくないと言う場合は、追加されているフック処理を削除することで対応可能です。

アクションフック処理を削除するのは remove_action 関数が用意されています。まず、記述のみご確認ください。

remove_action(
  <削除を行うフック定義名>,
  <追加されたコールバック関数名>,
  <追加された優先度(デフォルトは10 / デフォルトの場合は省略可能)>,
  <特定処理から渡される引数の数(デフォルトは1 / デフォルトの場合は省略可能)>
);

フィルターフック処理を削除するのは remove_filter 関数が用意されています。まず、記述のみご確認ください。

remove_filter(
  <削除を行うフック定義名>,
  <追加されたコールバック関数名>,
  <追加された優先度(デフォルトは10 / デフォルトの場合は省略可能)>,
  <特定処理から渡される引数の数(デフォルトは1 / デフォルトの場合は省略可能)>
);

どちらの関数も、使い方はほぼ同一で、フックの追加時の引数にもよく似ています。この記述のみで追加したフックを削除できます。

しかし、ここでフック追加時と異なり、気をつけなければならないことがあります。それは、削除を行う為には追加されたコールバック関数名が必要と言うことです。その為、フックの削除は無名関数で追加されている処理に対してできません。

ケミ

この仕様から、フックを追加する場合には、削除されると動作に影響する大切な処理などの場合、無名関数を使用して削除できなくするのも1つの有効手段ですね。

フックの種類が不明な場合の対応方法

ここまでフックの種類は2種類と解説し、追加や削除について解説も行いました。しかし、記述したいフックの定義が アクションフックフィルターフック なのかどのように理解すれば良いのかも不明です。

その場合は、まずは気にせずに フィルターフック としてコードを記述しましょう。フィルターフックアクションフック として動作することはできませんが、アクションフックフィルターフック として追加した場合は、値を処理しない フィルターフック と言うように処理を行われる為です。

ブリエ

え?どう言う事ですか?アクションフック なのに フィルターフック で動作するのでしょうか?

テネーブル

そうです。このことは WordPress のコアに記述されている add_actionfunction の動作を見てみると良く解ります。wp-includes/plugin.php に書かれています)

ブリエ

add_filterreturn されていますね。

テネーブル

そうです。このことから アクションフック と言うのは、値を返却しない フィルターフック と言っても良いですよね。

ルミェール

だから、わからない場合や慣れていない場合は、フィルターフック で追加するのも間違いじゃなくて、1つの正解と思おう。間違いを気にせず、気軽にコードを記述することは上達の早道だよ!

テネーブル

WordPress 本体の更新などで、アクションフック だった処理が フィルターフック の処理に変更されていたことも過去にいくつかありました。その為に、古くからのプラグインには故意に アクションフックフィルターフック の追加方法で書かれているも存在します。実は、フックの種類と言うのは大きく気にすることではありません

また、アクションフック は、追加と同様に、WordPress の内部では return remove_filterとして処理されています。その為、フィルターフック と同じように remove_filter と書いても削除することが可能です。

まずは、追加だけで慣れていこう

ブリエ

なかなか一度に覚えられませんね。

テネーブル

最初のうちは慣れるまで少し難しいですよね。

しかし、フックの削除は、削除する場合にのみ使うものですので、削除しない場合は使わなくても大丈夫です。まずはフックの追加だけでも覚えてみるのも良いと思います。やっていくうちに、少しずつ慣れていくことで何となく理解が進みます。

慣れたらリファレンスも読んでみよう

フックの細かい仕様については、WordPress のリファレンスサイトなどでも解説されています。そちらも参考にしてみてください。

add_action の関数リファレンス(日本語版)
add_filter の関数リファレンス(日本語版)
remove_action の関数リファレンス(日本語版)
remove_filter の関数リファレンス(日本語版)
]]>
テンプレートのルートディレクトリの基礎 – Snow Monkey カスタマイズ https://not-wiz.net/articles/snow-monkey/template-part-root/ Wed, 05 Feb 2020 15:00:55 +0000 https://not-wiz.net/?p=194 本記事は、「テンプレートのルートディレクトリ」について解説しています。

最初に

Snow Monkey の snow_monkey_template_part_render フックでは、テーマに存在しているテンプレートパーツの表示を置換することが可能です。しかし、テーマに存在していないテンプレートパーツを追加するのは、プラグインで行う場合はどのようにすれば良いのでしょうか?
それは、「テンプレートのルートディレクトリ」を使うことで解決します。

テンプレートのルートディレクトリとは

デバッグモードで、ページを表示してみましょう。

補足説明

デバッグモードで読み込むテンプレートパーツをコメントアウトで表示する方法については、「Snow Monkey カスタマイズをはじめよう – 準備編」の記事で解説しています。

<!-- Start : template-parts/nav/drawer -->

と言った記述などが、デベロッパーツール や Webインスペクタ内で記述されているのを確認可能です。

テネーブル

確認できたところで、「ルートディレクトリ」の言葉について調べてみましょう。

ルートディレクトリroot directory

ファイル構造システムにおいて、階層における最上位ディレクトリ

デジタル言葉辞典より引用

と、デジタル言葉辞典には記載されています。

先ほど確認した template-parts/nav/drawer と言うテンプレートパーツのファイルは Snow Monkey のテーマディレクトリ/template-parts/nav/drawer.php ファイルでした。では、この場合のルートディレクトリは、どうなるでしょうか?

テネーブル

この場合のケースであれば、template-parts/nav/drawer と書かれている元のディレクトリが、ルートディレクトリに該当します。なので、この場合「テンプレートのルートディレクトリ」とは、その最上位のディレクトリである Snow Monkeyのテーマディレクトリ となります。

プラグインにテンプレートパーツファイルを追加してみよう

何が問題になるのか、考えてみましょう

プラグインでテンプレートパーツを扱いたい場合、読み込みには\Framework\Helper::get_template_part( テンプレートパーツの<slug>-<name>, 渡したい情報配列 ); の形で \Framework\Helper::get_template_part 関数を使用していました。
しかし、この関数の第1引数に指定されているのは テンプレートパーツの<slug>-<name> です。
テンプレートのルートディレクトリなどの指定はありません。指定した テンプレートパーツの<slug>-<name>Snow Monkeyのテーマディレクトリ 内のテンプレートパーツを読んでいます。なので、このままではSnow Monkey のテーマディレクトリ内のテンプレートパーツしか読まれません。どうすれば、プラグイン内のテンプレートパーツを読み込めるのでしょうか?

プラグイン内のディレクトリもテンプレートのルートディレクトリに設定できれば、問題を解決できそうです。

テンプレートのルートディレクトリを設定しよう

問題解決のステップとして、まずは Snow Monkey でそのような機能があるかフックの定義を探すことから始めましょう。

Snow Monkey フック一覧 – snow_monkey_template_part_root

Snow Monkey のフック一覧を確認してみると Filter Hooksnow_monkey_template_part_root フックが該当しそうなことが解るでしょう。

テネーブル

しかし、snow_monkey_template_part_root フックの説明を読めば、このフックは Snow Monkey v5.3.1 で非推奨になっていることも解ります。代わりに snow_monkey_template_part_root_hierarchy と言うフックが用意されていることも記載されていることが解ります。そちらを使うようにしましょう。

snow_monkey_template_part_root_hierarchy フックを使う

試しに「My Snow Monkey プラグイン」にフック処理を書いてみましょう。my-snow-monkey.php に次の記述を追加しましょう。

add_filter(
	'snow_monkey_template_part_root_hierarchy',
	function( $hierarchy, $slug, $name, $vars ) {
		// 渡されてきた $hierarchy に、プラグインディレクトリ内の template_root を追加する
		$hierarchy[] = untrailingslashit( __DIR__ ) . '/template_root';
		return $hierarchy;
	},
	10,
	4
);

上記のコードを追加し、プラグインのディレクトリに template_root の名前でディレクトリを新規生成します。

plugins(プラグインディレクトリ)

my-snow-monkey

my-snow-monkey.php

template_root(新規生成)

template-parts(新規生成)

nav(テスト用に新規生成)

global.php(テスト用に新規生成)

この template_root ディレクトリが、プラグインのテンプレートルートのディレクトリになります。

この template_root ディレクトリに template-parts/nav/global.php ファイルを生成し、次のように記述します。

<?php
  echo 'test';

実際にページを開いて確認しましょう。

テネーブル

グローバルメニューの部分が test と言う文字列に変わっているのを確認できましたか?

追加したプラグイン内の template_rootテンプレートのルートディレクトリ として見るようになったので、グローバルメニューを表示する為にあるテンプレートパーツの template-parts/nav/global.php がそちらを読み込むようになっているからです。

確認が済みましたら template-parts/nav/global.php ファイルを削除して、元のグローバルメニューが表示されるようにしておきましょう。

snow_monkey_template_part_root_hierarchy フックの実行タイミング、引数と返却値について

snow_monkey_template_part_root_hierarchy フックは、テンプレートの読込み時に実行されるフックです。

  • 第1引数の $hierarchy は、テンプレートのルートディレクトリを値として持つ配列です。返却値にも使用されます。
  • 第2引数の $slug は、読み込まれたテンプレートの slug値 となります。
  • 第3引数の $name は、読み込まれたテンプレートの name値 となります。
  • 第4引数の $vars は、テンプレートの読込み時に渡される値になります。
ルミェール

\Framework\Helper::get_template_part( テンプレートパーツ<slug>-<name>, 渡したい情報配列 ); の処理などが実行された時に、このフックも実行されるみたい。引数の感じも凄く似てるよね。

テネーブル

ほとんどの場合は、第2引数などは使われないでしょう。しかし、第2引数の値などを条件にすることで、条件に該当された時だけテンプレートを読み込むルートディレクトリを切り替えるなどの条件判定を可能になっています。

snow_monkey_template_part_root_hierarchy フック、配列を返却するのは何故?

snow_monkey_template_part_root_hierarchy フックが、ルートディレクトリの配列を返却するのは何故でしょうか?ルートディレクトリは、1つでは駄目なのは何故なのかを解説します。

非推奨となった snow_monkey_template_part_root フックは、配列を返却しないフックであり、返却値は1つです。その為、基本的にルートディレクトリは設定した1つか、テーマディレクトリになってしまう問題がありました。その問題の結果としては、もし複数のプラグインで snow_monkey_template_part_root フックを使用した場合は、優先度の高い該当のフックの返却値がルートディレクトリに設定されてしまう問題がありました。もし、優先度が他のプラグインより低ければ、そのプラグインで設定したルートディレクトリは正しく参照されません。その為、意図しない動作で処理をされてしまうか、複数のプラグインで動作させた場合には処理エラーが発生してしまう問題がありました。

その問題を踏まえ、snow_monkey_template_part_root フックは非推奨となりました。 代わりに Snow Monkey v5.3.1 から snow_monkey_template_part_root_hierarchy フックが追加され、複数のルートパスを配列で設定できる仕様になっています。

テンプレート読み込みは、設定されたルートディレクトリ配列を次々に調べていきます

snow_monkey_template_part_root_hierarchy フックで return しているのは $hierarchy と言うディレクトリパスを値に持つ配列です。

各テンプレートパーツの読込み処理は、この $hierarchy に値が追加された順に、ディレクトリパス内のテンプレートパーツのファイルが存在するかチェックし、ファイルが存在する場合にはそのテンプレートパーツを使用する仕様になっています。存在しない場合の最後は、テーマディレクトリを調べます。それでもファイルが存在しない場合は、テンプレートパーツファイルの読込みは行われません。

テネーブル

追加された順に読み込むので、配列の並び順が先頭にあればあるほど優先的になります。

ルミェール

フックの優先度を低く設定しても array_unshift 関数などを使うと配列の先頭に追加可能なので、フックの優先度でルートディレクトリの読込み順が必ずしも決まる訳じゃないよ。そこは注意しよう!

また、テンプレートパーツファイルの読込みが行われない場合であっても snow_monkey_get_template_part_args フックや snow_monkey_get_template_part_<slug> フックと言ったテンプレートパーツを処理するフックを実行されます。それらのフック処理に何らかの出力を行う処理があった場合は、その処理結果を出力します。テンプレートパーツファイルを必ず存在させる必要はありません。

テネーブル

テンプレートパーツファイルを使わない条件の時に、snow_monkey_template_part_root_hierarchy フックを処理する場合は、空の配列をすぐに返却させるのが良いでしょう。順にチェックしていくファイルチェック処理を行わなくすれば、少しの高速化も可能です。

カスタマイズ用のテンプレートパーツを追加

さて、テンプレートのルートディレクトリについて理解が深まったところで、カスタマイズ用のテンプレートパーツを追加する場合も、どうすれば良いか見当がついたと思います。

テンプレートのルートディレクトリを設定し、その中に customize/test.php などと言ったファイルを配置するだけです。

この追加したテンプレートパーツの読込み処理は

ob_start();
\Framework\Helper::get_template_part( 'customize/test' );
$_html = ob_get_clean();

と言ったように get_template_part 関数を使用して、テンプレートパーツを読み込みます。

テンプレートパーツの読込みを get_template_part 関数で行うことで customize/test.php も通常のテンプレートパーツと同じように読込まれます。なので、snow_monkey_get_template_part_args フックや snow_monkey_get_template_part_<slug>-<name> フック、snow_monkey_template_part_render フックなども処理した時に実行されます。

ルミェール

独自のテンプレートパーツでもテンプレート系のフックが自動的に呼ばれるようになることで、標準のテンプレートパーツのようにカスタマイズしやすくなるんだ。従来の子テーマなどより、凄く便利に扱えるはず!

カスタムページテンプレートをプラグインで

本記事で解説した snow_monkey_template_part_root_hierarchy フックを使用することで、Snow Monkey v6 以降ではカスタムページテンプレートもプラグインで追加できるようになっています。

Snow Monkey公式Webサイト – 使い方「カスタムページテンプレートの追加方法」

上記の Snow Monkey 公式ウェブサイトの記事では子テーマで追加を行なっていますが、その「1. 子テーマを用意する」部分を行わず、その手順の代わりにテンプレートのルートディレクトリを snow_monkey_template_part_root_hierarchy フックを使用して設定してください。
2. カスタムページテンプレート用のディレクトリを作成する」からの手順も子テーマで追加などせず、次のようにプラグインのテンプレートルートディレクトリ内で同様に page-templates ディレクトリを新規生成します。

プラグインのテンプレートルートディレクトリ

page-templates(新規生成)

それ以降の手順は、同様に新規生成した page-templates ディレクトリ内でファイル作成などを行えば、プラグインでカスタムページテンプレートを作ることが可能になっています。

テネーブル

子テーマの style.css に記述するスタイルシートの手順に関しましては style.css に記述する代わりに、管理画面から [外観] > [カスタマイズ] メニューの [追加CSS] 設定を使用されるか、wp_enqueue_style フックなどを使用しプラグインから CSS を追加で読込む処理を行なって適用するようにしてください。

最後に

本記事で解説をしたテンプレートのルートディレクトリについて理解すれば、ウェブサイトにオリジナルのテンプレートを追加しやすくなります。別記事も参考にし、上手く応用して制作を行ってみてください。予想以上にウェブサイトのデザインを思い通りにカスタマイズできるでしょう。是非、挑戦してみてください。

]]>
テンプレート系フックの意図と最適解の考案 – Snow Monkey カスタマイズ https://not-wiz.net/articles/snow-monkey/intention-templates-hook/ Wed, 05 Feb 2020 15:00:54 +0000 https://not-wiz.net/?p=185 本記事は、Snow Monkey のテーマカスタマイズでよく使われているテンプレート系フックの意図や最適解などについて整理をしました。

最初に

先日、「Snow Monkey 公式サポートフォーラム」で Snow Monkey 開発者のキタジマタカシ氏から、フックに対する意見を頂きました。それをベースにテンプレート置換、定義、追加をプラグインでのカスタマイズで行う場合のフックの最適解についても整理をして考えてみました。

開発者が設計した、それぞれのフックの意図

それぞれのフックの意図としては、
– snow_monkey_get_template_part_<slug> … テンプレートをつくらなくても、 functions.php などから中身を定義できる
– snow_monkey_template_part_render … テンプレートの書き換え
となります。

 snow_monkey_get_template_part_<slug> は書き換え用途ではなく、複数個フックした場合は最終のものだけが反映される形になって混乱するかなと思ったので、最初のだけ反映されるようにしています。なので、これは基本エンドユーザーが使って、プラグインからは使わないほうがスマートかもしれませんね…。

Snow Monkey 公式サポートフォーラム内トピック – キタジマタカシさんの返信より

外部プラグインの場合、snow_monkey_get_template_part_<slug> を使用非推奨ではなく使用しない

My Snow Monkey プラグイン」は、そのウェブサイトを彩る自分専用のプラグインなので、使用するのは非推奨ではありますが問題ないです。

snow_monkey_get_template_part_<slug> のフックは、最初のコールバック処理だけが反映されるようにされています。

その為、外部プラグインで開発する場合は、My Snow Monkey プラグインで該当フックの処理を設定することを想定すると、外部プラグインの該当処理を行うことはコールバックを複数にしてしまうことから使用できません。

キタジマ タカシ氏の意図も踏まえて考えた場合、外部プラグインを開発する場合にテンプレートの置換には snow_monkey_get_template_part_<slug> フックを使用することをしない方が良いです。

テンプレートの置換には、snow_monkey_template_part_render を使う

Snow Monkey v5 時代までは snow_monkey_get_template_part_<slug> フックを使用した書き換えでも問題ないような感じがありました。自分のウェブサイトのみで使う「My Snow Monkeyプラグイン」であれば、最初のコールバック処理だけが反映されるようにされていても、ほとんどのケースで大丈夫だからです。

しかし、外部プラグインへの移植、フックの意図から考えれば、テンプレートの置換に関する処理は、Snow Monkey v6 以降の場合は、すべて snow_monkey_template_part_render フックを使うのが意図や考えを踏まえた上での最適解でしょう。

snow_monkey_get_template_part_<slug> フックを使用する場合

テンプレートの置換では snow_monkey_template_part_render フックを使用する形になるとして、snow_monkey_get_template_part_<slug> フックは、どう言う場合に使用するのが良いと言うことなのかを整理します。

テンプレートをつくらなくても、 functions.php などから中身を定義できる

Snow Monkey 開発者 キタジマ タカシ氏の返答より

が、意図としてあります。なので、それが1つの解となります。

\Framework\Helper::get_template_part と組み合わせる

作っていないテンプレートは、別記事「Snow Monkey カスタマイズをはじめよう – 準備・基礎・初歩編」で解説を行っている \Framework\Helper::get_template_part 関数を使って呼び出すことができます。\Framework\Helper::get_template_part 関数で呼び出した場合は、テンプレートが無い場合でも該当のテンプレートを slug にした snow_monkey_get_template_part_<slug> フックがあれば、テンプレートがあるかのように処理されます。

また、Snow Monkey 標準で用意されているテンプレートの表示結果を別のオリジナルテンプレートパーツとしても使いたい場合は、 snow_monkey_get_template_part_<slug> フックと組み合わせることで新しくテンプレートを作る必要がありません。

外部プラグインではsnow_monkey_template_part_root_hierarchyも必要がない

My Snow Monkey プラグイン」の場合は、snow_monkey_template_part_root_hierarchy フックを使用していても全く問題ないでしょう。

しかし、それ以外の外部プラグインの場合、新しいテンプレートを生成する時は snow_monkey_template_part_root_hierarchy フックを使用してプラグインのrootディレクトリを加えるのではなく、キタジマタカシ氏の開発された WP Plugin View Controller ライブラリを用いたほうが良いのではないかと思います。

WP Plugin View Controller

WP Plugin View Controllerを使用するとは

きちんとした使用方法は記載されていませんが、WP Plugin View Controller で定義した場合は、 snow_monkey_template_part_root_hierarchy とは別にプラグイン用の root ディレクトリ用フックを定義できます。

その為、配布するような外部プラグインの場合は、可能であれば WP Plugin View Controller を使用するのが良いと思っています。 WP Plugin View Controller は Snow Monkey テーマ外でも Snow Monkey テーマと同じようにテンプレートパーツ機能を使用しやすくしてくれます。

まとめ

My Snow Monkey プラグイン」を使用している場合は、フックの意図に関して深く考えなくてもカスタマイズ可能です。

しかし、それとは別に、他の方に配布する Snow Monkey カスタマイズプラグインを作る場合などは、フックの意図を正しく理解した上で開発しなければ、他のプラグインで置換できないなどの障害が発生します。フックの意図も考えた上で Snow Monkey をカスタマイズするようにしましょう。

]]>