WordPressのカスタム投稿(ポスト)タイプを作成するまでの手順リスト

Ads

Warning: Undefined array key "HTTP_USER_AGENT" in /home/youhei0828/kachibito.net/public_html/wp-content/themes/kachibito7_with_cocoon_child/functions-module/other/tiny-fixed.php on line 75

捜し物をしている最中に、ちょっと気になったのでテスト的に記事にしてみます。WordPressに新たに追加されたカスタム投稿タイプですが、多少なりにカスタマイズ経験が無いとハードルも低くはない印象なので手っ取り早く作成出来る用にリスト化します。

便利なのにさほど深く浸透していない印象のカスタム投稿タイプ(カスタムポストタイプ)やカスタムタクソノミー(タグに親子関係を持たせる的な機能)とかいろいろと不可解なキーワードで混乱してる方も多いような気がします。

個人的には理解の前にとりあえず触ってみるのもひとつの手だと思いますので、まずは気軽に追加してみてからどういったものか調べればいいかなと。(賛否両論あるでしょうけど僕はとりあえず触って失敗して学びたい人なので

カスタム投稿タイプってなんだろう


カスタム投稿タイプとは、WordPressにデフォルトである「投稿」という機能とは別の「投稿」機能を加える、というもの。上記のように、元々ある「投稿」とは別に「ワンコ動画」という項目の投稿コンテンツが出来ています。最高ですよね、ワンコ動画。もうこの時点でテンション上がります。「ワンコ動画を書く」って日本語おかしいのに気にならないくらい。

「投稿」をもう一つ作る、みたいな感じ

普通は「カテゴリ」で記事を分けていましたが、「投稿」という機能を丸ごと分けることで、本来ブログエンジンであるWordPressを、よりCMSに近い状態にすることが出来ます。

「いや、やはり先にちゃんと理解しておきたい」という方は以下のエントリをご参照下さい。ただし、現在WPはVer.3.1であることにご注意です。

  1. カスタム投稿タイプ(Custom Post Type)の導入と使い方 [WordPress 3.0]
  2. WPをカスタマイズするなら絶対覚えておきたい条件分岐やカスタム投稿タイプなどいろいろ
  3. 何となく分かった!「カスタム投稿タイプ」の表示方法や条件分岐など

そういうわけで、この記事がカスタム投稿タイプを始める切欠になることを祈りつつ、また、カスタム投稿タイプに興味はあるけどどこみても良く解らんという方向けに、とりあえずよく理解できてなくても追加できるように手順をリスト化します。

手順リスト

プラグインを使わずに行う手順です。WP3.1以上。

  1. 新たに作りたい投稿カテゴリを考える(例えば動画、本など)
  2. 使用中のテーマのfunctions.phpにコード追加※後述
  3. 管理画面左メニューのどの部分に入れるか決める※後述
  4. 作成したカスタム投稿タイプ用のsingle.php等を作成
  5. パーマリンク設定を空更新する
  6. テスト投稿して表示されれば完成

たったの数ステップで使えるようになります。難しそうで実は簡単なんですけど、いろいろとややこしいので説明が難しくなりがちなため、どうしても難しく感じてしまいますね。

1の「作りたい投稿カテゴリ」は決まっていることを前提に、以下に部分的な詳細を必要最低限書いておきます。

2.使用中のテーマのfunctions.phpにコード追加

上記リストの2が肝になるので、公式サイトにあるテストコード(register post type)を使ってテンプレ化しました。

この例の場合、投稿タイプは「dogs」としています。※今はあまり気にしないでください

これをfunctions.phpに追記すれば一応管理画面への投稿タイプの追加はOKです。分かりやすくする為に、ややしつこい感じにしてあります。

add_action('init', 'my_custom_init');
function my_custom_init() 
{
  $labels = array(
    'name' => _x('ワンコ動画', 'post type general name'),
    'singular_name' => _x('犬の動画', 'post type singular name'),
    'add_new' => _x('新しく記事を書く', 'dogs'),
    'add_new_item' => __('ワンコ動画記事を書く'),
    'edit_item' => __('ワンコ記事を編集'),
    'new_item' => __('新しいワンコ記事'),
    'view_item' => __('ワンコ記事を見る'),
    'search_items' => __('ワンコ記事を探す'),
    'not_found' =>  __('ワンコ記事はありません'),
    'not_found_in_trash' => __('ゴミ箱にワンコ記事はありません'), 
    'parent_item_colon' => ''
  );
  $args = array(
    'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'query_var' => true,
    'rewrite' => true,
    'capability_type' => 'post',
    'hierarchical' => false,
    'menu_position' => 5,
    'supports' => array('title','editor','thumbnail','custom-fields','excerpt','author','trackbacks','comments','revisions','page-attributes'),
    'has_archive' => true
  ); 
  register_post_type('dogs',$args);
}

//投稿時のメッセージとか
add_filter('post_updated_messages', 'book_updated_messages');
function book_updated_messages( $messages ) {

  $messages['dogs'] = array(
    0 => '', // ここは使用しません
    1 => sprintf( __('ワンコ動画を更新しました <a href="%s">記事を見る</a>'), esc_url( get_permalink($post_ID) ) ),
    2 => __('カスタムフィールドを更新しました'),
    3 => __('カスタムフィールドを削除しました'),
    4 => __('ワンコ動画更新'),
    5 => isset($_GET['revision']) ? sprintf( __(' %s 前にワンコ動画を保存しました'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
    6 => sprintf( __('ワンコ動画が公開されました <a href="%s">記事を見る</a>'), esc_url( get_permalink($post_ID) ) ),
    7 => __('ワンコ動画記事を保存'),
    8 => sprintf( __('ワンコ動画記事を送信 <a target="_blank" href="%s">プレビュー</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
    9 => sprintf( __('ワンコ動画を予約投稿しました: <strong>%1$s</strong>. <a target="_blank" href="%2$s">プレビュー</a>'),
      date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
    10 => sprintf( __('ワンコ動画の下書きを更新しました <a target="_blank" href="%s">プレビュー</a>'), esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
  );

  return $messages;
}

//追加したカスタム投稿タイプの投稿ページ上部にあるプルダウンするヘルプ内テキスト
add_action( 'contextual_help', 'add_help_text', 10, 3 );

function add_help_text($contextual_help, $screen_id, $screen) { 

  if ('dogs' == $screen->id ) {
    $contextual_help =
      '<p>' . __('ワンコ動画がなぜ最高なのかを以下に解説します') . '</p>' .
      '<ul>' .
      '<li>' . __('擬似的にモフモフ出来る') . '</li>' .
      '<li>' . __('とにかく可愛い') . '</li>' .
      '</ul>' .
      '<p>' . __('もし貴方がワンコ動画で満足できないならぬこ様動画も試すべきです:') . '</p>' .
      '<ul>' .
      '<li>' . __('擬似的にもふもふ出来r') . '</li>' .
      '<li>' . __('お腹すいた。') . '</li>' .
      '</ul>' .
      '<p><strong>' . __('解決しないときは:') . '</strong></p>' .
      '<p>' . __('<a href="http://codex.wordpress.org/Posts_Edit_SubPanel" target="_blank">ドキュメント</a>') . '</p>' .
      '<p>' . __('<a href="http://wordpress.org/support/" target="_blank">フォーラム</a>') . '</p>' ;
  } elseif ( 'edit-book' == $screen->id ) {
    $contextual_help = 
      '<p>' . __('カスタム投稿タイプむずいようで簡単ですね。でも僕にはむずいです。') . '</p>' ;
  }
  return $contextual_help;
}

ワンコがウンkに見えてきますね。上記のコードをfunctions.phpにコピペしてアップロードすれば管理画面メニューにカスタム投稿タイプが加わります。
[note]※公式サイトには有りませんでしたが、WP3.1からアーカイブを作成出来るようになりました。’has_archive’ はその為の項目です。[/note]


ご覧のように、いろいろ自由に設定できます。

3.管理画面左メニューのどの部分に入れるか決める

さて、追加したカスタム投稿タイプですが、管理画面メニューの場所を選べます。割と大事ですので、用途に合わせてお決め下さい。先程のコードの26行目、 ‘menu_position’ => 5,というのが場所の指定です。

5 投稿の下
10 メディアの下
15 リンクの下
20 固定ページの下
25 コメントの下
60 外観の下
65 プラグインの下
70 ユーザーの下
75 ツールの下
80 設定の下
100 最下部に独立させる

4.作成したカスタム投稿タイプ用のsingle-***.php等を作成

さて、カスタム投稿タイプを作ったはいいけど、どこに表示させるの、という話なんですが、基本的には既存のsingle.phpが使われますので、無きゃないでいいんですけど、折角分けたので専用のを作ってみます。

先ほど、「投稿タイプは「dogs」としています」と書きました。この投稿タイプに合わせたsingle.phpを作ります。

single-dogs.php

ファイル名を上記のようにsingle-投稿タイプ名.phpとすればそのファイルを優先して読み込んでくれます。で、このファイルをカスタマイズすれば、通常の記事とは別のコンテンツを自由に作れますよ、というのがカスタム投稿タイプのメリットです。

※アーカイブ用のファイル

アーカイブ用のファイルも同様に作れます。

archive-dogs.php

このファイルを使うには、2で前述したように、‘has_archive’がtrueである必要があります。

5.パーマリンク設定を空更新する

既にパーマリンクを設定している場合、2でコードを追加したfunctions.phpと、新たに作成したsingle-dogs.phpをアップロードしたら、管理画面でパーマリンクの設定を空更新(設定を変えずに保存)してください。変えたければ変更して保存します。

空更新することで、wp_optionsテーブル内のrewrite_rulesが更新されて閲覧できるようになる、ということだと思います。これをしないとページが見つかりませんって言われますので注意が必要です。でも、どの環境でも必要なものかは僕にはちょっと分かりません。(多分必要

6.テスト投稿して表示されれば完成


かわいい動画の記事が出来ました。ここまでが基本の手順です。簡単なのでぜひチャレンジしてみてください。

まとめ

  1. コードをfunctions.phpにコピペしてアップロード
  2. 投稿タイプ用のsingleファイルとかarchiveファイルを作ってアップロード
  3. パーマリンクを更新
  4. テスト投稿して表示確認
  5. Done

長い記事になりましたけど、やることは上記の手順だけです。基本4ステップで導入出来ますね。

削ってもOK

2で書いた長いコード。あれは機能が要らなければ省略できます。

function my_custom_init() {
    register_post_type( 'dogs', array(
        'label' => 'ワンコ動画',
        'public' => true,
        'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'custom-fields' ,'comments' ),
        'menu_position' => 5,
        'has_archive' => true
    ));
}
add_action( 'init', 'my_custom_init' );

別にこんな短いコードでもカスタム投稿タイプの追加は可能です。好みで削ってあげてください。

さらに1歩進んだ使い方

カスタム投稿タイプ関連の記事等も出てきていますのでリンク集的にご紹介しますね。

  1. リファレンス / 公式のカスタム投稿タイプリファレンス
  2. WPのカスタム投稿タイプでイベント情報ページを作ってみる / かなり実践的です
  3. カスタム投稿タイプのアーカイブをパーマリンクで表示できるようにしてみた / パラメータの付くURLを美しく
  4. WPでサイト設計をする時に覚えておきたいポストタイプの特徴など / 実践前に知っておくと良
  5. カスタム投稿タイプを、実案件を想定して実践してみる / ありがちな案件を想定したコード
  6. カスタム投稿タイプの RSS を配信する方法 / パスは/feed/?post_type=投稿タイプ名
  7. URLに’.html’を付ける / 末尾に.htmlを付けるプラグイン
  8. 公式フォーラム / 公式フォーラムでの検索結果です
  9. WordPress 3.1 カスタム投稿タイプで CMS機能が充実 / 複数追加された基本的且つ実践的Tips

いろいろ有難いTipsです。

尚、合わせて使うと便利なカスタムタクソノミーはまた別の機会があれば記事にします。(有るか分かりません

ちょっと雑感

あんまり自分の考えを書くことは少ないんですが折角なので。カスタム投稿タイプ(カスタムタクソノミーもですけど)は凄く便利ですし、本来ブログエンジンであるWordPressが脱ブログをし、CMSとして使うには必須の機能です。実際、カスタム投稿タイプで、WPのCMS化が非常に楽になりました。

しかし、本来CMSとはこういった機能も楽に追加できるシステムであることを目指しているはずです。そういう意味で、functions.phpにコードを書いたり、プラグインに頼らないと作成出来ない、というようではまだまだ実用段階では無い気がします。ネーミングもどういう機能なのかピンと来ない=分かりにくいですし、ページングの不具合等もまだ聞きます。もちろん、ブログエンジンに拘るのであればこのままで十分でしょうけど・・

WordPressがブログエンジンに留まらず、更に飛躍するためにもCMS化を簡略化出来るカスタム投稿タイプは将来的にWordPressに必要不可欠な機能となるはずです。いずれ、直感的操作でカスタム投稿タイプを追加出来るように進化できることを期待しつつ、メモ的にここに残しておきます。

version 3.0.83 (Wed, 16 Apr 2014 03:56:09 GMT)
http://alexgorbatchev.com/SyntaxHighlighter
JavaScript code syntax highlighter.
Copyright 2004-2013 Alex Gorbatchev.
If you like this script, please donate to
keep development active!

'}},vars:{discoveredBrushes:null,highlighters:{}},brushes:{},regexLib:{multiLineCComments:XRegExp("/\\*.*?\\*/","gs"),singleLineCComments:/\/\/.*$/gm,singleLinePerlComments:/#.*$/gm,doubleQuotedString:/"([^\\"\n]|\\.)*"/g,singleQuotedString:/'([^\\'\n]|\\.)*'/g,multiLineDoubleQuotedString:XRegExp('"([^\\\\"]|\\\\.)*"',"gs"),multiLineSingleQuotedString:XRegExp("'([^\\\\']|\\\\.)*'","gs"),xmlComments:XRegExp("(<|<)!--.*?--(>|>)","gs"),url:/https?:\/\/[\w-.\/?%&=:@;#]*/g,phpScriptTags:{left:/(<|<)\?(?:=|php)?/g,right:/\?(>|>)/g,eof:!0},aspScriptTags:{left:/(<|<)%=?/g,right:/%(>|>)/g},scriptScriptTags:{left:/(<|<)\s*script.*?(>|>)/gi,right:/(<|<)\/\s*script\s*(>|>)/gi}},toolbar:{getHtml:function(e){function t(e,t){return B.toolbar.getButtonHtml(e,t,B.config.strings[t])}for(var n='

',r=B.toolbar.items,i=r.list,a=0,l=i.length;l>a;a++)n+=(r[i[a]].getHtml||t)(e,i[a]);return n+="

"},getButtonHtml:function(t,n,r){return n=e(n),''+e(r)+""},handler:function(e){function t(e){var t=RegExp(e+"_(\\w+)"),n=t.exec(r);return n?n[1]:null}var n=e.target,r=n.className||"",i=s(g(n,".syntaxhighlighter").id),a=t("command");i&&a&&B.toolbar.items[a].execute(i),e.preventDefault()},items:{list:["expandSource","help"],expandSource:{getHtml:function(e){if(1!=e.getParam("collapse"))return"";var t=e.getParam("title");return B.toolbar.getButtonHtml(e,"expandSource",t?t:B.config.strings.expandSource)},execute:function(e){var t=o(e.id);r(t,"collapsed")}},help:{execute:function(){var e=x("","_blank",500,250,"scrollbars=0"),t=e.document;t.write(B.config.strings.aboutDialog),t.close(),e.focus()}}}},findElements:function(e,t){var n=t?[t]:i(document.getElementsByTagName(B.config.tagName)),r=B.config,a=[];if(r.useScriptTags&&(n=n.concat(A())),0===n.length)return a;for(var l=0,s=n.length;s>l;l++){var o={target:n[l],params:p(e,E(n[l].className))};null!=o.params.brush&&a.push(o)}return a},highlight:function(e,t){var n=this.findElements(e,t),r="innerHTML",i=null,a=B.config;if(0!==n.length)for(var l=0,s=n.length;s>l;l++){var o,t=n[l],u=t.target,c=t.params,g=c.brush;if(null!=g){if("true"==c["html-script"]||1==B.defaults["html-script"])i=new B.HtmlScript(g),g="htmlscript";else{var h=b(g);if(!h)continue;i=new h}o=u[r],a.useScriptTags&&(o=M(o)),""!=(u.title||"")&&(c.title=u.title),c.brush=g,i.init(c),t=i.getDiv(o),""!=(u.id||"")&&(t.id=u.id),u.parentNode.replaceChild(t,u)}}},all:function(e){m(window,"load",function(){B.highlight(e)})}};return B.Match=function(e,t,n){this.value=e,this.index=t,this.length=e.length,this.css=n,this.brushName=null},B.Match.prototype.toString=function(){return this.value},B.HtmlScript=function(e){function t(e,t){for(var n=0,r=e.length;r>n;n++)e[n].index+=t}function n(e){for(var n,a=e.code,l=[],s=r.regexList,o=e.index+e.left.length,u=r.htmlScript,c=0,g=s.length;g>c;c++)n=L(a,s[c]),t(n,o),l=l.concat(n);null!=u.left&&null!=e.left&&(n=L(e.left,u.left),t(n,e.index),l=l.concat(n)),null!=u.right&&null!=e.right&&(n=L(e.right,u.right),t(n,e.index+e[0].lastIndexOf(e.right)),l=l.concat(n));for(var h=0,g=l.length;g>h;h++)l[h].brushName=i.brushName;return l}var r,i=b(e),a=new B.brushes.Xml,l=this,s="getDiv getHtml init".split(" ");if(null!=i){r=new i;for(var o=0,u=s.length;u>o;o++)(function(){var e=s[o];l[e]=function(){return a[e].apply(a,arguments)}})();return null==r.htmlScript?(v(B.config.strings.brushNotHtmlScript+e),void 0):(a.regexList.push({regex:r.htmlScript.code,func:n}),void 0)}},B.Highlighter=function(){},B.Highlighter.prototype={getParam:function(e,t){var n=this.params[e];return d(null==n?t:n)},create:function(e){return document.createElement(e)},findMatches:function(e,t){var n=[];if(null!=e)for(var r=0,i=e.length;i>r;r++)"object"==typeof e[r]&&(n=n.concat(L(t,e[r])));return this.removeNestedMatches(n.sort(k))},removeNestedMatches:function(e){for(var t=0,n=e.length;n>t;t++)if(null!==e[t])for(var r=e[t],i=r.index+r.length,a=t+1,n=e.length;n>a&&null!==e[t];a++){var l=e[a];if(null!==l){if(l.index>i)break;l.index==r.index&&l.length>r.length?e[t]=null:l.index>=r.index&&i>l.index&&(e[a]=null)}}return e},figureOutLineNumbers:function(e){var t=[],n=parseInt(this.getParam("first-line"));return y(e,function(e,r){t.push(r+n)}),t},isLineHighlighted:function(e){var t=this.getParam("highlight",[]);return"object"!=typeof t&&null==t.push&&(t=[t]),-1!=h(t,""+e)},getLineHtml:function(e,t,n){var r=["line","number"+t,"index"+e,"alt"+(""+(0==t%2?1:2))];return this.isLineHighlighted(t)&&r.push("highlighted"),0==t&&r.push("break"),'

'+n+"

"},getLineNumbersHtml:function(e,t){var n="",r=a(e).length,i=parseInt(this.getParam("first-line")),l=this.getParam("pad-line-numbers");1==l?l=(""+(i+r-1)).length:1==isNaN(l)&&(l=0);for(var s=0;r>s;s++){var o=t?t[s]:i+s,e=0==o?B.config.space:S(o,l);n+=this.getLineHtml(s,o,e)}return n},getCodeLinesHtml:function(e,t){e=C(e);for(var n=a(e),r=(this.getParam("pad-line-numbers"),parseInt(this.getParam("first-line"))),e="",i=this.getParam("brush"),l=0,s=n.length;s>l;l++){var o=n[l],u=/^( |\s)+/.exec(o),c=null,g=t?t[l]:r+l;null!=u&&(c=""+u[0],o=o.substr(c.length),c=c.replace(" ",B.config.space)),o=C(o),0==o.length&&(o=B.config.space),e+=this.getLineHtml(l,g,(null!=c?''+c+"":"")+o)}return e},getTitleHtml:function(t){return t?"

"+e(t)+"

":""},getMatchesHtml:function(e,t){function n(e){var t=e?e.brushName||a:a;return t?t+" ":""}for(var r=0,i="",a=this.getParam("brush",""),l=0,s=t.length;s>l;l++){var o,u=t[l];null!==u&&0!==u.length&&(o=n(u),i+=N(e.substr(r,u.index-r),o+"plain")+N(u.value,o+u.css),r=u.index+u.length+(u.offset||0))}return i+=N(e.substr(r),n()+"plain")},getHtml:function(t){var n,r,i,a="",s=["syntaxhighlighter"];return 1==this.getParam("light")&&(this.params.toolbar=this.params.gutter=!1),className="syntaxhighlighter",1==this.getParam("collapse")&&s.push("collapsed"),0==(gutter=this.getParam("gutter"))&&s.push("nogutter"),s.push(this.getParam("class-name")),s.push(this.getParam("brush")),t=w(t).replace(/\r/g," "),n=this.getParam("tab-size"),t=1==this.getParam("smart-tabs")?R(t,n):H(t,n),this.getParam("unindent")&&(t=P(t)),gutter&&(i=this.figureOutLineNumbers(t)),r=this.findMatches(this.regexList,t),a=this.getMatchesHtml(t,r),a=this.getCodeLinesHtml(a,i),this.getParam("auto-links")&&(a=I(a)),"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.match(/MSIE/)&&s.push("ie"),a='

'+(this.getParam("toolbar")?B.toolbar.getHtml(this):"")+''+this.getTitleHtml(this.getParam("title"))+""+""+(gutter?'":"")+'"+""+""+"
'+this.getLineNumbersHtml(t)+"'+'
'+a+"
"+"
"+"

"},getDiv:function(e){null===e&&(e=""),this.code=e;var t=this.create("div");return t.innerHTML=this.getHtml(e),this.getParam("toolbar")&&m(c(t,".toolbar"),"click",B.toolbar.handler),this.getParam("quick-code")&&m(c(t,".code"),"dblclick",X),t},init:function(e){this.id=f(),u(this),this.params=p(B.defaults,e||{}),1==this.getParam("light")&&(this.params.toolbar=this.params.gutter=!1)},getKeywords:function(e){return e=e.replace(/^\s+|\s+$/g,"").replace(/\s+/g,"|"),"\\b(?:"+e+")\\b"},forHtmlScript:function(e){var t={end:e.right.source};e.eof&&(t.end="(?:(?:"+t.end+")|$)"),this.htmlScript={left:{regex:e.left,css:"script"},right:{regex:e.right,css:"script"},code:XRegExp("(?"+e.left.source+")"+"(?.*?)"+"(?"+t.end+")","sgi")}}},B}();"undefined"!=typeof exports?exports.SyntaxHighlighter=SyntaxHighlighter:null