Wonderful! WordPress

カスタム分類による画像個別の分類

この記事は公開または最後に更新されてから1963日が経過しています。情報が古くなっている可能性があるのでご注意下さい。

実は私には、このやみくもに鳥画像を貼っているだけのブログの他にもう一つ、バードウォッチングに行った時の鳥見報告のようなサイトが別にあったりします。
同じく wordpress で、こことテンプレートや背景画像などほぼ同じものを使い回しているのでほとんど見た目は同じだったりしますが、内容は先にも言った通り少し趣が異なっています。

その鳥見報告サイトの場合、鳥見に行った場所をカテゴリー、鳥種を投稿タグで分類していますが、当然、行った先で複数の鳥を見る事になります。
この場合、一つの投稿に数種類の投稿タグが混在してしまうわけで、ある鳥だけ投稿タグで分類しようとしてもその投稿に属している投稿タグの別の鳥も入って来てしまいます。
これはあまりスマートではありません。

そこで、画像個別に分類できないものかと探してみると、 File gallery というとても良いプラグインがありました。
この File gallery を使うと画像を記事に挿入するときにまとめて一度に出来たり、なにより良かったのはカスタム分類を使って画像を個別に分類することが出来たのです。

当分の間、この File gallery を愛用していたのですが、たしか wordpress のバージョンアップに伴っての File gallery 自体のバージョンアップで何か使いづらくなってしまい使用するのをあきらめたという記憶があります。

そうなると別のプラグインを探すか、自らカスタム分類を設定するしかありません。
メディアの個別のカスタム分類の設定というのが、色々探して見ましたがなかなか見つからず、それでもやっと見つける事ができたので、この時は光明がさしました。

<?php
function create_attachment_taxonomy(){
	$labels = array(
		'name' => 'media tag',
		'singular_name' => 'media tag',
		'search_items' => 'media tagで検索',
		'all_items' => '全てのmedia tag',
		'edit_item' => 'media tagの編集',
		'update_item' => 'media tagを更新',
		'add_new_item' => 'media tagを追加',
		'new_item_name' => '新規media tag',
	); 
 
	register_taxonomy(
		'media_tag',
		array( 'attachment' ),
		array(
		'hierarchical' => false,
		'labels' => $labels,
		'query_var' => true,
		'update_count_callback' => '_update_generic_term_count', //2016/4/21に訂正済み
		'rewrite' => array(
			'slug' => 'media-tag',
			'hierarchical' => true,
			'with_front' => false
			),
		)
	);
}
add_action('init','create_attachment_taxonomy',0);
?>
PHP
CopyExpand

肝心なのは14行、15行、20行目。
14行目はカスタム分類名で、これは File gallery が使っていたものをそのまま引き継ぎました。
15行目は何を分類するかという分類の対象を指定するところで、 attachment を指定することでメディアの個別の分類が可能になります。分類するのが投稿タグやカテゴリーと同じ投稿であるなら post となります。
20行目の update_count_callback が指定してないと、メディアファイルを更新した時にそのメディアのカスタム分類に属する物の合計数が更新されません。
hierarchical はカテゴリーのようにその分類に親子関係を持たせるかという設定です。

通常、カテゴリーや投稿タグにおいてはその分類に属する投稿の数は、記事の公開の際に更新されますが、カスタム分類において分類の対象を attachment に指定した場合、記事の公開の際にはメディアのカスタム分類に属する物の合計数が更新されません。
その点、 File gallery はどのタイミングで更新していたのかはわかりませんが、自動的に更新されていたのでとても便利だったのです。
・・・

2016年4月21日訂正追記;

上記のーカスタム分類において分類の対象を attachment に指定した場合、記事の公開の際には更新されません。ーというのは間違っていました。
20行目の update_count_callback の指定に、 _update_generic_term_count を指定することで、記事の公開の際に投稿に張り付けた画像、及び投稿に張り付けていなくてもその記事にアップロードした画像を含めてカウントし合計数が更新されます。当然のことながら、投稿に張り付けていないメディアに関しても、そのカスタム分類の指定をすることが必要です。

_update_generic_term_count についての詳しくはcodexの関数リファレンス/register taxonomyをご覧ください。

と、いうことで以下は全く必要ありません。間違っていた事実を葬り去るのも潔くないので、無駄な努力の形跡としてここに残してあるだけです。
やはりWordPressは素晴らしい。あなどってはいけませんね。ちょっと気が付くのに時間がかかり過ぎましたが・・・。
そしてもうひとつ、以前は管理画面のメディア メニューに表示させるための関数、add_media_taxonomy_menu() というものをadmin_menu フックにて使用していました。が、いつからそうなったのかはよくわからないのですが、現在の4.6.1 というバージョンにおいては、そんな関数がなくとも自動的にメニューに追加されるので削除しました。
・・・

そうなると、いつ更新させるかということですが、メディアライブラリからそれぞれの分類に関して一つのメディアのカスタム分類を更新すればその一つの分類においては個数が更新されます。
たとえば、その日4種類の鳥の画像をアップしたとしたらそれぞれの鳥の画像に関して1枚づつ、計4枚の画像のカスタム分類の項目を更新すればいいわけです。実は本当はその半分の手間で済むのですが、それでも面倒です。あっでも、更新されるのはその画像が属する投稿が既に公開されていることが前提です。
File gallery のソースを覗いたりして、なんとか自動的に更新する方法はないものかと探してみたのですが、今のところこの件に関してはどうにもなりません。
・・・

2013年4月6日追記;

続、画像の枚数によるタグクラウドの自作」の件において、投稿を保存するときのアクションフックsave_postの使い方をいろいろ考えるときに、上述のカスタム分類のcountの更新も出来るのではと思いつきました。
save_postの引数 $post_id からその投稿に含まれる画像分類用のカスタム分類を取得して、それにより画像数を求め、countを更新すればいいのではと。
しかし、随分探してやって見ましたが、画像用のカスタム分類を投稿IDからは用意された関数では得られないよう。
それならSQLを使えばいいのですが。
画像の枚数を取得するのもSQLを使います。
あとはそれぞれ取得したデータでcountを更新すればいいだけとなりますが、これが簡単に出来るかと思えばさにあらず。
wp_update_termを使えばいいのだと思っていたのだけれど、そもそもこの関数を使う意図するところは全く違うようです。よくわからん。
散々じたばたしたあげく、結局、SQLに解決の糸口を見つけました。
はじめからSQLで考えれば良かったのに、教科書にもなるべくならwordpressで用意された関数を使った方が良いと書いてあるし。
で、以下のコードです。

<?php
function update_media_count($post_id){
	//自動保存なら無効
	if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
		return;
	}

	//function.php内の関数でSQLを使う時のお約束
	global $wpdb;

	$slugstr="";//確認用メールの文字列用変数
	/*引数の$post_idから投稿の情報を取得して
	post_tipeがpostの時だけ作動*/
	$mypost=get_post($post_id);
	$mytype=$mypost->post_type;

	if($mytype=='post'){//a
		$postid=$post_id;
		/*$post_idを使ってその投稿に付属する画像の
		カスタム分類のslugをSQLにて取得*/
$sql = <<< HERE
SELECT t.slug FROM $wpdb->posts a, $wpdb->term_relationships r, $wpdb->term_taxonomy x, $wpdb->terms t
WHERE a.ID = r.object_id
AND r.term_taxonomy_id =x.term_taxonomy_id
AND x.term_id=t.term_id
AND a.post_mime_type LIKE 'image/%'
AND a.post_type = 'attachment'
AND x.taxonomy='media_tag'
AND a.post_parent='${postid}'
HERE;

			$tagslugs=$wpdb->get_results($sql);
			$treatslug=array();
			foreach($tagslugs as $val){
				$treatslug[]=$val->slug;
			}
			//重複するカスタム分類のslugを配列から削除
			$newlist=array_unique($treatslug);
			$tagnum=count($newlist);
			foreach($newlist as $val){
				$tagname=$val;
				$slugstr=$slugstr.'-'.$val;//確認用メールの文字列作成

$sql = <<< HERE
SELECT COUNT(a.ID) FROM $wpdb->posts a, $wpdb->term_relationships r, $wpdb->term_taxonomy x, $wpdb->terms t
WHERE a.ID = r.object_id
AND r.term_taxonomy_id =x.term_taxonomy_id
AND x.term_id=t.term_id
AND a.post_mime_type LIKE 'image/%'
AND a.post_type = 'attachment'
AND x.taxonomy='media_tag'
AND t.slug='${tagname}'
HERE;

				//SQLで画像の数を取得
				$tagcount=$wpdb->get_var($sql);
				//カスタム分類のslugからterm_idを取得
				$tagid=get_term_by('slug',$tagname,'media_tag');
				$targetid=$tagid->term_id;
				//得られたterm_idを使ってterm_taxonomyテーブルのcountを更新するUPDATE SQL
				$wpdb->query($wpdb->prepare("UPDATE $wpdb->term_taxonomy SET count=%d WHERE taxonomy='media_tag' AND term_id=%d",$tagcount,$targetid));	
			}
			
			//確認用メール*必要無
			$sendstr='success update media_tag count :tag '.$slugstr;
			wp_mail('info@*****.com','update done',$sendstr);
	}//a
}

add_action('save_post','update_media_count');
?>
PHP
CopyExpand

3~5行目の自動保存の時に処理を回避する書き方はネット上に複数見つけました。
どれが大元かはわかりません、意味もわからない、こういう書式ということですか。
56~57行目はget_term_by()でカスタム分類のslugでそのterm_idを得ています。
そして、その得たterm_idを使って59行目のSQL UPDATEで、やっと目的のcountを更新しています。
この場合はSQLプリペアドステートメント prepareを使う必要も無いのですが、変数をセットしやすかったという感じです。
それにしてもこの辺に関してはあまりにも資料が乏しいように思います。

とりあえずはこれで目的達成。
わざわざ手動にてメディアからの更新をする手間は省けるようになりました。
なんとかなるものですね。
wordpressの自由度の高さのおかげですかね。

Leave a Reply!

JavaScript is necessary to send a comment.
You can edit and delete your comment if you input a edit key.
Edit key is necessary for attesting you when you edit and delete it.
The tag of HTML cannot be used in comment.
When you comment for the first time, it is displayed after the approval of the administrator.
Because I cannot speak English so much, it takes time to answer.
Required fields are marked *.

※Please enter more than 5 characters only alphabets.
※Edit or delete are possible for 2000 days after approval.

*

♠Simplistic Comment User Editable v4.0

♠When visitors leave comments on the site this site collect the data shown in the comments form, and also the visitor’s IP address and browser user agent string to help spam detection.
♠This site does not use cookie when visitors leave comments and commenter edit comment.
♠This site uses Akismet to reduce spam. Learn how your comment data is processed.

Comments feed

Trackback URL : https://strix.main.jp/wp-trackback.php?p=15495

Sanbanse Funabashi
2010.10.24 sunrise

Top

スクロールさせるか画像をクリックすると元に戻ります。