作成日:2021/04/12 更新日:2022/08/19
#6 Wordpressでサイトの下層ページを作る
下層ページの種類
TOPページは完成しました。続いては下層ページを作って見ましょう。下層ページとはTOPページと頂点として、それ以降にリンクされているページのことです。
下層ページは2つの種類あります。 固定ページ と 投稿ページ です。
| 固定ページ | 第2下層ページで、あまり変化のないLPや固定のページを作る際に使用します。 | 
| 投稿ページ | カテゴリーページとリンクしており、RSSなどの配信に対応できるので投稿日などの時間を使うコンテンツページなどに使用します。 | 
コーポレート・ブランドサイトのようなものは固定ページを主に使い、blog・アフィリエイトなど記事を集めたページは投稿ページを主に使うことになります。
固定ページの作成
固定ページはpage.phpという名前のテンプレートファイルを自動で読み込みますのでpage.phpファイルを作成しましょう。
<?php
/*
  Template Name: 固定ページ
*/
get_header();
?>
<div class="contents_wrap">
<main class="main">
  <?php if(have_posts()): while(have_posts()) : the_post(); ?>
    <h1><?php the_title();?></h1>
    <?php the_content(); ?>
  <?php endwhile; endif; ?>
</main>
</div>
<?php
get_footer();
wordpressなどのCMSで、if文などのphpの構文をhtmlテンプレート内で書きたいときは、phpのコードを分割して記述する書き方があります。
↓
以下はhave_posts()など、wordpressでつくられている独自関数の一部です。
wordpressの独自関数リファレンス
固定ページ用に新たなクラスを追加したので、下記のスタイルを、scss/style.scssに記述します。.footerの次ぐらいに書いておきましょう。
if(have_posts()){        /* もし投稿があれば */
  while(have_posts()){   /* 全部の記事データをループ */
    the_post();          /* ひとつの記事を表示 */
  }
}
↓
<body>
<main>
<?php if(have_posts()): while(have_posts()) : the_post(); ?> /*もしpostが存在すれば、あるだけ出力する*/
  なにか文字情報〜
<?php endwhile; endif; ?>
</main>
以下はhave_posts()など、wordpressでつくられている独自関数の一部です。
have_posts()    /*記事があればtrueを返す*/
the_post()      /*特定の投稿のいろんな情報を取得*/
the_title()     /*タイトルを表示*/
the_content()   /*コンテンツ表示*/
get_sidebar()   /*サイドバーを表示*/
wordpressの独自関数リファレンス
/* wp下層ページ追加分 */
.contents_wrap{
  width:95%;
  margin:70px auto 0;
  @include v.mq('min','lg'){
    width:1024px;
  }
  .main{
    padding:10px;
    font:normal 1.2em/2 sans-serif;
    h1{
      margin-bottom:20px;
      color:#666;
      font:bold 2em/2 sans-serif;
    }
  }
}

編集をクリックする
 右上の歯車をクリックすると、メニューが出ます。
右上の歯車をクリックすると、メニューが出ます。固定ページの属性という部分でpage.phpの上部にTemplate Name: 〜 で記述したテンプレート名が選べるようになっています。
Template Nameは指定しなくても、固定ページのテンプレートは自動でpost.phpがデフォルトテンプレートとして選ばれます。
固定ページのレイアウトが複数必要な場合などにファイル名、Template Nameで切り分けます。
このように下層ページでは、テンプレートを作成し、コンテンツ内容を管理画面内で登録していきます。

※テンプレートが適応されずこのように表示されない場合は、⌘+shiftキー+Rでスーパーリロードしてみましょう。
投稿ページの作成
投稿ページのテンプレートはsingle.phpという名前になります。
<?php
/*
 Template Name: 投稿ページ
 Template Post Type: post
*/
get_header();
?>
<div class="contents_wrap">
<main class="main">
  <?php if(have_posts()): while(have_posts()) : the_post(); ?>
    <h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
    <time datetime="<?php the_time('Y-m-d'); ?>"><?php the_time('Y.m.d'); ?></time>
    <span class="category"><?php the_category(', '); ?></span>
    <div class="content"><?php the_content(); ?></div>
  <?php endwhile; endif; ?>
</main>
</div>
<?php
get_footer();
Template Nameは指定しなくても、投稿ページのテンプレートは自動でsingle.phpがデフォルトテンプレートとして選ばれます。
the_permalink()     /*パーマリンクを表示*/
the_time('Y-m-d')   /*日時を表示*/
the_category(', ')  /*投稿のカテゴリーをコンマ区切りで表示*/
投稿ページ用に新たなクラスを追加したので、scss/style.scssに追記しましょう。
/* page.php作成時に追記した.main部分に以下を追記しましょう */
.main{
  padding:10px;
  font:normal 1.2em/2 sans-serif;
  /* 以下を追加 */
  @include v.mq('min','lg'){
    margin-right:50px;
  }
  time{
    font:normal 1.1em/2 serif;
  }
  .category{
    display:inline-block;
    padding:0px 20px;
    border: 1px solid #ccc;
  }
  .content{
    margin:20px 0;
  }
  /* ここまで追加 */
  h1{
    margin-bottom:20px;
    color:#666;
    font:bold 2em/2 sans-serif;
    /* 以下を追加 */
    a{
      color:#666;
      @include v.mq('max','lg'){
        font-size:0.7em;
      }
    }
    /* ここまで追加 */
  }
}

※テンプレートが適応されずこのように表示されない場合は、⌘+shiftキー+Rでスーパーリロードしてみましょう。
テンプレート読み込み順
TOPページ、固定ページ、投稿ページ、一覧(アーカイブ)ページ、その他ページのテンプレートはWordPressが読み込む順位が決まっており、優先順位の高いテンプレートを探し、 最初に存在したテンプレートで表示させます。| 優先順位 | TOPページ | 固定ページ | 投稿ページ | その他ページ | 
| ① | front-page.php | page-スラッグ名.php | single-ポストタイプ名.php | category.php search.php archive.php author.phpなど | 
| ② | home.php | page-ID.php | ||
| ③ | page.php | single.php | ||
| ④ | index.php | |||
※逆に固定も投稿も同じテンプレートで良ければ、index.phpのみ用意すればよいでしょう。
フロントページのテンプレートを変更する
index.phpをフロントページとして利用していましたが、front-page.phpに変更します。index.phpをコピーせずにfront-page.phpに名称変更しましょう。
ただ、最も優先順位が低いテンプレートとしてindex.phpも欲しいので、 先程作成したsingle.phpをコピーして、index.phpとリネームしておきます。作られたindex.phpのコメント部分は削除しておきましょう。

ここまでのファイル構成
#7 固定ページにNEWS投稿を読み込む
トップページ(固定ページ)に、あるカテゴリとして登録した投稿記事の最新記事を4つだけ表示する
手順としてはこのような感じです。
画像をダウンロード
   新規カテゴリーより「instagram」と追加し、記事に画像をアップロードします。
新規カテゴリーより「instagram」と追加し、記事に画像をアップロードします。
 

テキストに適当な文字を入れて、公開ボタンを押します。
例)インスタグラムにアップした写真の説明文なんかが入ってくるでしょう。
投稿一覧で見るとこの様になっています。
②は、固定ページfront-page.phpで使う「ショートコード」を設定する関数です。
$posts_arrayに全データが入ります。
後ほど使う$postをglobal設定しておきます。
setup_postdata($post)はグローバル変数$postを使うための設定です。なくても使えることもあるが便宜上入れます。
setup_postdata($post)の引数は必ず$postにします。 ですので、foreachの値の名称は必ず$postにするのがルールです。
また上記に記したとおり、$postは事前にグローバル変数設定しておきましょう。
get_posts関数で指定している「カテゴリーID」は3になっていますが、カテゴリを一度削除し作り直したりすると番号が新しく発行されます。


試しに4枚目の投稿をして挙動を確認してみましょう。
また、ショートコード [top_instagram] が直接画面に表示されている場合は以下のとこを確認してみましょう
   モジュール化した場合は手間がかかっているように思えますが、管理画面から投稿した記事をレイアウトに使えるために、
htmlの知識がなくてもwebサイトを更新できるメリットがあります。
モジュール化した場合は手間がかかっているように思えますが、管理画面から投稿した記事をレイアウトに使えるために、
htmlの知識がなくてもwebサイトを更新できるメリットがあります。
 
対応させたいテンプレートファイルの該当箇所に、上記のコードを入れてあげればOKです。
ここまでのファイル構成
手順としてはこのような感じです。
- 管理画面 > 投稿 から4つの記事を新規追加・公開
- 表示するための設定をfunctions.phpに記述
- 特定カテゴリだけを表示させるテンプレートの作成
- TOPページのfront-page.phpにテンプレートのショートコードを記述
管理画面 > 投稿から新規で4つの記事を登録公開
左ナビから投稿 > 新規追加をクリック。タイトルをInstagram01にし、画像を選択しアップロードします。 右ナビのカテゴリを開いて新規カテゴリを追加からInstagramを追加します。この方法で4つの記事を作成します。画像は適当に選びましょう。画像をダウンロード
 

テキストに適当な文字を入れて、公開ボタンを押します。
例)インスタグラムにアップした写真の説明文なんかが入ってくるでしょう。

投稿一覧で見るとこの様になっています。
functions.phpで表示の設定
固定ページに投稿ページの記事を読み込ませるため、functions.phpに設定が必要になります。
<?php
/**
 * CBC restaurant
 *
 */
...他の記述がある...
/**
 *
 * 固定ページに投稿ページの記事を読み込ませる
**/
/* ① */
function first_image() {
  global $post;  /* $postは投稿記事のオブジェクトデータ */
  $first_img = '';
  preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches);
  $first_img = $matches[1][0];
  if(empty($first_img)){
    $first_img = "/assets/img/default.jpg";
  }
  return $first_img;
}
/* ② */
function instagram_template_part() {
  get_template_part('instagram');
}
add_shortcode('top_instagram', 'instagram_template_part');
②は、固定ページfront-page.phpで使う「ショートコード」を設定する関数です。
① 後ほどテンプレートファイルで使用するための独自関数を設定しています。
正規表現によるマッチング
preg_match_all(パターン, 検索対象の文字列, 結果を入れる多次元配列変数)
$matches[1][0]で一番最初に出てくる画像のファイルパスを取得されているので、$first_imgに代入しています。
② TOPページにinstagramカテゴリの画像を表示する
ページ内にtop_instagramというショートコードがあれば、 独自関数のinstagram_template_part()関数を実行する。
function first_image() { }
global $post;     /* $postはグローバル宣言してfunction内でアクセスします */
$first_img = '';  /* 変数の初期化 */
preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches);
正規表現によるマッチング
preg_match_all(パターン, 検索対象の文字列, 結果を入れる多次元配列変数)
$matches[1][0]で一番最初に出てくる画像のファイルパスを取得されているので、$first_imgに代入しています。
if(empty($first_img)){
  $first_img = "/assets/img/images/default.jpg"; /* ←画像は時間があるときに設定してみましょう*/
}
② TOPページにinstagramカテゴリの画像を表示する
function instagram_template_part() {
  get_template_part('instagram');
}
add_shortcode('top_instagram', 'instagram_template_part');
ページ内にtop_instagramというショートコードがあれば、 独自関数のinstagram_template_part()関数を実行する。
Instagramカテゴリの記事だけを表示させるモジュールテンプレート作成
ページ表示用テンプレートと同じ考え方ですが、今回はページとしての利用ではなく、TOPページfront-page.phpへ埋め込むための、 モジュールテンプレートとして作成します。
<?php
/**
 * instagram表示モジュール
 * instagram.php
 */
$args = [
  'numberposts' => 4,
  'category'    => 3
];
$posts_array = get_posts($args);
global $post;
?>
<ul class="instagram__list">
  <?php if($posts_array): foreach( $posts_array as $post ): setup_postdata($post); ?>
    <li>
      <a href="<?php echo the_permalink(); ?>">
        <div class="instagram__list-img">
          <img src="<?php echo first_image(); ?>" alt="<?php the_title(); ?>">
          <?php the_excerpt(); ?>
        </div>
      </a>
    </li>
  <?php endforeach; wp_reset_postdata(); endif; ?> 
</ul>
$args = [
  'numberposts' => 4, /* 取得する記事数 */
  'category'    => 3  /* カテゴリID */
];
$posts_array = get_posts($args);
global $post;
$posts_arrayに全データが入ります。
後ほど使う$postをglobal設定しておきます。
<?php if($posts): foreach($posts as $post): setup_postdata($post); ?>
if($posts){
  foreach($posts as $post){
    setup_postdata($post);
    処理・・・
  }
}
setup_postdata($post)はグローバル変数$postを使うための設定です。なくても使えることもあるが便宜上入れます。
setup_postdata($post)の引数は必ず$postにします。 ですので、foreachの値の名称は必ず$postにするのがルールです。
また上記に記したとおり、$postは事前にグローバル変数設定しておきましょう。
<img src="<?php echo first_image(); ?>" alt="<?php the_title(); ?>">
get_posts関数で指定している「カテゴリーID」は3になっていますが、カテゴリを一度削除し作り直したりすると番号が新しく発行されます。

front-page.phpにショートコードを記述
front-page.php内に以下の内容がありますが、
<ul class="instagram__list">
  <li>
    <a href="<?php echo get_permalink(0); ?>">
      <div class="instagram__list-img">
        <img alt="" src="<?php echo get_template_directory_uri(); ?>/assets/img/news01.jpg">
      </div>
    </a>
  </li>
  ・
  ・
  ・
</ul>
<?php echo do_shortcode('[top_instagram]'); ?>
<section class="instagram">
  <h2 class="instagram__title">INSTAGRAM</h2>
    <?php echo do_shortcode('[top_instagram]'); ?>
  <div class="instagram__button">
    <a href="#">FOLLOW US</a>
  </div>
</section>
.instagram {
    ・
    ・
  &__list {
    ・
    ・
    ・
    &-img p{  /* 追加しておきましょう */
      padding-top:5px;
      font:normal 0.7em/1.3em sans-serif;
    }
  }
}

試しに4枚目の投稿をして挙動を確認してみましょう。
また、ショートコード [top_instagram] が直接画面に表示されている場合は以下のとこを確認してみましょう
- 各関数名を打ち間違えていないか
- functions.phpファイル名がfunction.phpと、最後のsがない
ファイル構成をまとめてみました
 
固定記事をモジュール用途で利用する
また、とある固定ページで作った一つの記事をモジュールとして使うことも可能です。
<div>
<?php $page_info = get_page_by_path('スラッグ名');
      $page = get_post($page_info); ?>  /* スラッグ名の記事を取得します */
    <h1><?= $page->post_title; ?></h1>  /* $page->post_title などで情報を表示させます */
    <?= $page->post_content; ?>
</div>
対応させたいテンプレートファイルの該当箇所に、上記のコードを入れてあげればOKです。

ここまでのファイル構成
 入門
入門 基礎
基礎 応用
応用 実践フロントエンド
実践フロントエンド 実践バックエンド
実践バックエンド デザイン
デザイン キッズ
キッズ