パーソナルツール
現在の場所: ホーム なごぶろ COREBlog2のメディアビューにAmazon Itemを表示
このBlogについて
なごすいぶろぐ。「すべてはなごすいのために」。
カテゴリ
Plone (90)
Plone Products (22)
COREBlog2 (31)
COREBlog1 (29)
ReadingCOREBlog (7)
Zope (63)
Turbogears (18)
Django (12)
Python (23)
Linux (30)
Nagosui (11)
Design (30)
Misc (48)
moblog (5)
最近のエントリ
fastcgiでmercurial on nginx nyusuke 2008年10月08日
Kupuにスタイルを追加する nyusuke 2008年10月06日
Plone Help Centerを導入してみた nyusuke 2008年10月03日
ぽっどきゃすてぃんぐ落語が隔週から毎週に戻る nyusuke 2008年10月02日
最近のコメント
Re:WebデザイナーのためのDjangoはじめの一歩 nyusuke 2007年06月01日
Re:WebデザイナーのためのDjangoはじめの一歩 pateo 2007年05月31日
Re:東海Python Workshop 01終了 nyusuke 2007年05月31日
Re:東海Python Workshop 01終了 kfuruhata 2007年05月30日
 

COREBlog2のメディアビューにAmazon Itemを表示

せっかくATAmazonを使っているのだから、どうせならCOREBlog2でも関連オブジェクトとして画像やら何やらを表示してみたいなぁ。だってそのままだとかっこわるいんだもの。例えばこんな感じ。

メディアビューを設定していない状態←メディアビューを設定してないのでカッコワルイ


メディアビューを設定した状態←メディアビューを設定したのでカッコイイ(・∀・)!


と思ったのでトライ。

まずはCOREBlog2 0.9にて取り込まれたATVideoの関連オブジェクトのコードを書かれたかぶとじゅうぞうさんのエントリを拝見してみると、どうやらmedia_view, getRefByKindを修正することで実現できるようです。

仕組みとしてはgetRefByKindに登録してあるmedia_typeのものが「mediaである」と認識されて、そのビューをmedia_viewで決めるという感じのようです。うーむ、何かお手軽な感じが…。とかいってるとはまるのですが、やっぱりはまりました。

getRefByKindを見てみる

これはすごく簡単みたいです。

# Portal types for media
media_types = ('Image','ATVideo',
               'File:video/quicktime','File:video/x-ms-wmv')

というように、特別なmedia_viewを設定したいportal_typeをここに書いてやればよいようです。

ATAmazonによって提供されるオブジェクトのportal_typeは、ZMIから「ploneインスタンス/portal_types/Amazon Item」で調べることができます。

portal_typeを調べる

これによればportal_typeは「Amazon Item」らしいので、Amazon Itemにmedia_viewを設定するということで以下のようにしてやりました。

# Portal types for media
media_types = ('Image','ATVideo','Amazon Item', ←追加
               'File:video/quicktime','File:video/x-ms-wmv')

しかしアレですね(横道)。

何か36行目あたりインデントがおかしいような気がしなくもないです…。って全然おかしくなかった…。33~35行目が続けて書かれていてるから変な風に見えてしまうんですねorz

33        if obj.portal_type in media_types or \
34           obj.portal_type + ct in media_types or \
35           itool.objectImplements(obj, INTERFACE):
36            if kind == 'media':
37                ret_l.append(obj)
38        elif kind != 'media':
39            ret_l.append(obj)

media_viewはどうなってるの

では次にmedia_viewの方を見てみたいと思います。冒頭にコメントがあります。

Store collection of macros for media object, defining object presentation in entry.
A 'macro id' should be case insensitive portal_type - so image or Image will go well :-).
Some local valiables will pass from parent template

entry_obj : Entry itself.
obj : A object to be shown

「macro idはportal_typeに応じてうまいことやってくれるよ、だから例えばimageでもImageでもOKなのさ」ということらしいけど、「macro id」って何ぃ(*´Д`)…

と、media_viewをよくよく見てみると、どうやらportal_type別にビューが記述されてるようなのですが、それぞれのコードの開始部分がこんな感じになってる。

雑多な関連オブジェクトの場合:

<!-- macro for others - simply call object itself -->
<metal:commentform_macro define-macro="Othrers__">

関連オブジェクトがImageの場合:

<!-- macro for Image -->
<metal:commentform_macro define-macro="image" ~

関連オブジェクトがquicktimeの場合:

<!-- macro for QuickTime Movie(video/quicktime) -->
<metal:commentform_macro define-macro="file_video_quicktime">
関連オブジェクトがATVideoの場合:
<!-- macro for ATVideo by Ryosuke Tajima -->
<metal:commentform_macro define-macro="atvideo" ~
こやつらの共通点はmetalの開始部分。「metal:commentform_macro define-macro="○○"」という部分が同じで、「○○」の部分にportal_typeっぽい名前が入るようになっているようです。さてわこれが「macro id」かっ(゜д゜)y\〟

ということは…。

冒頭部のコメントと考え合わせれば、「metal:commentform_macro define-macro="○○"」と書けば、そのportal_type用のmedia_viewが書ける、という予測がつきます。

しかしこの「○○」の部分に入るportal_typeっぽい名前はどのくらいの冗長性をもっていて、これはどのように実現されているのでしょうか。

答えはgetMediaPresentationの中に

いろいろ探してみるとgetMediaPresentationの中にその秘密があるようです。

# Metal tempate for media handler
tp = container['media_view']
macro_keys = tp.macros.keys()
ct = ''
try:
ct = '_' + obj.getContentType()
ct = ct.replace('/','_')
except:
pass

# First,see object portal_type and return appropreate template
otp = obj.portal_type
lotp = obj.portal_type.lower()

key_trials = [otp,lotp,otp + ct,lotp + ct]

for trial in key_trials:
if trial in macro_keys:
# The macro for object is there !
return tp.macros[trial]

# No custom template, so return object itself...
return tp.macros['Othrers__']

このkey_trialsの中に入っていればOKのようです。入ってなければ雑多なアイテム用のテンプレートが適用されるというわけですな。

key_trialsの中身は、otp, lotp, otp+ct, lotp+ctです。

  • otp→オブジェクトのportal_type(例えばImageとかFileなど)
  • lotp→オブジェクトのportal_typeを小文字にしたもの(例えばimageとかfileなど)
  • ct→オブジェクトのコンテントタイプの「/」を「_」に変えたやつの先頭に「_」がついたもの(例えば_video_quicktimeなど)

なのでkey_trialsの中身は

  • オブジェクトのportal_type
  • オブジェクトのportal_typeを小文字にしたもの
  • オブジェクトのportal_type+オブジェクトのコンテントタイプの「/」を「_」に変えたものの先頭に「_」がついたもの
  • オブジェクトのportal_typeを小文字にしたもの+オブジェクトのコンテントタイプの「/」を「_」に変えたものの先頭に「_」がついたもの

となります。

なので例えば、atvideoのビューは

<metal:commentform_macro define-macro="atvideo" ~

という感じで始まっていますが

<metal:commentform_macro define-macro="ATVideo" ~

としてもOKということです。

ふ~む、仕組みがだんだんわかってきたぞぅ(゜▽゜*)

それじゃAmazon Itemはどうなるのさ

さていよいよ問題なのですがAmazon Itemのビューなのですが、ここがはまりポイントです。なぜならAmazon Itemはホワイトスペースを含むからです。

例えば…

<metal:commentform_macro define-macro="Amazon Item" ~

これはエラーになります。マクロ定義にホワイトスペースは使用できません。

しかし既に見たようにgetMediaPresentationのkey_trialsの中身はotp, lotp, otp+ct, lotp+ctです。このままではホワイトスペースはそのまま残ってしまいます。

っていうかそれ以前にホワイトスペースなんて使うなよっ(;`Д´)

とはいえ何とかしないといけません。のでgetMediaPresentationを編集してやります。35行目あたり。

# First,see object portal_type and return appropreate template
otp = obj.portal_type
try:
    otp = otp.replace(' ','') ←ホワイトスペース除去
except:
    pass
lotp = obj.portal_type.lower()

こんな感じでホワイトスペースを取ってやりました。

これによって「Amazon Item」は

  • opt→AmazonItem
  • lopt→amazonitem

となりますので、テンプレートで利用できるようになります。

Amazon Itemのビューを書く

準備は整いましたので、ビューを書いてみます。Amazon Itemにはタイトルはもちろん、著者や価格などいろんな情報がありますので、どん欲にガンガン表示してやりたいと思います。

コードはportlet_amazonを参考にしてこんな感じでどうでしょう。

    <!-- macro for Amazon Item -->
    <metal:commentform_macro define-macro="AmazonItem"
     tal:define="scale python:test(mediasizestr != 'no_resize',mediasizestr,None);">
    <div class="contentsHanderItem">
        <div class="contentsHanderImageWrapper">
                <a href=""
                     tal:attributes="href obj/getAmazonUrl;
                                   title obj/Title">
                    <img class="contentsHanderImage" tal:attributes="src obj/getImageUrlMedium; alt obj/Title" /><br />
                    <span class="contentsHanderImageCaption" tal:content="obj/Title" > Title </span>
                </a>
        </div>
        <ul>
        <li tal:define="authors obj/getAuthors">
          Author<span tal:condition="python:len(authors) != 1" tal:omit-tag="">s</span>:
          <span tal:content="python:', '.join(authors)">Authors</span>
        </li>
        <li>
          Publisher:
          <span tal:content="obj/getManufacturer">Publisher</span>
        </li>
        <li>
          ISBN:
          <span tal:content="obj/getIsbn">ISBN</span>
        </li>
        <li tal:define="listPrice obj/getListPrice;
                       amazonPrice obj/getAmazonPrice;
               thirdPartyPrice obj/getThirdPartyLowPrice;
                       amazonSavings obj/getAmazonSavings;
                       thirdPartySavings obj/getThirdPartySavings">
          <tal:amazon tal:condition="amazonPrice">
            Amazon Price:
            <strike tal:condition="amazonSavings" tal:content="listPrice">List price</strike>
            <em tal:content="amazonPrice">Price</em>
            <span tal:condition="amazonSavings">&nbsp;&nbsp;&nbsp;&nbsp;<em>You save</em>
              <span tal:content="obj/getAmazonSavings" />
          </span>
          </tal:amazon>
          <br tal:condition="python:amazonPrice and thirdPartySavings" />
          <tal:third_party tal:condition="thirdPartySavings">
            Third Party Price:<em tal:content="thirdPartyPrice">ThirdParty price</em>&nbsp;&nbsp;&nbsp;&nbsp;
              <em>You save</em>
              <span tal:content="thirdPartySavings" />
          </tal:third_party>
        </li>
        </ul>
    </div>
    </metal:commentform_macro>

9行目では画像のsrcをobj/getImageUrlMediumとしていますが、でかすぎると思う場合にはこれをobj/getImageUrlSmallにすればよいですし、(Mediumでも十分大きいですが)小さすぎると思う場合にはobj/getImageUrlLargeにすればOKです。

長くなったので簡単なまとめ

基本的な流れとしては

  1. getRefByKindにportal_typeを追加
  2. media_viewにビューを定義

ですが、portal_typeにスペースが含まれているなどの不都合がある場合には、getMediaPresentationにてKey_trialsに含まれるように操作をする必要があります。

そうすると例えば下記のような感じになります。Amazon Itemをかっこよく表示するときのgetRefByKind, media_view, getMediaPresentationも貼り付けておきますので、おかしなところがありましたらご指摘いただけると嬉しいです~。

次の目標は、mp3とflashですかね(´ω`)っていうか誰か作らないかな…


getRefsByKind.py getRefsByKind.py
サイズ 1.1 kB - File type text/python-source
getMediaPresentation.py getMediaPresentation.py
サイズ 1.2 kB - File type text/python-source
media_view.pt media_view.pt
サイズ 5.4 kB - File type application/octet-stream
トラックバック用URL:
http://nagosui.org/Nagosui/COREBlog2/display-amazon-item-in-media-view/tbping
コメントを追加

下のフォームに記入してコメントを追加できます。平文テキスト形式。

(必須)
(必須)
(必須)
(Required)
Enter the word