<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>高橋文樹.com &#187; Web制作</title>
	<atom:link href="http://takahashifumiki.com/topics/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://takahashifumiki.com</link>
	<description>小説家高橋文樹が自ら情報を発信するブログです。小説・Web制作などの話があります。</description>
	<lastBuildDate>Fri, 18 May 2012 10:30:27 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>僕は君たちに金を配りたい</title>
		<link>http://takahashifumiki.com/web/programing/2041/</link>
		<comments>http://takahashifumiki.com/web/programing/2041/#comments</comments>
		<pubDate>Mon, 07 May 2012 12:32:57 +0000</pubDate>
		<dc:creator>高橋文樹</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[お金]]></category>
		<category><![CDATA[電子書籍]]></category>

		<guid isPermaLink="false">http://takahashifumiki.com/?p=2041</guid>
		<description><![CDATA[先月のCourier Japonで瀧本哲史さんを知ったのですが、書名があまりにも素晴らしかったのでパクりました。 さて、本題です。結論から申し上げますと、僕のサイトの電子書籍を宣伝してくれた方には１冊売れるたびに50%以 [...]]]></description>
			<content:encoded><![CDATA[<p>先月のCourier Japonで瀧本哲史さんを知ったのですが、書名があまりにも素晴らしかったのでパクりました。</p>
<div class="tmkm-amazon-view">
<p class="tmkm-amazon-title"><a href="http://www.amazon.co.jp/%E5%83%95%E3%81%AF%E5%90%9B%E3%81%9F%E3%81%A1%E3%81%AB%E6%AD%A6%E5%99%A8%E3%82%92%E9%85%8D%E3%82%8A%E3%81%9F%E3%81%84-%E7%80%A7%E6%9C%AC-%E5%93%B2%E5%8F%B2/dp/4062170663%3FSubscriptionId%3D0Q5JKQGKGX1PM5K1CPG2%26tag%3Dtakahashifumiki-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4062170663" target="_blank">僕は君たちに武器を配りたい <small>[書籍]</small></a></p>
<p><a href="http://www.amazon.co.jp/%E5%83%95%E3%81%AF%E5%90%9B%E3%81%9F%E3%81%A1%E3%81%AB%E6%AD%A6%E5%99%A8%E3%82%92%E9%85%8D%E3%82%8A%E3%81%9F%E3%81%84-%E7%80%A7%E6%9C%AC-%E5%93%B2%E5%8F%B2/dp/4062170663%3FSubscriptionId%3D0Q5JKQGKGX1PM5K1CPG2%26tag%3Dtakahashifumiki-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4062170663" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41Orzvr-U9L._SL160_.jpg" border="0" alt="僕は君たちに武器を配りたい" /></a></p>
<p><em>価格: </em>￥ 1,890</p><p><em>著者: </em>瀧本 哲史</p><p><em>出版社: </em>講談社</p><p><em>出版日: </em>2011-09-22</p><p><em>商品カテゴリー: </em>単行本</p><p><em>ページ数: </em>296</p><p><em>ISBN: </em>4062170663</p>
<hr class="tmkm-amazon-clear" />
</div>
<p>さて、本題です。結論から申し上げますと、僕のサイトの電子書籍を宣伝してくれた方には１冊売れるたびに50%以上を差し上げることにしました。要するに、アフィリエイト機能ってことですね。</p>
<div id="attachment_2042" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-2042" title="各書籍ページにリンクが出ます（要ログイン）" src="http://s.takahashifumiki.com/wp-content/uploads/2012/05/adwords1-600x344.png" alt="各書籍ページにリンクが出ます（要ログイン）" width="600" height="344" /><p class="wp-caption-text">各書籍ページにリンクが出ます（要ログイン）</p></div>
<p>詳しくは「ハムスターに水を」などの詳細ページをご覧下さい。1,000円以上を超えたら管理画面から申請していただくと、翌月10日に振り込みます。成果を眺めてニヤニヤするための管理画面もがんばって作りました。ヘッダーの「MENU」から飛べます。</p>
<div id="attachment_2044" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-2044" title="下の方にはエリアチャートもあります" src="http://s.takahashifumiki.com/wp-content/uploads/2012/05/adwords3-600x350.png" alt="下の方にはエリアチャートもあります" width="600" height="350" /><p class="wp-caption-text">下の方にはエリアチャートもあります</p></div>
<p>バグがあったらごめんなさい。</p>
<p>&nbsp;</p>
<h2>アフィリエイト機能開発の経緯</h2>
<p>僕のサイトでは自ら電子書籍を売っていますが、まったく売れないので色々と方法を模索しています。で、以前Google Adwordsを試したことがありました。その際の成績が以下の通りです。2ヶ月ぐらい掲載していました。</p>
<div id="attachment_2043" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-2043" title="Adwordsの成果" src="http://s.takahashifumiki.com/wp-content/uploads/2012/05/adwords2-600x284.png" alt="Adwordsの成果" width="600" height="284" /><p class="wp-caption-text">Adwordsの成果</p></div>
<table>
<tbody>
<tr>
<th>クリック数</th>
<td>868</td>
</tr>
<tr>
<th>表示回数</th>
<td>4,549,470</td>
</tr>
<tr>
<th>クリック率</th>
<td>0.02%</td>
</tr>
<tr>
<th>平均クリック単価</th>
<td>¥40</td>
</tr>
<tr>
<th>総額</th>
<td>¥34,662</td>
</tr>
</tbody>
</table>
<p>1回のクリックを40円で買ったことになります。結果だけ端的に申し上げると大赤字でした。</p>
<h3>SEM（検索エンジンマーケティング）は単価が高くないとダメ</h3>
<p>実はSEMの経験はあまりないので、もっと効果的なキーワードで出稿したり、ランディングページをカスタマイズしたり、できることは色々あるのですが、やったところで大した意味ないだろうなーという結論に至りました。</p>
<p>普通こういうクリック広告から来たユーザーのコンバージョン率（ページを見て買おうと思う確率）は1〜3%ぐらいで、かなり高いサイト（楽天の専門店とか）でも12%ぐらいだったような気がします。となると、ぼくのように電子書籍を数百円で売っている場合、Adwordsだと赤字が拡大する一方です。</p>
<p>実はSEOやSEMといった、「検索エンジンに対してコストを投下する広告」というものはある程度商品単価が高くないとダメということが言われています。一つの単価が安いにもかかわらずバンバン広告を打っているものはリピーターになるもの（ex. 健康食品）と言われています。</p>
<p>そういえば、Amazonは一時期「◯◯ならAmazon」という具合にあらゆるキーワードを買っていましたが（<a href="http://togetter.com/li/96555" target="_blank">参考</a>）、あれがずっと謎でした。「高橋文樹ならAmazon」とか出るんですね。ぼくはずっと「文庫１冊のために広告出したら損しちゃうんじゃないの」と思っていたのですが、Amazonの場合は「一度顧客になってくれた人はまたAmazonで◯◯円使う」ということがわかっているはずなので、広告費もそこから捻出しているのではないかと推察します。もちろん、大きな企業なのでGoogleとの契約も普通の出稿者とは異なるとは思いますが、アグリゲーターならではですね。僕のサイトの商品をすべて買ったとしても1,000円ぐらいなので、とても真似はできません。</p>
<h3>Dropboxの事例を参考に</h3>
<p>ファイル共有サービスにDropboxというのがあります。ここは有料サービスを展開しているのですが、あるインタビュー（URL失念）によれば、はじめAdwordsを使ってうまくいかなかったそうです。一人のユーザーを獲得するのに$400ぐらいかかっていたとか。そこでDropboxは「友達を一人紹介したら容量250MBプレゼント」というキャンペーンをはじめたそうです。TwitterとかやっているとDropboxを薦めるつぶやきを見ることがあるでしょう。</p>
<p>あのプロモーションは凄まじい成果を上げ、Dropboxに膨大な数のユーザーを与えたそうです。ユーザーが増えれば、有料サービスをやる人も増えますからね。ちなみに僕も有料ユーザーです。</p>
<p>本当は僕のサイトでもDropboxのようにお金以外の利便性を提供できたらいいのですが、<strong>僕には特にあげられるものがない</strong>ので、お金をあげようと思いました。</p>
<h2>好きな人ほど得をする</h2>
<p>さて、コンテンツを収益化するにあたってよくあるのが「好きな人ほど金を払う」というプレミアムモデルです。信者モデルと言いかえてもいいかもしれません。最近の有料メルマガとかはこの信者モデルではありますが、僕にはたぶん向いていません。というのは、「好きな人ほどコストがかかる」のは変だなーと思うからです。好きな人ほど安くあがるというのが理想です。</p>
<p>このアフィリエイト機能の肝は面白いと思ってくれた読者が得をするという点です。もし僕の書いたものを面白いと思ってくれた人がブログでもTwitterでも紹介してくれれば、それを読んだ人は「面白そうだな」と思う可能性が高いでしょう。しかも、紹介してくれた人はお金まで入ってきます。50%なので、<strong>一作品自腹で買っても2人に売りつければタダ</strong>です。</p>
<p>もちろん、「ほんとうは全然面白いと思っていないけれども売上を上げる人」も出てくるかもしれませんが、それはそれで特異な才能の持ち主ではあるので、別に構いません。また、ウルトラCとして「読んでいないのに人に買わせる」ということも可能ですが、優れた読み手はあたかもすべての本を読んだかのような顔をしているものなので、別にオッケーです。システムの仕様上、買わなくても宣伝できるようにしてあります。</p>
<div class="tmkm-amazon-view">
<p class="tmkm-amazon-title"><a href="http://www.amazon.co.jp/%E8%AA%AD%E3%82%93%E3%81%A7%E3%81%84%E3%81%AA%E3%81%84%E6%9C%AC%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E5%A0%82%E3%80%85%E3%81%A8%E8%AA%9E%E3%82%8B%E6%96%B9%E6%B3%95-%E3%83%94%E3%82%A8%E3%83%BC%E3%83%AB%E3%83%BB%E3%83%90%E3%82%A4%E3%83%A4%E3%83%BC%E3%83%AB/dp/4480837167%3FSubscriptionId%3D0Q5JKQGKGX1PM5K1CPG2%26tag%3Dtakahashifumiki-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4480837167" target="_blank">読んでいない本について堂々と語る方法 <small>[書籍]</small></a></p>
<p><a href="http://www.amazon.co.jp/%E8%AA%AD%E3%82%93%E3%81%A7%E3%81%84%E3%81%AA%E3%81%84%E6%9C%AC%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E5%A0%82%E3%80%85%E3%81%A8%E8%AA%9E%E3%82%8B%E6%96%B9%E6%B3%95-%E3%83%94%E3%82%A8%E3%83%BC%E3%83%AB%E3%83%BB%E3%83%90%E3%82%A4%E3%83%A4%E3%83%BC%E3%83%AB/dp/4480837167%3FSubscriptionId%3D0Q5JKQGKGX1PM5K1CPG2%26tag%3Dtakahashifumiki-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4480837167" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41Nsw%2BD7WWL._SL160_.jpg" border="0" alt="読んでいない本について堂々と語る方法" /></a></p>
<p><em>価格: </em>￥ 1,995</p><p><em>著者: </em>ピエール・バイヤール</p><p><em>クリエーター: </em>大浦 康介</p><p><em>出版社: </em>筑摩書房</p><p><em>出版日: </em>2008-11-27</p><p><em>商品カテゴリー: </em>単行本</p><p><em>ページ数: </em>248</p><p><em>ISBN: </em>4480837167</p>
<hr class="tmkm-amazon-clear" />
</div>
<h2>料率は何%にすべきか？</h2>
<p>今回は50%という料率を設定していますが、個人的には80%ぐらいでもいいと思っています。他に広告費としてさくべき対象も見当たらないので、作品が有名になるにつれて料率を下げていけばいいでしょう。</p>
<p>デジタル時代のコンテンツは価格変動が当たり前ですし、利益も変わります。なにかの間違いで大ブレイクを果たした場合に一番利益が出るようにすればいいのかなーと思います。</p>
<p>いずれにせよ、ここら辺は事例がないのでよくわかりません。トライ＆エラーの繰り返しですね。</p>
<h3>おまけ1. 投稿者に対して還元できる機能も作った</h3>
<p>この機能はWordPressのプラグインとして作っている（参考：<a title="俺の印税がこんなに高いわけがない〜WordPressで電子書籍を販売〜" href="http://takahashifumiki.com/web/programing/1579/" target="_blank">俺の印税がこんない高いわけがない</a>）のですが、投稿者に対しても還元できるようにしました。もしあなたがニュースサイトのようなものを作っていて、投稿者を募っている場合、利益を還元することができます。定期購読の利益分配はできないのですが、上で紹介したリンクのように投稿自体に値段を付けた場合はその投稿作成者が利益を得られます。</p>
<p>僕は無謀にも文学という歴史上マネタイズできていたことがほとんどない分野のものを売ろうとしていますが、料理レシピとか、ペットとか、セックスとか、健康とか、およそ多くの人が興味を持っている分野でそれなりに差別化できればビジネスにはなると思います。</p>
<h3>おまけ2. 今後の予定</h3>
<p>このプラグインですが、今後はこんな機能を予定しています。</p>
<ul>
<li>PayPal Digital Goodsに対応</li>
<li>PayPal Adaptive Payment（定期購読の自動引き落とし）に対応</li>
<li>ウォーターマーク（ePubとかPDFにメールアドレスなどのユーザー情報をon the flyでぶっ込む緩いDRM）</li>
</ul>
<h3>おまけ3. 法律的なこととか</h3>
<p>「お金振り込みます」とか勝手に言っていますが、法律的にアウトだったらAmaoznギフト券に変わります。詳しい人がいたら教えてください。</p>
<h3>おまけ4. 宣伝</h3>
<p>ちなみに、最近破滅派の方で<a href="http://hametuha.com/series/my-ambiguous-literature-in-meta-meta-eras/" target="_blank">メタメタな時代の曖昧な私の文学</a>というエッセーを書いています。電子化の進んだ時代におけるテキストについての考察を重ねたものです。文学とITに興味のある方はぜひ。</p>
<p>Related posts:<ol>
<li><a href='http://takahashifumiki.com/web/programing/774/' rel='bookmark' title='WordPressとFlashでブログ縦書き化計画(10)'>WordPressとFlashでブログ縦書き化計画(10)</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1712/' rel='bookmark' title='WP tmkm Amazonを動くように修正'>WP tmkm Amazonを動くように修正</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1312/' rel='bookmark' title='PayPalのWeb Paymetn StandardとExpress Checkoutの違いが理解できないあなたへ'>PayPalのWeb Paymetn StandardとExpress Checkoutの違いが理解できないあなたへ</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://takahashifumiki.com/web/programing/2041/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ぼくがかんがえたさいきょうのWordPressテーマ開発のはじめかた</title>
		<link>http://takahashifumiki.com/web/programing/2033/</link>
		<comments>http://takahashifumiki.com/web/programing/2033/#comments</comments>
		<pubDate>Wed, 02 May 2012 11:41:09 +0000</pubDate>
		<dc:creator>高橋文樹</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://takahashifumiki.com/?p=2033</guid>
		<description><![CDATA[そろそろテーマを変更しようかなと思っているので、その前準備について。ぼくのサイトのWordPressテーマは子テーマとか既存テーマのカスタマイズではなく、完全フルスクラッチなんですが、その際に「こんな風に作り始めてるよ」 [...]]]></description>
			<content:encoded><![CDATA[<p>そろそろテーマを変更しようかなと思っているので、その前準備について。ぼくのサイトのWordPressテーマは子テーマとか既存テーマのカスタマイズではなく、完全フルスクラッチなんですが、その際に「こんな風に作り始めてるよ」という問わず語りです。</p>
<h2>1. 開発環境</h2>
<p>開発ツールは最近<a href="http://ja.netbeans.org/" target="_blank">Netbeans</a>を使ってます。NetbeansはWordPressのルートフォルダーをプロジェクトに指定すると、関数が予測変換で呼び出せるようになります。グローバル関数なんて全部覚えていられないので、これは便利ですね。変なタイプミスをなくすためにも、予測変換機能は絶対使うようにした方がいいと思います。DreamWeaverもCS5ぐらいからこういう機能が実装されたように思います。</p>
<div id="attachment_2034" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-2034" title="NetBeansの予測変換機能" src="http://s.takahashifumiki.com/wp-content/uploads/2012/05/netbeans1-600x375.png" alt="NetBeansの予測変換機能" width="600" height="375" /><p class="wp-caption-text">NetBeansの予測変換機能</p></div>
<h3>$thisのコードヒント</h3>
<p>いきなり余談ですが、以前はAptanaを使っていました。最近はPythonのお勉強をしていたり、モバイルアプリ作れるTitaniumとかもあるので、Aptanaの後継であるTitanium Studioもよく起動しますが、PHP書く時はNetbeansです。Netbeansに変えたのは$thisの型定義がどうしてもできなかったからです。</p>
<p>CodeIgniterとかCakePHPとかでビューファイルをいじくってるときに、$thisのメソッドを使いたいよーということがあると思います。そういう場合、Netbeansはビューファイルにこんな風に書いておくと、$thisの予測変換が使えるようになります。</p>
<pre class="brush: php; title: ; notranslate">
/* @var $this My_View_Class */
$this-&gt; //これでMy_View_Classのメソッドが出てくる
</pre>
<p>WordPressでも管理画面をバキバキ作っているときなんかは便利です。</p>
<h2>2. 基本フォルダ配置</h2>
<div id="attachment_2036" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-2036" title="基本フォルダ配置" src="http://s.takahashifumiki.com/wp-content/uploads/2012/05/netbeans3-600x257.png" alt="基本フォルダ配置" width="600" height="257" /><p class="wp-caption-text">基本フォルダ配置</p></div>
<p>個別のテンプレートファイルについては割愛しますが、こんな感じです。フォルダの役割に付いて説明しておきます。</p>
<p>&nbsp;</p>
<dl>
<dt>scripts</dt>
<dd>JSファイルを置いておくところ。別にフォルダ名はjsとかでもいいです。</dd>
<dt>compass</dt>
<dd>CSSファイルを置いておくところ。<a href="http://howtohp.com/css/compass.html" target="_blank">compassフレームワーク</a>を使いたいので、compassにしましたが、styleとかでもいいです。</dd>
<dt>functions</dt>
<dd>機能別にまとめたphpファイルを置いておくところ。</dd>
<dt>img</dt>
<dd>画像ファイルを置いておくところ。</dd>
<dt>widgets</dt>
<dd>ウィジェットを置いておくところ。普通はあんまり自作ウィジェットとか作らないかもしれませんが、一応。</dd>
</dl>
<p>&nbsp;</p>
<p>他にも色々必要に応じてフォルダでわけておくといいんじゃないでしょうか。</p>
<h2>3. style.cssは使わないで、はやりのSCSS</h2>
<p>style.cssはテーマの必須ファイルですが、これは使いません。こんな感じでヘッダーだけ書いておきます。</p>
<pre class="brush: css; title: ; notranslate">
/*
THEME NAME: Takahashi Fumiki
THEME URI: http://takahashifumiki.com
DESCRIPTION: Just Only for Takahashi Fumiki
VERSION: 2.0
AUTHOR: Takahashi_Fumiki
AUTHOR URI:http://takahashifumiki.com
*/
</pre>
<p>あとは<a href="http://hail2u.net/documents/sass-and-sassy-css.html" target="_blank">SCSS</a>とかを使います。別に<a href="http://lesscss.org/" target="_blank">LESS</a>でもいいんですが、いずれにせよ保存しただけでコンパイルしてくれるソフトを別に入れておいた方が楽でしょう。</p>
<p><a href="http://havelog.ayumusato.com/computer/software/e218-less_better_css.html" target="_blank">LESSはMac用のアプリがある</a>ので、それを使いましょう。SCSSだと<a href="http://www.moongift.jp/2012/04/20120430/" target="_blank">ついこの間MoonGiftさんで紹介されていたFire.app</a>というのを使うといいと思います。</p>
<h3>Fire.appのインストール方法（Mac）</h3>
<p><a href="http://fireapp.handlino.com/" target="_blank">Fire.appはシェアウェア</a>なのですが、なぜか<a href="https://github.com/handlino/fireapp/" target="_blank">Githubでソースが公開されている</a>ので自分で無料インストールが可能です。Macportsをインストールしたことのある人はすぐ入れられるので、やってみてください。ターミナルほとんど触ったことないし触りたくないという人は$14なので買った方がいいです。</p>
<p>さて、普段rvmとか使ってRails開発とかやってる人は<a href="http://log.nissuk.info/2012/05/fireapp.html" target="_blank">Fire.appのビルド</a>というエントリーを参照すればできます。「はにゃ？　rvmってなあに？」という人は以下の通りにやってください。</p>
<p>インストールにはjrubyとrawrが必要なので入れます。ターミナルでインストールしてください。管理者権限が必要なので、su &#8211; root をするか、sudoをつけてください。</p>
<pre class="brush: bash; title: ; notranslate">
port install jruby
jruby -S gem install rawr
#ダウンロードフォルダに移動
cd ~/Downlods
#githubからクローン
git clone https://github.com/handlino/FireApp.git
cd FireApp
#binフォルダにあるbuild-all.shの2行目の先頭にjruby -Sをつけて実行
jruby -S rake rawr:bundle:all
</pre>
<p>これでFireApp/packages/osxにFireApp.appが作成されます。あとは普通のアプリケーションと同じなので、/Applicationsフォルダに移動して起動します。</p>
<h3>Fire.appの使い方</h3>
<p>SCSSの文法については僕も学び始めたばっかりなのでよく知りませんが、とにかくFireAppにフォルダを監視させると、そのフォルダ内のSCSSファイルを保存するたびにCSSをコンパイルしてくれます。<a href="http://code.google.com/p/scss-editor/" target="_blank">NetbeansにはSCSS用のプラグインもある</a>ので、普通にCSSを編集するようにSCSSを導入することができます。ただ、コンパイルはこのプラグインではなく、Fire.appに任せた方が良さそうです。コンパイルエラーが起きると教えてくれますし。</p>
<div id="attachment_2035" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-2035" title="コンパイルエラーを教えてくれる" src="http://s.takahashifumiki.com/wp-content/uploads/2012/05/netbeans2-600x375.png" alt="コンパイルエラーを教えてくれる" width="600" height="375" /><p class="wp-caption-text">コンパイルエラーを教えてくれる</p></div>
<p>上で紹介したLESS.appも基本的な流れは同じだと思うので、好きな方を試してみてください。<a href="http://dxd8.com/archives/217/" target="_blank">SCSSとLESSの比較記事</a>も見つけました。はじめHAMLとかCoffeeScriptとかを見た時は正気の沙汰とは思えなかったですが、SCSSはいいですね。今後中間言語が当たり前になってくると思いますので、覚えておくといいかもしれません。</p>
<h2>4. functions.phpは設定情報と読み込みだけ</h2>
<p>よくWordPressのTIPS記事なんかに「functions.phpに以下のコードを書いてください」とありますが、functions.phpが増えすぎると困っちゃうので、基本は機能別にファイルをわけて、functionsフォルダに保存し、funcions.phpはそれを読み込むだけにします。</p>
<p>また、バージョン定数のようなものが決まっていると何かと便利なので、デバッグレベルとともにこれも記載しておきます。</p>
<pre class="brush: php; title: ; notranslate">
//テーマ全体のバージョン
define('MY_THEME_VERSION', '1.0');

//デバッグ定数を決めておく
if($_SERVER['SERVER_NAME'] =='takahashifumiki.com'){
     define('MY_DEBUG_LEVEL', 0); //本番
}elseif($_SERVER['SERVER_NAME'] =='d.takahashifumiki.com'){
     define('MY_DEBUG_LEVEL', 1); //ステージング
}else{
     define('MY_DEBUG_LEVEL', 2); //ローカルとか
}

//機能別に分けたファイルを読み込む
get_template_part('functions/override');
get_template_part('functions/assets');
get_template_part('functions/override');
get_template_part('functions/admin');
</pre>
<p>これの何が便利かというと、後述するCSS・JSの読み込みとか、ログ系の関数ですね。var_dumpなんかはデバッグによく使うと思いますが、こんな関数を書いておくと、そのまま本番にアップしても問題ありません。</p>
<pre class="brush: php; title: ; notranslate">
/**
 * 本番環境以外でvar_dump
 */
function var_d(){
     if(MY_DEBUG_LEVEL &gt; 0){
          call_user_func_array('var_dump', func_get_args());
     }
}
</pre>
<p>他にも本番と開発環境で変えたい情報がある場合は、このデバッグ定数を使います。本番だけCDN使うからドメイン変えたいとか、色々あるでしょう。</p>
<h3>分割する利点</h3>
<p>functions.phpを分割する利点としては、他のテーマでも流用が利くということですね。たとえばブラウザ判別なんかはどのサイトでも使うと思いますが、browser.phpというファイルを用意しておいて、以下のような関数書いておくと便利です。</p>
<ul>
<li>IEをバージョン別に判定する関数</li>
<li>スマートフォンか否かを判定する関数</li>
<li>タブレットか否かを判定する関数</li>
<li>Retinaディスプレイか否かを判定する関数</li>
<li>上記の関数を利用して、body_classにクラス名を追加するフィルター関数</li>
</ul>
<p>これらをまとめておけば、他のサイトにコピペで済みます。</p>
<h2>5. CSSとJSは必ずwp_enqueueで読み込む</h2>
<p>CSSとJSは必ずWordPressの関数を使って読み込みます。主にキャッシュ対策と環境変化に対応するためです。</p>
<p>まともなWebサーバなら負荷を軽減するためにmod_expiresなどを使ってCSSやJSをブラウザにキャッシュさせるようになっていますが、ファイルを更新した場合は読み込むファイル名を変えないとキャッシュが残ってしまいます。<strong>「デザイン変更しました。ご確認ください」「変わってないですよ」「F5押してみてください」「あ、変わりましたね」「では、オッケーですね。請求書をお送りいたします」</strong>という会話はもしかしたら日常的に交わされているのかもしれませんが、普通のユーザーはF5押してブラウザキャッシュをクリアしないので、全然オッケーじゃありません。意味が分からないという人はmod_expiresなどでググってみてください。</p>
<p>wp_enqueue_scriptやwp_enqueue_styleはバージョン番号をURLに付与してくれるので、更新を本番に反映させるタイミングで上で紹介したバージョン定数を変えれば済みます。また、以前紹介した<a href="http://takahashifumiki.com/web/programing/1795/" target="_blank">SSLありのWordPressだけど高速化したいからCloudFlareのCDNを無料で使う</a>のように、サイト全体に対して設定を変更するようなハックのメリットが得られなくなってしまうので、出来る限りwp_enqueue_*で読み込むようにしましょう。詳しくは<a href="http://dogmap.jp/2008/07/12/wp_enqueue_script/" target="_blank">wp_enqueue_scriptのススメ</a>などを参考にしてください。</p>
<h2>まとめ</h2>
<p>以上、手短ですが、もう銀行にいかないとしまっちゃうので終わりです。自作テーマを作るのは茨の道ですが、色々と発見も多いのでやってみましょう。</p>
<p>Related posts:<ol>
<li><a href='http://takahashifumiki.com/web/603/' rel='bookmark' title='WordPressが重くなる理由わかった～結局さくらサーバ移転へ'>WordPressが重くなる理由わかった～結局さくらサーバ移転へ</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1679/' rel='bookmark' title='ぼくのユーザーを守って〜Tips on WordPress + SSL〜'>ぼくのユーザーを守って〜Tips on WordPress + SSL〜</a></li>
<li><a href='http://takahashifumiki.com/web/programing/717/' rel='bookmark' title='WordPressクラックされちゃった記念、2.8.4にアップデート'>WordPressクラックされちゃった記念、2.8.4にアップデート</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://takahashifumiki.com/web/programing/2033/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mac OS XにMegaMをインストールする</title>
		<link>http://takahashifumiki.com/web/programing/1992/</link>
		<comments>http://takahashifumiki.com/web/programing/1992/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 11:00:22 +0000</pubDate>
		<dc:creator>高橋文樹</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[自然言語処理]]></category>

		<guid isPermaLink="false">http://takahashifumiki.com/?p=1992</guid>
		<description><![CDATA[現在、文学機械を作るという使命感の元、自然言語処理を勉強するべく『入門　自然言語処理』を紐といています。 基本的にはPythonのNLTK(Natural Language Tool Kit)を使いながらお勉強していくの [...]]]></description>
			<content:encoded><![CDATA[<p>現在、文学機械を作るという使命感の元、自然言語処理を勉強するべく『入門　自然言語処理』を紐といています。</p>
<div class="tmkm-amazon-view">
<p class="tmkm-amazon-title"><a href="http://www.amazon.co.jp/%E5%85%A5%E9%96%80-%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86-Steven-Bird/dp/4873114705%3FSubscriptionId%3D0Q5JKQGKGX1PM5K1CPG2%26tag%3Dtakahashifumiki-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4873114705" target="_blank">入門 自然言語処理 <small>[書籍]</small></a></p>
<p><a href="http://www.amazon.co.jp/%E5%85%A5%E9%96%80-%E8%87%AA%E7%84%B6%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86-Steven-Bird/dp/4873114705%3FSubscriptionId%3D0Q5JKQGKGX1PM5K1CPG2%26tag%3Dtakahashifumiki-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4873114705" target="_blank"><img src="http://ecx.images-amazon.com/images/I/51EoFqAGo1L._SL160_.jpg" border="0" alt="入門 自然言語処理" /></a></p>
<p><em>価格: </em>￥ 3,990</p><p><em>著者: </em>Steven Bird, Ewan Klein, Edward Loper</p><p><em>クリエーター: </em>萩原 正人, 中山 敬広, 水野 貴明</p><p><em>出版社: </em>オライリージャパン</p><p><em>出版日: </em>2010-11-11</p><p><em>商品カテゴリー: </em>大型本</p><p><em>ページ数: </em>592</p><p><em>ISBN: </em>4873114705</p>
<hr class="tmkm-amazon-clear" />
</div>
<p>基本的にはPythonのNLTK(Natural Language Tool Kit)を使いながらお勉強していくのですが、この本の第七章でつまづいたので、シェアしておきます。ちなみに僕の環境はMac OS X 10.7.3でPythonはMacportsで入れた2.6、NLTKも同じくMacportsで入れました。</p>
<h2>MegaMとか言われる</h2>
<p>自然言語処理にまつわるアルゴリスムの紹介を読んで感心しつつひたすら写経していくのがこの本の読み方なのですが、普通に進めていると、第七章 7.3.3でエラーが発生。MegaMが入ってねーぞとか言われます。</p>
<pre class="brush: bash; title: ; notranslate">
===========================================================================
  NLTK was unable to find the megam executable!  Use config_megam() or
  set the MEGAM environment variable.

    &gt;&gt;&gt; config_megam('/path/to/megam')

  For more information, on megam, see:
    &lt;http://www.cs.utah.edu/~hal/megam/&gt;
===========================================================================
</pre>
<p>MegaMってなんやねんと思って調べると、<a href="http://www.nltk.org/download" target="_blank">NLTKのページ</a>に小さく書いてあります。エントロピーを計算するときのライブラリのようですね。</p>
<blockquote><p>MegaM: http://hal3.name/megam/megam_src.tgz (requires ocaml; edit Makefile to set WITHCLIBS to point to location of ocaml .h files; locate these using macports with port contents ocaml, install megam binary, e.g. to /usr/local/bin and set MEGAMHOME to point to this directory).</p></blockquote>
<p>え、こんどはocaml（&#8230;おかむら？）が必要らしいです。言われるがまま、macportsでインストールします。</p>
<pre class="brush: bash; title: ; notranslate">
sudo port install ocaml
which ocaml
# /opt/local/bin/ocaml
</pre>
<p>ちょっと調べてみたところ、ocamlは「オーキャメル」と読むらしいです。</p>
<p>さて、言われるがままMakefileを編集します。./configureじゃない時点で僕はもうなにがなんだかわからないのですが、唯々諾々と従います。</p>
<pre class="brush: bash; title: ; notranslate">
cd ~/Applications
wget http://hal3.name/megam/megam_src.tgz
tar xzvf megam_src
cd megam_0.92
vim Makefile
</pre>
<p>NLTKのサイトに書いてある通り、WITHCLIBSをocamlのヘッダーファイルが入っているフォルダに直します。macportsで入れたやつは普通のUnix系とは変わってしまうので、変えた方が良さそうな奴を片っ端から変えます。</p>
<pre class="brush: diff; title: ; notranslate">
--- Makefile
-CAMLC = ocamlc -g
+CAMLC = /opt/local/bin/ocamlc -g
-CAMLOPT = ocamlopt -unsafe -ccopt -O4 -ccopt -ffast-math -inline 99999
+CAMLOPT = /opt/local/bin/ocamlopt -unsafe -ccopt -O4 -ccopt -ffast-math -inline 99999
-CAMLDEP = ocamldep
+CAMLDEP = /opt/local/bin/ocamldep
-CAMLLEX = ocamllex
+CAMLLEX = /opt/local/bin/ocamllex
-CAMLYACC = ocamlyacc
+CAMLYACC = /opt/local/bin/ocamlyacc
-WITHCLIBS =-I /usr/lib/ocaml/caml
+WITHCLIBS =-I /opt/local/lib/ocaml/caml
</pre>
<p>これでmakeします。</p>
<pre class="brush: bash; title: ; notranslate">
make
# clang: warning: argument unused during compilation: '-fno-defer-pop'
# clang: warning: argument unused during compilation: '-no-cpp-precomp'
# ld: library not found for -lstr
# clang: error: linker command failed with exit code 1 (use -v to see invocation)
# File &quot;fastdot_c.c&quot;, line 1, characters 0-1:
# Error: Error while building custom runtime system
# make: *** [megam] Error 2
</pre>
<p>エラーが起きました。-lstrがないよと怒られています。Makefileの指定がおかしいのかと思ってWITHSTRの項目を直してみましたが、意味なし。</p>
<pre class="brush: diff; title: ; notranslate">
-WITHSTR = str.cma -cclib -lstr
+WITHSTR = /opt/local/lib/ocaml/str.cma --cclib -lstr
</pre>
<p>さんざんググった挙げ句、こんな記事に行き当たりました。最近、stackoverflowの問題解決率高いですねー。</p>
<blockquote><p>The problem appears to be that this Makefile specifies which C compiler and libraries the OCaml compiler should use as its back-end, using the -cc and -cclib options. On most systems, it will work OK to just specify the standard C compiler as the back-end for OCaml. On Mac OS X, there are 32-bit/64-bit architectural complications. Since you can compile OCaml successfully without this Makefile, I&#8217;d suggest that the OCaml compiler already knows how to compile and link OCaml programs. So you might try just removing the -cc and -cclib options from the Makefile.</p>
<p><a href="http://stackoverflow.com/questions/9272566/gcc-ld-symbols-not-found-for-architecture-x86-64" target="_blank"><cite>gcc ld: symbol(s) not found for architecture x86_64</cite></a></p></blockquote>
<p>要するに、ocamlのコンパイラocamlcは-cclibオプションで使うCライブラリを決めるんだけど、macの場合は32bitと64bit両方あるんで下手にオプション指定しないで、ocamlcに自動で読み込ませた方がいいよってことですね。</p>
<p>それでは、この人の言う通り、Makefile内の-cclibオプションを全部消します。</p>
<pre class="brush: diff; title: ; notranslate">
---Makefile
-WITHGRAPHICS = graphics.cma -cclib -lgraphics -cclib -L/usr/X11R6/lib -cclib -lX11
+WITHGRAPHICS =graphics.cma
-WITHUNIX = unix.cma -cclib  -lunix
+WITHUNIX =unix.cma
-WITHSTR = str.cma -cclib -lstr
+WITHSTR =str.cma
-WITHBIGARRAY = bigarray.cma -cclib -lbigarray
+WITHBIGARRAY =bigarray.cma
-WITHNUMS = nums.cma -cclib -lnums
+WITHNUMS =nums.cma
-WITHTHREADS = threads.cma -cclib -lthreads
+WITHTHREADS =threads.cma
-WITHDBM = dbm.cma -cclib -lmldbm -cclib -lndbm
+WITHDBM =dbm.cma
</pre>
<p>これでmakeします。</p>
<pre class="brush: bash; title: ; notranslate">
make
</pre>
<p>通りました。バイナリはどこにあるのかなーと思ったら、ダウンロードしたフォルダにありました。なので、これに対してシンボリックリンクを張ります。</p>
<pre class="brush: bash; title: ; notranslate">
#ユーザー名は自分のに変えてください
ln -s /Users/guy/Applications/megam_0.97/megam /Users/guy/bin/megam
which megam
#/Users/guy/bin/megam
</pre>
<p>これでmegamはインストールできたっぽいので、NLTKのプログラムに戻り、指示通りPython内で設定を行います。</p>
<pre class="brush: python; title: ; notranslate">
nltk.config_megam('/Users/guy/bin/megam')
</pre>
<p>さて、これで動くようになったのですが、トレーニングさせてる間にエラーメッセージを吐き続けるんですよね……</p>
<pre class="brush: python; title: ; notranslate">
chunker = ConsecutiveNPChunker(train_sents)
#optimizing with lambda = 0...
#optimizing with lambda = 0...
#optimizing with lambda = 0...
#これがずっと続く
</pre>
<p>ソースを追ってみましたが、わかりませんでした。<a href="https://groups.google.com/forum/?fromgroups#!topic/nltk-users/bO9NdbJxQck" target="_blank">同じエラーが起きている人はいる</a>のですが、解決はしていないっぽいです。というわけで、大変尻切れトンボですみません。</p>
<h2>自然言語処理を学んでいる感想</h2>
<p>まだ途中なので一概には言えませんが、基本的には機械学習の一分野なので、統計解析を知っていないとどうしようもないなーという感じがします。なので、これが終わったら統計解析の勉強を本格的にやる必要がありますね。</p>
<p>ナイーブベイズとか、交差検定とか、色んなアルゴリスムが出てくるので、これまでのWebサイトを作るためのプログラミングとは違って骨太な感じがします。基本を知れば具体的にやりたいことも固まってくるんじゃないかなーと気長に構えて終わりにします。</p>
<p>Related posts:<ol>
<li><a href='http://takahashifumiki.com/web/programing/794/' rel='bookmark' title='Flashの低帯域ユーザ体験を再現するための低速サーバ構築 on Mac OS X'>Flashの低帯域ユーザ体験を再現するための低速サーバ構築 on Mac OS X</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1985/' rel='bookmark' title='特定のフォルダのPNG画像を全部最適化するMac用ドロップレット'>特定のフォルダのPNG画像を全部最適化するMac用ドロップレット</a></li>
<li><a href='http://takahashifumiki.com/web/programing/777/' rel='bookmark' title='Flex SDK 4のアップデートで色々エラー'>Flex SDK 4のアップデートで色々エラー</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://takahashifumiki.com/web/programing/1992/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>特定のフォルダのPNG画像を全部最適化するMac用ドロップレット</title>
		<link>http://takahashifumiki.com/web/programing/1985/</link>
		<comments>http://takahashifumiki.com/web/programing/1985/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 02:20:03 +0000</pubDate>
		<dc:creator>高橋文樹</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://takahashifumiki.com/?p=1985</guid>
		<description><![CDATA[最近早起きなので、ちょっとしたユーティリティーを作りました。もしかしたらすでに存在しているかもしれませんが、今朝MacOSにOptiPNGをインストールしてコマンドでPNG画像をまとめて軽量化というエントリーを見てGUI [...]]]></description>
			<content:encoded><![CDATA[<p>最近早起きなので、ちょっとしたユーティリティーを作りました。もしかしたらすでに存在しているかもしれませんが、今朝<a href="http://firegoby.jp/archives/2847" target="_blank">MacOSにOptiPNGをインストールしてコマンドでPNG画像をまとめて軽量化</a>というエントリーを見てGUIでできたらいいなーと思ったので作りました。</p>
<dl>
<dt>用途</dt>
<dd>特定のフォルダ以下に存在するPNG画像を最適化する</dd>
<dt>必要構成</dt>
<dd>Mac OS X 10.7以上を使っていて、macports経由でoptiPNGをインストール済み（詳しくは上記エントリー参照）</dd>
</dl>
<h2>使い方</h2>
<p><a href="http://s.takahashifumiki.com/wp-content/uploads/2012/04/OptiPNG.zip">OptiPNG.zip</a>をダウンロードして解凍、中にあるOptiPNG.appをFinderのツールバーにドラッグ&amp;ドロップします</p>
<div id="attachment_1987" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1987" title="OptiPNGをツールバーに追加" src="http://s.takahashifumiki.com/wp-content/uploads/2012/04/optipng1-600x249.png" alt="OptiPNGをツールバーに追加" width="600" height="249" /><p class="wp-caption-text">OptiPNGをツールバーに追加</p></div>
<p>ツールバーにあるOptiPNGのアイコンの上に最適化したいPNG画像が含まれているフォルダをドラッグ&amp;ドロップ</p>
<div id="attachment_1988" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1988" title="最適化したい画像フォルダをD&amp;D" src="http://s.takahashifumiki.com/wp-content/uploads/2012/04/optipng2-600x257.png" alt="最適化したい画像フォルダをD&amp;D" width="600" height="257" /><p class="wp-caption-text">最適化したい画像フォルダをD&amp;D</p></div>
<p>以上です。<a href="http://growl.info/documentation/applescript-support.php" target="_blank">Growlに対応</a>させようと思いましたが、めんどうだったのでやめました。</p>
<h2>Automatorでできるこんなこと</h2>
<p>このアプリ（というか、ドロップレット）はAutomatorで作りました。Automatorは結構便利で、色んなことで来ます。特にファイルのリストを取得するのが簡単なので、Unixコマンドを組み合せると色んなアプリがさくっと作れます。</p>
<div id="attachment_1989" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1989" title="意外と便利なAutomator" src="http://s.takahashifumiki.com/wp-content/uploads/2012/04/15123534a5a6ec5e0a859a1d1391885a-600x382.png" alt="意外と便利なAutomator" width="600" height="382" /><p class="wp-caption-text">意外と便利なAutomator</p></div>
<p>今回はPNGの最適化と組み合わせましたが、他にも色んなUnixコマンドと組み合せることができます。今回書いたワークフローは以下のようなものですが、他でも代替同じです。</p>
<ol>
<li>Automatorを起動して新規アプリケーションを作成</li>
<li><strong>フォルダの内容を取得</strong>を配置</li>
<li><strong>Finder項目にフィルタを適用</strong>を配置し、拡張子pngでフィルタリング</li>
<li><strong>Applescriptを実行</strong>を配置</li>
</ol>
<p>これでApplescriptはファイルのリストを受け取ります。今回のアプリでは、ファイルリストのそれぞれに対して以下のシェルコマンドを発行しているだけです。</p>
<pre class="brush: bash; title: ; notranslate">
optipng $FILE_NAME
</pre>
<p>ただし、ApplescriptのファイルパスはPOSIXじゃなかったような気がするので、そこで一工夫必要です。また、シェルコマンドも環境変数が適用されないので、単純にoptipngとやっても、command not foundになってしまいます。以下のようにやるといいでしょう。</p>
<pre class="brush: objc; title: ; notranslate">
on run {input, parameters}
	--inputにファイルのリストが渡ってきます
	repeat with file_alias in input
		--ファイルのエイリアスをPOSIXパスに変換
		set file_path to (POSIX path of file_alias)
		--シェルコマンドを発行（ログインシェルではないので、コマンドは絶対パス）
		do shell script &quot;/opt/local/bin/optipng &quot; &amp; file_path
	end repeat

	--通知本文を設定
	set notify_text to &quot;処理が終わりました&quot;

	--ダイアログ
	display dialog notify_text giving up after 2 buttons {&quot;OK&quot;} default button 1

	return input
end run
</pre>
<p>ポイントはコマンドをフルパスで書くことと、コマンドを発行する前にファイルパスを変換することでしょうか。</p>
<p>これを応用して do shell command 以下の部分を書き換えれば、色んなドロップレットが作れます。Webサイトを本番環境にデプロイする前にポチッと押すだけになります。</p>
<ol>
<li>特定のフォルダの.svnフォルダを全部削除する</li>
<li>特定のフォルダのCSSやJSすべてをgzipや<a href="http://yuilibrary.com/download/yuicompressor/" target="_blank">YUI Compressor</a>や<a href="http://www.moongift.jp/2009/03/css_compressor/" target="_blank">CSS compressor</a>で圧縮する</li>
<li>QuickTimeやFFmpegを呼び出して動画の形式を変換する</li>
</ol>
<p>そうえいば、3とかは昔仕事で作りましたね。泣きながらソフトバンク向けのH264ハイスペック動画を出力したのはいい想い出です。</p>
<p>もっとも、Unixコマンドをインストールしないといけないことに変わりはないので、「誰でも使える」という感じではないですね。もし「誰でも使える」ことを目指すのなら、時間をかけてCocoaで作り、必要なコマンドは全部バンドルして、AppStoreで売るのがいいと思います。</p>
<h2>おまけ アイコン変えたい</h2>
<p>同梱したアイコンは僕が作ったものですが、ダサいので変えたいという場合は以下の方法で。</p>
<ol>
<li>OptiPNG.appを右クリックして、「パッケージの内容を表示」をクリック</li>
<li>ResourcesフォルダにあるAutomatorApplet.icnsをIconComposer.app（Xcodeをインストールするとついてくるはず）で開く</li>
<li>ドラッグ&amp;ドロップで画像を配置していき、保存</li>
</ol>
<p>注意点としては、アプリをAutomatorで編集してしまうとアイコンが元に戻っちゃうことでしょうか。</p>
<p>Related posts:<ol>
<li><a href='http://takahashifumiki.com/web/programing/802/' rel='bookmark' title='MooShellでJavascriptのコードをブログに貼って自慢する方法'>MooShellでJavascriptのコードをブログに貼って自慢する方法</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1403/' rel='bookmark' title='Mac用テキストエディタの最高峰CotEditorを入力補完できるまで設定する'>Mac用テキストエディタの最高峰CotEditorを入力補完できるまで設定する</a></li>
<li><a href='http://takahashifumiki.com/web/design/1508/' rel='bookmark' title='MacをLion(10.7)にしても挫けなかったけどカラーピッカーで挫けた'>MacをLion(10.7)にしても挫けなかったけどカラーピッカーで挫けた</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://takahashifumiki.com/web/programing/1985/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>いまさらだけどWordPressでAjaxのやり方</title>
		<link>http://takahashifumiki.com/web/programing/1978/</link>
		<comments>http://takahashifumiki.com/web/programing/1978/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 02:59:16 +0000</pubDate>
		<dc:creator>高橋文樹</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[プラグイン]]></category>

		<guid isPermaLink="false">http://takahashifumiki.com/?p=1978</guid>
		<description><![CDATA[先ほど拙作WordPressプラグインのNever Let Me Goをアップデートしたので、その際の作業ログです。基本的にはWordPressを知っていて、PHPとかJavascriptとかはまあわかるかなという人を対 [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1875" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1875" title="Never Let Me Go" src="http://s.takahashifumiki.com/wp-content/uploads/2012/01/de44680d806555fd5ae30d729f6b4f0f-600x196.png" alt="Never Let Me Go" width="600" height="196" /><p class="wp-caption-text">Never Let Me Go</p></div>
<p>先ほど拙作WordPressプラグインの<a href="http://wordpress.org/extend/plugins/never-let-me-go/" target="_blank">Never Let Me Go</a>をアップデートしたので、その際の作業ログです。基本的にはWordPressを知っていて、PHPとかJavascriptとかはまあわかるかなという人を対象にしています。それでは、レッツスタディ。かなり長いですよ。</p>
<h2>成果物</h2>
<p>Ajaxでユーザーを検索して、IDと名前の一覧を取得して表示、選択すると該当するユーザーIDをinputタグにセットします。</p>
<div id="attachment_1979" class="wp-caption aligncenter" style="width: 610px"><img class="size-large wp-image-1979" title="インクリメンタル検索" src="http://s.takahashifumiki.com/wp-content/uploads/2012/04/inc-search1-600x277.png" alt="インクリメンタル検索" width="600" height="277" /><p class="wp-caption-text">管理画面でのインクリメンタル検索</p></div>
<h2>Ajaxを導入した経緯</h2>
<p>Never Let Me Go（以下NLMG）はユーザーが自分で退会できるようにするプラグインなのですが（<a title="GREEよりひどいWordPressの退会機能をなんとかするプラグイン" href="http://takahashifumiki.com/web/programing/1655/">参考</a>）、そのユーザーがコンテンツを作成していた場合、そのコンテンツは消えてしまいます。</p>
<p>Q&amp;Aサイトのようなナレッジサイトを作っていた場合のように、コンテンツが消えちゃうと困るケースがでてきます。ユーザーからすると「自分の書いたものは自分のものなんだから、退会するときは消してほしい」という思いもあるでしょうが、掲示板などのスレッド形式のものは後からコンテンツがなくなると困っちゃいますよね。</p>
<p>で、NLMGはユーザーが退会する場合にコンテンツを特定のユーザーに割り当てる機能を付けることにしました。たとえば、「削除されたユーザー」というユーザーを作っておいて、退会した場合は退会者のコンテンツがすべて「削除されたユーザー」のものになるということですね。こうすればテーマをそれほどいじることなくコンテンツを残すことができます。投稿数ランキングなんかを作っている場合は、「削除されたユーザー」が一位になってしまうという問題がありますが、それぐらいは我慢してコーディングしてもらうことにします。</p>
<p>さて、こうなるとNLMGの設定ページで割当先のユーザーIDを指定する必要があるのですが、素直に考えるとプルダウンにするのが楽ですね。しかしながら、これはこれで問題があります。</p>
<p>ユーザーが3,000人いる場合を想定してもらえばわかると思うのですが、プルダウン（selectタグ）は100件ぐらいが限度で、それ以上になると自分が探しているものを見つけ出すのが困難です。また、3,000件も一気に出力すると、普通はPHPがタイムアウトを起こします。</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php $users; //3,000件のデータが入った配列 ?&gt;
&lt;select name=&quot;users&quot;&gt;
&lt;?php foreach($users as $user): /*3,000回ループ*/?&gt;
    &lt;option value=&quot;&lt;?php echo esc_attr($user-&gt;ID); ?&gt;&quot;&gt;
        &lt;?php echo esc_html($user-&gt;display_name); ?&gt;
    &lt;/option&gt;
&lt;?php endforeach; ?&gt;
&lt;/select&gt;
</pre>
<p>かといってわざわざ別に検索用ページを設けるのも大変なので、Ajax+インクリメンタル検索によって実装すれば、会員が10万人になっても速やかにユーザーIDが取得できるということにします。</p>
<h2>Ajax != DHTML</h2>
<p>たまに勘違いしている人がいるのですが、Ajaxというのは単にHTMLページが切り替わることではなく、ページ遷移することなく裏側でデータを取得しにいくことまで含んでいます。たとえばTwitterのタイムラインを取得するだけならJavascriptをちょろっと書けば動きますが、自分の作ったサイトのデータをAjaxで取得する場合、Javascriptを書くのはもちろん、DBからデータを引っこ抜いてJSONとかXMLに変換して出力しなければなりません。</p>
<p>一概に「Ajaxで更新されるUIを作った」といっても、データを取りにいく先がGoogleマップやTwitterなのか、自分のサイトなのかで負担はかなり違います。ここら辺をきちんと把握していないと痛い目を見ることがよくあります。</p>
<h2>WordPressでAjaxをやるときの定石</h2>
<p>WordPressでは管理画面がAjaxバキバキなので、このための機能が用意されています。基本的なやり方は以下の通りです。</p>
<ol>
<li>wp_ajax_xxxというアクションフックに関数を登録する</li>
<li>POSTまたはGETでリクエストを受け取り、データを返す関数を作成する</li>
<li>エンドポイントに対してリクエストを発行し、結果を受け取るJSを作成する</li>
</ol>
<p>これが基本です。</p>
<h3>1. アクションフックを登録する</h3>
<p>ではまずアクションフックの登録の仕方です。アクションフックの名前はwp_ajaxと自分で決めたアクション名を連結したものになります。今回はユーザー名とIDを検索するものなので、プラグイン接頭辞としてnlmg_という文字列を使い、wp_ajax_nlmg_user_searchとしましょう。</p>
<pre class="brush: php; title: ; notranslate">
add_action('wp_ajax_nlmg_user_search', '_nlmg_user_search');
</pre>
<p>なお、WordPressのAjax機能は元々管理画面向けのものだったため、wp_ajax_xxxというフックはログインしたユーザーにしか有効になりません。ログインしていないユーザー向けにはwp_ajax_nopriv_xxxというフックも用意されているのですが、これはこれでログインしているユーザーには有効にならないという不思議な仕様になっているので、「ログインしているユーザーにもログインしていないユーザーにもAjax用のエンドポイントを用意したい」という場合は両方にフックを登録する必要があります。</p>
<pre class="brush: php; title: ; notranslate">
add_action('wp_ajax_nlmg_user_search', '_nlmg_user_search');
add_action('wp_ajax_nopriv_nlmg_user_search', '_nlmg_user_search');
</pre>
<h3>2. 登録した関数を作成する</h3>
<p>さて、上でフックに登録した関数_my_user_searchの機能を作成します。今日日Ajaxで言葉通りにXMLを使うケースはあまりないので、JSONを出力するようにしましょう。</p>
<p>今回の仕様では、「検索クエリを受け取り、ユーザー一覧を返す」という関数を作ります。「検索クエリをスペースで区切ってAND検索」などという複雑な機能は面倒なので実装しません。ちょっと長いですが、一気に書きます。ポイントは<strong>JSONを出力したあと、dieかexitを使って必ずプログラムを終了させる</strong>ことです。</p>
<pre class="brush: php; title: ; notranslate">
function _nlmg_user_search(){
	//配列の初期値
	$result = array(
		'status' =&gt; false,
		'total' =&gt; 0,
		'results' =&gt; array()
	);
	//ユーザーが管理者でクエリが設定されていたら
	if(current_user_can('manage_options') &amp;&amp; isset($_POST['query'])){
		global $wpdb; //データベース接続オブジェクト
		$query = '%'.(string)$_POST['query'].'%';
		$sql = &lt;&lt;&lt;EOS
			SELECT SQL_CALC_FOUND_ROWS ID, display_name FROM {$wpdb-&gt;users}
			WHERE user_login LIKE %s OR user_email LIKE %s OR display_name LIKE %s
			LIMIT 10
EOS;
		$result['results'] = $wpdb-&gt;get_results($wpdb-&gt;prepare($sql, $query, $query, $query), ARRAY_A);
		$result['total'] = (int)$wpdb-&gt;get_var(&quot;SELECT FOUND_ROWS()&quot;);
		$result['status'] = (boolean)$result['total'];
	}
	//PHPの配列をJSONに変換して出力
	header('Content-Type: application/json; charset=utf-8');
	echo json_encode($result);
	die();
}
</pre>
<p>これで、機能はできたのですが、どのURLにアクセスすればこのJSONが得られるのかを知っていないとJSが書けません。これを知っておきましょう。</p>
<p>wp_ajax_のエンドポイントは<em>ブログのURL/wp-admin/admin-ajax.php</em>です。ただし、フックに登録した関数を起動させるには、リクエストのactionパラメータにwp_ajax_の次に指定した文字列（この場合はnlmg_user_search）を指定しないといけません。また、検索を行うためにはクエリを指定する必要があるので、送信するべきデータはaction=nlmg_user_search&amp;query=［検索したい語句］となります。</p>
<p>この時点でデータの取得がきちんと出来ているかどうかを確かめるためには、<a href="https://addons.mozilla.org/en-US/firefox/addon/restclient/" target="_blank">Firefox拡張</a>とか<a href="https://chrome.google.com/webstore/detail/fhjcajmcbmldlhcimfajhfbgofnpcjmb" target="_blank">Chrome拡張</a>とか、POSTを投げられる機能を持つものを使ってください。</p>
<h3>3. データの取得を行うJSを作成する</h3>
<p>まずはJSを読み込みます。今回はonload.jsというファイルを作成し、管理画面だけで読み込むようにします。JSには読み込みを確認するため、alertでも書いておいてください。</p>
<pre class="brush: jscript; title: ; notranslate">
//onload.js
alert('読み込めたかな？');
</pre>
<pre class="brush: php; title: ; notranslate">
//管理画面でJSを読み込むフックを登録
add_action( 'admin_enqueue_scripts', '_nlmg_enqueue_script' );

function _nlmg_enqueue_script(){
    wp_enqueue_script('nlmg-onload', &quot;path/to/onload.js&quot;, array('jquery'));
}
</pre>
<p>さて、これでとりあえずJSの読みこみはできましたが、一つ問題があります。エンドポイントがブログのURL/wp-admin/admin-ajax.phpだということは書きましたが、これは開発環境（localhost）や本番環境で変わります。プラグインだとなおさら。これをJSにべた書きすることは難しいので、wp_localize_scriptという関数を使ってPHPから値を渡します。</p>
<pre class="brush: php; title: ; notranslate">
function _nlmg_enqueue_script(){
    wp_enqueue_script('nlmg-onload', &quot;path/to/onload.js&quot;, array('jquery'));
    wp_loalize_script('nlmg-onload', 'NLMG', array(
        'endpoint' =&gt; admin_url('admin-ajax.php'),
        'action' =&gt; 'nlmg_user_search'
    ));
}
</pre>
<p>これでNLMGというグローバルオブジェクトに値がアサインされます。</p>
<pre class="brush: jscript; title: ; notranslate">
alert(NLMG.action);
// -&gt; {String} 'nlmg_user_search'
</pre>
<p>やっと準備が出来ました。まずは試しに単純にAjaxを行うコードを書いてみます。</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(document).ready(function($){
    $.post(NLMG.endpoint, {
        action: NLMG.action,
        query: 'テスト'
    }, function(response){
        console.log(response);
        // -&gt; {Object}
    });
});
</pre>
<p>きちんとresponseが返ってきていたらオッケーです。</p>
<h2>インクリメンタル検索の実装</h2>
<p>それでは、インクリメンタル検索の実装をonload.jsにて行っていきます。ベースとなるHTMLはこんな感じにしましょう。</p>
<pre class="brush: php; title: ; notranslate">
&lt;label&gt;
	&lt;?php $this-&gt;e('User ID'); ?&gt;
	&lt;input type=&quot;text&quot; class=&quot;small-text&quot; id=&quot;nlmg_assign_to&quot; name=&quot;nlmg_assign_to&quot; /&gt;
&lt;/label&gt;
&lt;div class=&quot;inc-search-container&quot;&gt;
	&lt;input type=&quot;text&quot; class=&quot;regular-text&quot; id=&quot;user-inc-search&quot; placeholder=&quot;検索してください&quot; /&gt;
	&lt;img class=&quot;loader toggle&quot; src=&quot;&lt;?php echo get_template_directory_uri(); ?&gt;/assets/ajax-loader.gif&quot; width=&quot;16&quot; height=&quot;11&quot; /&gt;
	&lt;ul id=&quot;user-inc-search-result&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
</pre>
<p>#nlmg_assign_toに文字が入力され、それが2文字以上だったら検索を実行し、その結果を#user-inc-search-result内にliタグで表示。さらに#user-inc-search-result内のリンクがクリックされたら、#nlmg_assign_toのvalueを設定します。また、Ajax検索中であることを示すGIF画像も追加しておきます。</p>
<h3>インクリメンタル検索の遅延実行</h3>
<p>キーボードのイベントを補足するのはkeyUpなのですが、日本語の場合は日本語変換モードがあるため、ブラウザ間の挙動もバラバラです。また、打った文字すべてで検索されるというのは負荷も高いですし、そもそもユーザーが意図していない可能性が高いです。「高橋」と入力する途中の「高h」で検索されたらうざいでしょう。WordPressのデフォルトタグ入力欄もちょっと挙動が変（漢字変換を確定させるとタグが決定してしまう）なので、日本語特有の問題といえます。</p>
<p>こうした問題に対処するため、イベント処理は下記のフローで行うことにします。</p>
<ol>
<li>入力イベントをすべて補足し、現在の文字数が2文字以上であるかをチェックする</li>
<li>2文字以上だった場合は、現在の文字を保存する</li>
<li>現在Ajaxリクエストを発生しているかどうかをチェックし、発生していなかったら0.5秒後に検索を行うようにする</li>
<li>Ajaxリクエストは発生していないが、カウントダウン中だった場合はカウントダウンをリセットする</li>
</ol>
<p>これらすべてを実装すれば、「ユーザーが一通り検索語句を入力し終えたタイミングでAjaxリクエストが発生する」ようになります。</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(document).ready(function($){
	var incSearch = {
		currentChar: '',
		timer: null,
		onloading: false,
		setUserId: function(e){
			e.preventDefault();
			$('#nlmg_assign_to').val($(this).attr('href').replace(/[^0-9]/, ''));
		},

		fire: function(){
			incSearch.onloading = true;
			$('.inc-search-container .loader').removeClass('toggle');
			$.post(NLMG.endpoint, {
				action: NLMG.action,
				query: incSearch.currentChar
			}, incSearch.result);
		},

		result: function(response){
			incSearch.onloading = false;
			incSearch.timer = null;
			$('.inc-search-container .loader').addClass('toggle');
			//Empty container
			var container = $('#user-inc-search-result');
			container.empty().css({
				display: 'block'
			});
			if(response.total &gt; 0){
				container.append('&lt;li class=&quot;no-result&quot;&gt;' + NLMG.found.replace(/%%/, response.total) + '&lt;/li&gt;');
				for(i = 0, l = response.results.length; i &lt; l; i++){
					container.prepend('&lt;a href=&quot;#' + response.results[i].ID + '&quot;&gt;' + response.results[i].display_name + '&lt;/a&gt;');
				}
				container.find('a').click(incSearch.setUserId).fadeIn();
			}else{
				container.append('&lt;li class=&quot;no-result&quot;&gt;' + NLMG.noResults + '&lt;/li&gt;').fadeIn('fast', function(){
					setTimeout(function(){
						container.fadeOut();
					}, 2000);
				});
			}
		},

		clearResults: function(e){
			$(this).val('');
			$('#user-inc-search-result').fadeOut('fast', function(){
				$(this).css('display', 'none');
			});
		}
	};

	$('#user-inc-search').keyup(function(e){
		incSearch.currentChar = $(this).val();
		if(incSearch.currentChar.length &gt; 2 &amp;&amp; !incSearch.onloading){
			if(incSearch.timer){
				//Timer exists, reset
				clearTimeout(incSearch.timer);
			}
			//Enqueue AJAX search
			incSearch.timer = setTimeout(incSearch.fire, 500);
		}
	});

	$('#user-inc-search').blur(incSearch.clearResults);
});
</pre>
<p>ポイントとしては、処理の多くをincSearchというオブジェクトにまとめていることでしょうか。jQueryのthisスコープがよくわからないので、いつもこんな感じにしてます。お疲れさまでした。</p>
<h2>Ajaxの便利な使い方</h2>
<p>これはWordPressに限った話ではありませんし、僕自身試していない方法もあるですが、こんなところに使いどころがあるんじゃないかなと思っています。</p>
<h3>スマートフォンサイト対策</h3>
<p>スマートフォンは貧弱なネットワーク環境なので、コンテンツを丸っと読み込むと重いなーということがよくあります。コンテンツを一通り読んでもらった後にスクロール位置を判断しておすすめコンテンツやナビゲーションなどをAjaxで出すのはいいんじゃないでしょうか。</p>
<h3>キャッシュ対策</h3>
<p>最近はNginxとかでプロキシキャッシュを利用することがよくありますが、ユーザーがログインしている場合、これが使えません。ユーザーAとユーザーBの購入履歴ページが混ざっちゃったらヤバいですよね。そこで、ユーザー情報に関してはAjaxで読み込むようにしておけば、サイトの大部分にプロキシキャッシュを適用しつつ、ユーザー最適化されたコンテンツを出力できます。ちなみに高速化の本などを読むと、「AjaxリクエストもGETにしてキャッシュするようにしておけ」とか書いてありますね。</p>
<p>というわけで、一通り書いたのでここで終わります。試してみてください。</p>
<p>Related posts:<ol>
<li><a href='http://takahashifumiki.com/web/programing/1960/' rel='bookmark' title='一般ユーザーがバカと嘆くより早くWordPressポインターを出す'>一般ユーザーがバカと嘆くより早くWordPressポインターを出す</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1440/' rel='bookmark' title='WordPressでデータベースを使ったプラグインを作成する'>WordPressでデータベースを使ったプラグインを作成する</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1829/' rel='bookmark' title='ソート考（WordPressの検索結果を絞り込み）'>ソート考（WordPressの検索結果を絞り込み）</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://takahashifumiki.com/web/programing/1978/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一般ユーザーがバカと嘆くより早くWordPressポインターを出す</title>
		<link>http://takahashifumiki.com/web/programing/1960/</link>
		<comments>http://takahashifumiki.com/web/programing/1960/#comments</comments>
		<pubDate>Thu, 22 Mar 2012 14:38:09 +0000</pubDate>
		<dc:creator>高橋文樹</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[プラグイン]]></category>

		<guid isPermaLink="false">http://takahashifumiki.com/?p=1960</guid>
		<description><![CDATA[例によってWordPressで会員制サイトを運営するときのユーザビリティ向上Tipsです。プラグイン作ったことあるとか、functions.phpをいじってるという人向きです。 ユーザーというのは思いもよらない使い方をす [...]]]></description>
			<content:encoded><![CDATA[<p>例によってWordPressで会員制サイトを運営するときのユーザビリティ向上Tipsです。プラグイン作ったことあるとか、functions.phpをいじってるという人向きです。</p>
<p>ユーザーというのは思いもよらない使い方をするもので、誰でも登録できるようにすると、とんでもないことが起きたりします。また、新しい機能を追加しても、ナビゲーションバーを発見してもらえなかったりして、「使われない」という悲しい事態に陥ります。</p>
<p>こういうことがあると、管理者としては「これだからユーザーってやつは！」と絶望してしまいがちですが、「管理者がWordPressの管理画面を見慣れているだけで、ほとんどの人にとってはそうではない」という専門家にありがちなジレンマが起きているだけともいえます。</p>
<p>とはいえ、Twitterのようにドシンプルにするのも難しいので、都度ユーザーに教えるようなのがあると便利ですね……と思ったら、WordPress 3.3からそういう機能が実装されていました。このやり方を紹介します。</p>
<div id="attachment_1963" class="wp-caption alignnone" style="width: 610px"><img class="size-large wp-image-1963" title="WordPress 3.3から加わった新機能ポインター" src="http://s.takahashifumiki.com/wp-content/uploads/2012/03/zeckerberg-1-600x440.png" alt="WordPress 3.3から加わった新機能ポインター" width="600" height="440" /><p class="wp-caption-text">WordPress 3.3から加わった新機能ポインター</p></div>
<h2>ポインターの出し方</h2>
<p>WordPress 3.3にアップグレードした方は、なにやら青いツールバーが出てきて、ポチッと押すという消えたという経験をお持ちだと思います。これは3.3の新機能であるポインターというもので、プラグインやテーマから呼び出すことができます。任意の要素を指定することができ、メッセージも選べます。こいつは便利ですね！</p>
<p>これを説明するために、オリジナルのプラグイン「Mark Zuckerberg」というの15分ぐらいかけて作りました。管理画面の「ユーザー」の下に「ザッカーバーグ」というリンクが表れ、そのリンクをクリックするとザッカーバーグの名言が書いてあるという、ただそれだけのプラグインです。画像はザッカーバーグのFacebookページから拝借しました。</p>
<p>このプラグインの問題点は有効にしただけだと、なにが起きているのかわからないという点です。管理画面のサブナビゲーション下層メニューは普段隠れていますからね。</p>
<p>設定しないと使えないプラグイン（Twitter IDを入力しないと動かないとか）を作っているとたまにあるのが、「プラグインを有効にしたんだけど動きません！」という問い合わせです。僕なんかはわりと「何か設定しないといけないのかな？」とか思うタイプなのですが、そうではない人も結構いるようです。こんなとき、「ここで設定してね！」というメッセージを出しておけば、プラグイン作者もめんどくさい問い合わせが来なくて幸せ、ユーザーもさくさく使えて幸せという、「手と手を合わせなくても幸せ」状態です。</p>
<h3>1. JSとCSSを読み込ませる</h3>
<p>なにはともあれ、JSとCSSを使うので、それを読み込みます。</p>
<pre class="brush: php; title: ; notranslate">
/**
 * 管理画面にページを追加するフック
 */
function _zuck_admin_menu(){
    //ポインタ用JSとCSSを管理画面に追加するフックを登録
    add_action('admin_print_scripts', '_zuck_scripts');
    add_action('admin_print_styles', '_zuck_styles');
}
add_action('admin_menu', '_zuck_admin_menu');

/**
 * 管理画面でJSを読み込む
 */
function _zuck_scripts(){
    //自分が作ったJS pointer.jsを読み込む。
    //jqueryとwp-pointerに依存することを明示すれば、
    //勝手に読み込んでくれます。詳しくは以下を参照
    //http://codex.wordpress.org/Function_Reference/wp_enqueue_script
    wp_enqueue_script('zuck-pointer', plugin_dir_url(__FILE__).'pointer.js', array('jquery', 'wp-pointer'), 1.0);
}

/**
 * 管理画面でCSSを読み込む
 */
function _zuck_styles(){
    //これだけで登録済みのポインター用CSSが読み込まれます。
    wp_enqueue_style( 'wp-pointer' );
}
</pre>
<p>さて、上の関数でCSSとJSが読み込まれます。この場合、自作のpointer.jsをこんな風にします。</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(document).ready(function($){
    $('.wp-submenu-wrap a[href*=zuckerberg]').pointer({
        content: '&lt;h3&gt;新しいユーザーの登録&lt;/h3&gt;&lt;p&gt;I\'m CEO, Bitch!&lt;/p&gt;',
        close: function(){
            //閉じるが押された時のコールバック
	}).pointer('open');
});
</pre>
<p>「$(element).pointer(option).pointer(&#8216;open&#8217;)って変じゃね？」と思いますが（$(elm).pointer(opt).open()じゃないのか）、まあいいでしょう。これでポインターがjQueryセレクタで指定した要素の近くに表示され、ザッカーバーグの名刺に書いてあるという<q cite="マーク・ザッカーバーグ"> I&#8217;m CEO, Bitch! </q>が表示されます。</p>
<h3>2. ユーザーの「非表示にする」という選択を覚えておく</h3>
<p>表示するだけならどうってことないのですが、ここからがキモです。ユーザーが一度閉じるを押したら、おそらく「わかったよ」という意味であり、毎回これが表示されたらうざったいでしょう。そこで、「非表示にする」が押されたらそれを保存しておくようにします。</p>
<p>このためには、まず設定を保存しなくてはなりません。幸い、そのための方法が用意されています。JSのコールバック関数にこんなのを書きます。</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(document).ready(function($){
    $('.wp-submenu-wrap a[href*=zuckerberg]').pointer({
        content: '&lt;h3&gt;新しいユーザーの登録&lt;/h3&gt;&lt;p&gt;I\'m CEO, Bitch!&lt;/p&gt;',
        close: function(){
            //閉じるが押された時のコールバック
            $.post('/wp-admin/admin-ajax.php', {
                action: 'dismiss-wp-pointer',
                pointer: 'zuckerberg_pointer'
            });
	}).pointer('open');
});
</pre>
<p>これでポインタが閉じると同時にAjaxで「zuckerberg_pointerは非表示」という設定が保存されました。具体的には、dismissed_wp_pointersというユーザーメタにカンマ区切り形式で格納されています。今度は読み込む時の設定をちょっといじりしょう。</p>
<pre class="brush: php; title: ; notranslate">
function _zuck_admin_menu(){
    //非表示設定のポインタ名を取得し、配列に変換
    $dismissed = explode(',', get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ));
    //非表示設定されていないときだけポインタを表示
    if(false === array_search('zuckerberg_pointer', $dissmissed)){
        //ポインタ用JSとCSSを管理画面に追加するフックを登録
        add_action('admin_print_scripts', '_zuck_scripts');
        add_action('admin_print_styles', '_zuck_styles');
    }
}
</pre>
<p>これで「非表示にする」をクリックすると、二度と表示されないようになります。お疲れさまでした。本当はJSとPHPにまたがって定数を記入していたり、AJAXのエンドポイントをJSに直書きにしていたりするのが気持ち悪いのですが、説明するのがめんどくさいのであとは<a href="http://s.takahashifumiki.com/wp-content/uploads/2012/03/zuckerberg.zip">Zipをダウンロード</a>してください。こっちはもうちょっとスマートになってます。</p>
<h2>ポインターのもっといい使い方</h2>
<p>これまで説明した内容でもいいかなーとは思うのですが、なんらかの手順に則って出すのも便利そうです。たとえば、WordPressの投稿画面に生まれて始めて入った人に対して、こんな風に順番で出すのはどうでしょうか。</p>
<ol>
<li>これはタイトルだよ！　いくらなんでもタイトルなしはまずいから絶対入力してね！</li>
<li>これは本文！　ビジュアルエディターというボタンがいっぱいあるだろ？　押すと何かが起きるよ！　お楽しみに！</li>
<li>ここはカテゴリー！　かならずどれか一つのカテゴリーを決めてね！　君のコンテンツがどんなものなのか、ユーザーは知りたがっているよ！</li>
<li>これが公開ボタン！　準備ができたら押してね！　押した瞬間に君のコンテンツは世界中の人に読まれるよ！　準備はいいかな？</li>
</ol>
<p>こんな感じで連続で出し、最後の5個目が非表示にされたら、「今後しない」という設定を保存するという案配です。これでチュートリアルっぽい管理画面になりますね。ソースはめんどくさいので、書きませんが。</p>
<h2>余談：ユーザビリティ向上にはゲームを参考にするといいっぽい</h2>
<p>最近破滅派を誰でも登録できるようにして「あ、そこがわかんないんだ」という経験をすることが多く、ユーザビリティを向上させる必要性を痛感しているのですが、ゲームを参考にするといいみたいですね。</p>
<p>ゲームというのは、それぞれのゲームによってルールが異なるわけで、ユーザーは必ず操作方法を覚えないといけないわけです。しかも、そのユーザーというのは大体子供です。（いまはそうでもないかもしれませんが……）</p>
<p>最近のゲームには必ずチュートリアルが用意されていて、一番簡単なミッションをこなしながら操作方法を覚えていくようにできているそうです。これは大変参考になりますね。そして、徐々に難易度が上がってきて、そのゲームに習熟していくと。『たけしの挑戦状』みたいに不条理なゲームが淘汰されてきたのもこうした流れでしょうか。</p>
<p>僕自身、これまでヘルプやマニュアルを作ったり、スクリーンキャストで操作方法のビデオを作ったりという作業に多大なる時間を費やしてきたのですが、たとえ操作方法のすべてを記しておいたとしても使い方がわからない人というのは出てきます。そういう人はそもそも「使い方を調べる」という発想がないのではないか、そして、けっこう沢山いるんじゃないか、ということに最近気づきました。</p>
<p>そういえば、ロンドンブーツ１号２号の田村淳が昔TVで<q cite="田村淳">僕は携帯電話を買ったら説明書を隅から隅まで読んで、使い方をマスターします。女の子に携帯を見られるようなミスはしません</q>と言っていましたが、もしもすべてのユーザーがそういった人種であったら、iPhoneがこれだけ売れることもなかったでしょう。「何も考えずに初見で使いたい」という人は沢山いるはずなので、ゲームのチュートリアル方式は参考にしていきたいと思います。</p>
<p>ちなみに、jQueryとかでこうしたチュートリアル方式のライブラリはあるみたいなので（ex. <a href="http://embedded-help.net/usage" target="_blank">Embedded help system</a>）、WordPress以外でも採用してみるのはいいかもしれませんね。</p>
<p>Related posts:<ol>
<li><a href='http://takahashifumiki.com/web/programing/360/' rel='bookmark' title='MooToolsとWordPressを使う人が、摩擦の少ない人生を送るために。'>MooToolsとWordPressを使う人が、摩擦の少ない人生を送るために。</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1801/' rel='bookmark' title='Literally WordPress 0.8.8で定期購読とスマートフォン対応'>Literally WordPress 0.8.8で定期購読とスマートフォン対応</a></li>
<li><a href='http://takahashifumiki.com/web/design/937/' rel='bookmark' title='WordPressのテーマちょびっとカスタマイズ'>WordPressのテーマちょびっとカスタマイズ</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://takahashifumiki.com/web/programing/1960/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPressの管理バーを僕は見捨てない</title>
		<link>http://takahashifumiki.com/web/programing/1931/</link>
		<comments>http://takahashifumiki.com/web/programing/1931/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 23:16:51 +0000</pubDate>
		<dc:creator>高橋文樹</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://takahashifumiki.com/?p=1931</guid>
		<description><![CDATA[WordPressの3.0だったか、3.1だったか忘れましたが、管理バー（admin bar）というのが採用されました。WordPressにログインしているユーザーの便宜を計るための粋な計らいだったのですが、江戸時代に多 [...]]]></description>
			<content:encoded><![CDATA[<p>WordPressの3.0だったか、3.1だったか忘れましたが、管理バー（admin bar）というのが採用されました。WordPressにログインしているユーザーの便宜を計るための粋な計らいだったのですが、江戸時代に多くの人が写真を撮られると魂を抜かれると思ったのと同様、大変嫌われました。「WordPress 管理バー 非表示」という検索クエリが飛び交ったことと思います。</p>
<div id="attachment_1932" class="wp-caption alignnone" style="width: 610px"><img class="size-large wp-image-1932" title="みんな嫌いな管理バー" src="http://s.takahashifumiki.com/wp-content/uploads/2012/02/admin-bar-600x317.png" alt="みんな嫌いな管理バー" width="600" height="317" /><p class="wp-caption-text">みんな嫌いな管理バー</p></div>
<h2>なぜWordPressコアに管理バーが採用されたのか？</h2>
<p>僕がまだ高校生だった頃、柔道部のくせに美容院に通っていたのですが、美容師（女）との会話で一つの真理に到達しました。僕が自分でいいと思った髪型（機嫌の悪い浅野忠信みたいなヤツ）よりも、美容師（女）が好きな髪型にした方がいい、と。</p>
<p>師曰く「男の子が考えた髪型だったら世界中の女の子が一人もいいと思わない可能性があるけど、少なくとも私が付き合ってもいいと思う髪型だったら、それはないよね」</p>
<div class="tmkm-amazon-view">
<p class="tmkm-amazon-title"><a href="http://www.amazon.co.jp/%E7%94%B7%E3%81%AE%E3%83%A2%E3%83%86%E9%AB%AA%E9%A0%82%E4%B8%8A%E3%82%AB%E3%82%BF%E3%83%AD%E3%82%B0400-2011-2012%E5%B9%B4%E7%89%88-%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%E3%83%A0%E3%83%84%E3%82%AF/dp/4757334966%3FSubscriptionId%3D0Q5JKQGKGX1PM5K1CPG2%26tag%3Dtakahashifumiki-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4757334966" target="_blank">男のモテ髪頂上カタログ400 2011-2012年版 (インデックスムツク) <small>[書籍]</small></a></p>
<p><a href="http://www.amazon.co.jp/%E7%94%B7%E3%81%AE%E3%83%A2%E3%83%86%E9%AB%AA%E9%A0%82%E4%B8%8A%E3%82%AB%E3%82%BF%E3%83%AD%E3%82%B0400-2011-2012%E5%B9%B4%E7%89%88-%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%E3%83%A0%E3%83%84%E3%82%AF/dp/4757334966%3FSubscriptionId%3D0Q5JKQGKGX1PM5K1CPG2%26tag%3Dtakahashifumiki-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D4757334966" target="_blank"><img src="http://ecx.images-amazon.com/images/I/61Y1feYDLWL._SL160_.jpg" border="0" alt="男のモテ髪頂上カタログ400 2011-2012年版 (インデックスムツク)" /></a></p>
<p><em>価格: </em>￥ 800</p><p><em>出版社: </em>インデックス・コミュニケーションズ</p><p><em>出版日: </em>2011-08-29</p><p><em>商品カテゴリー: </em>ムック</p><p><em>ページ数: </em>151</p><p><em>ISBN: </em>4757334966</p>
<hr class="tmkm-amazon-clear" />
</div>
<p>というわけで、WordPressに管理バーが採用されたのはある程度の理由があると僕は思うのです。</p>
<p>昨今のWebサービスではアカウント登録があるのは当たり前で、それによってパーソナライズをはかっています。ユーザーの側でも「自分のアカウント関係のことは大体右上にあるなー」というのが感覚的にわかっているんではないでしょうか。WordPressもそうしたトレンドを取り入れつつ管理バーを採用したことと思います。</p>
<h2>会員制サービスを運営するにあたって必ず必要になるアカウント周り</h2>
<p>さて、普通のブログを運営していて、「コンテンツを作るのは俺だけな！　おまえら読者どもはコンテンツをありがたく読むだけだぞ！　あ、コメントぐらいはしてもいいからな！　ちゃんとバズらせろよ！」という姿勢であれば、パーソナライズとかはいらないと思いますが、熱心な読者にアカウントを発行し、そのアカウントを利用してその読者向きのコンテンツを提供しようと思っている場合、必ずアカウント操作が必要になります。</p>
<div id="attachment_1948" class="wp-caption alignnone" style="width: 610px"><img class="size-large wp-image-1948" title="Facebookも上に管理バーみたいなのがある" src="http://s.takahashifumiki.com/wp-content/uploads/2012/02/facebook-600x313.png" alt="Facebookも上に管理バーみたいなのがある" width="600" height="313" /><p class="wp-caption-text">Facebookも上に管理バーみたいなのがある</p></div>
<p>&nbsp;</p>
<div id="attachment_1950" class="wp-caption alignnone" style="width: 610px"><img class="size-large wp-image-1950" title="もちろんTwitterも上に管理バーがある" src="http://s.takahashifumiki.com/wp-content/uploads/2012/02/twitter-600x254.png" alt="もちろんTwitterも上に管理バーがある" width="600" height="254" /><p class="wp-caption-text">もちろんTwitterも上に管理バーがある</p></div>
<div id="attachment_1949" class="wp-caption alignnone" style="width: 610px"><img class="size-large wp-image-1949" title="最近話題のPinterestも管理バー" src="http://s.takahashifumiki.com/wp-content/uploads/2012/02/pinterest-600x265.png" alt="最近話題のPinterestも管理バー" width="600" height="265" /><p class="wp-caption-text">最近話題のPinterestも管理バー</p></div>
<p>プロフィールを表示するならプロフィール編集画面が必要になりますし、当然リンクも提供しなければいけません。その他にもそれぞれのユーザーに特化したコンテンツを提供するページが必要になってくるので、そうしたものを丸っとまとめて表示したくなりますね。</p>
<p>その場合、管理バーを非表示にしてスクラッチで作るのではなく、管理バーをカスタマイズした方が楽だと思います。</p>
<h2>管理バーを常に表示する</h2>
<p>この管理バーなのですが、基本的にはログインしているユーザーにしか表示されません。この「表示されたりされなかったり」が魂を抜かれるのではと思う原因です。最近僕がやっきになってリニューアルしている破滅派では、常に表示するようにしてみました。このやり方は簡単です。</p>
<pre class="brush: php; title: ; notranslate">
/**
 * アドミンバーを常に表示
 * @return boolean
 */
function _my_show_admin_bar(){
     return true;
}
add_filter( 'show_admin_bar', '_my_show_admin_bar' , 1000 );
</pre>
<p>これで常に管理バーが表示されるようになります。trueを返す条件を変えれば色々できます。</p>
<ul>
<li>ログインしていても、特定の権限がないと表示しない</li>
<li>IPアドレスやクッキーを見て、特定の場合だけ表示する</li>
</ul>
<p>デフォルトでも、ユーザー１人１人が管理バーを表示するかしないかを選べるようにはなっているのですが、そもそも普通のユーザーは自分が始めて見たものを非表示にしたいとか思わないはずなので、出すなら出す、出さないなら出さないで統一した方が親切だと思われます。</p>
<h2>管理バーの項目をカスタマイズする</h2>
<p>管理バーを出力したのはいいものの、ログインしていない場合はなにも表示されません。これだと困るので、色々調整します。</p>
<pre class="brush: php; title: ; notranslate">
/**
 * 管理バーの項目を変更する
 * @param WP_Admin_Bar $wp_admin_bar
 */
function _my_adminbar( $wp_admin_bar) {
     if ( !is_user_logged_in() ){
          //ログインしていないユーザー向け
          //ウェルカムページへのリンクを追加
          $wp_admin_bar-&gt;add_menu(array(
               'id' =&gt; 'my-blog-logo',
               'title' =&gt; 'ようこそ私のブログへ！',
               'href' =&gt; home_url('/about/')
          ));
          //ログインリンク
          $wp_admin_bar-&gt;add_menu( array( 'title' =&gt; 'ログイン', 'href' =&gt; wp_login_url() ) );
          //新規登録リンク
          $wp_admin_bar-&gt;add_menu( array( 'title' =&gt; '新規登録', 'href' =&gt; preg_replace(&quot;/^.*href=\&quot;([^\&quot;]+)\&quot;.*$/&quot;, &quot;$1&quot;, wp_register('', '', false))));
     }else{
          //ユーザーがログインしていて、投稿権限を持っていたら
          if(current_user_can('edit_posts')){
               $wp_admin_bar-&gt;add_menu(array(
                    'id' =&gt; 'dashboard-shotrlink',
                    'title' =&gt; 'ダッシュボード',
                    'href' =&gt; admin_url(),
                    'parent' =&gt; 'user-actions' /* プロフィールのリンクに追加 */
               ));
          }
     }
     //WordPressとは？のロゴを削除
     $wp_admin_bar-&gt;remove_node('wp-logo');
}
//adminbarにフック。最後に処理したいので、1,000番目に登録
add_action( 'admin_bar_menu', '_my_adminbar', 1000);
</pre>
<p>関数書いてみましたが、ちょっと疲れたので<a href="http://wpdevel.wordpress.com/2011/12/07/admin-bar-api-changes-in-3-3/" target="_blank">Admin Bar API changes in 3.3</a>というエントリーを参考にしてください。色々書いてあります。</p>
<h2>管理バーの見映えを合わせる</h2>
<p>WPerはデザインにこだわる人が多いので、管理バーの許しがたいところに「なんか黒いし、クール」というのがあると思います。日本でクールなのはGacktぐらいなので、これは受け入れがたいでしょう。サイトをクールにするのも一つの手だとは思いますが、いきなり黒い帯をつっこんでも違和感のないサイトは少ないはずなので、せめて色味ぐらいはあわせたいものです。</p>
<p>なので、そのやりかたを紹介……と思ったのですが、基本はCSSだけでなんとかなります。最近はTwitter Bootstlapとかも話題になっているので、「デザインもモジュール化しないとダメなんだな」と思ってるデザイナーも多いことでしょう。管理バーなどは「可変要素が追加され、デザインが統一されている必要のあるパーツ」なので、モジュール的なデザインをするのにうってつけなのではないでしょうか。詳しくは<a href="http://www.wpbeginner.com/wp-tutorials/what-everybody-ought-to-know-about-the-wordpress-admin-bar/" target="_blank">What Everybody Ought to Know about the WordPress Admin Bar</a>（WordPressの管理バーについてみんなが知っておくべきこと）というエントリーを参考にしてください。</p>
<h2>デザインをあえて変えるということ</h2>
<p>WordPressをどう使うかによって判断は色々だと思うのですが、ユーザー登録が自由で投稿も自由なサイトをWordPressで作る場合、管理画面のデザインを必死にカスタマイズするのは考えものだと思います。</p>
<p><a href="http://hametuha.com" target="_blank">破滅派</a>をリニュアールするときは、なるべく管理バーや各種ボタンなどがWordPressデフォルトのものと違和感がないようにはじめっから合わせちゃいました。少なくとも、僕みたいな素人がデザインしたものより、多くの人が熟考を重ねたデザインの方がよいでしょう。カスタマイズするとしても、西川さんの<a href="http://nskw-style.com/2011/wordpress/cawaii-admi.html" target="_blank">Kawaii Admin</a>を使ってCSSだけいじるぐらいにとどめておいた方が無難です。WordPressをフレームワークとして捉えたとき、管理画面をいじる工数は公開画面をいじる工数よりも遥かに高いので、そこらへんのトレードオフをしっかり計算する必要があります。</p>
<p>一般ユーザーを管理画面に入れるべきか否かというのはWordPressをどれだけCGM的に使うかということで判断が分かれると思いますので、あとはお任せします。</p>
<p>ちなみにこのブログでは管理バーを表示していませんが、これは単に管理バーがある前から一生懸命自分で管理バー的なものを実装したら、そのあとすぐに管理バーが実装されたという悲しいボタンのかけちがいによるものです。</p>
<p>Related posts:<ol>
<li><a href='http://takahashifumiki.com/web/programing/1667/' rel='bookmark' title='WordPressのTinyMCEをチキチキにカスタマイズする'>WordPressのTinyMCEをチキチキにカスタマイズする</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1712/' rel='bookmark' title='WP tmkm Amazonを動くように修正'>WP tmkm Amazonを動くように修正</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1266/' rel='bookmark' title='WordPressで会員制サイトを作るときの勘所'>WordPressで会員制サイトを作るときの勘所</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://takahashifumiki.com/web/programing/1931/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iBooks用のePub作成覚え書き（ePub3.0とかフォント指定とか）</title>
		<link>http://takahashifumiki.com/web/design/1842/</link>
		<comments>http://takahashifumiki.com/web/design/1842/#comments</comments>
		<pubDate>Sun, 25 Dec 2011 23:30:07 +0000</pubDate>
		<dc:creator>高橋文樹</dc:creator>
				<category><![CDATA[デザイン]]></category>
		<category><![CDATA[ePub]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[電子書籍]]></category>

		<guid isPermaLink="false">http://takahashifumiki.com/?p=1842</guid>
		<description><![CDATA[最近めっきりePubを触っていなかったのですが、iOS5.0になってからCSS3のサポートが目覚ましく、ePub3.0の対応も縦書き時のページングさえ除けば概ね満足できるレベルまで来たので、拙著『ハムスターに水を』をeP [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1844" class="wp-caption alignleft" style="width: 310px"><a href="http://s.takahashifumiki.com/wp-content/uploads/2011/12/IMG_0808.png"><img class="size-medium wp-image-1844" title="ePub3 on iBooks" src="http://s.takahashifumiki.com/wp-content/uploads/2011/12/IMG_0808-300x450.png" alt="ePub3 on iBooks" width="300" height="450" /></a><p class="wp-caption-text">ePub3 on iBooks</p></div>
<p>最近めっきりePubを触っていなかったのですが、iOS5.0になってからCSS3のサポートが目覚ましく、ePub3.0の対応も縦書き時のページングさえ除けば概ね満足できるレベルまで来たので、拙著『<a title="ハムスターに水を" href="http://takahashifumiki.com/ebook/%e3%83%8f%e3%83%a0%e3%82%b9%e3%82%bf%e3%83%bc%e3%81%ab%e6%b0%b4%e3%82%92">ハムスターに水を</a>』をePub3.0対応にしてみました。以下、その雑感です。</p>
<h2 class="clrL">iBooks日本語組版対応でイケてる内容</h2>
<p>iOS4の時点で「駄目だコリャ」と思ったていたものが改善されたケースが以下になります。</p>
<h3>ルビ対応</h3>
<p>これが今回個人的に一番重要だったものです。あくまで小説家としての意見ですが、ルビというのは見映え（ルビなんてカッコで書いときゃいいじゃん）やアクセシビリティ（低年齢向けに難しい感じは読みがなが振られるべき）の観点とは別に、「ルビそのものが表現の一種である」という意識があります。これから言及するそれ以外の改善点ははっきりいって見映え状の問題に過ぎないとさえ思うのですが、ルビだけは別格です。</p>
<p>ルビというのは、文字とそのメタ文字がバイリニアルに併記される世界的にも珍しい表記法であり、日本に印刷術が持ち込まれてからの最大の革命的副産物だと思います。<ruby><rb>聖剣</rb><rt>エクスカリバー</rt></ruby>とかがそうだと思うのですが、単に「漢字をどのように読むか」というよりも、「ある言葉にどのような意味を付与するか」という遊びのような表現ですね。小説家としてここらへんは譲れないところがあったのですが、対応されて嬉しいです。まあ、詩人などからすると、改行位置を指定できないリフロー型がそもそも許しがたかったりするのでしょうが。</p>
<p>さて、そのルビ対応なのですが、以下のように書けば有効になります。</p>
<pre class="brush: xml; title: ; notranslate">
&lt;ruby&gt;聖剣&lt;rt&gt;エクスカリバー&lt;/rt&gt;&lt;/ruby&gt;
</pre>
<p>ルビに対応していないブラウザ向けにrpというタグもありますが、めんどくさいので今回は割愛。あと、rbタグはCSS3のドラフトから削除されたっぽいので、書かなくてもいいんじゃないでしょうか。</p>
<p>rtタグのデフォルトサイズはよくわかりませんが、0.5emとかにしておけばそれっぽくなるんじゃないでしょうか。</p>
<h3>テキスト両端揃え対応</h3>
<p>テキスト両端揃えが対応されました。和欧入り交じった文章では「ひでーな」と思うこともままありましたが、両端揃えがサポートされたので、我慢できるレベルになりました。</p>
<pre class="brush: css; title: ; notranslate">
p{
text-align:justify;
text-justify:inter-ideograph;
}
</pre>
<p>もしかしたら、設定 &gt; iBooksで両端揃えで有効になるのかもしれません。</p>
<h3>フォントをはじめとする上書き設定の無効化</h3>
<p>iOS4.3ぐらいからだったと思うのですが、いつからかiBooks用のePub作成覚え書き（text-alignハックと明朝体とか）で得意げに書いた明朝体の指定が無効になっていました。「Apple様の指定したフォント以外使うなよこのクズ」と受け取り、半ば諦めていました。</p>
<p>iBooksはフォントの指定が一応できるのですが、なぜか日本語のフォントは一つも入っていません。結果として、すべての文字がヒラギノゴシックで表示されるようになってしまいました。</p>
<p>ところがどっこい、<a href="http://imagedrive.tumblr.com/post/7251542317/using-embedded-fonts-in-epub-for-ibooks" target="_blank">iBooks用のEPUBで埋め込みフォントを使う</a>というエントリーに従って設定ファイルを追加することで、フォントの指定が有効になりました。</p>
<p>これでヒラギノ明朝を使うことができるようになりました。font-familyの指定は<a href="http://blog.imagedrive.jp/web/research/2011/10/20/css-font-family-for-ibooks-on-ios5" target="_blank">iOS5 の iBooks でフォントを指定する方法</a>というエントリーをご覧下さい。</p>
<p>あと、このファイルを追加した副産物として、リンク色を指定できるようになりました。これまではa:linkとかa:visitedとかに色やテキスト装飾を指定しても無視されていたのですが、ちゃんと効くようになりました。もしかしたら、「この程度の情報にも辿り着けないアホはデザインすんじゃねーぞ」っていうAppleからのメッセージなのかもしれませんね。</p>
<h3>圏点サポート</h3>
<p>CSS3がサポートされたので、圏点もサポートされるようになりました。サポートのされ具合は<a href="http://momdo.s35.xrea.com/web-html-test/CSS3-memo/text-emphasis.html" target="_blank">text-emphasis (CSS3 Text)</a>をMobile Safariで見るとわかりやすいです。</p>
<h2>iBooks日本語組版対応でイケてない内容</h2>
<h3>フォント指定</h3>
<p>まだしっかり検証していない情報。フォント指定で以下のように書くことで和欧混植ができたのですが、なんとなく一つ目のフォント以外は無視されているような気がします。</p>
<pre class="brush: css; title: ; notranslate">
font-family:georgia, 'HiraMinProN-W3', serif;
</pre>
<p>いつのバージョンだったか忘れましたが、PC版Safariがfont-familyをちゃんと読まないというバグがありました。他のブラウザは1番目のフォントがなかったら次のフォントという具合に読んでいってくれるので、上記の指定で和欧混植が出来たのですが、無理っぽいですね。</p>
<p>まあ、そのうち対応するでしょう。和漢混植が実現するのはいつのことやら……</p>
<h3>縦書き</h3>
<p>縦書きは表示されますが、ページングが逆になるみたいです。</p>
<h2>その他</h2>
<ul>
<li>ePub3.0になって、メタファイルがどう変わったのかを調べましたが、けっこうめんどくさかった。とりあえず<a href="http://www.epubcafe.jp/jbasic" target="_blank">イーストのサンプル</a>をダウンロードしてことなきを得る。基本は変わってない。</li>
<li>まだePub3.0対応のエディタはないっぽい。Sigilの対応に期待。基本的にはメタファイルのxmlタグ名や属性値なんて覚えたくないので、IDEの発展が待たれる。</li>
<li>Androidのことはよくわからない。</li>
<li><a href="http://labs.adobe.com/downloads/digitaleditions1-8.html" target="_blank">Adobe Digital Editionのプレビュー版</a>があればPCでもそこそこ読める。</li>
</ul>
<h2>終りに</h2>
<p>今回、旧作をアップデートしてみましたが、やはり沢山コンテンツがないと意味ないと思ったので、年内に2〜3本新作を追加してみたいと思います。あと、PDFも作ってると大変なので、しばらくは「iOS5端末を持っている人向けにePub3を出していく」という方針でいきます。</p>
<p>あと、立ち読みページなんかも作ってみましたので、まだ買っていない人は『<a title="ハムスターに水を" href="http://takahashifumiki.com/ebook/%e3%83%8f%e3%83%a0%e3%82%b9%e3%82%bf%e3%83%bc%e3%81%ab%e6%b0%b4%e3%82%92">ハムスターに水を</a>』を見てみてください。。</p>
<div id="fastlookup_top" style="display: none;"></div>
<p>Related posts:<ol>
<li><a href='http://takahashifumiki.com/web/design/1035/' rel='bookmark' title='iBooks用のePub作成覚え書き（ルビ、ジャスティフィケーションetc）'>iBooks用のePub作成覚え書き（ルビ、ジャスティフィケーションetc）</a></li>
<li><a href='http://takahashifumiki.com/web/design/1063/' rel='bookmark' title='iBooks用のePub作成覚え書き（text-alignハックと明朝体とか）'>iBooks用のePub作成覚え書き（text-alignハックと明朝体とか）</a></li>
<li><a href='http://takahashifumiki.com/announcement/984/' rel='bookmark' title='長編小説「ハムスターに水を」ePub版販売開始'>長編小説「ハムスターに水を」ePub版販売開始</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://takahashifumiki.com/web/design/1842/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ソート考（WordPressの検索結果を絞り込み）</title>
		<link>http://takahashifumiki.com/web/programing/1829/</link>
		<comments>http://takahashifumiki.com/web/programing/1829/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 23:00:36 +0000</pubDate>
		<dc:creator>高橋文樹</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[サイト運営]]></category>

		<guid isPermaLink="false">http://takahashifumiki.com/?p=1829</guid>
		<description><![CDATA[僕のブログには一覧ページというものがあるのですが、ここに最近素敵なフォームをつけました。なんと、一覧ページのソート順を変更できるんですね。誰かが羨ましがったら教えてあげようと思ったのですが、誰も聞いてこないので自分で書き [...]]]></description>
			<content:encoded><![CDATA[<p>僕のブログには一覧ページというものがあるのですが、ここに最近素敵なフォームをつけました。なんと、一覧ページのソート順を変更できるんですね。誰かが羨ましがったら教えてあげようと思ったのですが、誰も聞いてこないので自分で書きました。</p>
<p>このフォームのソースはこんな感じです。</p>
<pre class="brush: php; title: ; notranslate">
&lt;form method=&quot;get&quot; id=&quot;sorter&quot; class=&quot;dark_bg center&quot;&gt;
	&lt;p&gt;
		&lt;?php if(is_search()): ?&gt;
		&lt;label&gt;検索&lt;input type=&quot;text&quot; name=&quot;s&quot; value=&quot;&lt;?php the_search_query(); ?&gt;&quot; /&gt;&lt;/label&gt;
		&lt;?php endif; ?&gt;
		&lt;select name=&quot;order&quot;&gt;
			&lt;option value=&quot;ASC&quot;&lt;?php if(isset($_REQUEST['order']) &amp;&amp; $_REQUEST['order'] == 'ASC') echo ' selected=&quot;selected&quot;';?&gt;&gt;昇順&lt;/option&gt;
			&lt;option value=&quot;DESC&quot;&lt;?php if(!isset($_REQUEST['order']) || $_REQUEST['order'] != 'ASC') echo ' selected=&quot;selected&quot;';?&gt;&gt;降順&lt;/option&gt;
		&lt;/select&gt;
		&lt;select name=&quot;orderby&quot;&gt;
			&lt;option value=&quot;date&quot;&lt;?php if(!isset($_REQUEST['orderby']) || $_REQUEST['orderby'] == 'date') echo ' selected=&quot;selected&quot;';?&gt;&gt;公開日&lt;/option&gt;
			&lt;option value=&quot;modified&quot;&lt;?php if(isset($_REQUEST['orderby']) &amp;&amp; $_REQUEST['orderby'] == 'modified') echo ' selected=&quot;selected&quot;';?&gt;&gt;最終更新日&lt;/option&gt;
			&lt;option value=&quot;title&quot;&lt;?php if(isset($_REQUEST['orderby']) &amp;&amp; $_REQUEST['orderby'] == 'title') echo ' selected=&quot;selected&quot;';?&gt;&gt;タイトル&lt;/option&gt;
			&lt;option value=&quot;comment_count&quot;&lt;?php if(isset($_REQUEST['orderby']) &amp;&amp; $_REQUEST['orderby'] == 'comment_count') echo ' selected=&quot;selected&quot;';?&gt;&gt;コメント数&lt;/option&gt;
		&lt;/select&gt;
		&lt;input type=&quot;submit&quot; class=&quot;submit button&quot; value=&quot;SORT!&quot; /&gt;
	&lt;/p&gt;
&lt;/form&gt;
</pre>
<p>ちょっとselected属性を出すのがめんどくさいですが、ようするにGETリクエストで色々値を渡しているだけです。</p>
<h2>なんでこんなことが可能なのか</h2>
<p>この他にも色々できることはあるのですが、基本的に知っておけばいいのは、以下の2点です。</p>
<ol>
<li>WordPressはURLから求められるコンテンツを類推して表示している</li>
<li>URLはごにょごにょ解析され、最終的にquery_postsに渡される</li>
</ol>
<p>とりあえずこれを理解し、以下の例を見てみましょう。</p>
<h3>ex.1 どの一覧ページでも検索してみる</h3>
<p>たとえば、僕のブログにおいてカテゴリーWeb制作のURLは以下になります。</p>
<p>http://takahashifumiki.com/topics/web/</p>
<p>これの尻尾に検索クエリをつけてmootollsを含むURLにしてみます。</p>
<p>http://takahashifumiki.com/topics/web/?s=mootools</p>
<p>そうすると、mootoolsを含む投稿だけが表示されます。不思議ですね！</p>
<div id="attachment_1831" class="wp-caption alignnone" style="width: 310px"><a href="http://s.takahashifumiki.com/wp-content/uploads/2011/12/query.png"><img class="size-medium wp-image-1831" title="検索結果が表示された！" src="http://s.takahashifumiki.com/wp-content/uploads/2011/12/query-300x229.png" alt="検索結果が表示された！" width="300" height="229" /></a><p class="wp-caption-text">検索結果が表示された！</p></div>
<h3>ex.2 日付一覧を古い順にしてみる</h3>
<p>僕のブログの2011年10月のエントリー一覧は以下のURLです。</p>
<p>http://takahashifumiki.com/date/2011/10/</p>
<p>これを古い順にしてみます。</p>
<p>http://takahashifumiki.com/date/2011/10/?order=ASC</p>
<p>どうでしょう、 古い順になってますよね。</p>
<div id="attachment_1830" class="wp-caption alignnone" style="width: 310px"><a href="http://s.takahashifumiki.com/wp-content/uploads/2011/12/order-asc.png"><img class="size-medium wp-image-1830" title="順番が変わった！" src="http://s.takahashifumiki.com/wp-content/uploads/2011/12/order-asc-300x249.png" alt="順番が変わった！" width="300" height="249" /></a><p class="wp-caption-text">順番が変わった！</p></div>
<p>このように、WordPressはURLに色んなクエリ（?key1=value1&amp;key2=value2）を渡すことで、表示される結果がコントロールできるということです。このkeyとvalueに何を使えるかは、Codexを参考にしてください。色々あります。</p>
<h2>絞り込み検索を実装してみる</h2>
<p>おそらく需要が高いであろう絞り込み検索もそんなにめんどくさくありません。ためしに僕のサイトで、カテゴリーが「その他（ID:10）」または「文芸活動（ID:3）」に属していて、なおかつ「web」という単語を含むページの一覧を表示するためには以下のURLでOKです。</p>
<p>http://takahashifumiki.com/?s=web&#038;cat=3,10</p>
<div id="attachment_1832" class="wp-caption alignnone" style="width: 310px"><a href="http://s.takahashifumiki.com/wp-content/uploads/2011/12/search.png"><img class="size-medium wp-image-1832" title="検索結果で特定のカテゴリーのみ出力" src="http://s.takahashifumiki.com/wp-content/uploads/2011/12/search-300x240.png" alt="検索結果で特定のカテゴリーのみ出力" width="300" height="240" /></a><p class="wp-caption-text">検索結果で特定のカテゴリーのみ出力</p></div>
<p>つまり、こういう値を渡してくれるフォームを作ればいいだけですね。ただし、カンマ区切りで値を渡してくれるインターフェースはないので、Javascriptでサポートする必要があります。</p>
<pre class="brush: php; title: ; notranslate">

&lt;form id=&quot;search-form&quot; method=&quot;get&quot; action=&quot;&lt;?php bloginfo('url');?&gt;&quot;&gt;
   &lt;label&gt;&lt;input type=&quot;text&quot; name=&quot;s&quot; value=&quot;&lt;?php the_search_query(); ?&gt;&quot; /&gt;&lt;/label&gt;
   &lt;p&gt;
   &lt;?php
      //登録されたカテゴリーを名前の昇順で取得
      $cats = get_categories(array('orderby' =&gt; 'name', 'order' =&gt; 'asc'));
      foreach($cats as $cat){
         //ループ処理でカテゴリーを全部出力
         printf('&lt;label&gt;&lt;input class=&quot;cat&quot; type=&quot;checkbox&quot; value=&quot;%d&quot; /&gt;%s&lt;/label&gt;', $cat-&gt;term_id, $cat-&gt;name);
      }
   ?&gt;
   &lt;/p&gt;
   &lt;input type=&quot;hidden&quot; name=&quot;cat&quot; value=&quot;&quot; /&gt;
   &lt;input type=&quot;submit&quot; value=&quot;検索&quot; /&gt;
&lt;/form&gt;
</pre>
<p>本当は現在設定されているカテゴリーを選択済みにする処理などあるのが望ましいですが、割愛。<a href="http://wpdocs.sourceforge.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/get_categories" target="_blank">get_categoriesについてはCodexを確認</a>してください。</p>
<p>上記で出力されたフォームだけだとcatが常に空っぽになってしまうので、こんなJavascriptを読み込みます。</p>
<pre class="brush: jscript; title: ; notranslate">
jQuery(document).ready(function($){
      //フォーム送信直前に実行
     $('#search-form').submit(function(e){
          //チェックボックスのチェック済みをすべて取得
          var cats = [];
          $('input.cat:checked').each(function(index, elt){
               cats.push($(elt).val());
          });
          //1つ以上チェックされていたら隠しinputに格納
          //なかったら削除
          if(cats.length &gt; 0){
               $('input[name=cat]').val(cats.join(','));
          }else{
               $('input[name=cat']).remove();
          }
     });
});
</pre>
<p>これでカテゴリーによる絞り込み検索は実装できます。他にもタグとかカスタムフィールドとかもできるので、色々試してみてください。ポイントはCodexをよく読むことです。</p>
<h2>さらなるカスタマイズは茨の道</h2>
<p>よくWordPressを導入した場合に言われるのが「Googleみたいに便利な検索機能をつけられないか」ということなのですが、これが難しいのは技術的な問題もさることながら、もっと高次な問題があるように思います。「ゆらぎ検索」や「低レイテンシ」などの様々な技術的難題を突破したとしても、最後に「どんな基準で表示するか」という最大の難問が発生するからです。逆に言えば、これさえわかってしまえば答えは出たも同然です。</p>
<p>Googleが便利なのは「どんな順番で検索結果を表示するとユーザーが便利だと思うか」ということだけを考えているからです。基準もちゃんと持ってます。</p>
<ul>
<li>たくさんのサイトからリンクされているWebページはいいページ</li>
<li>いいサイトからリンクされているWebページはいいページ</li>
<li>東京の人は東京の店舗情報を知りたいに違いない</li>
<li>友達が進めているWebページは気に入るに違いない</li>
</ul>
<p>最近はどんどんパーソナライズの方向へ向かっているので、Googleならびに各種検索エンジン・SNSはこうしたデータをやっきになって集めているのですね。便利さはあくまで結果でしかないわけです。</p>
<p>翻ってWordPressのことを考えてみると、よくも悪くもブログシステムが元になっているので、発想の根本がブログ（つまり日記）です。このエントリーで紹介しているソート機能というのは、突き詰めれば「コンテンツをどう評価するかの基準」ということになります。WordPressは日記が元なので、時系列がデフォルトのソート順になっています。</p>
<p>WordPressはデフォルトのままだと「いまこのサイトを誰が見ているか」も知らないし、「このページがどれだけアクセスされたか」もわかりません。評価しようにも評価するべき基準がないのです。この基準を集めるのは結構大変です。ちょっと幾つか具体例を考えてみました。</p>
<h3>ケーススタディ１ PVでソート</h3>
<p>PVというWordPressが持っていない外部的な指標によってコンテンツをソートする場合を考えてみます。これはMySQL知らなくてもできますね。僕もまだ実践したわけではなく、今度こういうのを作ろうと思っているだけなので、概要だけサラッと。</p>
<ol>
<li><a href="http://code.google.com/intl/ja/apis/analytics/docs/gdata/home.html" target="_blank">Google AnalyticsでAPIを叩いて</a>特定のURLを取得する</li>
<li>取得したPVをカスタムフィールドに保存する</li>
<li>上記の処理をwp_cronなどで毎週実行する</li>
</ol>
<p>こんな感じでPVという情報を投稿に不可することは可能です。とりあえずこれでWordPressに「どれだけの人は見たか」ということを教え込ませることはできたので、色々ソートできます。まあ、この程度のことしかやらないなら、Jetpackに入ってるstats使った方が楽ですね。</p>
<h3>ケーススタディ2 はてなブックマーク方式</h3>
<p>ここからMySQLの知識が必要になります。WordPressはデフォルトだと、タグと投稿は1対1の関係になります。これをテーブル構造的に見るとこうなります。</p>
<div id="attachment_1833" class="wp-caption alignnone" style="width: 610px"><a href="http://s.takahashifumiki.com/wp-content/uploads/2011/12/terms1.png"><img class="size-large wp-image-1833" title="通常のタクソノミー関係構造" src="http://s.takahashifumiki.com/wp-content/uploads/2011/12/terms1-600x266.png" alt="通常のタクソノミー関係構造" width="600" height="266" /></a><p class="wp-caption-text">通常のタクソノミー関係構造</p></div>
<p>これだと、タグはあくまで投稿のメタデータにしかならず、あんまり有用な情報ではありません。日付とかと一緒ですね。</p>
<p>一方、はてなブックマークはタグとURLは紐づいていますが、さらにそのタグとURLに対する関係にユーザーが入ってきます。「誰がどのURLにどんなタグをつけたか」ということですね。これをテーブル構造的に見るとこうなります。</p>
<div id="attachment_1834" class="wp-caption alignnone" style="width: 610px"><a href="http://s.takahashifumiki.com/wp-content/uploads/2011/12/terms2.png"><img class="size-large wp-image-1834" title="はてぶっぽいテーブル構造" src="http://s.takahashifumiki.com/wp-content/uploads/2011/12/terms2-600x255.png" alt="はてぶっぽいテーブル構造" width="600" height="255" /></a><p class="wp-caption-text">はてぶっぽいテーブル構造</p></div>
<p>これはWordPressのテーブル構造にないので、作らないといけなくなります。これは単にデータベースをphpMyAdminで作ればいいというだけのことではなく、CRUDというデータの保存・検索・更新・削除の機能をつけなくてはいけないですし、一覧ページをどうやって出力するかも考えなくてはなりません。ここら辺になるとフレームワークを使った方が早いんじゃないかなーと思い始める人が出てきますね。</p>
<p>ただ、コンテンツを漫然と並べ立てるだけでは飽き足らなくなった場合、これは避けて通れない道だと思います。Web制作業についているだけであれば、学習コストや開発工数をトレードオフして「やらない」という結論もぜんぜんアリだとは思うのですが、コストを度外視してでも実現したいものがある人は、ぜひMySQLを勉強してみることをオススメします。そうじゃないと、新しいものを作れないような気がします。その理由は次節。</p>
<h2>凡庸・オア・ダイ</h2>
<p>最近破滅派をリニューアル作業をしていてとみに思うのが、データをどのように蓄積してどのように評価するかが結局キモでありコンテンツなんだなーということです。ちょっと前ですが、はてなからGREEに移籍した<a href="http://naoya.hatenablog.com/entry/2011/11/22/234059" target="_blank">伊藤直也さんが古巣に提言した内容</a>もそうなんですが、最近ちょっとエッジの効いたサービスをやろうと思ったら、ユーザー最適化などは避けて通れないですね。ロラン・バルトが言ってた作者の死ってこういうことだったんですかね。</p>
<p>PVや「いいね!」「はてぶ」の数などの外部的な指標を上述したような単純なやり方で自分のサイトに持ち込んでも、結局は同じ結果になると思います。伊藤直也さんは「衆愚」という言葉を使っていましたが、<q cite="セオドア・スタージョン">たしかにSFの90%はクズだが、そもそもあらゆるものの90%はクズである</q>とか、<q cite="マルセル・プルースト『失われた時を求めて』">どこに国に行っても馬鹿の数が一番多い</q>とか、<q cite="ウィンストン・チャーチル">民主主義は最悪の政治制度だ、ただしこれまで試みられたあらゆる政治制度を除けば</q>と言い換えてもいいかもしれません。はてなブックマークのトップを見ていると、「いつまで部屋片付けてんだ？」「何年TOEIC勉強してんだ？」って思うことしきりですからね。こんなこと書くと炎上しますかね。</p>
<p>ともかく、集計＆ソーティングというのはすでに陳腐な技術であり、そこらへんのフリーソフトでサクッと実現できてしまいます。その結果、どんな指標を使ったにせよ、出来上がるものは大体似たようなものになってしまいまそうな予感。このままいったら僕らはみんなマトリックスにつながれて、偽物の幸福な夢を見ながらGoogleの餌になるしかないですよ。</p>
<p>ちょっと話が大きくなりましたが、ますます便利になりつつあるインターネッツの世界でエッジの効いたデータ提示をしたかったら、茨の道だけどMySQLいじるようにした方がいろいろ捗るぞというメッセージでした。</p>
<div class="tmkm-amazon-view">
<p class="tmkm-amazon-title"><a href="http://www.amazon.co.jp/%E3%83%9E%E3%83%88%E3%83%AA%E3%83%83%E3%82%AF%E3%82%B9-%E3%82%B9%E3%83%9A%E3%82%B7%E3%83%A3%E3%83%AB%E3%83%BB%E3%82%A8%E3%83%87%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3%E3%80%90%E5%AD%97%E5%B9%95%E7%89%88%E3%80%91-VHS-%E3%82%A2%E3%83%B3%E3%83%87%E3%82%A3%E3%83%BB%E3%82%A6%E3%82%A9%E3%82%B7%E3%83%A3%E3%82%A6%E3%82%B9%E3%82%AD%E3%83%BC/dp/B00005HCUI%3FSubscriptionId%3D0Q5JKQGKGX1PM5K1CPG2%26tag%3Dtakahashifumiki-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00005HCUI" target="_blank">マトリックス スペシャル・エディション【字幕版】 [VHS] <small>[ビデオ]</small></a></p>
<p><a href="http://www.amazon.co.jp/%E3%83%9E%E3%83%88%E3%83%AA%E3%83%83%E3%82%AF%E3%82%B9-%E3%82%B9%E3%83%9A%E3%82%B7%E3%83%A3%E3%83%AB%E3%83%BB%E3%82%A8%E3%83%87%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3%E3%80%90%E5%AD%97%E5%B9%95%E7%89%88%E3%80%91-VHS-%E3%82%A2%E3%83%B3%E3%83%87%E3%82%A3%E3%83%BB%E3%82%A6%E3%82%A9%E3%82%B7%E3%83%A3%E3%82%A6%E3%82%B9%E3%82%AD%E3%83%BC/dp/B00005HCUI%3FSubscriptionId%3D0Q5JKQGKGX1PM5K1CPG2%26tag%3Dtakahashifumiki-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00005HCUI" target="_blank"><img src="http://ecx.images-amazon.com/images/I/5166SZSKV0L._SL160_.jpg" border="0" alt="マトリックス スペシャル・エディション【字幕版】 [VHS]" /></a></p>
<p><em>価格: </em>￥ 4,179</p><p><em>監督: </em>アンディ・ウォシャウスキー, ラリー・ウォシャウスキー</p><p><em>出演者: </em>キアヌ・リーブス</p><p><em>出版社: </em>ワーナー・ホーム・ビデオ</p><p><em>商品カテゴリー: </em>VHS</p>
<hr class="tmkm-amazon-clear" />
</div>
<div id="fastlookup_top" style="display: none;"></div>
<p>Related posts:<ol>
<li><a href='http://takahashifumiki.com/web/programing/1440/' rel='bookmark' title='WordPressでデータベースを使ったプラグインを作成する'>WordPressでデータベースを使ったプラグインを作成する</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1348/' rel='bookmark' title='WordPressでbloginfoなくしてもDB負荷は減らないんじゃないかという話'>WordPressでbloginfoなくしてもDB負荷は減らないんじゃないかという話</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1266/' rel='bookmark' title='WordPressで会員制サイトを作るときの勘所'>WordPressで会員制サイトを作るときの勘所</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://takahashifumiki.com/web/programing/1829/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress使ってても巨人の肩に乗れ</title>
		<link>http://takahashifumiki.com/web/programing/1821/</link>
		<comments>http://takahashifumiki.com/web/programing/1821/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 13:44:31 +0000</pubDate>
		<dc:creator>高橋文樹</dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[プラグイン]]></category>

		<guid isPermaLink="false">http://takahashifumiki.com/?p=1821</guid>
		<description><![CDATA[さて、先日「忠実なファンは1000人で足りるか〜電子書籍時代の皮算用〜」というエントリーをアップしてもさして話題になっていない不肖高橋ですが、己の電子書籍売上をアップすべく、またWordPressのプラグインを作って公開 [...]]]></description>
			<content:encoded><![CDATA[<p>さて、先日「<a title="忠実なファンは1000人で足りるか〜電子書籍時代の皮算用〜" href="http://takahashifumiki.com/literature/reading/1813/">忠実なファンは1000人で足りるか〜電子書籍時代の皮算用〜</a>」というエントリーをアップしてもさして話題になっていない不肖高橋ですが、己の電子書籍売上をアップすべく、またWordPressのプラグインを作って公開しました。プラグイン名を間違ったまま公開するという大チョンボをやらかしましたが、まだ9人しかダウンロードしてないしいいよね。</p>
<h2>新プラグインGianism</h2>
<p><a href="http://wordpress.org/extend/plugins/gianism/" target="_blank">http://wordpress.org/extend/plugins/gianism/</a></p>
<p>プラグイン名は「ジャイアニズム」と読みます。これは簡単に言うと、WordPressにTwitterやFacebookでログインできるようにするものです。詳しくはこのサイトの<a href="https://takahashifumiki.com/login/">ログインページ</a>を見てみてください。</p>
<div id="attachment_1824" class="wp-caption alignnone" style="width: 610px"><img class="size-large wp-image-1824" title="ログインページにボタン追加" src="http://s.takahashifumiki.com/wp-content/uploads/2011/12/a1e0bbe0d11e529f4a022c3f8d9f650f-600x422.png" alt="ログインページにボタン追加" width="600" height="422" /><p class="wp-caption-text">ログインページにボタン追加</p></div>
<p>実は<a href="http://wordpress.org/extend/plugins/social-connect/" target="_blank">Social Connect</a>というほぼ同じ機能を提供するプラグインがあったりしますが、おそらく100年待ったところで日本のサービスには対応しないだろうなと思ったので、作りました。ただ、作ってはみたものの、OAuthで接続する場合のライブラリがあったりなかったり（あってもPEARだったり）でめんどくさくなったので、mixiなどにはまだ対応していません。すいません。「mixiのヘビーユーザーってどうせ電子書籍買わないんじゃないの」という邪推があったのは内緒です。こちらもあわせてすいません。</p>
<h2>Gianismの見所</h2>
<p>というわけで、機能的に特に目新しいところはないのですが、お勉強のために車輪の再発名をしたわけではありません。このプラグインはそもそも僕のサイト用に作ったので、「Twitterやmixiのように外部サイトに対して認証機能を提供しているが、メールアドレスは渡さないサービス」向けの機能を備えています。まあ、他のプラグインをよく見ていないので、もしかしたらそういう機能があったのかもしれませんが。</p>
<p>で、どうなるかというと、GianismはWordPressで内部的に使われるメール送信関数wp_mailをフックし、そのメッセージを保存します。送信されるはずだったメールはユーザーのプロフィールページに一覧として表示され、ちょど簡易Webメールのような感じになります。</p>
<div id="attachment_1825" class="wp-caption alignnone" style="width: 610px"><img class="size-large wp-image-1825" title="プロフィールページにメッセージ一覧" src="http://s.takahashifumiki.com/wp-content/uploads/2011/12/8b83db6aced85ee00601cfad36fb4c49-600x429.png" alt="プロフィールページにメッセージ一覧" width="600" height="429" /><p class="wp-caption-text">プロフィールページにメッセージ一覧</p></div>
<p>そしてさらに、登録した外部サービスを経由して、「高橋文樹.comだけど、あなたにメッセージがあるよ http://example.jp/wp-admin/profile.php 」という具合にメッセージがある旨を教えます。</p>
<div id="attachment_1822" class="wp-caption alignnone" style="width: 547px"><img class="size-full wp-image-1822" title="TwitterにDM送信" src="http://s.takahashifumiki.com/wp-content/uploads/2011/12/a63c8a201787e1940fdd9af8fc9d9ff6.png" alt="TwitterにDM送信" width="537" height="498" /><p class="wp-caption-text">TwitterにDM送信（日本語化は完了してます）</p></div>
<p>僕が作っている電子書籍販売用プラグイン<a href="http://wordpress.org/extend/plugins/literally-wordpress/" target="_blank">Literally WordPress</a>は振込にも対応しているため、メール送信が必須です。というより、振込先をメールしないとほぼ確実に振り込んでもらえません。かといってTwitterは140文字以内という制限があるためメール全文をそのままDMも無理…というわけで、こんな仕様になりました。</p>
<p class="message notice">一応、検証してはいますが、届かない場合もあるみたいです。この機能はβ版という位置づけにしておきます。</p>
<p>あと、地味な機能ですが、FacebookのファンページでWordPressを使っている場合、その人がファンかどうかも判別できる関数もつけときました。<a href="https://www.facebook.com/TakahashiFumiki.Page" target="_blank">僕のファンページ</a>はこちらです。</p>
<p>ECショップ系のプラグインを使っている方は、うまくいけば連携できると思います。</p>
<h2>Gianismの名前の由来</h2>
<p><a title="「Facebookアプリ開発徹底入門」ePub買ってみた雑感" href="http://takahashifumiki.com/web/programing/1699/">「Facebookアプリ開発徹底入門」ePub買ってみた雑感</a>でもちょろっと書きましたが、「お前のものは俺のもの」というジャイアニズムと、プログラミングの世界でよく言われる格言「巨人の肩に乗れ」の二つをかけました。その結果としてずいぶん滑った名前になりましたが、もう出しちゃったからしょうがないです。</p>
<h2>Gianismの今後</h2>
<p>とりあえずログインまではできたのですが、なるべくよそのメディアでバズを作るような機能を盛り込んでいきたいと思います。と同時に、国産サービスでOAuthを公開しており、なおかつ良さげなAPIを備えているところも追加していきます。こんなのがあると便利ですかね。</p>
<ol>
<li>WordPress内の特定のURLをいいねしてくれたかどうかわかる</li>
<li>twitterでURLを含んだツイートが合計100RTされたかどうかわかる</li>
<li>上記の指標を累計して、ファンの忠誠度を計る</li>
</ol>
<p>なんか嫌らしい機能ばっかりですが、がんばって実装したいと思います。</p>
<h2>困ったときは</h2>
<p>使ってみて動かなかったら、この記事にコメントしてください。メールでも一応お答えするようにしますが、コメントで公開した方が同じ問題で困っている人に役立つので。</p>
<h2>その他雑感</h2>
<p>先述した「千人の忠実なファン」モデルですが、僕個人にはあんまり向いてないかなーという気もしています。僕と親しい人にはバレているのですが、ファンサービスに向いている人間ではないのです。</p>
<ul>
<li>人からメールが来ても応えない場合が結構ある</li>
<li>誘われたら行くけど自分から誘わないし誘ってくれとも言わない</li>
<li>自分が持っている名刺全部にBCCでメール送らない</li>
</ul>
<p>軽く列挙しただけでもこれだけの悪習を備えていますし、もう30歳も超えて矯正する気もないので、「高橋文樹のことを大好きで出すものを何でも買ってくれるファン」を増やすのは正直難しいんじゃないかと思っています。</p>
<p>ただそうはいってもファンを増やさないことには飢えてしまうので、「高橋文樹のことがちょっと気になっていて、何か出したら買ってみようかなと思ってくれるファン」を増やすことにしました。</p>
<p>ファンとのリレーションを保つために「自分のマメさ」とかは信頼できないので、なるべくプログラムなどで外部化したいと思います。乞うご期待。</p>
<div id="fastlookup_top" style="display: none;"></div>
<p>Related posts:<ol>
<li><a href='http://takahashifumiki.com/web/programing/1801/' rel='bookmark' title='Literally WordPress 0.8.8で定期購読とスマートフォン対応'>Literally WordPress 0.8.8で定期購読とスマートフォン対応</a></li>
<li><a href='http://takahashifumiki.com/web/programing/919/' rel='bookmark' title='WordPressでrubyタグを挿入できるプラグイン作った'>WordPressでrubyタグを挿入できるプラグイン作った</a></li>
<li><a href='http://takahashifumiki.com/web/programing/1766/' rel='bookmark' title='Literally WordPressを0.8.6に更新'>Literally WordPressを0.8.6に更新</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://takahashifumiki.com/web/programing/1821/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>

