にっき

WordPressでこのイラストサイトを作るときに詰まったところ(ギャラリーページ編)

このサイトはWordPressで出来ているけど、正直言って今のようなサイトの骨組みを作り上げるまでかなり苦労した。特にギャラリーページ関係。まだいくつか気になるところはあるけど一段落。そこで、また改造しようという時に同じ過ちをしないために、このサイトを作り上げる間でつまづいた所をメモしておこうと思う。今回はギャラリーページ編。

ギャラリーのスペースの作成

ギャラリーの記事一覧画面

イラストサイトとなると一番大事なのはここ。元々ある管理画面の左サイドバーの「投稿」から「イラスト」のカテゴリーを追加して済ませるという手もあるけど、ここではギャラリー用の容器のようなものを新たに作るという、完全に分離する作戦に出ました。

具体的にどうするかというと、初期から既にある「投稿」という容器(WordPress公式では投稿タイプと言う)と、さらにもう一つギャラリー用に「ギャラリー」という名のついた容器を作るために、新たに投稿タイプを追加してやります。具体的な名称があって、「カスタム投稿タイプ」と言ったりするらしいです。

テーマフォルダにあるfunctions.phpにコードを追加するだけなんですが、引数が多すぎて難解のため、プラグインを用いたやり方が分かりやすいです。別の記事でプラグインを使った分かりやすいやり方を説明した記事を用意した方がいいかもしれない。ここではオレが使っているコードを記します。

register_post_type('works', array(	'label' => 'ギャラリー','description' => '','public' => true,'show_ui' => true,'show_in_menu' => true,'capability_type' => 'post','hierarchical' => true,'rewrite' => array('slug' => false, 'with_front' => false),'query_var' => true,'has_archive' => true,'exclude_from_search' => false,'supports' => array('title','editor','excerpt','trackbacks','custom-fields','comments','revisions','thumbnail','author','page-attributes',),'taxonomies' => array('works',),'labels' => array (
  'name' => 'ギャラリー',
  'singular_name' => 'ギャラリー',
  'menu_name' => 'ギャラリー',
  'add_new' => '新規追加',
  'add_new_item' => '新規ギャラリーを追加',
  'edit' => '編集',
  'edit_item' => 'ギャラリーの編集',
  'new_item' => '新しいギャラリー',
  'view' => 'ギャラリーを見る',
  'view_item' => 'ギャラリーを表示',
  'search_items' => 'ギャラリーの検索',
  'not_found' => 'ギャラリーの記事が見つかりませんでした',
  'not_found_in_trash' => 'ゴミ箱にギャラリーの記事はありませんでした',
  'parent' => '親のギャラリー',
),) );
register_taxonomy('works-cat',array (0 => 'works',),array( 'hierarchical' => true, 'label' => 'ギャラリーカテゴリー','show_ui' => true,'query_var' => true,'rewrite' =>true,'singular_label' => 'work') );
register_taxonomy('works-tag',array (0 => 'works',),array( 'hierarchical' => false, 'label' => 'ギャラリータグ','show_ui' => true,'query_var' => true,'rewrite' =>true,'singular_label' => 'work') );

これをコピペするだけでも機能します。

前半のregister_post_type関数が、新しい容器を作るための関数です。上の場合だと、容器の名前は「ギャラリー」、URLの直接の決め手となるスラッグ名は「works」となります。このスラッグ名は基本的に英語の複数名が無難そうです。ちなみに、この容器にアクセスする場合は、次のURLにアクセスすればいけます。

http://WordPressを設置したURL/works

また、labelsというのは、記事を追加する時に表示されているボタンのラベル等に使われる名前を設定する部分です。その辺は好みで弄ってもらえればいいかと思います。

後半のregister_taxonomy関数は、カテゴリーやタグを設定できるようにするための関数です。ちなみにタグやカテゴリーの階層のことをWordPress上ではタクソノミーと言ったりします。

「array (0 => ‘works’,)」というところの「works」の部分は、設定するタグやカテゴリーをどの投稿タイプで利用するかを指定する部分なので、間違いのないように気をつけて。

上の場合だと、「works-cat」というカテゴリーのタクソノミーを設定していて、下が「works-tag」というタグのタクソノミーを設定しています。例えばイラストの投稿タイプの何らかのカテゴリーをURLからアクセスする場合、ここのギャラリーページのイラストのカテゴリーを見てもらえると分かるように、次のようになります。

http://WordPressを設置したURL/works-cat/カテゴリー名

というわけで、上の長いコードをfunctions.phpに貼付ければ無事に容器を作れます。

サイドバーにギャラリーのカテゴリー一覧を表示

ギャラリーのカテゴリー一覧表示

サイドバーのナビゲーションの各画像リンクについては、現在表示しているページがにっき関係のページだったりと、ギャラリー関係のページだったり、おしらせ関係のページだったりした場合、上のようなカテゴリー階層を表示するようにします。

wp_list_categories関数を用いて表示しますが、元々ある投稿タイプである「投稿」部分のカテゴリー一覧を表示するのであれば、次のようなコードを使えば実現できます。

<?php wp_list_categories('&title_li='); ?>

ギャラリーの場合だとカスタム投稿タイプを利用していたりと特殊なので、上の通りにはいきません。タクソノミー名を指定してやるとうまくいきます。なので次のようにしましょう。

<?php wp_list_categories('taxonomy=works-cat&title_li='); ?>

関係ないページではカテゴリー階層が表示されないようにしたいので、さらにカテゴリーを表示したい部分にこのようにコードを記します。

<?php if(get_post_type() == "works"): ?>
<ul class="child">
<?php wp_list_categories('taxonomy=works-cat&title_li='); ?>
</ul>
<?php endif; ?>

これで前に用意したギャラリーという容器内のページ以外を表示しても、ギャラリーのカテゴリー階層は表示されなくなりました。

ギャラリー投稿タイプ追加による見出し・タイトル部分の表示の修正

見出し部分の修正

元々ある投稿タイプだけであれば別に弄る必要の無い部分ですが、ギャラリー用に新たに追加したため、元々ある投稿タイプとギャラリーの投稿タイプを一緒に利用するとなれば、カテゴリー名やタグ名が被ってしまう可能性が高いと思います。

システム上は被っても全く問題ないですが、閲覧者側に立っていざGoogle検索等でたどり着いたときに、同じタイトルにも関わらず全く違うページとなるとちょっとがっかりしちゃいますよね。なので、元々ある投稿タイプとギャラリーの投稿タイプとでカテゴリーやタグ名が被らないように弄ります。

オレは次のようなfunctions.phpに貼付ける関数を用意しました。

function html_title(){
	$blog_title="";

	if( is_front_page() ) { $blog_title="トップページ";}
	elseif ( is_search() ) {  $blog_title="「".get_search_query()."」での検索結果";}
	elseif ( is_single() ) { $blog_title=get_the_title();}
	elseif ( is_page() || is_home()) { $blog_title=wp_title('',0,'');}
	elseif ( is_category() ) { $blog_title=single_cat_title("",false)."のにっき";}
	elseif ( is_tag() ) { $blog_title="「".single_tag_title("",false)."」一覧";}
	elseif ( is_tax() ) {
		$cat = get_queried_object();
		$blog_title = esc_html($cat->name)."の".esc_html(get_post_type_object(get_post_type())->label);
	} elseif ( is_archive() ){
		if(get_post_type_object(get_post_type())->name !== "post"){
			$blog_title=esc_html(get_post_type_object(get_post_type())->label);
		}else{
			$blog_title="にっき";
		}
	} elseif ( is_month() ) {
		if(get_post_type_object(get_post_type())->name !== "post"){
			$blog_title=get_the_time('Y年F')."の".esc_html(get_post_type_object(get_post_type())->label);
		}else{
			$blog_title=get_the_time('Y年F')."のにっき";
		}
	} elseif ( is_year() ) {
		if(get_post_type_object(get_post_type())->name !== "post"){
			$blog_title=get_the_time('Y年')."の".esc_html(get_post_type_object(get_post_type())->label);
		}else{
			$blog_title=get_the_time('Y年')."のにっき";
		}
	} else { $blog_title="404エラー";}

	return $blog_title;
}

面倒なやり方かもしれませんが、表示するページの種類によって分岐して見出しを変える関数を新たに作って被らないようにすることにしました。ヘッダー部分にそのままベタっと貼っても動くけど、こんな長い関数が貼ってあると邪魔になるので、functions.phpに貼付けてこの関数をタイトルや見出し部分から呼び出すようにしました。

では元々の投稿タイプとギャラリーの投稿タイプのタグやカテゴリーの見出しが被らないようにする対策ですが、is_tax()とis_month()とis_year()の中の処理に注目。

処理の中では、今見ている記事の投稿タイプが初期の投稿タイプかどうかの判定をしています。is_month()の中を通った場合、もしも初期からある投稿タイプであれば「2013年11月のにっき」と表示され、もしギャラリーの投稿タイプの記事であれば「2013年11月のギャラリー」となります。

では関数を早速使ってみましょう。オレはタイトルとh1タグでこの関数を利用しています。タイトルで利用する場合は次のような感じです。

<title><?php
	if( is_front_page() ){echo get_bloginfo('name')." - ".get_bloginfo('description')." -";	
	}else{echo html_title()." | ".get_bloginfo('name');}
 ?></title>

もしトップページが表示されていたら、「ブログの名前 – キャッチフレーズ -」というタイトルになり、それ以外のページでは「html_title()関数からの見出しの出力 | ブログの名前」となります。

これで見出し・タイトル部分の表示の問題は解消されたはずです。

検索フォームに何も入力せずに検索をかけた場合の問題などを修正 (2014.11)

現状のhtml_title関数を用いてしまうと、検索フォームに何も入力せずに検索をかけた時の分岐を記してしないために、表示がおかしくなってしまいます。そのため、検索ワードを入力しなかった場合の分岐を追加しました。

また、検索とは関係ありませんが、カスタムタクソノミーのタイトル部分について、今までではタグかカテゴリーを区別せずにタイトルを表示していましたが、区別して表示できるようにしました。

function html_title(){
	global $post;
	$blog_title="";

	if ( isset($_GET['s']) && empty($_GET['s']) ){$blog_title="検索キーワードが空っぽ";}
	elseif( is_front_page() ) { $blog_title="トップページ";}
	elseif ( is_search() ) { $blog_title="「".get_search_query()."」での検索結果";}
	elseif ( is_single() ) { $blog_title=get_the_title();}
	elseif ( is_page() || is_home()) { $blog_title=wp_title('',0,'');}
	elseif ( is_category() ) { $blog_title=single_cat_title("",false)."のにっき";}
	elseif ( is_tag() ) { $blog_title="「".single_tag_title("",false)."」タグ";}
	elseif ( is_tax() ) {
		$cat = get_queried_object();
		$post_type_taxonomies = get_object_taxonomies( get_post_type(), 'objects' );
		if ( !empty($post_type_taxonomies) ) {
			foreach( $post_type_taxonomies as $post_type_taxonomy ) {
				if($post_type_taxonomy->name == $cat->taxonomy){
					if(!$post_type_taxonomy->hierarchical == 1){
						$blog_title = "".esc_html($cat->name)."のタグが付いた".esc_html(get_post_type_object(get_post_type())->label);
					}else{
						$blog_title = "".esc_html($cat->name)."の".esc_html(get_post_type_object(get_post_type())->label);
					}
					break;
				}
			}
		}
	} elseif ( is_month() ) {
		if(get_post_type_object(get_post_type())->name !== "post"){
			$blog_title=get_the_time('Y年F')."の".esc_html(get_post_type_object(get_post_type())->label);
		}else{
			$blog_title=get_the_time('Y年F')."のにっき";
		}
	} elseif ( is_year() ) {
		if(get_post_type_object(get_post_type())->name !== "post"){
			$blog_title=get_the_time('Y年')."の".esc_html(get_post_type_object(get_post_type())->label);
		}else{
			$blog_title=get_the_time('Y年')."のにっき";
		}
	} elseif ( is_archive() ){
		if(get_post_type_object(get_post_type())->name !== "post"){
			$blog_title=esc_html(get_post_type_object(get_post_type())->label);
		}else{
			$blog_title="にっき";
		}
	} elseif ( is_404() ) { $blog_title="404エラー";}

	return $blog_title;
}

肝心な検索ワードが入力されなかった場合の処理については次の部分です。検索時に「s」という変数のGETメソッドが送られるので、その検索時に使われる変数が空っぽ、もしくは変数が存在しなければ、タイトルに「検索キーワードが空っぽ」と表示されます。

	if ( isset($_GET['s']) && empty($_GET['s']) ){$blog_title="検索キーワードが空っぽ";}

これだけではタイトル部分だけ表示されることになるので、search.php内のコードを次のようにしました。これで、検索キーワードが入力されていなければ、入力してほしいというメッセージが表示されて処理が止まります。

<?php get_header(); ?>
<?php if(isset($_GET['s']) && empty($_GET['s'])): ?>
	<p>記事を検索したいキーワードを入力してね。</p>
<?php else: ?>
<?php 	if (have_posts()) : ?>
<?php 		while (have_posts()) : the_post(); ?>
<?php 			get_template_part( 'loop' ); ?>
<?php 		endwhile; ?>
<?php 		if(function_exists('wp_pagenavi')) { wp_pagenavi(); } ?>
<?php 		wp_reset_postdata(); ?>
<?php 	else : ?>
		<p>記事が見つかりませんでした。</p>
<?php 	endif; ?>
<?php endif; ?>
<?php get_footer(); ?>

また、カスタムタクソノミーのページのタイトルをタグかカテゴリーかを区別して表示できるように修正した箇所は次の通りです。タグかカテゴリーかはhierarchicalの値でわかるため、hierarchicalが0であればタグ、そうでなければカテゴリーとしています。

	elseif ( is_tax() ) {
		$cat = get_queried_object();
		$post_type_taxonomies = get_object_taxonomies( get_post_type(), 'objects' );
		if ( !empty($post_type_taxonomies) ) {
			foreach( $post_type_taxonomies as $post_type_taxonomy ) {
				if($post_type_taxonomy->name == $cat->taxonomy){
					if(!$post_type_taxonomy->hierarchical == 1){
						$blog_title = "".esc_html($cat->name)."のタグが付いた".esc_html(get_post_type_object(get_post_type())->label);
					}else{
						$blog_title = "".esc_html($cat->name)."の".esc_html(get_post_type_object(get_post_type())->label);
					}
					break;
				}
			}
		}

また、もう一箇所修正していて、404エラーの表示部分についても手をつけました。以前はelseだけで分岐して404エラーというタイトルで表示していましたが、今回の検索関係の追記によって問題が出るようになったため、もう少し厳しく判定を記しました。これで問題なしです。

} elseif ( is_404() ) { $blog_title="404エラー";}

個別投稿表示テンプレートの修正

初期からある投稿タイプを利用するだけであれば修正はいらないのですが、今回はギャラリー(works)の投稿タイプを追加したため、もしもギャラリー投稿タイプの記事を表示した場合、カテゴリー部分等がうまく表示されません。

個別投稿表示テンプレートとなればsingle.phpが使われますが、その中のまずカテゴリー表示部分を次のようにしました。

if(esc_html(get_post_type_object(get_post_type())->name) == "works"):
	echo get_the_term_list( $posts->ID, 'works-cat', 'カテゴリー: ', ', ', '' );
else:
	echo 'カテゴリー: ';
	the_category(', ');
endif;

タグ部分は次のようにしました。

if(esc_html(get_post_type_object(get_post_type())->name) == "works"):
	echo get_the_term_list( $posts->ID, 'works-tag', 'タグ: ', ', ', '' );
else:
	the_tags( 'タグ: ', ', ', '' );
endif;

いずれもギャラリー(works)投稿タイプの記事が表示された場合、get_the_term_list関数を使ってカテゴリーやタグを表示しています。これでうまく表示されるはずです。

ギャラリーのイラスト等のサムネイル表示

ギャラリーページのサムネイル

ギャラリーのページとなると、ただ各記事のタイトルが縦に並んでいるだけというのは明らかに見づらいです。サムネイルサイズの絵とタイトルは並んで表示してあった方が見やすいでしょう。

というわけで、上の画像のように各カテゴリーごとに最新の6件のサムネイルとタイトルで並べて表示できるようにしていきます。

ギャラリーのアーカイブページ用カスタムテンプレートを作る

現在のオレのギャラリーページはサムネイル表示になって見やすくなっていますが、これを実現するためにはカスタムテンプレートと言って、最初の方で作ったギャラリーの投稿タイプで利用する場合には、その投稿タイプ用の独自のテンプレートを作ることで実現できます。

カスタムテンプレートはアーカイブ用のページ(オレのサイトのギャラリーのトップページはアーカイブページ)、カテゴリー用ページ、タグ用ページと、柔軟にテンプレートを用意できますが、ここではアーカイブ用とカテゴリー用のカスタムテンプレートを作ってサムネイル表示されるようにしましょう。ちなみにタグ用ページが無い状態でタグのリンクをクリックした場合は、カテゴリー用のカスタムテンプレートが参照されるため問題ありません。

ギャラリーのトップページをカテゴリーごとにサムネイル表示する

まずはギャラリー用のアーカイブページを作ります。普通のアーカイブページ向けのテンプレートファイル名はarchive.phpですが、カスタムテンプレートを用意する場合はファイルの名前は次のようにします。

archive-(投稿タイプ名).php

これでギャラリーの投稿タイプ用のアーカイブページ向けテンプレートファイルができます。ここでは一番上で用意したギャラリー投稿タイプの名称等を使っていくので、archive-works.phpとします。

では早速サムネイル表示できるようにコードを書いていきます。記事のカテゴリータイトルとサムネイル表示のループ部分だけですが、こうしました。

$works_category = get_terms("works-cat", "parent=0");
foreach($works_category as $works):
    $gallery_query = new WP_Query(array(
                    'post_type' => 'works',
                    'taxonomy' => 'works-cat',
                    'works-cat' => $works->slug,
                    'posts_per_page' => 6,
));
	if ($gallery_query->have_posts()): ?>
	<h2><a href="<?php echo home_url(); ?>/works-cat/<?php echo esc_html($works->slug); ?>" title="<?php echo esc_html($works->name); ?>"><?php echo esc_html($works->name); ?></a></h2>
	<div id="gallery-thumbnails" class="clearfix">
		<ul>
	<?php while ($gallery_query->have_posts()): ?>
		<?php $gallery_query->the_post(); ?>
		<?php get_template_part( 'loop', 'works'); ?>
	<?php endwhile; ?>
		</ul>
	</div>
<?php wp_reset_postdata(); ?>
<?php else : ?>
	<p>イラストがみつかりませんでした。</p>
<?php endif; ?>
<?php endforeach; ?>

これをカスタムテンプレートに記しました。

  • 1行目で親カテゴリー情報を読み込む
  • 2行目でforeach関数を用いて親カテゴリーの数の分だけループする
  • 3行目から8行目で$gallery_queryにworks投稿タイプ、タクソノミーがworks-cat、works-cat階層がforeachで反復ループして読み込まれた$works->slugに記憶されたカテゴリースラッグ名、posts_par_pageで6つの記事のみに読み込み、というふうに絞り込んで読み込む
  • 9行目で$gallery/query内に記事があるかどうか確認
  • 10行目でカテゴリーへ移動するリンクが付いたカテゴリータイトルを出力
  • 13行目で$gallery_query内の記事の数の分だけループする
  • 14行目はおまじないです。ないとまともに動いてくれない(実はオレもよくわかっていない)
  • 15行目でloop-works.phpテンプレートファイルを読み込む(サムネイル表示部分)
  • 19行目はおまじない。

ちなみに、これだけではサムネイルは表示されません。15行目でget_template_part関数を用いて別のテンプレートファイルを読み込んでいるためです。わざわざ別にテンプレートファイルを読み込んで分けなくても良いのですが、カテゴリー用のカスタムテンプレートでも同じコードを利用することになるので、後々のメンテナンスを考えるとこうした方がよいです。

get_template_partで読み込んでいるloop-works.phpは次の通りです。

<li>
	<div class="gallery-image"><a href="<?php the_permalink() ?>" title="<?php the_title(); ?>"><?php echo get_the_post_thumbnail($post->ID,array(150,150)); ?></a></div>
	<div class="gallery-name"><?php the_title(); ?></div>
</li>

2行目で絵のサムネイルを取得して表示し、3行目でタイトルを表示しています。

カテゴリー名とサムネイル部分のCSS

カテゴリー名とサムネイル表示部分のCSSは次のようにしました。

div#gallery-thumbnails{
	margin:0 auto;
}

div#gallery-thumbnails ul{
	margin:0 auto;
	padding:0;
}

div#gallery-thumbnails ul li{
	float:left;
	width:150px;
	height:220px;
	list-style:none;
	margin:0 20px;
}

div#gallery-thumbnails ul li div.gallery-image a img{
	display:block;
}

div#gallery-thumbnails ul li div.gallery-name{
	padding:5px 0;
	font-size:0.9em;
}

また、このサムネイル表示にはfloatを利用して表示していて、その副作用のようなレイアウト乱れを回避するために、clearfixというテクニックを利用しています。clearfixのコードは「clearfixとは – webデザイナーのメモ」から拝借しました。ありがとうございます。

.clearfix:after {
content: "."; 
display: block; 
height: 0; 
clear: both; 
visibility: hidden;
}

.clearfix {display: inline-block;}

/* Hides from IE-mac */

* html .clearfix {height: 1%;}
.clearfix {display: block;}

/* End hide from IE-mac */

以上のCSSを利用することでサムネイル表示ができると思います。

ギャラリーのカテゴリー用カスタムテンプレートを作る

さっきのカスタムテンプレートと似通っているので楽ですが、所々が厄介です。works-catというカテゴリー用のカスタムテンプレートというよりも、works-catというタクソノミーの階層のカスタムテンプレートと言った方がいいかもしれないです。

ここでもギャラリー用のアーカイブページを作ったときと同じく、ファイルの名前が決まっています。次のようなファイル名にします。

taxonomy-(カスタムタクソノミー名).php

なので、ここではtaxonomy-works-cat.phpとなります。次に中の処理のお部分ですが、次のようにしました。

$term = array_shift(get_the_terms($post->ID, 'works-cat'));

$works_query = new WP_Query(array(
	'post_type' => 'works',
	'taxonomy' => 'works-cat',
	'term' => $term->slug,
	'posts_per_page' => 12,
	'paged'	=> $paged,
));

if ($works_query->have_posts()) : ?>
	<div id="gallery-thumbnails" class="clearfix">
		<ul>
<?php while ($works_query->have_posts()) : $works_query->the_post(); ?>
<?php get_template_part( 'loop', 'works'); ?>
<?php endwhile; ?>
		</ul>
	</div>
<?php if(function_exists('wp_pagenavi')) { wp_pagenavi(); } ?>
<?php wp_reset_postdata(); ?>
<?php else : ?>
			<section>
				<h2>記事が存在しませんでした</h2>
				<p>記事が見つかりませんでした。</p>
			</section>
<?php endif; ?>
  • 1行目では、ページを開いたギャラリーのカテゴリーの情報を取得
  • 3行目から9行目では、works投稿タイプ、works-catタクソノミー、1行目で取得したカテゴリー名、以上の条件に当てはまる記事を12件表示。8行目のpgaedというのはページ送りに使っています。
  • 19行目はWP-PageNaviプラグインを利用してページ送りのリンクを表示。この辺は各自で弄ってね。

他の部分はarchive-works.phpやloop-works.phpと被っているので説明は省きます。

おしまい

これでギャラリー部分は終わって、イラストサイトとしていい感じに機能してくれる訳です。

これを作るのにかなり苦労した。本当に。

コメント&トラックバック

コメントを残す

名前とメールアドレスは必須項目です。(メールアドレスは公開されません)

トラックバックURL