カスタム投稿タイプでWordPressの更新管理を便利にする プラグイン不使用

仕事や趣味でWordPressを利用している場合には、毎回の記事更新時に必ず入力する項目があるかと思います。通販サイトであれば、「商品名」、「価格」、「商品の特徴」などといった項目です。記事本文中にテーブルなどを作成して、これらのレイアウトを整える方法もあるかもしれません。

でもそれって、かなり面倒ではありませんか?私は、毎度毎度同じ作業を繰り返すのがとてもストレスになるタイプの人間なので、なんとかしてこういった状況を改善したい派の人間です。

そんな時には、WordPressの「カスタム投稿タイプ」という機能を使えば、バッチリです!

スポンサーリンク

カスタム投稿タイプとは?

カスタム投稿タイプ?なんじゃらほい!!

という声が聞こえてまいりましたので、簡単に説明いたします。WordPressの「カスタム投稿タイプ」とは、自分だけの記事投稿テンプレートを追加する機能の事です。投稿を作成する上で毎回決まった入力項目がある場合には、このカスタム投稿タイプは大いに役に立ちます。

プラグインを使えば簡単に実現できてしまうのですが、可能な限りプラグインを使わない派の私は、「functions.php」をゴリゴリ改造してカスタム投稿タイプを作成していきます。

※「functions.php」を編集しますので、本番の環境でいきなり試すのではなく、必ずローカルやテストサイトにて確認をすることをオススメします。

カスタム投稿タイプが役に立つ具体的事例

私がすぐに思いつく事例は「通販サイト」での「商品登録」です。毎回必ず入力する、固定項目がいくつかあるためです。

  • 商品価格
  • 商品ジャンル
  • 商品画像
  • 商品の特徴
  • 特記事項

などなど、考えたらキリがないほどですね。それぞれの情報を打ち込む場所が準備されていて、上から順番に入力をしていく、とういう流れで記事作成ができたら効率がとても上がります。そして表示もきれいになされる。こんな仕組みがあったらとても便利ですよね!

WordPressのカスタム投稿機能があれば、実現ができます!

入力が必要な項目を洗い出す

前項と内容がかぶりますが、通販サイトを作るという前提で、入力すべき項目を考えてみましょう!また、入力方法についても同時に考えられれば、その後の作業が進めやすくなります。

商品の定価

通販サイトを見ると、売値だけでなく定価も併記し「お買い得である」ことを強調していますね。「オープン価格」なんていう商品も増えていますが、定価の案内があった方が親切であり、購買意欲も湧きまくりです。

入力方法は「テキスト」。PHPやJavascriptにて、「テキスト」から「数値」に変換する場面もあるかもしれません。

商品の売値

定価を黒い文字で、売値を赤い文字で表記をすれば、お得感が増し増しです。売値もテキストにて入力をするようにします。

商品のジャンル

ジャンル分けの方法は店舗ごとに様々なルールがあるかと思います。商品検索や関連商品表示の事を意識すれば、ジャンル分けの必要になってきます。

複数のジャンルに属する可能性があるかもしれませんので、入力方法は「チェックボックス」が適しているかと思います。

商品の画像

入力というか登録となりますね。商品の画像は買い手側からしてみれば、絶対に載せてほしいと思います。1枚だけでなく、色々な角度から撮影したものが数枚あると、よりテンションが上がりますよね。

10枚くらい画像が登録できれば、商品の良さをガンガンアピールできちゃいます!

表示レイアウトを考えよう

WordPressでは、カスタム投稿タイプを表示するための専用テンプレートを簡単に作ることができます。特に専用テンプレートを準備しない場合には、通常の投稿と同じテンプレートにてカスタム投稿タイプの記事が表示されます。

先ほどの入力項目、「定価」とか「売り値」とかをページ内のどこに、どんな風に表示をするのかを決めて、テンプレートを作るのです。

自在にレイアウトが可能なので、テンションが上がりまくりますね!きっと素晴らしいページになること間違いありません。

カスタム投稿タイプを登録する

では、早速具体的なコードを書いていきましょう。大丈夫、簡単です。今回の場合には、このようなコードになるかと思います。

functions.php
//カスタム投稿を登録
add_action( 'init', 'register_my_post_type' );
function register_my_post_type() {
  // 「shop」というカスタム投稿タイプを作成
  register_post_type(
    'shop',
    array(
      'labels' => array(  
        'name' => 'オンラインショップ',  //ダッシュボードでの表記
        'singular_name' => 'オンラインショップ'
    ),
    'public' => true,
    'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'custom-fields' ,'comments' ),
    'register_meta_box_cb' => 'add_meta_box_shop',  //記事作成画面関連の関数
    'menu_position' => 5,
    'has_archive' => true,
    'rewrite' => array(
      'slug' => $slug,
      'with_front' => false
    )
  ));
}

このコードをfunctions.phpに加えるだけで、カスタム投稿タイプが作成できてしまいます!!カスタム投稿タイプの作成って、こんなに簡単だったのかーーー!!と思えてしまいますね。

 wordpress カスタム投稿タイプ追加 プラグイン不使用

このように、「投稿」の下に「オンラインショップ」という項目が追加されました。

コメントのない項目については、別の機会に説明をしようかと思います。

記事作成ページをカスタマイズする

カスタム投稿タイプの作成(登録)と一対になっている作業が、このカスタム投稿タイプ記事の作成画面の編集です。先ほど考えた「定価」や「売り値」の入力欄を作成します。

カスタム投稿タイプの記事作成ページの編集の編集です。コードは以下です。

functions.php
// オンラインショップ専用メタボックス追加
function add_meta_box_shop($post){
  add_meta_box('meta_box_shop', '詳細項目', 'add_field_shop', 'shop', 'normal', 'high');
}

//エントリー情報アップフィールド
function add_field_shop($post, $box) {
  //既に値がある場合は値をフォームに反映して出力
  echo wp_nonce_field('salty_meta', 'my_meta_nonce');
  $uploaded_model = get_post_meta($post->ID, 'uploaded_model', true);
  $uploaded_price = get_post_meta($post->ID, 'uploaded_price', true);
  
  $uploaded_image1 = get_post_meta($post->ID, 'uploaded_image1', true);
  $uploaded_image2 = get_post_meta($post->ID, 'uploaded_image2', true);
  $uploaded_image3 = get_post_meta($post->ID, 'uploaded_image3', true);
  
  $uploaded_cart = get_post_meta($post->ID, 'uploaded_cart', true);
  
  echo '<div id="uploadedProductForm">
      <label for="uploaded_model">商品名</label>
      <input id="uploaded_model" type="text" size="10" name="uploaded_model" value="' . $uploaded_model . '" />';
      
      echo '</div>';
      
  echo '<div id="uploadedProductForm">
      <label for="uploaded_price">価格</label>
      <input id="uploaded_price" type="text" size="30" name="uploaded_price" value="' . $uploaded_price . '" />';
      
      echo '</div>';
      
  echo '<div id="uploadedImageView5"></div>';
      
  echo '<div id="uploadedProductForm">
        <label for="uploaded_image1">画像1</label>
        <input id="uploaded_image1" type="text" size="100" name="uploaded_image1" value="' . $uploaded_image1 . '" />
        <input id="uploaded_image_button1" type="button" value="画像設定" />
        </div>';
  
  echo '<div id="uploadedProductForm">
        <label for="uploaded_image2">画像2</label>
        <input id="uploaded_image2" type="text" size="100" name="uploaded_image2" value="' . $uploaded_image2 . '" />
        <input id="uploaded_image_button2" type="button" value="画像設定" />
        </div>';
  
  echo '<div id="uploadedProductForm">
        <label for="uploaded_image3">画像3</label>
        <input id="uploaded_image3" type="text" size="100" name="uploaded_image3" value="' . $uploaded_image3 . '" />
        <input id="uploaded_image_button3" type="button" value="画像設定" />
        </div>';
  
}

//更新
add_action('save_post', 'entry_meta_update');
function entry_meta_update($post_id){
  if(!wp_verify_nonce( $_POST['my_meta_nonce'], 'salty_meta'))
    return $post_id;

  if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) 
    return $post_id;

  if(
    'shop' == $_POST['post_type']
    ){
    if(!current_user_can('edit_post', $post_id))
      return $post_id;
  }else{
    return $post_id;
  }
  
  $uploaded_model = $_POST['uploaded_model'];
  if($uploaded_model == '') 
    delete_post_meta($post_id, 'uploaded_model');
  else
    update_post_meta($post_id, 'uploaded_model', $uploaded_model);
    
  
  $uploaded_price = $_POST['uploaded_price'];
  if($uploaded_price == '') 
    delete_post_meta($post_id, 'uploaded_price');
  else
    update_post_meta($post_id, 'uploaded_price', $uploaded_price);
    
  
  $uploaded_image1 = $_POST['uploaded_image1'];
  if($uploaded_image1 == '') 
    delete_post_meta($post_id, 'uploaded_image1');
  else
    update_post_meta($post_id, 'uploaded_image1', $uploaded_image1);
  
  $uploaded_image2 = $_POST['uploaded_image2'];
  if($uploaded_image2 == '') 
    delete_post_meta($post_id, 'uploaded_image2');
  else
    update_post_meta($post_id, 'uploaded_image2', $uploaded_image2);
  
  $uploaded_image3 = $_POST['uploaded_image3'];
  if($uploaded_image3 == '') 
    delete_post_meta($post_id, 'uploaded_image3');
  else
    update_post_meta($post_id, 'uploaded_image3', $uploaded_image3);
}

//画像アップロードボタン関連
add_action('admin_print_scripts', 'add_my_js');
add_action('admin_head' , 'add_my_css');
function add_my_js() {
  wp_enqueue_script('admin_print_styles', '/wp-content/themes/テーマ名/add_image.js');
}
function add_my_css() {
  echo "\n" . '<link type="text/css" rel="stylesheet" href="' . get_bloginfo('url') . '/wp-content/themes/テーマ名/add_image.css" />' . "\n";
}

商品画像の登録ボタンについての詳細は別記事といたします。ひとまず、このボタンを動かすためにはさらにadd_image.jsadd_image.cssが必要ですので、ファイル内のコードを記しておきます。この二つのファイルは使用しているテーマの最上階層に置いてください。

add_image.js
jQuery(document).ready(function() {
  var formfield;
  //メタボックス内のボタンからmedia_upload.phpを呼び出す
  
  jQuery('#uploaded_image_button1').click(function() {
    formfield = jQuery('#uploaded_image1').attr('name');
    tb_show('', 'media-upload.php?type=image&TB_iframe=true');
    
    window.original_send_to_editor = window.send_to_editor;
    //メディアアップローダーからきた変数htmlを各々へ挿入
    window.send_to_editor = function(html){
      //「"」を「'」に変換
      html = new String(html).replace(/\"/g, "'");
      if (formfield) {
        fileurl = jQuery(html).attr('src');
        jQuery('#uploaded_image1').val(fileurl);
        tb_remove();
        //挿入した画像プレビューさせるエリアへソースをいれる
        jQuery('#uploadedImageView5').html(html);
      } else {
        window.original_send_to_editor(html);
      }
    };
  
    return false;
  });
  
  jQuery('#uploaded_image_button2').click(function() {
    formfield = jQuery('#uploaded_image2').attr('name');
    tb_show('', 'media-upload.php?type=image&TB_iframe=true');
    
    window.original_send_to_editor = window.send_to_editor;
    //メディアアップローダーからきた変数htmlを各々へ挿入
    window.send_to_editor = function(html){
      //「"」を「'」に変換
      html = new String(html).replace(/\"/g, "'");
      if (formfield) {
        fileurl = jQuery(html).attr('src');
        jQuery('#uploaded_image2').val(fileurl);
        tb_remove();
        //挿入した画像プレビューさせるエリアへソースをいれる
        jQuery('#uploadedImageView5').html(html);
      } else {
        window.original_send_to_editor(html);
      }
    };
  
    return false;
  });
  
  jQuery('#uploaded_image_button3').click(function() {
    formfield = jQuery('#uploaded_image3').attr('name');
    tb_show('', 'media-upload.php?type=image&TB_iframe=true');
    
    window.original_send_to_editor = window.send_to_editor;
    //メディアアップローダーからきた変数htmlを各々へ挿入
    window.send_to_editor = function(html){
      //「"」を「'」に変換
      html = new String(html).replace(/\"/g, "'");
      if (formfield) {
        fileurl = jQuery(html).attr('src');
        jQuery('#uploaded_image3').val(fileurl);
        tb_remove();
        //挿入した画像プレビューさせるエリアへソースをいれる
        jQuery('#uploadedImageView5').html(html);
      } else {
        window.original_send_to_editor(html);
      }
    };
  
    return false;
  });
  
});

 

add_image.css
#uploadedImageView {
  border-top: 1px solid #DFDFDF;
  margin-top: 10px;
  padding-top: 10px;
  overflow: auto;
}
#uploadedImageView img {
  border: 1px solid #DFDFDF;
  padding: 5px;
}

wordpress カスタム投稿タイプ プラグイン不使用 投稿画面

すると、「オンラインショップ」の「新規追加」の画面にこのような入力欄が追加されます。コードが長くなりすぎるので、項目数を5つにまで減らしていますが、同様の書き方をすれば自由に増やせるので、安心してください。

これで商品情報を入力するのにとても効率的になりました。

カスタム投稿ページの表示テンプレートを作成

そして、このカスタム投稿タイプの記事を表示するテンプレートを作ります。作成するファイル名は「single-カスタム投稿タイプ名.php」です。今回の場合には「single-shop.php」ということになりますね。基本的には、現在使用中のテーマの個別記事表示テンプレート(多くの場合は「single.php」)をコピーし、「single-shop.php」と改名する方法がよいかと思います。

single-shop.php JavaScript部分
  <script>
    $(function() {

      $('.thumbnails img').each(function(i) {
        $(this).wrap('<a></a>');
        $(this).closest('a').attr('href', '#view' + i);
      });

      $('.viewer img').each(function(i) {
        $(this).attr('id', 'view' + i);
      });

      $('.thumbnails a').click(function(e) {
        e.preventDefault();
        $('.viewer img').removeAttr('class');
        $(this.hash).addClass('active');
        return false;
      });

      $('.thumbnails a:eq(0)').trigger('click');
    });
  </script>

 

single-shop.php コンテンツ表示部分
    <div id="container">

      <!-- 本体部分 -->
      <div id="body">
        
        <div class="viewer">
          <img src="<?php echo get_post_meta($post->ID , 'uploaded_image1' ,true); ?>" />
          <img src="<?php echo get_post_meta($post->ID , 'uploaded_image2' ,true); ?>" />
          <img src="<?php echo get_post_meta($post->ID , 'uploaded_image3' ,true); ?>" />
        </div><!-- /.viewer -->
      
        <div class="thumbnails">
          <div class="one-thumbnail"><img src="<?php echo get_post_meta($post->ID , 'uploaded_image1' ,true); ?>" width="95px" height="95px" /></div>
          <div class="one-thumbnail"><img src="<?php echo get_post_meta($post->ID , 'uploaded_image2' ,true); ?>" width="95px" height="95px" /></div>
          <div class="one-thumbnail"><img src="<?php echo get_post_meta($post->ID , 'uploaded_image3' ,true); ?>" width="95px" height="95px" /></div>
        </div><!-- /.thumbnails -->
        <div style="background-color: yellow; margin-top: 5px;">小さな画像をクリックすると、上部枠に表示されます。</div>
        <div class="left-contents">
          <h1><?php echo get_post_meta($post->ID , 'uploaded_model' ,true); ?></h1>
          
          <?php //記事本文の表示
          the_content( get_theme_text_read_more() ); //デフォルト:続きを読む?>
          
        </div><!-- /.left-contents -->
        <div class="right-contents">
          
          <div class="cart">
            <?php echo get_post_meta($post->ID , 'uploaded_price' ,true); ?>
          </div><!-- /.cart -->
        </div><!-- /.right-contents -->
      
      </div><!-- /#body -->
    </div><!-- /#container -->

 

style.css
#container {
  width: 1000px;
  margin-top: 0px;
  margin-right: auto;
  margin-bottom: 0px;
  margin-left: auto;
  padding-top: 5px;
  padding-bottom: 5px;
  overflow-x: hidden;
  overflow-y: hidden;
}

.viewer {
  width: 500px;
  height: 500px;
  margin-top: 0px;
  margin-right: auto;
  margin-bottom: 0px;
  margin-left: auto;
  position: relative;
}

.viewer img {
  display: block;
  height: auto;
  max-width: 100%;
  opacity: 0;
  position: absolute;
  top: 0;
  left: 0;
  transition: 0.5s;
  -webkit-visibility: hidden;
  visibility: hidden;
}

.viewer img.active {
  opacity: 1;
  -webkit-visibility: visible;
  visibility: visible;
  z-index: 100;
}


.thumbnails {
  width: 1000px;
  height: 95px;
  margin-top: 5px;
  margin-right: auto;
  margin-bottom: 0px;
  margin-left: auto;
  list-style: none;
  font-size: 0;
}

.one-thumbnail {
  background: #ccc;
  position: relative;
  overflow: hidden;
  width: 95px;
  height: 95px;
  margin-top: 0px;
  margin-right: 5px;
  margin-bottom: 0px;
  margin-left: 0;
  float: left;
}

.main img {
  display: block;
  height: auto;
  max-width: 100%;
  opacity: 0;
  position: absolute;
  top: 0;
  left: 0;
  transition: 0.5s;
  -webkit-visibility: hidden;
  visibility: hidden;
}

.main img.active {
  opacity: 1;
  -webkit-visibility: visible;
  visibility: visible;
  z-index: 100;
}

.left-contents {
  width: 700px;
  float: left;
  margin-top: 10px;
}

.left-contents h1 {
  background: #c2edff;
  margin-top: 0;
  padding: 0.5em;
}

.left-contents h2 {
  padding: 1em;
  border: 3px solid #cc3333;
  border-radius: 3em .7em 2em .7em/.7em 2em .7em 3em;
}

.right-contents {
  width: 280px;
  float: right;
  margin-top: 10px;
}

.cart {
  background-color: #ddd;
  padding: 3px;
}

 

少々コードが多いですね。でも、これでようやくカスタム投稿タイプで作成したページの表示が可能となりました!どのような表示となっているか見てみましょう!

wordpress カスタム投稿タイプ 表示テンプレート作成

見栄えの問題のため、画像を10個登録した時のページを貼り付けます。ついでにこのページにはショッピングカートまでついていますね。。。

画像の表示位置などを細かく指定できるので、とても便利です。アイデア次第でどんなページにも変身できますね!

カスタム投稿タイプの記事が表示されない場合(404エラー)

ほとんどの場合、パーマリンクの更新を行わないとカスタム投稿ページの記事は表示されません。パーマリンクの設定は変更しなくても大丈夫ですので、パーマリンク設定ページを開き「変更を保存」ボタンを押してパーマリンクの設定を更新してください。

まとめ

そんなわけで、今回の記事ではカスタム投稿タイプの作成と表示のしかたについて書き記しました。WordPress通常投稿の「カテゴリー」や「タグ」の機能だけでは管理しきれない記事については、カスタム投稿タイプを使えば、とても便利になることがおわかりいただけたかと思います。

表示に使用しているJavaScriptなどは別の記事で詳細を書く予定です。予定は未定という可能性もありますので、その点はご了承ください。では!

コメント