前回はフロントページにて個別投稿ページのヘッダ内リソース読み込みを行いたくて、固定ページをベースにメインクエリを上書きする方法でカスタムページを作りました。
当時は、lib フォルダ内ファイルの関数をテンプレートからオーバーライドできないと思っていたので、この方法をとったのですが、方法が分かったのでメインクエリを上書きせずに、より自然(たぶん)な方法でカスタムページを作ります。
ついでに、ブログカードを複数列にも対応するようにしています。
2020/9/16 現在、本サイトはこのカスタムテンプレートを使用しています。
変更方法検討
index.php を使用するページが多かったため、フロントページでのみ、新着投稿を全文表示にする方法を検討します。
前回使った、WordPress のホームページ設定を変更することでカスタムページ設定する方法は、解除の際もファイル管理やコード変更などの手間がかからないため採用することにしました。
ただし、前回と違って固定ページ表示ではなく投稿ページ表示設定を使います。
これでメインクエリを上書きせずに済みます。
あとは、フロントページでかつホームページ設定が特定の投稿ページ表示設定の時のみ、新着記事だけ全文表示するテンプレートを使うように場合分けしていきます。
以下の順にテンプレートが読まれているので、
- index.php
- tmp/list.php
- tmp/list-index.php
2. の「tmp/list.php」から分岐させることにします。
実装
全文表示判定関数
新着記事だけ全文表示するかどうかを判定するための条件は以下の通りです。
- ブログ投稿インデックスページの表示中である
- ホームページ設定が投稿ページ「full-text」である
これを判定する関数を、テーマフォルダ直下の functions.php に追記します。
Cocoon のテーマフォルダ直下の functions.php の変更には注意が必要です。
ファイル内容は以下の通りで、追記をする場合は必ず「//以下に子テーマ用の関数を書く」の次の行以降に追記してください。
<?php //子テーマ用関数
if ( !defined( 'ABSPATH' ) ) exit;
//子テーマ用のビジュアルエディタースタイルを適用
add_editor_style();
//以下に子テーマ用の関数を書く
ここで、「あれ?先頭の『<?php』タグ閉じてなくない?」と思われた場合は、WordPress の PHP コード規約が参考になります。
文末の空白の除去
コードの各行末尾のスペースは削除してください。ファイル末尾の PHP 終了タグの除去は推奨です。終了タグを使用する場合には、その後にスペースがないことを確認してください。
https://ja.wordpress.org/team/handbook/coding-standards/wordpress-coding-standards/php/#%e6%96%87%e6%9c%ab%e3%81%ae%e7%a9%ba%e7%99%bd%e3%81%ae%e9%99%a4%e5%8e%bb
要は、PHP 終了タグで閉じなくてOK!
ヘッダ内リソース読み込み関数のオーバーライド
ソースコードの色分けや画像のポップアップなどのスクリプトは、特定のページでしか読み込まないように設計されているので、全文表示判定のときも読み込むように関数オーバーライドします。
オーバーライド元の関数は以下の3つです。
(関数名 : ファイル)
- wp_enqueue_highlight_js() : lib/utils.php
- is_lightboxable_page() : lib/image.php
- is_lightboxable_page() : lib/utils.php
Cocoon は以下の場所で WordPress のアクションフックによるスクリプトやスタイルのエンキューを行っています。
- wp_enqueue_scripts_custom() : cocoon-master/lib/scripts.php
この関数内でコールされている関数を1個ずつ確認し、全文表示の際に必要だが、条件判定によりフロントページで実行されない関数を洗い出しました。
これらのオーバーライド関数を、テーマフォルダ直下の functions.php に追記します。
変更箇所の概要は以下の通りです。
|| is_full_text()
いずれの関数も、上記の判定を追加しました。
新着投稿の全文表示用条件分岐
tmp/list.php に条件分岐を追加して、新着投稿の全文表示用一覧テンプレート tmp/list-index-full-text を使うように変更します。
変更箇所の概要は以下の通りです。
(参照ファイル:cocoon-master/tmp/list.php)
/* add >>> */
} elseif ( is_full_text() ) {
get_template_part('tmp/list-index-full-text');
/* add <<< */
全文表示判定が真なら、tmp/list-index-full-text を使うように変更しています。
一覧表示テンプレート(新着投稿だけ全文表示用)
新着投稿だけ全文表示する一覧表示テンプレート tmp/list-index-full-text.php を作ります。
変更箇所の概要は以下の通りです。
(参照ファイル:cocoon-master/tmp/list-index.php)
ページ番号取得
$current_pgae = get_query_var( 'paged' );
$current_pgae = $current_pgae == 0 ? '1' : $current_pgae;
現在のページが一覧ページの何ページ目かを取得します。
新着投稿分岐
if ( $count == 1 ) {
if ( $current_pgae == 1 ) {
get_template_part( 'tmp/content-in-home' );
echo '<div id="list" class="' . get_index_list_classes() . ' front">';
get_template_part( 'tmp/entry-card' );
}
else {
echo '<div id="list" class="' . get_index_list_classes() . '">';
get_template_part( 'tmp/entry-card' );
}
}
else {
get_template_part( 'tmp/entry-card' );
}
新着投稿のみ一覧ブロックの前に全文表示し、他は一覧ブロックの中でブログカード表示するようにしています。
念のため、やっていることの詳細は以下の通りです。
- 新着投稿(1ページ目の1件目投稿)
- 全文表示用テンプレート tmp/content-in-home 使用
- 「<div id=”list”~」表示(一覧ブロックの開始)
- ブログカード表示用テンプレート tmp/entry-card 使用
- 2ページ目以降の1件目投稿
- 「<div id=”list”~」表示(一覧ブロックの開始)
- ブログカード表示用テンプレート tmp/entry-card 使用
- 2件目以降投稿
- ブログカード表示用テンプレート tmp/entry-card 使用
新着投稿のブログカード装飾
ブログカードを複数列表示設定にしている場合、新着投稿のブログカード非表示にするとレイアウトが著しくくずれてしまうため、新着投稿は全文表示にしつつブログカード表示も残すようにしました。
その代わり、スタイルシートで新着投稿のブログカードを装飾できるように、1ページ目の一覧ブロックにだけ「front」クラスを追加しています。
.front .entry-card-wrap:first-child
と指定することで、新着投稿のブログカードを装飾可能です。
サンプル
本サイトでは、以下の装飾を行っています。
- グレースケール化(80%)
- 半透明化(不透明度:40%)
- 表示中のアイコン表示
.front .entry-card-wrap:first-child {
filter: opacity(0.4) grayscale(0.8);
}
.front .entry-card-wrap:first-child::before {
filter: opacity(1);
width: 100px;
background-color: rgba(0,0,0,0);
color: #fff;
content: '表示中';
text-align: center;
position: absolute;
z-index: 100;
top: 50%;
left: 50%;
transform: translateY(15px) translateX(-50px);
}
.front .entry-card-wrap:first-child::after {
filter: opacity(0.8);
padding-top: 5px;
height: 100px;
width: 100px;
background-color: #000;
border-radius: 25%;
color: #fff;
font-family: "Font Awesome 5 Free";
font-weight: 900;
font-size: 2.4em;
content: '\f26c';
text-align: center;
vertical-align: middle;
position: absolute;
z-index: 99;
top: 50%;
left: 50%;
transform: translateY(-50px) translateX(-50px);
}
※ 日本語を使用していますので、css ファイルの文字コードにはお気を付けください。
フロントページでの全文表示テンプレート
個別投稿ページテンプレート参考に、新規ファイル tmp/content-in-home.php を作ります。
フロントページの構成と同じ要領で個別投稿ページで使用されるテンプレートを確認します。
- single.php
- tmp/single-contents.php
- tmp/content.php
single.php はヘッダフッタの作成部分で index.php で作成済みのため無視し、tmp/single-contents.php、tmp/content.php をコピペでひとまとめにし、適宜変更したテンプレートファイルを作ります。
変更箇所の概要は以下の通りです。
パンくずリストの強制表示
get_template_part('tmp/breadcrumbs-forced');
既存のパンくずリストテンプレートは、個別投稿やカテゴリページでのみの表示になっているため、現在のページに関わらず表示する tmp/breadcrumbs-forced テンプレートを作ることにしました。
ループ重複の削除
参考にした tmp/content.php の中で、if ( have_posts() ){ … } が行われていますが、tmp/list-index-content.php で既にこの処理を行っているので、重複しないように削除します。
不要コンテンツの削除
個別投稿ではコメントなどが表示されますが、フロントページでは不要と判断したので、それらをごっそり削っています。
カスタムスタイル、カスタムスクリプトの挿入
<?php // カスタムcss
$custom_css = get_post_meta(get_the_ID(), '_custom_css', true);
if ($custom_css) {
echo '<!-- '.THEME_NAME.' Custom CSS -->'.PHP_EOL;
echo '<style>' . $custom_css . '</style>'.PHP_EOL;
}
?>
<?php // カスタムjs
$custom_js = get_post_meta(get_the_ID(), '_custom_js', true) ;
if ($custom_js) {
echo '<!-- '.THEME_NAME.' Custom JS -->'.PHP_EOL;
echo '<script type="text/javascript">' . $custom_js . '</script>'.PHP_EOL;
}
?>
従来はヘッダ作成時に挿入されるカスタム css やカスタム js ですが、すでにヘッダは作成済みなので body タグ内に挿入しています。
ヘッダで読み込まれるスクリプトなどは、前述の通り固定ページ用のものなので、投稿ページ用のカスタム~系をここで挿入します。
個別投稿ページへのリンク
<a href="<?php echo esc_url(get_the_permalink()); ?>" class="entry-card-wrap a-wrap border-element cf" title="<?php echo esc_attr(get_the_title()); ?>">
個別投稿ページへのジャンプ方法として、記事ヘッダにリンクを貼りました。
強制パンくずリスト表示テンプレート
投稿ページパンくずリストテンプレート tmp/breadcrumbs.php を参考に、新規ファイル tmp/breadcrumbs-forced.php を作ります。
以下の場所にファイルを新規作成します。
変更箇所の概要は以下の通りです。
現在のページによる分岐削除
is_single() などの現在のページ分類による条件を削除します。
個別投稿ページへのリンク
echo '<div class="breadcrumb-item"><span class="fa fa-file-o fa-fw" aria-hidden="true"></span><a href="<?php echo esc_url(get_the_permalink()); ?>"><span class="breadcrumb-caption">'.esc_html(get_the_title()).'</span></a></div>';
ページタイトル部分に個別投稿ページへのリンクを追加しました。
最後に
メインクエリの上書きをせず、より自然な形で実装できたのはいいですが、functions.php の変更が配布には向かないのが困りものですね…
コメント