謎解きウェブ

なぜなにどうして。

Amazon Web ServiceとRightFields Pluginを連携させてみた(3)

text:

前回・前々回でそれぞれAmazon Web Service ECS 3.0の使い方と、RightFields Pluginの設置方法について解説しました。あまりにも限定的かつ簡単すぎる解説であんまり役に立っていないよという噂はさておき、多分最終回の今回は、ECS 3.0とRightFields Pluginの連携・ページへの広告埋め込み方法について書いてみます。

いちおう目的を振り返っておくと、新規エントリー作成時にRightFields Pluginで作成した拡張フィールドへ「キーワード」と「商品ジャンル」を入力し、生成されたエントリーページにそれに対応するAmazon商品広告を動的に埋め込む、というものです。これにより常に新鮮な広告を表示しつつ、その内容についてはある程度制御が出来るという状態になります。まあ広告・広告と言っておりますが、それをちゃんと自分でやってみようというのがそもそもの主旨でございます。

前々回にRightFields Pluginで「キーワード」「商品ジャンル」というフィールドを作成し、また前回はECS 3.0のデータ取得・(X)HTML化を解説しました。ECSのデータ取得用URLはフォーマットが決まっているわけですから、このフォーマットにRightFieldsを組み合わせることができればいいわけです。これはもう見てしまった方が早いと思うのですが、

<MTExtraFields>
  <MTIfExtraFields>
    http://xml.amazon.com/onca/xml3
    ?t=worldending-22
    &dev-t=1ZVTCEVFR0STNWHJHE82
    &KeywordSearch=<MTIfExtraField field="awskey"><$MTExtraFieldValue field="awskey" encode_url="1"></MTIfExtraField>
    &mode=<MTIfExtraField field="awstype"><$MTExtraFieldValue field="awstype"></MTIfExtraField>
    &type=heavy
    &locale=jp
    &f=http%3A%2F%2Fblog-worldending.onotakehiko.com%2Faws.xsl
  </MTIfExtraFields>
</MTExtraFields>

※実際にはURL部分の改行は必要ありません。
※各プロパティのパラメータは適宜変更してください。

とすれば、各エントリーごとに固有のキーワードと商品ジャンルが指定された、データ取得用URLが生成されます。あとはこのURLをコールして得られる出力結果すなわちソースを、「個別エントリーページ」テンプレートの任意の場所に埋め込むことを検討すればOKです。外部ソースや外部ファイルの埋め込みにはインラインフレームをはじめやり方はいくつかあると思いますが、僕はPHPを利用しました。

PHPの場合に埋め込みによく使われるのは「include("ファイル名")」か「require("ファイル名")」だと思いますが、実はこれが上手くいく場合とそうでない場合とがあります。結論から言うと、XSLTによって成形された出力データがXHTMLのときはNGになります。自分がいったいどちらの形でデータを取得しているかを知るには、出力結果を見ても結構ですが、まずは作成したXSLTファイルを確認しましょう。僕の作ったXSLTファイルはリンク先の通りですが、ソースの3行目に

<xsl:output method="xhtml" encoding="utf-8" indent="yes"/>

とあります。ここで出力ソースをHTMLにするかXHTMLにするかを指定可能なのですが、このブログのソースをそもそもXHTMLで記述しているため、上記の通りXSLT出力ソースもXHTMLに設定しています。

では、XHTMLの場合になぜPHPのinclude()やrequire()がNGになるかという点ですが、それはXHTMLのXML宣言が原因です。出力データのソース中、先頭にある

<?xml version="1.0" encoding="utf-8"?>

がXML宣言となります。この部分でinclude()やrequire()ではシンタックス・エラーが発生してしまうのです。正直ジャマなのですが、XHTMLでXML宣言をするのはむしろ正しいことですし、XSLT出力ソースには有無を言わさず入ってくるものですので、この部分だけ出力されないようにすることを考えるのはナンセンスです。

というわけで、XML宣言のソースを「無視」するかたちで読み込む方法。

<MTExtraFields>
  <MTIfExtraFields>
    <?php
      $handle = fopen("http://xml-jp.amznxslt.com/onca/xml3?
      t=worldending-22
      &dev-t=1ZVTCEVFR0STNWHJHE82
      &KeywordSearch=<MTIfExtraField field="awskey"><$MTExtraFieldValue field="awskey" encode_url="1"></MTIfExtraField>
      &mode=<MTIfExtraField field="awstype"><$MTExtraFieldValue field="awstype"></MTIfExtraField>
      &nosim=1
      &type=heavy
      &locale=jp
      &f=http%3A%2F%2Fblog-worldending.onotakehiko.com%2Faws.xsl", 'rb');
      fseek($handle, 38);
      while (!feof($handle))
      {
        echo fread($handle, 4096);
        flush();
      }
      fclose($handle);
    ?>
  </MTIfExtraFields>
</MTExtraFields>

※実際にはURL部分の改行は必要ありません。
※各プロパティのパラメータは適宜変更してください。

細かい点は端折りますが、fseek($handle, 38); で、出力ソース中のまずXML宣言(先述の例で言うと38文字)の終わった39文字目へ移動し、それ以降を読み込んで、ページに出力をするという方法です。これならPHPでエラーが発生することもありません。

以上でいっちょあがり。あとは実際にエントリーに対しキーワードや商品ジャンルを指定して、ページを再構築して確認してみてください。上手くいっていれば動的にAmazonの商品広告が表示されていることでしょう。もちろん、CSSでのデザインもお忘れ無くですが。

いやいや〜、畑ちがいなのにエラそうに書き始めてしまったのが過ちでした...。技術系の話は書き出したらキリがないね。ぜんぜん情報量足りないと思いますし間違いがところどころあるかもしれませんが、まあ大目に見てやってください!