管理画面でカスタムタクソノミーを使って絞り込みが出来るようにする

管理画面のカスタム投稿タイプの記事一覧ページで、カテゴリ(カスタムタクソノミ―)による絞り込みを行う。
元はこちら。

管理画面でカスタムタクソノミーを使って絞り込みが出来るようにする

大変役立ったのだけど、階層化されたタクソノミーの親子関係を維持して表示したかった。
自分で少し変えてみた。
ただし、作成した際に二階層目までしか必要なかったので、三階層目以降には未対応。

function add_post_taxonomy_restrict_filter() {
    global $post_type;
    if ( '作成したカスタム投稿タイプ' == $post_type ) {
        echo '<select name="作成したカスタムタクソノミ―">';
            echo '<option value="">カテゴリー指定なし</option>';
            $terms = get_terms('作成したカスタムタクソノミ―', 'hide_empty=0');
            foreach ($terms as $term) :
             if ($term->parent == 0):
              echo '<option value="' . $term->slug . '">' . $term->name . '</option>';
              $parentID = $term->term_id;

              $children = get_term_children( $parentID , '作成したカスタムタクソノミ―' );
              if(!empty($children)):

               foreach($children as $childID):
                $child=get_term_by('id', $childID, '作成したカスタムタクソノミ―');
                echo '<option value="' . $child->slug  . '"> ' . $child->name . '</option>';
               endforeach;

              endif;
             endif;
           endforeach;

        echo '</select>';
    }
}
add_action( 'restrict_manage_posts', 'add_post_taxonomy_restrict_filter' );

投稿が表示されないぞ、Custom Post Type Generator

カスタム投稿タイプを追加して、記事を投稿して、表示・・・されない。
そういえば、記事投稿用にカスタム投稿タイプ使うの久しぶりだ。

Custom Post Type Generatorの
高度な設定の
publicly_queryableをtrueに変更したら表示された。

あと

高度な設定の
publicがfalseのままだと、管理画面の記事一覧や投稿ページに「表示する」のリンクがでなくて不便。
こちらもtrueにした。

Auto Post Thumbnailは便利だけど。

Auto Post Thumbnailは便利だけど、少しはまったのでメモ。

記事の中の一番最初の画像を取ってくるので、絵文字アイコンとかが文中にあると悲惨なことに。
それらは.gifや.pngである可能性が高いので、以下の方法で回避。

プラグインのファイル、auto-post-thumbnail.php で

preg_match_all('/<\s*img [^\>]*src\s*=\s*[\""\']?([^\""\'>]*)/i', $post[0]->post_content, $matches);

となっているの部分を

preg_match_all('/<\s*img [^\>]*src\s*=\s*[\""\']?([^\""\'>]*.jpg)/i', $post[0]->post_content, $matches);

に変更。(2か所)
完ぺきではないけど、これで一応。

設定 - メディアで指定されているサムネイルのサイズにならない。

テーマ内のfunctions.phpにサムネイルサイズが指定されている可能性がある。
私の場合、
set_post_thumbnail_size
の値が優先されていた。
こちらの値を直接指定したら、直った。

スマホとPCの表示を別ファイルに分けてコーディング

WordPressで作ったサイトを、後付でスマホ対応にしたい。

テンプレートを使うならいいけど、自分でレスポンシブサイトを作るのは嫌だ。
既存サイトに後付なら、もっと嫌だ。
最悪だ。
いっそリニューアルにしてくれ。
なので、テーマファイル内に細工をして、PCとスマホで表示の切り分けをする。

例)テーマ内のsingle.phpでやってみる

まず、templateというフォルダを作成し、その中にpc.phpとsp.phpを設置。
それぞれのファイルにPC用、スマホ用の表示に最適化したコーディングをする。
pcからアクセスがあった場合はpc.phpをスマホの場合はsp.phpを呼び出すようにする。

こんな感じ。

if ( spSwitch() == 'pc' ){
	include  get_template_directory() . '/template/pc.php';
	exit();
}else{
	include  get_template_directory() . '/template/sp.php';
	exit();
}

function spSwitch(){
	$ua = $_SERVER['HTTP_USER_AGENT'];
	$pf = ((strpos($ua,'iPhone')!==false)||(strpos($ua,'iPod')!==false)||(strpos($ua,'Android')!==false)||(strpos($ua,'BlackBerry')!==false)||(strpos($ua,'Windows.Phone')!==false));

	if ($pf){
		return 'sp';
	}else{
		return 'pc';
	}
}

もちろん、別ファイルを呼び出さず、全部single.phpに書いてもいいけど、ソースが見にくくなるのでいや。
categoryやarchiveでも、templateフォルダ内のファイル名を変えて複数用意すれば同じことができる。

Advanced Custom Fieldsのデータをプレビューしたい

Advanced Custom Fieldsは非常に便利なのだけど、散々作りこんだ挙句にプレビュー出来ないことに気付いた。
今後も使い続けたいので、何とか解決方法を見つけようと四苦八苦・・・。

キレイな方法ではできなかったけど、一応下記のやり方で目的は達せられた。

step1.
SESSIONを使うので、/wp-config.phpの最後に以下を追記

if (!session_id()) session_start();

step2.
プレビューを押されたときのアクションにフックする。
使用しているthemeフォルダ内のfunctions.phpに追記。

function myCfPrev(){
    if ( !empty($_POST)){
        $_SESSION['posts'] = myHtmlSpecialChars($_POST);
    }
}
add_action( 'wp_insert_post', 'myCfPrev' );
// myHtmlSpecialCharsは配列の中もHTML エンティティに変換。不要なら外す。
function myHtmlSpecialChars($string) {
    if (is_array($string)) {
        return array_map("myhtmlspecialchars", $string);
    } else {
        return htmlspecialchars($string, ENT_QUOTES);
    }
}

プレビューボタンを押すと、Advanced Custom Fieldsを使って追加したフィールドは、「field_数字」という名前で$_POSTに格納される。
本来のフィール名との結び付けができなかったので、Wordpressの投稿画面のソース(Firebugなど使うと便利)から、Advanced Custom Fieldsを使って作成したinputフォームなどを調べ、イチイチ取得しなければならなかった。

上記で$_SESSION[‘posts’][‘fields’][‘field_数字’]にそれぞれのデータを格納できる。
また、$_SESSION[‘wp-preview’]に、「dopreview」が入る。
更新ボタンをクリックした場合は、$_SESSION[‘wp-preview’]は空。

$_SESSION[‘wp-preview’]の値を調べて条件分岐し、プレビューの場合はプレビューデータを表示するようにする。

画像の場合は、もう少し手間をかける。
画像のURLを格納したwp-postのpost_idが格納されているので、その値を使えばいい。
例えばこんな感じで。

$img_url = wp_get_attachment_image( $_SESSION['posts']['fields']['field_数字],'full', false );

もっとスマートなやり方があればいいのだけど、今の自分ではこれがやっと。
面倒なやり方だけど、手も足も出ない状況からは脱却できたので、メモ。

WordPress高速化への取り組み2

高速化への取り組み1では主にキャッシュ系のプラグインをメモ。
今回は画像系。

WP Smush.it
画像を劣化させずにファイルサイズを縮小してくれるオンラインサービス、Smush.itを利用できる。
管理画面のメディアからWordpressにアップ済みのファイルを個別/一括で利用可能。
Smush.itはよく失敗があるらしいので注意。
結果はメディア画面に表示されるので、失敗しても不安はない。
画像アップロード時にもSmush.itが利用できる設定も選べるが、アップロードが激遅になるので注意。

PNGGauntlet
プラグインではなく、ツール。
PNG限定だけど一括して画像を劣化させずにファイルサイズを縮小してくれる。
英語。
設定はデフォルトのままでも問題なし。
http://pnggauntlet.com/

ファイルの書き出しはファイルサイズ縮小の面でもFireworksが優秀だけど、職場にしかない。
個人作業のときは上記が有用なのでメモ。

ちなみにこのブログでは全く高速化の取り組みをしていない・・・。

WordPress高速化への取り組み1

今更だけど、Wordpressは遅い。
高速化に取り組んだメモ。

高速化が期待できるプラグイン。

WP Hyper Response
WordPressのレスポンスを向上させるプラグイン。
詳細はこちら

W3 Total Cache
ページなどをキャッシュできる。
データベース、オブジェクトキャッシュを有効にするとサーバーへの負担が増すらしいので、注意。
不安な場合はページキャッシュのみで。

MO Cache
日本語などマルチバイト環境の翻訳ファイルである.moファイルを読み込んだオブジェクトをキャッシュする。
W3 Total Cacheと併用し、オブジェクトキャッシュを有効化する必要あり。
もしくは、別のキャシュプラグインWP File Cacheなどと併用。

WP-DBManager
データベースの最適化。
その他、バックアップなども取れるので非常に有用。

毎回既存サイトの管理画面からチェックしてたので、メモ。

固定ページのページメニュー

最近はちょっと忙しくて更新が・・・。

さて、よく使うのに毎回考えて作ってたので、いい加減書いておこうと。
そのための備忘録だったし。

固定ページで親子関係を作ったとき、それをカテゴリのように見立てて、メニューを作成したい。
具体的には、親ページが表示されていても、子ページが表示されていても、サイドのカラムに同じメニューを表示する。

まず、functions.phpに、Wordpress Codexに載っているコードをそのまま追加する。

function is_subpage() {
	global $post;                                 // $post には現在の固定ページの情報があります
	if ( is_page() && $post->post_parent ) {      // 現在の固定ページが親ページを持つかどうかをチェックします
		return $post->post_parent;                      // 親ページの ID を返します
	} else {                                      // 親ページを持たないので...
		return false;                          // ...false を返します
	}
};

続いて、メニューを表示したい場所に以下のコード。

<div id="side_contents">
	<?php
		if ( is_subpage() == false ){
			//カテゴリトップページ
			$p_id = $post->ID;
			
		}else{
			//カテゴリサブページ
			$p_id = is_subpage();
		}
	?>

	<h2><?php echo get_the_title($p_id); ?> メニュー</h2>
	<nav>
	<ul>
	<?php $params='depth=2&child_of=' . $p_id . '&title_li=&sort_column=ID' ;?>
	<?php wp_list_pages($params); ?>
	</ul>
	</nav>
</div>

HTMLタグやID以外の$paramsの内容は任意に変更。