作成日:2021/04/12 更新日:2022/08/19

#8 便利なプラグインを使う

お問い合わせページにメールフォームを入れる

お問い合わせページに実装するメールフォームを「Contact form 7」というプラグインを使って実装してみましょう。
▼プラグインのインストール

管理画面のナビから「プラグイン」>「新規追加」と進み左上のキーワードに「Contact form 7」と入力します。

Contact form 7の右上の「今すぐインストール」をクリックし「有効化」を押せばインストール完了。

設定ボタンをクリック
▼プラグインの設定方法

編集ボタンをクリック
以下のように記載されています。

<label> お名前 (必須)
    [text* your-name] </label>
<label> メールアドレス (必須)
    [email* your-email] </label>
<label> 題名
    [text your-subject] </label>
<label> メッセージ本文
    [textarea your-message] </label>

[submit "送信"]
ショートコードをlabelタグで管理してあります。
text*とアスタリスクを入れると、入力必須項目になります。
ショートコードは、例えば

[contact-form-7 id="39" title="コンタクトフォーム 1"]
のような形です。
▼固定ページの設定方法

固定ページから「お問い合わせ」ページを作り、本文に先ほど作成されたショートコードを記述する。

固定ページ一覧 > お問い合わせ の表示リンクからお問い合わせページにアクセスすると、フォームが表示されます。

表示される文字を短くする (フックを学ぶ)

表示される文字を抜粋して、残りを「...」で表示してリンクさせる機能を実装します。
まず、WP Multibyte Patchというプラグインで日本語(マルチバイト)を扱えるようにします。
日本語などのマルチバイト環境でWordPressを構築する場合はこのプラグインを入れなくても動作する場合もありますが必ず入れておきましょう。

プラグイン > 新規追加よりWP Multibyte Patchを検索しインストールと有効化を行います。

文字を20文字に設定した場合このような表示になります
なにも設定せずに<?php the_excerpt(); ?>を使って記事本文を出力すると、110文字表示されその後[...]が表示されます。
WP Multibyte Patchの設定ファイルは/wp-content/plugins/wp-multibyte-patch.php'excerpt_mblength' => 110,という設定があり、この値を変更したいです。
しかし、本体 (コアファイル)やプラグインをアップデート(更新)した場合などに、設定が元に戻ってしまうため
直接本体やプラグインのファイルを変更せず、 functions.phpに記述します。
'excerpt_mblength'が使われるときに、functions.phpに設定している新たな条件関数で 上書きすることで本体やプラグインなどの機能をカスタマイズします。

/**
 *
 * 記事抜粋
**/
function my_custom_excerpt_mblength($length){
  return 20;
}
add_filter('excerpt_mblength','my_custom_excerpt_mblength');
functions.phpの最後の部分で良いので上記のコードを入れます。

▼説明
my_custom_excerpt_mblength()関数名は好きなものをつけましょう。
add_filter()はWordPressカスタマイズのときに必要な非常に重要な関数です。
add_filter('フック名', 'そのフックがあったときに使う関数');

という形で使います。
WP Multibyte Patchプラグインのexcerpt_mblength設定(フック)の 110文字を20文字と、値を変更する機能で上書きしています。

WordPressでは画面を表示するときに、このフックという機能を使ってレンダリングしていきます。 カスタマイズするときは自分の意図するタイミングのフック名を調べて、独自関数を作って上書きしていきます。
※フックについては後ほど詳しく説明します。

エラー対策:ページが表示されない場合

▼解説
WordPressには「パーマリンク設定」があります。
これは、実際にディレクトリやデータが存在しなくてもURLにアクセスできる機能です。リダイレクトと呼ばれる機能です。

今回は投稿名を設定してみましょう。
リダイレクトを設定するため、Apacheも設定変更を行います。
MAMP > conf > apache > httpd.conf

# LoadModule rewrite_module modules/mod_rewrite.so
↓ 
LoadModule rewrite_module modules/mod_rewrite.so


<Directory />
  Options Indexes FollowSymLinks
  AllowOverride None
  ↓
  AllowOverride All
</Directory>
① rewrite_module がコメントアウトされている場合は#を外して有効化。
② AllowOverride が Noneの場合、All(許可する)に変更する。

#9 カスタムフィールド機能を使う

管理画面の新規投稿ページにはタイトル本文という入力欄があり、そこに入力されたデータで構成されています。 投稿ページを表示すればその2つが表示されるという仕組みです。

<h1><?php the_title(); ?></h1>
<div class="content"><?php the_content(); ?></div>
the_title()というテンプレートタグ( の関数)でタイトルが表示されます。
the_content()というテンプレートタグで本文が表示されます。

テンプレートに表示設定してれば投稿日とカテゴリも表示されます

しかし、例えば料理ページの紹介ページというものがあり料理名と価格を入れたいなど、ページ内容によっては他の情報も追加したいときがあります。
もちろんhtmlタグで書けば済んでしまう話なのですが、CMSのメリットはhtmlの編集知識がなくても管理画面から入力した内容がテンプレートに沿って表示されるということなので、 このようなカスタムフィールド機能を使うメリットは十分にあります。

カスタムフィールドの設定

標準のカスタムフィールドはちょっと使いにくいため、基本的はプラグインを使うほうが良いでしょう。
一応、標準での設定方法を書いておきますが、実行しなくても良いです。
▼解説

右上のメニューをクリックして、最下部の設定ボタンをクリック

カスタムフィールドチェックボックスにチェックを入れ、有効化してリロードボタンをクリック

カスタムフィールドの作成


テンプレートに表示設定してれば投稿日とカテゴリも表示されます

一度登録すると他の投稿ページにも自動的に表示されるようになります。
管理画面からフィールドを追加するのは簡単でしたが、ページでフィールド内容を表示したい場合には投稿ページを表示させるテンプレートに、表示させる仕掛けを記述します。

テンプレートの設定


<div class="content"><?php the_content(); ?></div>
<div><?php the_meta(); ?></div>  ←追加
single.phpテンプレートに、テンプレートタグthe_meta()を入れると、以下のようにカスタムフィールドの内容が表示されます。

<ul class='post-meta'>
  <li><span class='post-meta-key'>メニュー:</span> パスタ</li>
  <li><span class='post-meta-key'>価格:</span> 980円</li>
</ul>
書き出されたhtmlはこのようになります。

カスタムフィールドを使いやすくする

標準の出力は使いにくいのでカスタマイズしていきましょう。
プラグインの導入
カスタムフィールドの表示をカスタマイズする際にはプラグインAdvanced Custom Fields(以下、ACF)を利用します。
Advanced Custom Fields設定

プラグインページからAdvanced Custom Fieldsを検索し、インストールボタンをクリックし、有効化しましょう。

左メニューにカスタムフィールドが現れますのでクリックし、新規追加をクリック


●フィールドグループにグループ名、フィールドラベルに名称を入力。(フィールド名は同じでよいです)
●フィールドタイプはテキストが標準ですが、画像やGogoleマップなど各種フォーマットを選択できます。
●位置のラベルにはフィールドを表示する投稿の種類を選べます。入れなければすべての投稿に出ます。
投稿ページ個別ページに移動します。

投稿ページ一覧から記事を確認すると、以前同様カスタムフィールドが入力されています。

テンプレートsingle.php変更
個別のフィールド情報が取得できるようになります。ACFの関数であるget_field()the_field()関数を使います。

<div class="content"><?php the_content(); ?></div>
<div><?php the_meta(); ?></div>

↓ /* 先程追加した上記のものを、以下のものに差し替えます */

<div class="content">
  <div><?php the_content(); ?></div>
  <div class="content__meta">
    <?php $flg = get_post_meta( get_the_ID() ); ?>
    <?php if(!empty($flg)): ?>

        
        <?php if(get_field('メニュー')): ?>
          <div class="content__meta-item">
            <h2>メニュー: </h2>
            <p><?php echo get_field('メニュー'); ?></p>
          </div>
        <?php endif; ?>

        
        <?php if(get_field('価格')): ?>
          <div class="content__meta-item">
            <h2>価格: </h2>
            <p><?php echo get_field('価格'); ?></p>
          </div>
        <?php endif; ?>

    <?php endif; ?>
  </div>
</div>
▼解説
<div class="content__meta">でラッピングします。後ほどscssも編集しましょう。

<?php $flg = get_post_meta( get_the_ID() ); ?>  /* ない場合 */
<?php $flg = get_post_meta( $post->ID ); ?>      /* テンプレート内で global $post がある場合 */

<?php if(!empty($flg)): ?>
  処理
<?php endif; ?>
引数のget_the_ID()、もしくは$post->IDで表示されている投稿ページのIDが取得できます。
テンプレートタグget_post_meta()で表示されているページのカスタムフィールドのデータを取得できます。 次に$flgに格納します。
次の行で、$flgの中身の有無を確認し、存在すれば以降の処理が実行されます。


<?php if(get_field('メニュー')): ?>
get_field('ラベル名')で、フィールドグループのラベル名を取得します。
例では「メニュー」と「価格」の2つのラベルがありますので、それぞれのラベル名に対するの取得を、if文で条件分岐しています。

<p><?php echo get_field('メニュー'); ?></p>
echoで値を出力しています。
cssを変更

.content{
  margin:20px 0;
  /* 以下を追加 */
  display:flex;
  > div{
    flex:1;
    padding:1em;
    border:1px solid #ccc;
  }
  &__meta{
    &-item{
      h2, p{
        display:inline-block;
      }
    }
  }
  /* ここまで追加 */
}

デザイン次第でいろんな可能性が広がりますね。

画像を登録するフィールドの追加

テキストが追加できたところで、画像も追加してみましょう。
一つのページで類似する他のメニューを3つ登録して表示させたいと思います。

フィールドグループに追加する


フィールドラベル(フィールド名)は類似画像1としました。好きな名前で結構です。
フィールドタイプは画像にします。
返り値のフォーマットは画像URLにします。
フィールドを追加ボタンをクリックして3つの画像フィールドを登録しましょう。


フィールドラベル名は類似画像1、類似画像2、類似画像3としました。

投稿一覧からInstagram01の記事の編集画面に画像を登録するスペースが追加されています。
画像を追加するボタンから、画像をどんどん追加しましょう。
画像をダウンロード

投稿テンプレートに追記

今回テンプレートに設定しているsingle.phpのカスタムフィールドを追記した箇所に、画像表示のテンプレートタグを追記します。

<div class="content__meta">
  <?php $flg = get_post_meta( get_the_ID() ); ?>
  <?php if(!empty($flg)): ?>

    <?php if(get_field('メニュー')): ?>
      <div class="content__meta-item">
        <h2>メニュー: </h2>
        <p><?php echo get_field('メニュー'); ?></p>
      </div>
    <?php endif; ?>
    <?php if(get_field('価格')): ?>
      <div class="content__meta-item">
        <h2>価格: </h2>
        <p><?php echo get_field('価格'); ?></p>
      </div>
    <?php endif; ?>

    <!-- カスタムフィールドで追加した画像×3こ -->
    <p>他のパスタはこちら</p>
    <?php if(get_field('類似画像1')): ?>
      <div class="content__meta-item">
        <p><img src="<?php the_field('類似画像1'); ?>"></p>
      </div>
    <?php endif; ?>
    <?php if(get_field('類似画像2')): ?>
      <div class="content__meta-item">
        <p><img src="<?php the_field('類似画像2'); ?>"></p>
      </div>
    <?php endif; ?>
    <?php if(get_field('類似画像3')): ?>
      <div class="content__meta-item">
        <p><img src="<?php the_field('類似画像3'); ?>"></p>
      </div>
    <?php endif; ?>

  <?php endif; ?>
</div>


<?php if(get_field('類似画像1')): ?>
  <div class="content__meta-item">
    <p><img src="<?php the_field('類似画像1'); ?>"></p>
  </div>
<?php endif; ?>
get_field('フィールド名')で画像データ*1が存在するかしないかを判断させます。ある場合はその下の行を実行します。
the_field('フィールド名')で画像のURLが取得できますのでaタグの属性タグsrcに入れます。get_fieldとの違いはechoが含まれているというだけで、取得できている値は同じです。

レイアウトを整えれば、管理画面から登録するだけできれいなページができますね
他の情報の表示
*1)フィールドグループの設定で、「返り値のフォーマット」を「画像オブジェクト」に設定していた場合には <?php var_dump(get_field('フィールド名')); ?>で配列データが確認できます。 altや幅情報などの画像情報が取得できるので、複雑なレイアウトをしたい場合はこちらを選択しましょう。
表示される内容

array(24) {
  ["ID"]=>
  int(30)
  ["id"]=>
  int(30)
  ["title"]=>
  string(2) "51"
  ["filename"]=>
  string(6) "51.jpg"
  ["filesize"]=>
  int(9255)
  ["url"]=>
  string(55) "http://localhost:8004/wp-content/uploads/2022/08/51.jpg"
  ["link"]=>
  string(59) "http://localhost:8004/2022/08/19/instagram04/attachment/51/"
  ["alt"]=>
  string(0) ""
  ["author"]=>
  string(1) "1"
  ["description"]=>
  string(0) ""
  ["caption"]=>
  string(0) ""
  ["name"]=>
  string(2) "51"
  ["status"]=>
  string(7) "inherit"
  ["uploaded_to"]=>
  int(17)
  ["date"]=>
  string(19) "2022-08-19 08:07:03"
  ["modified"]=>
  string(19) "2022-08-19 08:07:03"
  ["menu_order"]=>
  int(0)
  ["mime_type"]=>
  string(10) "image/jpeg"
  ["type"]=>
  string(5) "image"
  ["subtype"]=>
  string(4) "jpeg"
  ["icon"]=>
  string(58) "http://localhost:8004/wp-includes/images/media/default.png"
  ["width"]=>
  int(300)
  ["height"]=>
  int(180)
  ["sizes"]=>
  array(18) {
    ["thumbnail"]=>
    string(63) "http://localhost:8004/wp-content/uploads/2022/08/51-150x150.jpg"
    ["thumbnail-width"]=>
    int(150)
    ["thumbnail-height"]=>
    int(150)
    ["medium"]=>
    string(55) "http://localhost:8004/wp-content/uploads/2022/08/51.jpg"
    ["medium-width"]=>
    int(300)
    ["medium-height"]=>
    int(180)
    ["medium_large"]=>
    string(55) "http://localhost:8004/wp-content/uploads/2022/08/51.jpg"
    ["medium_large-width"]=>
    int(300)
    ["medium_large-height"]=>
    int(180)
    ["large"]=>
    string(55) "http://localhost:8004/wp-content/uploads/2022/08/51.jpg"
    ["large-width"]=>
    int(300)
    ["large-height"]=>
    int(180)
    ["1536x1536"]=>
    string(55) "http://localhost:8004/wp-content/uploads/2022/08/51.jpg"
    ["1536x1536-width"]=>
    int(300)
    ["1536x1536-height"]=>
    int(180)
    ["2048x2048"]=>
    string(55) "http://localhost:8004/wp-content/uploads/2022/08/51.jpg"
    ["2048x2048-width"]=>
    int(300)
    ["2048x2048-height"]=>
    int(180)
  }
}

#10 その他の便利なWordPressの機能

アイキャッチ画像を入れてみよう

twitterなどのSNSでURLを投稿すると、概要テキスト以外に画像が出てきて目を引きます。それがアイキャッチ画像です。
投稿記事にアイキャッチ画像を設定してしましょう。

/**
 *
 * アイキャッチ画像を有効にする。
**/
add_theme_support('post-thumbnails');
functions.phpに設定します。これだけです。

投稿記事に設定項目が増えていますので、画像を登録して更新してみましょう。

<?php if ( has_post_thumbnail()): ?>
  <?php the_post_thumbnail('thumbnail'); ?>
<?php endif; ?>
もし、記事ページで表示させたいときはthe_post_thumbnail()で表示されます。
引数はthumbnailの他にサイズ違いでmediumlargefullがあります。

$thumb_url = get_the_post_thumbnail( $post_id, 'thumbnail' );
echo esc_url($thumb_url);
値を変数に代入したいときはget_the_post_thumbnail_url()で取得したURLリンクは echoする際にesc_url()関数が用意されているので、エスケープ処理しておきましょう。

ウィジェットの設定

widgetウィジェットとは便利な小物・道具という意味です。
サイドバーを表示するときなどに、検索やカレンダー、カテゴリーなどの便利な機能を追加できます。また、管理画面から追加や削除が設定できるのでサイト運営が楽になります。

functions設定


/**
 *
 * ウィジェットの設定
**/
function sidebar_widget() {
  register_sidebar(
    array(
      'name'          => 'サイドバーウィジェット',
      'id'            => 'sidebar',  /*ウィジェットのエリア名*/
      'description'   => 'サイドバーに表示されます',
      'before_widget' => '
', 'after_widget' => '
', 'before_title' => '

', 'after_title' => '

' ) ); } add_action( 'widgets_init', 'sidebar_widget' );
ウィジェットを有効にするには、functions.phpに追記します。
add_action()で関数を呼び出します。

sidebar設定

表示したいテンプレートに以下のコードを入力します。よく使われるのはsidebar.phpでしょう。 sidebar.phpを新たに作り、次のコードを入力します。

<aside class="sidebar">
<?php if ( is_active_sidebar( 'sidebar' ) ) : ?>
  <?php dynamic_sidebar( 'sidebar' ); ?>
<?php endif; ?>
</aside>
dynamic_sidebar()の引数にはfunctions.phpのregister_sidebar()で設定したidの値を入れます。

表示テンプレート設定

sidebarを表示させたいテンプレートがsingle.phpだった場合


  <div><?php the_content(); ?></div>
  <div class="content__meta">
  
  </div>
  
  <?php get_sidebar(); ?>

新たに.main__blogクラスを作り、既存の.contentと 新たな.sidebarをflexラップして横並びにさせます。
.main__blog閉じタグの前にテンプレートタグget_sidebar()でsidebarテンプレートを読み込みます。

.main{
  .content{
    ・・・いろいろ
  }
  h1{
    ・・・いろいろ
  }
  /* ↓ 追加 */
  .sidebar{
    width:200px;
    padding:10px;
    border: 1px solid #cc5;
    ul{
      font-size:0.7em;
      li{
        margin:2px 0;
        border: 1px solid #cc5;
        .post-date{
          font-size:0.7em;
        }
      }
    }
  }
  /* ↑ ここまで */
}
scssも変更しましょう。 サンプルの.sidebarは適当に値を入れていますので、適宜デザインしてみましょう。

ウィジェットの設定


管理画面メニューの外観にウィジェットが表示されているので、クリックしてみましょう。


カテゴリーと最新の投稿を入れてみました。


段落を追加してタイトルを付けることも出来ます。


項目数を増減できます。

このようにサイドバーのウィジェットが表示されます。

カテゴリ一覧ページのテンプレート作成


スラッグ名はこちらにあります

テンプレート作成

カテゴリーのスラッグ名を使ってcategory-instagram.phpを作成します。

<?php
get_header();
?>

<!--category-instagram.php-->
<div class="contents_wrap">
<main class="main">
  <div class="main__blog">
  <div class="main__blog-area">
    <h1>INSTAGRAMカテゴリー</h1>

    <?php
      if(have_posts()): while(have_posts()) : the_post();
        $thumb_url = get_the_post_thumbnail_url($post->ID, 'medium');
        $thumb = '';
        if($thumb_url){
          $thumb = '<div><a href="'.esc_url(get_permalink()).'"><img src="'.esc_url($thumb_url).'" alt=""></a></div>';
        }
    ?>
      <div class="main__blog-title">
        <h2><?php the_title();?></h2>
        <time datetime="<?php the_time('c');?>"><?php the_time('Y.m.d');?></time>
      </div>
      <?php echo $thumb;?>
      <a href="<?php the_permalink();?>"><?php the_excerpt(); ?></a>
    <?php endwhile; endif; ?>

  </div>
  <?php get_sidebar(); ?>
  </div>
</main>
</div>

<?php
get_footer();
▼解説
サイドバーウィジェットを置きたいので.main__blog-areaでラッピングして親要素のflexで横並びにしました。

<?php
  if(have_posts()): while(have_posts()) : the_post();
    $thumb_url = get_the_post_thumbnail_url($post->ID, 'medium');
    $thumb = '';
    if($thumb_url){
      $thumb = '<div><a href="'.esc_url(get_permalink()).'"><img src="'.esc_url($thumb_url).'" alt=""></a></div>';
    }
?>

if(have_posts()): while(have_posts()) : the_post();
おなじみのこの部分で、記事があったらループさせます。

$thumb_url = get_the_post_thumbnail_url($post->ID, 'medium');
$thumb = '';
get_the_post_thumbnail_url() のテンプレートタグです。
get_the_post_thumbnail_url(ポストID, サイズ, 配列)で使います。
ループ中の記事IDは$post->IDで取得できます。サイズはmediumにしていますが、thumbnailにすると小さな画像になります。
サイズの種類は小さい順から、thumbnail、medium、large、fullです。
あとで使うために変数$thumbを空に設定しておきます。

if($thumb_url){
  $thumb = '<div><a href="'.esc_url(get_permalink()).'"><img src="'.esc_url($thumb_url).'" alt=""></a></div>';
}
IF文で投稿IDにサムネイル画像があれば処理を実行させます。
テンプレートタグget_permalink()で記事のURLが取得できます。

<?php echo $thumb;?>
<div>でラッピングしたhtmlタグを、前行で作った空の変数$thumbに入れ、テンプレートのループ内で出力します。

<?php the_time('c'); ?>
htmlのdatetime属性に入れる値は検索エンジン(ロボット)用のフォーマットです。

<a href="<?php the_permalink();?>"><?php the_excerpt(); ?></a>
the_permalink()はエスケープの必要はありません。the_excerpt()で文字制限した文章を出力します。

注意! echo時のエスケープについて

the_***を使った のテンプレートタグは、安全に文字列を出力(echo)するようエスケープ処理されていますが、 値を返しているだけのget_***を使ったテンプレートタグ(get_permalink()やget_the_title()など)は、 esc_html()esc_url()を使い、文字列をエスケープして出力(echo)しましょう。
esc_html()
htmlタグをエスケープします。<a href=" → &lt;a href=&quot;
esc_url()
URLをエスケープします。http://example.com/<script>alert('スクリプト')</script> → http://example.com/scriptalert(スクリプト)/script と出力されます。

scssの設定


.main{
  ・・・いろいろ
  &__blog{
    display:flex;
    &-area{
      width:70%;
    }
    &-title{
      display:flex;
      margin-top:40px;
      align-items:flex-end;
      time{
        padding:0 0 5px 5px;
        font:normal 0.7em/2 sans-serif;
      }
    }
  }
  h2{
    display:inline-block;
    font:bold 1.2em/2 sans-serif;
  }
  ・・・いろいろ
}
scssも適宜変えてみましょう。.main__blog.main__blog-area.main__blog-titleを追加しています。

http://localhost:8003/category/instagram/で、 このような表示になります。