WordPressのナビゲーションメニューで非公開の記事を自動的に非表示にする方法

WordPressのナビゲーションメニューは、管理画面上からドラッグ&ドロップで設定できて便利なのですが、非公開設定となっている投稿や固定ページなどが含まれている場合でも、表示の調整は行ってくれず全てが表示されてしまいます。このため、閲覧権限がないユーザーが非公開記事のメニューをクリックした場合「リンク切れか?」と思われてしまうことになります。

これでは、ユーザーエクスペリエンスもだだ下がりになってしまうので、メニューの記事が非公開の場合、自動的に表示されないようにしてみましょう。

“WordPressのナビゲーションメニューで非公開の記事を自動的に非表示にする方法” の続きを読む

WordCamp Tokyo アンケート集計サイトの舞台裏

@rie05 さんからのバトンを受けて、WordPress Advent Calendar 2011 の4番バッターを担当させていただきます。
Advent Calendarとはなんぞや??と思われる方もいらっしゃるかと思いますが、それは、先のお三方が十二分に説明いただいているので、さっくりと割愛。

たいさん、みやさん、りえさんと、ハードルを上げまくってくれたので、後の方を思ってここら辺で下げる役割をば。。。
私の紹介する内容ですが、WordCamp Tokyo 2011 のアンケート集計を担当させていただいているので、技術的内容含めて、その舞台裏など紹介してみたいと思います。

WordCamp Tokyo 2011は、11/27に800名を超える参加者を開催されましたが、アンケートを集計する役目に手を挙げてしまっていたので、私の WordCamp はまだ終わらない!
受付スタッフに集めて頂いたアンケートその数なんと414枚!!!
これほどの数をどう集計するかというと、これも WordPress やってしまうのがWPerの矜持ではないでしょうか。

実を言うと、前回、関東圏で開催された WordCamp Yokohama 2010 のアンケート集計も、公開はされていませんが WordPress を用いて行っていました。
ただし、Yokohama のときは、回収したアンケートの枚数も98枚と少なかったので、自分だけでもなんとかなりましたが、今回は、さすがに無理なので分担して入力することに。
414枚のアンケートは一旦、星野さんが預かり全てをスキャン。これを20枚ずつに分割して、21人での分担入力としました。

で、今回の集計サイトでは、横浜の時から以下の改善を行うようにしています。

  • 多人数での利用となるため、入力画面のユーザビリティー向上を図る。
  • 参加者の属性ごとでの集計を行えるようにする。

入力画面のユーザビリティー向上

今回のキモの入力画面がこちら。
通常の投稿を利用していますが、見ての通りアンケート入力用にインターフェイスはガラリと変えています。

変更のために行っている内容は、概ね下記の通り。

  • 管理画面上のデフォルトの入力ボックスを全て削除
  • 本文の入力欄も削除
  • スクリーンレイアウトの列の数を強制的に1に固定
  • 入力テンプレート用の入力ボックスを追加
  • 公開ボックスが最下部に表示されるように再度追加
  • 不要な表示などは、cssで非表示にして調整

管理画面上のデフォルトの入力ボックスを全て削除

デフォルトで配置される入力ボックスを多重配列として、remove_meta_box を使い削除します。

function remove_default_metaboxes( $post_type, $post ) {
	$meta_boxes = array(
		'side'		=> array( 'submitdiv', 'tagsdiv-post_tag', 'categorydiv', 'durationdiv', 'postimagediv' ),
		'normal'	=> array( 'trackbacksdiv', 'commentstatusdiv', 'commentsdiv', 'postexcerpt', 'postcustom', 'slugdiv', 'authordiv', 'revisionsdiv' )
	);
	
	foreach ( $meta_boxes as $position => $boxes ) {
		foreach ( $boxes as $box ) {
			remove_meta_box( $box, $post_type, $position );
		}
	}
}

本文の入力欄も削除

remove_post_type_support は、カスタム投稿タイプを設定する際に用いる、register_post_type の supports パラメータとは逆に、すでにサポートされている項目を非サポートにすることができます。ここで、パラメータに post と editor を指定して、投稿の本文入力を削除。

function remove_post_editor_support() {
	remove_post_type_support( 'post', 'editor' );
}

スクリーンレイアウトの列の数を強制的に1に固定

get_user_option_screen_layout_post にフックして、ユーザーのスクリーンレイアウト列数を1にすると共に、screen_layout_columnsにもフックして、最大の列数も1に変更します。

		// レイアウトを1カラム固定に
		add_filter( 'get_user_option_screen_layout_post', array( &$this, 'post_edit_fix_layout' ) );
		add_filter( 'screen_layout_columns'				, array( &$this, 'post_edit_fix_max_columns' ) );
function post_edit_fix_layout() {
	return 1;
}


function post_edit_fix_max_columns( $columns ) {
	$columns['post'] = 1;
	return $columns;
}

入力テンプレート用の入力ボックスを追加、公開ボックスが最下部に表示されるように再度追加

add_meta_box を使って、入力テンプレート用のボックスを追加、その下に公開のボックスが表示されるように、その後で、submitdiv を追加します。

function add_event_metabox( $post_type, $post ) {
	add_meta_box( 'enquete_meta_box', 'アンケート', array( &$this, 'event_meta_box' ), $post_type, 'normal', 'high');
	add_meta_box( 'submitdiv', __('Publish'), 'post_submit_meta_box', $post_type, 'normal', 'high' );
}

不要な表示などは、cssで非表示にして調整

function output_editor_style() {
	$css_url = preg_replace( '/^https?:/', '', plugin_dir_url( __FILE__ ) ) . 'css/post_admin.css';
?>
<link rel="stylesheet"  href="<?php echo esc_url( $css_url ); ?>" type="text/css" media="all" />
<?php
}

堀内さんのセッション「早く・良いものを作るための、WordPressサイト構築ワークフロー」にもありましたが、使いやすい管理画面を作ることは、Webサイトの運用を活性化させる必須条件。
今はまだ、アンケート集計などそれ毎にハードコーディングされていますが、これを汎用化させて、テンプレートディレクトリに投稿タイプのテンプレートが存在したら、自動的に管理画面を変更でき、テンプレートの作成も、WordPress のテーマ同様テンプレートタグのようなものが使えるようになれば、もっと使いやすい管理画面を簡単に実装でき、WordPress の使い勝手を格段に上げることができるようになるんじゃないかなと思っています。

ハードコーディングしたため、テーマとプラグインの両方がないと上手く動きませんが、とりあえず集計サイトのテーマとプラグインは下記からダウンロードできるようにしておきますので、詳細なコードを確認してみたい方や試してみたい方は是非。

tokyo2011-enquete.zip (表示用のTwentyEleven子テーマ)
editor-tempate.zip(投稿画面のカスタマイズプラグイン)

最後になりますが、たくさんの声をいただいたアンケートも、あと少しでみなさんにお見せできるようになるかと思います。もう少しお待ち下さいね。

それから、入力に携わった @naokomc@daipresents@k_mikage@kai4den@ShinichiN@hibiki443@makito_th@odyssey@waviaei@nakachon@kana_ko@shokun0803@Mighty_Works@barchin@naonyan_taicho@cuez_yuko@narikei1030@yorozu にも多大なる感謝を。

さ、次は、カクニンさんこと@horike37 さん、まかせたよ!

get_the_categoryをカテゴリーid順に取得するようにする

あんまり検証してないよ。

function get_the_category_orderby_id( $categories ) {
	usort( $categories, '_usort_terms_by_ID');
	return $categories;
}
add_filter( 'get_the_categories', 'get_the_category_orderby_id' );

WordCamp Tokyo 2011 講演資料「WordPress の動作原理詳説」

WordPress の動作原理詳説

WordPress の動作原理詳説

アンカンファレンス補足資料

WordPress関数の記述箇所を検索できる便利サイト

PHPXref 0.7: WordPress

たしか、@kzextream さんに教えてもらった WordPress関数がどのファイルの何行目に書いてあるか検索できるサイト。
表示が完了したら、Ctrl+fなどのブラウザ検索で、WordPress関数名を検索。ヒットした関数名をクリックすると、下記のように関数が記述されているファイルと行数。それから、参照(利用されている)箇所を表示してくれる。
注意点は、(確か)最新版のソースコードを参照しているため、バージョンによって違うことがあり得る。

get_the_category の場合は、wp-includes/category-template.php の 65行目に記述されていて、link-template.php ほか9カ所で利用されていることが分かる。

ナビゲーションメニューのclassにページやカテゴリーのスラッグを追加してみる

WordPressのナビゲーションメニューで出力されるソースにスラッグを追加してみました。
命名規則は、カテゴリーと固定ページなどで同じスラッグを使っても問題とならないよう、投稿タイプやタクソノミーのスラッグも含めて、menu-item-category-news(newsというカテゴリーのメニューの場合)となるようにしています。

function add_slug_nav_menu_css_class( $classes, $item ) {
	switch ( $item->type ) {
	case 'post_type' :
		$post = get_post( $item->object_id );
		if ( $post ) {
			$classes[] = esc_attr( 'menu-item-' . $item->object . '-' . $post->post_name );
		}
		break;
	case 'taxonomy' :
		$term = get_term( $item->object_id, $item->object );
		if ( $term ) {
			$classes[] = esc_attr( 'menu-item-' . $item->object . '-' . $term->slug );
		}
		break;
	default :
	}
	$classes = array_unique( $classes );
	return $classes;
}
add_filter( 'nav_menu_css_class', 'add_slug_nav_menu_css_class', 10, 2 );

出力例

<ul id="menu-header" class="menu">
	<li id="menu-item-250" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-246 current_page_item menu-item-250 menu-item-page-home"><a href="http://www.example.com/">トップページ</a></li>
	<li id="menu-item-36" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-36 menu-item-page-privacy"><a href="http://www.example.com/privacy/">個人情報保護方針</a></li>
	<li id="menu-item-35" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-35 menu-item-page-sitemap"><a href="http://www.example.com/sitemap/">サイトマップ</a></li>
</ul>