WordPressの管理画面ってシンプルですよね。
シンプルすぎるが故に、ちょっとものたりない場面もあります。
例えば、一覧画面。
固定ページはともかく、投稿やカスタム投稿なんかは、記事が多くなればなるほど「この記事って、どんな内容だったっけ?」と、なりがち。
一覧画面で、もう少し記事内容がわかれば、少し解消できそうです。
投稿の一覧画面のデフォルトはこんな表示。
タイトル、投稿者、カテゴリー、タグ、コメント、日付の列が並ぶシンプルな構成です。
この表示項目をカスタマイズしていくのが今回のテーマです。
プラグインを使う方法もありますが、考え方としてはそれほど難しくはないので、自前で作成してしまいましょう。
手順としては3つのフェーズです。
今回はカスタムフィールドで「出版社」「値段」「在庫状況」を持つ投稿を例にしてみます。
カスタムフィールドはAdvanced Custom Fieldsで作成しました。
「出版社」(フィールド名は’publisher’)と「値段」(同’price’)のフィールドタイプはテキスト、「在庫状況」(同’stock’)はボタングループで作成しています。
本文はブロックエディタで作成しています。
1
一覧画面に表示したい
列項目を設定する
まずは、表示したい項目の列を追加していきます。
今回は「タイトル」「コンテンツ」「出版社」「値段」「在庫状況」を表示して、デフォルトで表示される「タグ」と「コメント」は非表示にしたいと思います。
基本となる大枠のコードは以下のとおりです。
add_filter(
// 第一引数 = フィルターフック名
'manage_posts_columns',
// 第二引数 = 処理内容
function( $columns ){
// 実際の処理内容
}
);
WordPressにはフィルターフック・アクションフックというものが用意されていて、さまざまなカスタマイズを実現できます。
フィルターフックはadd_filter関数で実行します。
第一引数は、使用するフィルターフック名を記述。
今回はmanage_posts_columnsという一覧画面の表示項目をカスタマイズできるフィルターフックを使用します。
ちなみに、固定ページの場合にはmanage_pages_columnsを、
カスタム投稿タイプの場合には manage_{$post_type}_posts_columnsを使用します。
(スラッグが「project」というカスタム投稿タイプなら、manage_project_posts_columns)
第二引数は、表示する列名と見出しを設定していきます。
//第二引数部分だけ抜粋
function($columns){
$columns = array(
'cb' => '<input type="checkbox" />',
'title' => 'タイトル',
'content' => 'コンテンツ',
'publisher' => '出版社',
'price' => '値段',
'stock' => '在庫状況',
'date' => '公開日付',
);
return $columns;
}
引数でデフォルトの設定を受け取り(2行目)、カスタマイズした内容を(3〜11行目)、returnで上書きする(12行目)という処理です。
列の名前 => 列のヘッダーテキスト
という記述で好きなように列項目を設定することができます。
今回は、デフォルトの’cb’、’title’、’date’に加えて、表示したい「コンテンツ」「出版社」「値段」「在庫状況」を追加しています。
また、デフォルトの「タグ」「コメント」は記述しないことで非表示にしています。
列の名前やヘッダーテキストに決まったルールはありませんので、自由に名前をつけてください。
ちなみに、単にデフォルト表示される列項目を非表示にしたいだけなら、
function($columns){
unset(
$columns['tags'],
$columns['comments']
);
return $columns;
}
という具合に、非表示にする列項目をunsetするだけで大丈夫です。
具体的に記述するコードは以下のとおりです。
functions.phpに記述してみてください。これで、列項目の設定は完了です。
※functions.phpを編集する際には必ずバックアップをとり、すぐに元に戻せる状況にしておいてください。functions.phpの記述に誤りがあると、最悪、サイト全体が表示されなくなります。
add_filter(
'manage_posts_columns',
function($columns){
$columns = array(
'cb' => '<input type="checkbox" />',
'title' => 'タイトル',
'content' => 'コンテンツ',
'publisher' => '出版社',
'price' => '値段',
'stock' => '在庫状況',
'author' => '投稿者',
'date' => '公開日付',
);
return $columns;
}
);
ちなみに、上記のコードは以下のようにも記述できます。
add_filter( 'manage_posts_columns','admin_posts_columns');
function admin_posts_columns( $columns ) {
$columns = array(
'cb' => '<input type="checkbox" />',
'title' => 'タイトル',
'content' => 'コンテンツ',
'publisher' => '出版社',
'price' => '値段',
'stock' => '在庫状況',
'author' => '投稿者',
'date' => '公開日付',
);
return $columns;
}
第二引数の部分を関数として外に出して(2〜14行目)、add_filter関数の第二引数には関数名を記述する方法です。2行目以降の関数の名前は自由につけることができますが、add_filter関数の第二引数に記述する名前と相違ないように気をつけてください。
第二関数(処理内容)が長いような場合には、こちらのほうが使い勝手が良い気がします。 元の状態を確認したい際など、1行目のadd_filter関数だけをコメントアウトすればいいので手軽ですしね。
それでは、実際の表示を見てみましょう。
「コンテンツ」「出版社」「値段」「在庫状況」の列が追加され、「タグ」「コメント」の列がなくなりました。
ただし、列の見出しが設定されただけで、まだ各項目の中身は何にも表示されていない状態です。
2
追加した項目の
表示内容を設定する
それでは追加した項目の内容を表示するように設定していきましょう。
一覧画面の列項目の内容をカスタマイズするのがmanage_posts_custom_columnというアクションフックです。
ちなみに、manage_posts_custom_columnは投稿一覧の場合で、
固定ページの場合はmanage_pages_custom_column、
カスタム投稿の場合にはmanage_{$post_type}_posts_custom_columnに置き換えてください。
大枠のコードは以下になります。
add_action(
// 第一引数 = アクションフック名
'manage_posts_custom_column',
// 第二引数 = 処理内容
function($column_name, $post_id){
//実際の処理内容
},
//第三引数 = 処理の優先順位
10,
//第四引数 = 第二引数の処理内容で受け取る引数の数
2
);
add_action関数の第一引数にmanage_posts_custom_columnというアクションフックを記述して、第二引数に処理内容を記述します。
今回はアクションフックを利用しますが、使い方としてはadd_filterと同様です。
第三引数や第四引数があるのが異なりますが、こちらについては後述します。
add_actionの第二引数に記述された処理内容ですが、2つの引数を受け取ることができます。手順1で設定した列の名前(column_name)と、投稿それぞれの投稿ID(post_id)です。
これにより、各投稿の各列項目の表示内容をそれぞれ設定することができるというわけです。つまり、$post_idの投稿の$column_nameの内容はこれを表示する、という記述です。
デフォルト表示で良いものは特に記述は必要ありません。
今回のケースでは、タイトルはデフォルトでよいので記述なし、「コンテンツ」「出版社」「値段」「在庫状況」を第二引数の関数に記述していきます。
「コンテンツ」の場合
「コンテンツ」は通常のブロックエディタで作成している内容を表示したいので、以下の記述にしています。
if($column_name === 'content'){
if(!empty(get_the_content($post_id))){
the_content($post_id);
} else {
echo '';
}
}
1行目は列の名前が ‘content’の場合に以下の処理を行うという条件分岐で、2〜6行目でその処理内容を記述しています。
2〜6行目は、対象の投稿IDのコンテンツ内容が空かどうかで条件分岐しています。
コンテンツ内容が空でない場合には(2行目)コンテンツ内容を表示(3行目)、そうでない場合には(4行目)何も表示しないように(5行目)しています。
「出版社」「値段」の場合
「出版社」と「値段」は自由入力のカスタムフィールドですので、少し記述が異なります。
「出版社」を例にとると、
if($column_name === 'publisher'){
if(!empty(get_post_meta($post_id,'publisher'))){
echo esc_html(get_post_meta($post_id,'publisher',true));
} else {
echo '';
}
}
基本的には同じですが、2行目の判定の際にカスタムフィールドの値を取得するのにget_post_meta()を使用している点と、表示の際にエスケープ処理(esc_html())をしている点が異なります。get_post_meta()はプラグインに関係なくカスタムフィールドの値を取得する関数です。
「在庫状況」の場合
「在庫状況」は、「売り切れ」と「在庫あり」を選択肢としたカスタムフィールドですので、そのままだと「out」「in」という味気ない表示になってしまいます。
そこでひと工夫しています。
if($column_name === 'stock'){
$stock = get_post_meta($post_id,'stock',true);
$stock_choices = get_field_object('stock',$post_id)['choices'];
if($stock === 'out'){
echo '<span class="red">'.$stock_choices['out'].'</span>';
} else {
echo $stock_choices['in'];
}
}
ACFのget_field_object()という独自関数を使用してラベルを取得。
売り切れの場合にはredというクラス名をつけたspanタグでラベルを括るようにしました。
これは次の手順で使用します。
functions.phpに記述する実際のコードは以下のとおりです。
※functions.phpを編集する際には必ずバックアップをとり、すぐに元に戻せる状況にしておいてください。functions.phpの記述に誤りがあると、最悪、サイト全体が表示されなくなります。
add_action( 'manage_posts_custom_column', 'add_history_post_column', 10, 2 );
function add_history_post_column( $column_name, $post_id ) {
if($column_name === 'content'){
if(!empty(get_the_content($post_id))){
the_content($post_id);
} else {
echo '';
}
}
if($column_name === 'publisher'){
$publisher = get_post_meta($post_id,'publisher',true);
if(!empty($publisher)){
echo esc_html($publisher);
} else {
echo '';
}
}
if($column_name === 'price'){
$price = get_post_meta($post_id,'price',true);
if(!empty($price)){
echo esc_html($price.'円');
} else {
echo '';
}
}
if($column_name === 'stock'){
$stock = get_post_meta($post_id,'stock',true);
$stock_choices = get_field_object('stock',$post_id)['choices'];
if($stock === 'out'){
echo '<span class="red">'.$stock_choices['out'].'</span>';
} else {
echo $stock_choices['in'];
}
}
}
先ほど保留にしていたadd_action関数の第三引数と第四引数について。
第三引数は処理の優先順位を指定します。
特に優先度が高いものではないので、デフォルトの10を指定しています。
第四引数は第二引数の関数で使用する引数の数を指定します。
今回は2つの引数を受け取るので、2を指定しています。
第四引数が1の場合は、第三引数、第四引数ともに省略可能です。
これで、各列に内容が表示されました。
ただ、「コンテンツ」の例項目で文章量が多い場合には、一覧としては見にくいものになってしまいます。
ということで、文字数制限をすることにします。
if($column_name === 'content'){
$content = get_the_content($post_id);
$limit = 100;
if(!empty($content)){
if(mb_strlen($content) > $limit){
$text = mb_substr($content,0,$limit).'...';
} else {
$text = $content;
}
} else {
$text = '';
}
echo $text;
}
上記の例では100文字を上限に表示するように設定してみました。
これで無駄に縦方面に長くならずに、かつ、内容もある程度わかるということで、目的は達成できるのではないでしょうか。
3
(必要であれば)
列のデザインをcssで調整する
そのままでは各列等幅になっていますので、見にくい場合もあるかもしれません。
今回のケースではコンテンツの列の幅は広く表示した方が良さそうです。
ということで、列ごとの幅指定を行なっていきます。
※functions.phpを編集する際には必ずバックアップをとり、すぐに元に戻せる状況にしておいてください。functions.phpの記述に誤りがあると、最悪、サイト全体が表示されなくなります。
add_action('admin_head', 'posts_column_css');
function posts_column_css() {
global $post_type;
if($post_type === 'post'){
echo '<style type="text/css">
.column-title { width: 12% !important; }
.column-content { width: auto !important; }
.column-publisher { width: 10% !important; }
.column-price { width: 10% !important; }
.column-author { width: 10% !important; }
.column-stock { width: 10% !important; }
.column-stock .red { color: #cc0000; }
.column-date { width: 10% !important; }
</style>';
}
}
アクションフックのadmin_headを使用しています。
admin_headは、管理画面の<head>要素をカスタマイズするアクションフックで、今回は<head>要素内にcssを記述するという処理を行なっています。
通常のcss同様、幅だけでなく色や高さなども設定できます。
クラス名は、手順1で設定した列の名前の前に「.column-」を加えたものになります。
手順2のstockの項目でredというspanタグを追加しましたが、売り切れの場合には文字が赤くなるような指定も行なっています。
今回はアクションフックで指定していますが、通常のcssのように外部cssファイルで設定する方法もあります(割愛)。
これで、かなり一覧画面が見やすいものになったのではないでしょうか。
まとめ
WordPressの投稿一覧画面を少しでも使いやすくするための方法をご紹介しました。
表示したい列項目を設定して、そこに表示する内容の設定をして、必要とあればcssで見栄えを調整する。流れを理解すると、考え方としてはシンプルなものだと思います。
表示する内容の設定によってはさまざまな表示が可能です。
以前、「投稿した記事をメールマガジンで紹介したい」というクライアントがいらっしゃいました。
メールマガジンでURLを貼り付けるわけですが、投稿一覧画面にURLが表示されていたら便利かもしれないと思い、URLを表示する列を作成したことがあります。
この場合、get_permalink()で取得した情報を表示すればいいだけですが、
実は投稿内容の一部だけでなく、さまざまな情報を表示することが可能です。
例えば、値段のフィールドが複数あったとして、そのすべての合計を表示するとか。
住所のフィールドがあったとして、googlemapを表示してみるとか(あんまりないですかね)。
他にも、記事のアイキャッチ画像を表示したりすると、ぐんと使い勝手が良くなりそうです。
工夫してみてください。
ただ、項目が多くなりすぎると、それはそれで見にくい一覧になりそうですので、バランスを見ながら作成してみてください。
ちなみに、一覧の上部にあるプルダウンで絞り込みをする機能や、列のヘッダータイトルをクリックすることで並び替えできる機能などもありますが、それは別記事でご紹介しようと思います。
それにしても、WordPressではカスタマイズできる機能がさまざまあるのが面白いなと思います。
冒頭でシンプルと言いましたが、こうしたカスタマイズできる機能がたくさんあるからこそのシンプルさなのかもしれませんね。
絞り込み機能を拡張する記事はこちら↓
並べ替え機能を拡張する記事はこちら↓
最後に今回のすべてのコードを以下にまとめます。
※functions.phpを編集する際には必ずバックアップをとり、すぐに元に戻せる状況にしておいてください。functions.phpの記述に誤りがあると、最悪、サイト全体が表示されなくなります。
/*----------------
* 一覧画面に表示したい列項目を設定する
*----------------*/
add_filter('manage_posts_columns','admin_posts_columns');
function admin_posts_columns($columns){
$columns = array(
'cb' => '<input type="checkbox" />',
'title' => 'タイトル',
'content' => 'コンテンツ',
'publisher' => '出版社',
'price' => '値段',
'stock' => '在庫状況',
'date' => '公開日付',
);
return $columns;
}
/*----------------
* 追加した項目の表示内容を設定する
*----------------*/
add_action( 'manage_posts_custom_column', 'add_posts_column', 10, 2 );
function add_posts_column( $column_name, $post_id ) {
if($column_name === 'content'){
$content = get_the_content($post_id);
$limit = 100;
if(!empty($content)){
if(mb_strlen($content) > $limit){
$text = mb_substr($content,0,$limit).'...';
} else {
$text = $content;
}
} else {
$text = '';
}
echo $text;
}
/* 文字数制限をかけないコード
if($column_name === 'content'){
if(!empty(get_the_content($post_id))){
the_content($post_id);
} else {
echo '';
}
}
*/
if($column_name === 'publisher'){
$publisher = get_post_meta($post_id,'publisher',true);
if(!empty($publisher)){
echo esc_html($publisher);
} else {
echo '';
}
}
if($column_name === 'price'){
$price = get_post_meta($post_id,'price',true);
if(!empty($price)){
echo esc_html($price.'円');
} else {
echo '';
}
}
if($column_name === 'stock'){
$stock = get_post_meta($post_id,'stock',true);
$stock_choices = get_field_object('stock',$post_id)['choices'];
if($stock === 'out'){
echo '<span class="red">'.$stock_choices['out'].'</span>';
} else {
echo $stock_choices['in'];
}
}
}
/*----------------
* 追加した項目の表示内容を設定する
*----------------*/
add_action('admin_head', 'posts_column_css');
function posts_column_css() {
global $post_type;
if($post_type === 'post'){
echo '<style type="text/css">
.column-title { width: 12% !important; }
.column-content { width: auto !important; }
.column-publisher { width: 10% !important; }
.column-price { width: 10% !important; }
.column-author { width: 10% !important; }
.column-stock { width: 10% !important; }
.column-stock .red { color: #cc0000; }
.column-date { width: 10% !important; }
</style>';
}
}