Home > WP Core Hacks

WP Core Hacks Archive

[WPCH vol.05]RE:カテゴリー一覧の書式を変える

時々拝見してるブログに書いてあったので軽くメモしてみます。(元のブログはこちら

バージョンが進むに連れてコード的には読みやすくなってきてるはずの WordPress ですが、設計思想を把握していない門外漢にはやさしくない作りなのは否めないですよね。コアのソースがいじりにくいからフックが進化してるというかw 先日もどこぞのブログか何かで話題にあがっていた、優秀な人材が無能化なんたらじゃないですが、元々の機能だからここはいじらない、みたいなのが積み重なって出来てるよなぁって感じは否めない、ですかね。

さて、話を戻しましょう。 wp_list_categories (ちょっと古いテンプレだと wp_list_cat)で、show_count オプションを 1 にする( wp_list_cat だと optioncount を 1 にする)と、出力されるカテゴリーのリストの後ろに、カテゴリー毎の投稿数が表示されますが、このフォーマットは固定なので、echo オプションで変数化して置換する(元記事でやってる方法)か、フィルターフックで置換するか(これは後で別にエントリーしましょうw)、コアソースを直すか、のいずれかの手段をとるわけです。今日は、このコアソースを修正するについて、です。(前置き長いなー

前置きでひっぱっておいてアレですが、場所は /wp-includes/classes.php の1367行目付近です。あ、バージョンは2.9.2です。

if ( isset($show_count) && $show_count )
	$link .= ' (' . intval($category->count) . ')';

を

if ( isset($show_count) && $show_count )
	$link .= ' [' . intval($category->count) . ']';

のようにすればOKです。

ちなみに、wp_dropdown_categories を使う時は、同じファイルの1450行目付近の

if ( $args['show_count'] )
	$output .= '  ('. $category->count .')';

を

if ( $args['show_count'] )
	$output .= '  ['. $category->count .']';

のようにすればOKです。

もうデザイン的に丸括弧をやめたい、のであればコアソースを修正してしまうほうがそりゃ早いですね。上記付近を修正すれば、丸括弧までをリンクにするのも簡単ですし。

[WPCH vol.04] RSSをハック。ちょっとした工夫で gmail の random signature に対応

先日の投稿でバージョンアップでコアの変更が飛んだ話をしたばかりですが、プラグインだと変更しにくいものがあるのは確かなので、コアハックは続けていこうと思います(この投稿の内容は WordPress 2.7 で確認しています)。

今日は RSS の出力を変更する、です。

gmail を使っていて、WordPress でブログを書いたりサイトを運営したりしている人に朗報です。gmail のラボ機能にある random signature をご存知でしょうか。名前のとおり署名部分にランダムな1文を入れてくれる機能です。ラボ機能についてはGmailに13の新機能が追加!すべての機能を解説! | Google Mania – グーグルの便利な使い方あたりを参考にどうぞ。

で、この random signature ですが、そもそも簡易な1文を追加するお遊びの要素が強く、RSS 中の title 要素の中を出力してくれるだけなんですね。なので、たいていの RSS 出力を処理してくれます。ただ、名言を出力するというデフォルトの使い方では、自分で文章を選べませんし、せっかくのインターネット時代にパソコン通信的な使い方をしていたのでは面白くありません。せっかくだから自分の記事とそのリンクも貼りたいですよね。

というわけで(前置き長っ!)、本日は WordPress の RSS 出力をいじくって、記事タイトルとリンクの両方を gmail の新規メールに差し込んでみましょう、という試みです。

まず注意しないといけないことは、WordPress は RSS,RSS2,ATOM などのフォーマットでフィードを出力することができるので、どれを使っていて、どれが使われていないのか、を把握しないといけない、ということです。既に誰かが自サイトのフィードを購読しているのに、その出力をいじくってしまっては迷惑ですよね。気をつけてください。(自サイトがどのフィードを出力しているか、が把握できない人は対処しないほうがいいかもしれません。。。)

いじくるファイルは、フィードの種類に合わせて、wp-includes 中の、feed-rss.php , feed-rss2.php ,feed-rdf.php , feed-atom.php のいずれかです。今回は一番手軽な RSS をいじることにするので、feed-rss.php を修正します。バックアップは自己責任でちゃんと取ってください。

<?php
/**
 * RSS 0.92 Feed Template for displaying RSS 0.92 Posts feed.
 *
 * @package WordPress
 */

header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true);
$more = 1;

?>
<?php echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
<?php the_generator( 'comment' ); ?>
<rss version="0.92">
<channel>
	<title><?php bloginfo_rss('name'); wp_title_rss(); ?></title>
	<link><?php bloginfo_rss('url') ?></link>
	<description><?php bloginfo_rss('description') ?></description>
	<lastBuildDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></lastBuildDate>
	<docs>http://backend.userland.com/rss092</docs>
	<language><?php echo get_option('rss_language'); ?></language>
	<?php do_action('rss_head'); ?>

<?php while (have_posts()) : the_post(); ?>
	<item>
		<title><?php the_title_rss() ?> [ <?php the_permalink_rss() ?> ]</title>
<?php if (get_option('rss_use_excerpt')) { ?>
		<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
<?php } else { // use content ?>
		<description><?php the_content_rss('', 0, '', get_option('rss_excerpt_length')) ?></description>
<?php } ?>
		<link><?php the_permalink_rss() ?></link>
		<?php do_action('rss_item'); ?>
	</item>
<?php endwhile; ?>
</channel>
</rss>

赤字の部分を削除して、青字の部分を書き足すだけです。簡単!これで、http://自サイト/?feed=rss みたいにすると、各エントリが、”タイトル [ URL ]”って感じになるはずです。

きちんと確認できたわけではありませんが、random signature は読み込めるファイルサイズに制限があるようで、概要や本文などが含まれているデータ量の大きいフィードだと、ランダムにできないようです。これに対処するため、赤字部分(見てのとおり概要か全文を出力している部分)を取ってしまいます。また、フィードの性格からすると、link 要素をリンクとして出力してくれてもよさそうですが、残念ながら random signature は link 要素を出力してくれないので、title 要素の中に URL を入れてしまいます。これによりURLが出力できるわけですね。 link 要素自体は削除してしまってよさそうですが、将来的な変更に備えてとりあえず残しておきます。

修正した RSS が狙い通りに出力されることを確認したら、gmail に設定してください。メールを作成のリンクをクリックするたびに、署名としてタイトルとリンクが出力されれば完成です。(gmailの設定で言語を英語にし、labo タブで random signature を enable にして保存、その後言語を日本語に戻して、全般タブの署名のところにURLを入れればOKです。)

最後に今回の件で苦労した部分、気がついた部分をまとめておきます。なんかおかしいなと思ったら読んでみてください。

  • Firefox で RSS を確認しているとキャッシュが効きすぎるようです。Safari では即時反映されますが、Firefox でのRSS確認は時間がかかります。通常のリロードや Shift キーを押しながらのリロードでも更新されないのには参りました。
  • gmail で RSS がキャッシュされます。更新頻度がものすごく悪いようなので、gmail への設定は RSS の出力がうまく出来ていることを確認してからやるのがよいようです。
  • 本文にも書きましたが、RSS のサイズが大きいとランダム化されないようです。概要も本文もなしにしてサイズを削り、この対処を行うフィードは、random signature 用と割り切ったほうがよいようです。
  • タイトル部が長いのもまずいようです(メール的にも)。もし長いタイトルを頻繁に投稿するようであれば、substring 関数などで文字を削るといいでしょう。
  • もし特定のカテゴリだけを出力したい場合は、http://自サイトURL/?feed=rss&cat=1 のように、カテゴリIDを追加指定してあげればOKです。
  • なんらかの不具合で、Append a random signature from feed: のチェックが勝手に外れてしまうことがあるようです。出力されないと思ったら設定を再度見直してみてください。

それでは楽しい WordPress ライフ、もとい random signature ライフを!


追記:2009年02月17日(火)投稿から約5分後w
Twitter で、クイズ研 の中の人から、クイズ研API を教えていただきました。random signature でクイズが配信されてます。また、google 側の制限として、タイトル 96 文字以内、 item は 10 個まで、らしいと教えていただきました!ありがとうございます!>twk さん

[WPCH vol.03] ウィジェットをハック。ウィジェットタイトルをちょっとおしゃれに。

ウィジェットって本当に便利ですよね。並べ替えも簡単だし、テーマを変更しても基本的にはそのまま引き継がれるし。

ただ、設定がタイトなので、タイトル部分を装飾するのがちょっと難しいのが残念なところです。
タイトルの背景画像は CSS で対応できますが、タイトルそのものを装飾するには限界があります。ウィジェットタイトルは設定時にタグを使わせてくれないからです。

今回は、このウィジェットタイトルを CSS で装飾しやすくするために、ほんの少しだけ、タグ(span要素)を許可してあげる、というコアハックです。
具体的には、wp-users.jp 日本の WordPress ユーザのためのハブサイト のウィジェットタイトルのように、タイトルを span 要素で囲むことで、きめ細かい装飾を可能にします。

ではさっそく。今回は wp-includes/widgets.php を修正します。
複数個所ありますが、全てやり方は同じで、strip_tags で、stripslashes($_POST['XXXXX-title'])を処理しているところを修正するだけです。

例:380行目付近 wp_widget_pages_control という function の中(他も多数同様)。

$newoptions['title'] = strip_tags(stripslashes($_POST['pages-title']));

これを

$newoptions['title'] = strip_tags(stripslashes($_POST['pages-title']),'<span>');

このようにします。

処理的には、管理画面でウィジェットタイトルを変更したときあたりに呼ばれて、入力値($_POSTの値)をきれいにして、タグも消去、みたいなことをしているので、strip_tags の仕様に基づいて、span 要素を許可するようにした、ということです。

このようにすることで、CSS による装飾の幅が広がります。

HTMLとCSSの例:

<h2 class="widgettitle">monthly archive</h2>

の場合、管理画面で monthly <span>archive</span> と入力することで、

<h2 class="widgettitle">monthly <span>archive</span></h2>

のようになるので、

h2.widgettitle {
	color:#fff;
}

このような CSS に、

h2.widgettitle span {
	color:#000;
}

を追加することで、monthly は白、archive は黒、のようにできます。

あとは CSS の知識の話なので、それはまた別のお話。ということで。

[WPCH vol.02] フィルターをハック。投稿内容を valid に保つには

WordPress の投稿画面は、TinyMCE などによりとても高度なエディタになっています。ただ、タグ入力を手打ちで出来る場合には、若干というか、かなりいただけない仕様があります。それが wpautop フィルターです。

wpautop フィルターは、投稿内容などを整形し、p 要素でマークアップしたり、改行を br 要素に置換するなど、ただのテキストを入力している分には(たぶん)便利なものですが、不用意に改行すると悲しいことになったり、ともかく、投稿内容をそのまま出してよ!という要求をあっさり無視してくれます。

そこで、このフィルターを処理しないようにするために、remove_filter ('the_content', 'wpautop');などを function.php に記述しておくことで対処可能、のはずだったのですが、なぜかWP2.5 日本語版でうまくいきません。未検証なのですが、どこかで何かが悪さをしていて、removeできないようです。このままでは valid かつクリーンなコードが書けない!

というわけで、根本的に処理を止めてしまえ、というわけで、wp-dir/wp-includes/default-filters.php をいじります。


// 110行目付近
add_filter('the_content', 'wpautop');

add_filter('the_excerpt', 'wpautop');

// 上記2つをコメントアウト
// add_filter('the_content', 'wpautop');

// add_filter('the_excerpt', 'wpautop');

これで投稿内容に wpautop フィルターがかからなくなり、投稿(と抜粋)に入力したテキストが、そのまま使われるようになります。当サイトのように、pre 要素などでコードを多く書くとか、タグは手打ち、と考えている人で、同じように remove filter がうまくいかない、という場合に試してみてください。

[WPCH vol.01] ウィジェットをハック。タグクラウドのソート順を変更する

WordPress は様々な動作を、テーマやウィジェットなどに記述することで拡張することができます。ただ、ほんのちょっとのことだったり、こうだと便利なのに!と思う部分を、全部テーマやウィジェットで書き直すのはまず面倒ですし、最終的に全体のパフォーマンスに影響を与えます。

というわけで、新しいウィジェットを書いたり、テーマファイルに特別な記述をしたりするよりも、ほんのちょっとだけコアのプログラムに手を入れて、ほんのちょっとだけ楽したり、自己満足したりするカテゴリーを立ててみました。

第一弾として、多くの人がブログとして使う際に利用しているであろう、タグクラウドの並び順を変更してみます。
ファイルは、wp-dir/wp-includes/widgets.php です。


// 1340行目付近

function wp_widget_tag_cloud($args) {
	extract($args);
	$options = get_option('widget_tag_cloud');
	$title = empty($options['title']) ? __('Tags') : $options['title'];

	echo $before_widget;
	echo $before_title . $title . $after_title;
// wp_tag_cloud 並び順変更(デフォルトは名前の昇順。カウントの降順にする)
//	wp_tag_cloud(); // この行をコメントし、下のようにする
	wp_tag_cloud(array('orderby' => 'count', 'order' => 'DESC'));
	echo $after_widget;
}

上記のように、wp_tag_cloud();を、wp_tag_cloud(array('orderby' => 'count', 'order' => 'DESC'));にすることで、使用頻度(count)の高い順(DESC)に出力させることができます。

function wp_tag_cloud()は、wp-dir/wp-includes/category-template.phpにあって、以下のように書かれています。


// category-template.php function wp_tag_cloud() 内

	$defaults = array(
		'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45,
		'format' => 'flat', 'orderby' => 'name', 'order' => 'ASC',
		'exclude' => '', 'include' => ''
	);

というわけなので、これは次のように設定できることがわかります。


// 先の wp_tag_cloud()の呼び出し箇所

	wp_tag_cloud(array(
		'smallest' => 8,	// styleで定義されるフォントサイズ(小さい)
		'largest' => 22,	// 同上(最も大きい)
		'unit' => 'pt',		// フォントサイズのユニット(ex:pt,em,px)
		'number' => 45,		// リミッター(SQL の LIMIT 句に使われるので、多くのタグを使う場合増やすこと。)
		'format' => 'flat',	// 出力形式。list(デフォルト) と flat(内部的なデフォルト)が使える。array は未調査。
		'orderby' => 'name',	// ソートキー。name と count(内部的なデフォルト) が使える
		'order' => 'ASC',	// ソート順。DESC(降順) と RAND(ランダム) が使える。ASC(昇順)はデフォルト。
		'exclude' => '',	// 含まないタグID(未検証)
		'include' => ''		// 含みたいタグID(未検証)
	);

や、ぶっちゃけ、FC2ブログが同じようにできるらしくて、WPでもできない?って聞かれただけなんですけどね。

注:この情報は、WordPress 2.5 をベースに書かれています。また、WP自体をバージョンアップする場合に、ヘタに上書きしたり、逆に反映し忘れたりしないように、サブバージョン等でのファイル管理をお勧めします。

ホーム > WP Core Hacks

Search
Feeds
Meta


Return to page top