WordPress

最終更新日:
公開日:

ワークショップ

オリジナルのWordPressプラグインを作る(10)

プラグインのトップページを表示する

プラグインページを開いたときに最初に表示されるトップページを作成していきます。

この記事のポイント

  • コアのファイルと表示用のビューファイルを分けて読みやすい構造にする
  • プラグインページのCSSファイルはwp_register_style関数wp_enqueue_style関数で読み込む

目次

プラグインのトップページを作成する

前回の「プラグインのページを表示する」ではメニューから「お問い合せ管理」を押すとプラグインのページが表示されるところまで作成してきました。

前回作成したコード:GitHub

今回はプラグインのトップページの作り込みを進めていきましょう。

トップページはお問い合わせページから寄せられた内容を一覧で表示するようにしていきます。
最終的にはデータベースのcontactテーブルからデータを読み込んで一覧を作成しますが、今回はまずトップページを表示する形を整えていきましょう。

作成するプラグインのトップページ

トップページのビューファイルを作成する

プラグイン内のページは、お問い合せページのように変数の値で表示するページを切り替えるようにします。
ただし、お問い合わせページよりも内容が複雑なため、全てのページをcontactManager.phpにまとめてしまうとどこに何のコードが書いてあるか大変分かりづらくなってしまいます。

そこで今回は、contactManager.phpとは別にトップページ、編集ページ、削除ページそれぞれにビューファイルを作成して、表示に関する処理はcontactManager.phpから切り離すように実装していきます。

Note

フレームワークを使ったことがある方には馴染みがあるかと思いますが、表示を担当するファイルを「ビュー(View)ファイル」と呼ぶことがあります。

wp-content/plugins/contactManagerフォルダの中に、新しく_incフォルダviewsフォルダを作成してください。
その後、_incフォルダにはstyle.cssviewsフォルダにはindex.phpを作成してください。
作成したファイルの内容は後で記述するため、ここでは一旦何も書かない状態で大丈夫です。

ファイルを作成した後のcontactManagerフォルダは次のような構成になります。

contactManagerフォルダの構成

viewsフォルダに作成したindex.phpはトップページのビューファイルです。
このファイルを開いて、以下のHTMLを記述してください。

views/index.php

<table class="data_table">
	<tr>
		<th>日時</th><th>お名前</th><th>メールアドレス</th><th>お問い合わせ内容</th><th></th>
	</tr>
	<tr>
		<td>2022-04-07 00:00:00</td>
		<td>テスト太郎</td>
		<td>taro@gray-code.com</td>
		<td>テストです。</td>
		<td>
			<a href="&cm=edit&id=1">編集</a>  <a href="&cm=delete&id=1">削除</a>
		</td>
	</tr>
	<tr>
		<td>2022-04-07 01:01:00</td>
		<td>テスト花子</td>
		<td>hanako@gray-code.com</td>
		<td>テストです。</td>
		<td>
			<a href="&cm=edit&id=1">編集</a>  <a href="&cm=delete&id=1">削除</a>
		</td>
	</tr>
	<tr>
		<td>2022-04-07 02:02:00</td>
		<td>テスト健太</td>
		<td>kenta@gray-code.com</td>
		<td>テストです。</td>
		<td>
			<a href="&cm=edit&id=1">編集</a>  <a href="&cm=delete&id=1">削除</a>
		</td>
	</tr>
</table>

後ほどデータベースから取得したデータを表示するように変更していきますが、ここではまずHTMLのみを記述します。
続いて、_incフォルダに作成したstyle.cssを開いて、以下のCSSを記述してください。
お問い合わせページと同様に、今回はCSSの解説は省略します。

_inc/style.css

/* Reset style
------------------------------ */
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code,
del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var,
b, i,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
    margin:0;
    padding:0;
    border:0;
    outline:0;
    font-size:100%;
    vertical-align:baseline;
    background:transparent;
}

body {
	font-size: 16px;
    line-height:1;
}

article,aside,details,figcaption,figure,
footer,header,hgroup,menu,nav,section { 
    display:block;
}

nav ul {
    list-style:none;
}

blockquote, q {
    quotes:none;
}

blockquote:before, blockquote:after,
q:before, q:after {
    content:'';
    content:none;
}

a {
    margin:0;
    padding:0;
    font-size:100%;
    vertical-align:baseline;
    background:transparent;
}

/* change colours to suit your needs */
ins {
    background-color:#ff9;
    color:#000;
    text-decoration:none;
}

/* change colours to suit your needs */
mark {
    background-color:#ff9;
    color:#000; 
    font-style:italic;
    font-weight:bold;
}

del {
    text-decoration: line-through;
}

abbr[title], dfn[title] {
    border-bottom:1px dotted;
    cursor:help;
}

table {
    border-collapse:collapse;
    border-spacing:0;
}

hr {
    display:block;
    height:1px;
    border:0;   
    border-top:1px solid #cccccc;
    margin:1em 0;
    padding:0;
}

input, select {
    vertical-align:middle;
}



/* Common
------------------------------ */

body {
	background-color: #f7f7f7;
}

.wrap h1 {
	margin-bottom: 20px;
}

.wrap h2 {
	margin-bottom: 20px;
}

.btn_area {
	margin-bottom: 20px;
}

.btn {
	display: inline-block;
	padding: 10px 15px;
	border-radius: 4px;
	color: #fff;
	font-size: .86rem;
	text-decoration: none;
	background: #4383ef;
	transition-property: background-color;
	transition-duration: .2s;
	transition-timing-function: ease-in;
}
.btn:hover {
	color: #fff;
	background: #6a9ff7;
}

.link_back {
	margin-bottom: 20px;
}
.link_back a {
	font-size: .86rem;
}

.form_area {
	padding: 40px;
	width: 100%;
	border-radius: 10px;
	box-sizing: border-box;
	background: #fff;
}

.message {
	margin-bottom: 40px;
	padding: 20px;
	list-style-type: none;
	border-radius: 10px;
}

.success_message {
	animation: messageAnimation 2s ease-in 1;
	color: #5a9900;
	background: #d6f6a9;
}

.error_message {
	animation: messageAnimation 2s ease-in 1;
	color: #c00;
	background: #ffcbcb;
}

@keyframes messageAnimation {
	0%, 90% {
		transform: translateY(1.0);
	}
	100% {
		transform: translateY(0);
	}
}

.error_list {
	background: #ffcbcb;
}
.error_list li {
	margin-bottom: 5px;
	font-size: .93rem;
	line-height: 1.6em;
	color: #c00;
}
.error_list li::before {
	display: inline-block;
	margin-top: 7px;
	margin-right:10px;
	content: "";
	width: 8px;
	height: 8px;
	vertical-align: top;
	border-radius: 4px;
	background-color: #c00;
}
.error_list li:last-child {
	margin-bottom: 0;
}

.form_area input,
.form_area select,
.form_area textarea {
	font-size: 1.0rem;
}

.form_area input,
.form_area textarea {
	padding: 5px 10px;
}

.form_area .input_label {
	display: inline-block;
	margin-left: 20px;
	padding: 10px 0;
	vertical-align: top;
}
.form_area .first_label {
	margin-left: 0;
}

.form_area select {
	padding: 5px 40px 5px 10px;
}

.form_area input[type=submit] {
	appearance: none;
	display: inline-block;
	padding: 7px 15px;
	border-radius: 4px;
	border: none;
	color: #fff;
	font-size: 0.86rem;
	text-decoration: none;
	background: #4383ef;
	transition-property: background-color;
	transition-duration: .2s;
	transition-timing-function: ease-in;
}
.form_area input[type=submit]:hover {
	color: #fff;
	background: #6a9ff7;
}



/* Top
------------------------------ */

.data_table {
	width: 100%;
	border: 1px solid #bbb;
}

.data_table tr:nth-child(even) {
	background-color: #eee;
}

.data_table th {
	padding: 15px 20px;
	color: #222;
	font-size: .86rem;
	font-weight: bold;
	text-align: left;
	background: #91c6f3;
}

.data_table th:nth-child(1),
.data_table th:nth-child(2) {
	width: 15%;
}
.data_table th:nth-child(3) {
	width: 20%;
}
.data_table th:nth-child(4) {
	width: 35%;
}
.data_table th:nth-child(5) {
	width: 15%;
}

.data_table td {
	padding: 10px 20px;
	color: #222;
	font-size: .86rem;
	line-height: 1.8em;
}



/* Create & Edit & Delete
------------------------------ */

.form_list {
	flex-wrap: wrap;
	width: 100%;
	box-sizing: border-box;
}

.form_list dt {
	margin-bottom: 10px;
	width: 100%;
	font-size: 0.93rem;
}

.form_list dd {
	margin-bottom: 30px;
	width: 100%;
	font-size: 0.86rem;
}

.form_list dd input[type=text],
.form_list dd textarea {
	min-width: 50%;
}

.form_area .link_back {
	margin-bottom: 0;
}

.text_delete {
	padding: 7px 10px;
	border: 1px solid #bbb;
	border-radius: 4px;
	color: #222;
	font-size: .93rem;
	line-height: 1.8em;
	box-sizing: border-box;
}

ビューファイルを表示する

続いて、作成したビューファイルを表示できるようにしていきます。
ビューファイルを読み込むメソッドを用意して、指定した名前に対応するビューファイルを読み込むようにしましょう。

まず、contactManagerフォルダclass.cm.phpという名前のファイルを作成してください。
このファイルは名前の通りCmクラスを定義していきますが、この中にはお問い合わせプラグイン内で使うメソッドを書いていきます。
今回のビューファイルを読み込むメソッドもその1つです。

それでは作成したclass.cm.phpを開いて、以下のコードを書いていきましょう。

class.cm.php

<?php

class Cm {

	public static function view( $name) {
		$file = CM_PLUGIN_DIR . 'views/'. $name . '.php';
		include($file);
	}

	public static function getBaseUrl() {
		return (is_ssl() ? 'https' : 'http') . '://' . $_SERVER["HTTP_HOST"] . $_SERVER['SCRIPT_NAME'] . '?page=cm';
	}
}

Cmクラスには2つのメソッドを定義しています。
1つは今回のビューを読み込むためのviewメソッド、そしてもう1つはプラグインページのURLを取得するgetBaseUrlメソッドです。
getBaseUrlメソッドはやっていることはシンプルですが、ビューファイル内などでプラグインのURLを参照するときに度々活用します。

続いて、作成したCmクラスを使用できるようにcontactManager.phpで読み込みます。
以下のようにrequire_once関数を追加してください。

contactManager.php

<?php
/*
Plugin Name: Contact Manager
Description: お問い合わせを管理するためのプラグイン
Version: 0.1
Author: GRAYCODE
Author URI: https://gray-code.com
Licence: GPL v2 or later
Licence URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

define( 'CM_VERSION', '0.1.1' );
define( 'CM_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );

require_once( CM_PLUGIN_DIR . 'class.cm.php' );

function cm_option_page_html() {

----- 省略 -----

さらに、前回contactManager.phpに書いたcm_option_page_html関数をビューファイルを出力するように書き直していきます。
以下のようにページタイトルを入れる$page_titleと、ビューファイル名を入れる$viewを追加しましょう。

contactManager.php

<?php

----- 省略 -----

require_once( CM_PLUGIN_DIR . 'class.cm.php' );

function cm_option_page_html() {

$page_title = 'お問い合わせ管理';
$view = 'index';

?>

<div class="wrap">
	<h1><?php echo $page_title; ?></h1>
	<?php Cm::view($view); ?>
</div>

<?php
}

----- 省略 -----

$page_titleは今後ページが増えたときに、表示するタイトルをページに合わせて動的に変更できるようにしています。
例えば、編集ページはタイトルを「お問い合わせ管理 編集」にしたり、削除ページのタイトルを「お問い合わせ管理 削除」にするときに$page_titleへ入れる文字列を変更することで対応します。

Cmクラスを作成したときにメソッドの定義でstaticキーワードを付けたため、クラスのインスタンスを作成せずに「Cm::view(…);」のような形でダイレクトにメソッドを実行できます。

$viewには「index」を入れているため、viewメソッドviews/index.phpが読み込まて表示されます。
ここまでの変更を保存して、ブラウザでプラグインのページを表示してみてください。
以下のようにindex.phpに書いたHTMLが表示されているでしょうか。

お問い合せページにビューファイルの内容を表示

リソースファイルを読み込む

HTMLが表示されたところで、先ほど作成したもう1つのファイルである_inc/style.cssも読み込んでページに適用していきましょう。

今回のように、管理ページのプラグインページのみに適用するCSSなどのリソースファイルを読み込む場合は、WordPressで用意されているアクションadmin_enqueue_scriptsにフックさせて読み込む形にすると実現できます。
そこで、プラグインページに限定したリソースファイルを読み込むためのclass.cm-admin.phpを作成して、以下のコードを記述してください。

class.cm-admin.php

<?php

class Cm_Admin {

	private static $initiated = false;

	public static function init() {
		if ( ! self::$initiated ) {
			self::init_hooks();
		}
	}

	public static function init_hooks() {

		self::$initiated = true;
		add_action( 'admin_enqueue_scripts', array( 'Cm_Admin', 'load_resources' ) );
	}

	public static function load_resources() {
		wp_register_style( 'style.css', plugin_dir_url( __FILE__ ) . '_inc/style.css', array() );
		wp_enqueue_style( 'style.css');
	}

}

Cm_Adminクラスinitメソッドを実行すると、init_hooksメソッドを実行してadmin_enqueue_scriptsに読み込むリソースファイルをセットします。

読み込むファイルはもう1つのload_resourcesメソッドによって、wp_register_style関数より登録してwp_enqueue_style関数でキューに追加しています。
キューに追加されたリソースファイルはページを読み込むときにWordPressによって自動的に読み込まれるようになります。

続いて、contactManager.phpからCm_Adminクラスを読み込んで実行するようにコードを追加していきます。
contactManager.phpを開いて、以下のコードを追加してください。

contactManager.php

<?php

----- 省略 -----

add_action('admin_menu', 'cm_options_page');

function cm_options_page() {
	add_menu_page(
		'お問い合わせ管理',
		'お問い合わせ管理',
		'manage_options',
		'cm',
		'cm_option_page_html',
		'dashicons-feedback',
		3
	);
}


if ( is_admin() ) {
	require_once( CM_PLUGIN_DIR . 'class.cm-admin.php' );
	add_action( 'init', array( 'Cm_Admin', 'init' ) );
}

if文is_admin関数は表示しているページが管理ページであるかどうかを確認します。
その中で、Cmクラスと同様にrequire_once関数を使ってCm_Adminクラスのファイルを読み込みます。

続いて、プラグインの初期化のタイミングで発生するアクションinitにフックさせる形でCm_Adminクラスinitメソッドを実行するように設定します。
これで、お問い合わせ管理ページを開くタイミングでアクションinitが発生したらCm_Adminクラスよりリソースファイルを読み込むことができます。

今回はCSSを1ファイルだけ読み込んでいますが、複数のCSSファイルを読み込んだり、wp_register_script関数wp_enqueue_script関数を使ってJavaScriptファイルを読み込むように設定することもできます。

ここまでの変更を保存して、改めてブラウザでプラグインのページを表示してみてください。
CSSが適用されると、以下のようなページが表示されます。

CSSが適用されたトップページ

今回はファイルやフォルダをたくさん作成しましたが、現在のプラグインフォルダ内は以下のファイル構成になっています。

現在のファイル構成

次回はトップページの一覧に表示するお問い合わせのデータをデータベースから取得する機能を実装していきます。

今回作成したコード:GitHub

前のページへ 一覧に戻る 次のページへ