おぎろぐはてブロ

なんだかんだエンジニアになって10年以上

r3 と stickleback を試してみる - テンプレートの特殊化

デモのチュートリアルを引き続き試してみます。
今日のところは、

  • テンプレートの特殊化 (specialize)

あたりです。

テンプレートの特殊化

注) specializing = 特殊化と訳してます。なんかすっきりしない
テンプレートの中のいくつかをコピーして、違うプロダクトとintlに変更します。ここの例では、最終的に、下の表の様な構成にします。

プロダクトIntl内容
specific product (特定のプロダクト)specific intl (特定のintl)コンテンツ
generic_intlサイト・ブランディング、ナビゲーション
generic_productspecific intl (特定のintl)(ヘッダ)
generic_intlコンテナ, ヘッダ, コア・ブランディング

ヘッダについてはgeneric_productの下の特定のintlレベルで特殊化をしています。

補足) specific と generic

specific productは、特定のプロダクトを指しており。ここでは、cookery, wine, cars。specific intlは同じく、us, ca, fr, jpです。
generic_productは、全てのプロダクトが継承している(共通の祖先)、特定のプロダクトに属さない仮想的なプロダクト。generic_intlも同じく。プロジェクトの事前設定を参照してください。

補足) コアブランディングとサイトブランディング

例えば、コアブランディングが、"Yahoo!"、で、サイトブランディングが "News" や "Mail" といった感じかなと思います。コアとなるブランドは、Yahoo!で、それにぶら下がるサブサイトとして、"Yahoo! News" や "Yahoo! Mail" があると。

特殊化する

ここでは、全12個のプロダクトとintlの組み合わせを全て別々に特殊化していきます。
特殊化するために、特定のターゲットのページを生成するために探される全てのロケーションを見る必要があります。これは以下のように実行できます。

$ r3 template searchpath cookery/us/index.html

  0         cookery/us/index.html
  1         cookery/us/generic
  2         cookery/generic_intl/index.html
  3         cookery/generic_intl/generic
  4         generic_product/us/index.html
  5         generic_product/us/generic
  6         generic_product/generic_intl/index.html index.html.ros
  7         generic_product/generic_intl/generic

cookery/us/index.htmlを生成するために探している場所を表示しています。左の数字(レベル)が少ない方がより詳細のものとなっていて、最も大域である generic_product/generic_intl/generic から始まり、最も詳細な cookery/us/index.html まで続いています。
特定のターゲットの視点から、特定のテンプレートについて見たいときは、オプション引数にテンプレート名を加えます。

$ r3 template searchpath cookery/us/index.html content.ros

  0         cookery/us/index.html
  1         cookery/us/generic
  2         cookery/generic_intl/index.html
  3         cookery/generic_intl/generic
  4         generic_product/us/index.html
  5         generic_product/us/generic
  6         generic_product/generic_intl/index.html content.ros
  7         generic_product/generic_intl/generic

content.rosは、レベル6のgeneric_product/generic_intl/index.htmlで見つかることが分かります。
content.rosを、このターゲットの最も詳細なレベル(左側の数字のレベル0)で、特殊化したいと思います。

$ r3 template specialize cookery/us/index.html content.ros 0
Template specialised from generic_product/generic_intl/index.html to cookery/us/index.html

  0         cookery/us/index.html            content.ros
  1         cookery/us/generic
  2         cookery/generic_intl/index.html
  3         cookery/generic_intl/generic
  4         generic_product/us/index.html
  5         generic_product/us/generic
  6         generic_product/generic_intl/index.html content.ros
  7         generic_product/generic_intl/generic

注意: これは、複製操作であり、移動ではありません。元のcontent.rosはgeneric levelに存在しており、他のプロダクトとintlではまだ参照されています。この複製したcontent.rosが使われるのは、cookery/us/index.html だけです。
では、cookery/us/index.html用のcontent.rosを編集していきます。テンプレートをエディタで開いて、

$ vim $R3HOME/templates/cookery/us/index.html/content.ros

以下のように修正します。

Content: Cookery in the USA

他のプロダクトとintlについても、この操作を繰り返したとしましょう。以下のようなコマンドで、各ターゲットの特殊化とvimの編集を順に行えます。

$ for product in cookery wine cars 
  do for intl in us ca fr jp 
  do r3 template specialize $product/$intl/index.html content.ros 0 
  vim $R3HOME/templates/$product/$intl/index.html/content.ros 
  done 
  done

終わったら、再生成します。

$ r3 generate -a
generating cars/ca
generating cars/fr
generating cars/generic_intl
generating cars/jp
generating cars/us
generating cookery/ca
generating cookery/fr
generating cookery/generic_intl
generating cookery/jp
generating cookery/us
generating generic_product/ca
generating generic_product/fr
generating generic_product/generic_intl
generating generic_product/jp
generating generic_product/us
generating wine/ca
generating wine/fr
generating wine/generic_intl
generating wine/jp
generating wine/us

生成されたファイルを試しに表示してみると、

  • $R3HOME/htdocs/cars/ca/index.html
Container: Container
Header: Header
Core Branding: Core Branding Site Branding: Site Branding
Navigation: Navigation Content: Canadian Ford Cars
  • $R3HOME/htdocs/cars/fr/index.html
Container: Container
Header: Header
Core Branding: Core Branding Site Branding: Site Branding
Navigation: Navigation Content: Peugeot
  • $R3HOME/htdocs/cars/jp/index.html
Container: Container
Header: Header
Core Branding: Core Branding Site Branding: Site Branding
Navigation: Navigation Content: Nissan Micra

などといった感じ。各ページが自身の特殊化されたコンテンツを表示していることに注意してみてください。

話変わりますけど...

ここのチュートリアルで、cars/jp/index.htmlに書かれている車名 "Nissan Micra" って、欧州で販売されてる日産マーチのオープンカーなんですね。「マイクラC+C」は2007年7月に日本発売で、予約受付中ですって。

generic intlレベルでプロダクトを特殊化

次に、site_branding.rosnavigation.ros を特定のプロダクトにおいて、しかし、特定のintlには属さない generic_intl のレベルで特殊化します。これは、プロダクトの中の全てのintlが、同じサイトブランディングとナビゲーションのテンプレートを共有することができるということを意味します。 (補足: 2つの .rosファイルは以前に作ったテンプレートです。前のエントリの「テンプレートの編集」セクションを参照)
また、wineプロダクトにおいて、サイトブランディングをcookeryから継承することを許可します。
まず、site_branding.roscookery/generic_intl/index.html のレベルで特殊化します。

$ r3 template searchpath cookery/us/index.html site_branding.ros

  0         cookery/us/index.html
  1         cookery/us/generic
  2         cookery/generic_intl/index.html
  3         cookery/generic_intl/generic
  4         generic_product/us/index.html
  5         generic_product/us/generic
  6         generic_product/generic_intl/index.html site_branding.ros
  7         generic_product/generic_intl/generic

$ r3 template specialize cookery/us/index.html site_branding.ros 2
Template specialised from generic_product/generic_intl/index.html to cookery/generic_intl/index.html

  0         cookery/us/index.html
  1         cookery/us/generic
  2         cookery/generic_intl/index.html  site_branding.ros
  3         cookery/generic_intl/generic
  4         generic_product/us/index.html
  5         generic_product/us/generic
  6         generic_product/generic_intl/index.html site_branding.ros
  7         generic_product/generic_intl/generic

特殊化したテンプレートのロケーションが、cookeryプロダクトの他のintlでも見えることを確認します。

$ r3 template searchpath cookery/jp/index.html site_branding.ros

  0         cookery/jp/index.html
  1         cookery/jp/generic
  2         cookery/generic_intl/index.html  site_branding.ros
  3         cookery/generic_intl/generic
  4         generic_product/jp/index.html
  5         generic_product/jp/generic
  6         generic_product/generic_intl/index.html site_branding.ros
  7         generic_product/generic_intl/generic

ファイルを開いて、以下のように修正します。なんか、<r3:trans>という要素が出てきましたね。

Cookery Site Branding: <r3:trans>Cookery Site Branding</r3:trans>

これをcarsプロダクトについても行います。(wineプロダクトはcookeryプロダクトからsite_brandingを継承するので。念のため)

$ r3 template searchpath cars/us/index.html site_branding.ros

  0         cars/us/index.html
  1         cars/us/generic
  2         cars/generic_intl/index.html
  3         cars/generic_intl/generic
  4         generic_product/us/index.html
  5         generic_product/us/generic
  6         generic_product/generic_intl/index.html site_branding.ros
  7         generic_product/generic_intl/generic

$ r3 template specialize cars/us/index.html site_branding.ros 2
Template specialised from generic_product/generic_intl/index.html to cars/generic_intl/index.html

  0         cars/us/index.html
  1         cars/us/generic
  2         cars/generic_intl/index.html     site_branding.ros
  3         cars/generic_intl/generic
  4         generic_product/us/index.html
  5         generic_product/us/generic
  6         generic_product/generic_intl/index.html site_branding.ros
  7         generic_product/generic_intl/generic

それから、$R3HOME/templates/cars/generic_intl/index.html/site_branding.rosを以下のように編集します。

Cars Site Branding: <r3:trans>Cars Site Branding</r3:trans>

さらに、navigation.rosについても同じように処理していきます。ここでは、wineプロダクトも作成します。
now we repeat the whole process for navigation.ros, and this time we'll give the wine product it's own copy:

$ r3 template specialize cookery/us/index.html navigation.ros 2
$ vim $R3HOME/templates/cookery/generic_intl/index.html/navigation.ros
$ r3 template specialize wine/us/index.html navigation.ros 2
$ vim $R3HOME/templates/wine/generic_intl/index.html/navigation.ros
$ r3 template specialize cars/us/index.html navigation.ros 2
$ vim $R3HOME/templates/cars/generic_intl/index.html/navigation.ros

generic productが持つIntlの特殊化

議論するために、アジア圏のサイト、ここの場合だと、cookery/jp, wine/jp, cars/jp において、core_brandingsite_brandingの並びが他のintlと左右逆に配置されると仮定します。
これらの要素の順番は、ヘッダによって制御されるので、generic_product/jp レベルで変更するだけで、これに対応することができます。

$ r3 template searchpath cars/jp/index.html header.ros

  0         cars/jp/index.html
  1         cars/jp/generic
  2         cars/generic_intl/index.html
  3         cars/generic_intl/generic
  4         generic_product/jp/index.html
  5         generic_product/jp/generic
  6         generic_product/generic_intl/index.htmlheader.ros
  7         generic_product/generic_intl/generic

$ r3 template specialize cars/jp/index.html header.ros 4
Template specialised from generic_product/generic_intl/index.html to generic_product/jp/index.html

  0         cars/jp/index.html
  1         cars/jp/generic
  2         cars/generic_intl/index.html
  3         cars/generic_intl/generic
  4         generic_product/jp/index.html    header.ros
  5         generic_product/jp/generic
  6         generic_product/generic_intl/index.htmlheader.ros
  7         generic_product/generic_intl/generic

$ vim $R3HOME/templates/generic_product/jp/index.html/header.ros

ファイルを開いて、以下のように修正します。

<table width="100%" border="2">
<tr>
<th colspan=2>Japanese Header: <r3:trans>Japanese Header</r3:trans></th>

<tr>
<td><r3:include path="site_branding.ros" /></td>
<td><r3:include path="core_branding.ros" /></td>
</tr>
</table>

generic_product/generic_intl/index.html/header.rosと、core_branding と site_branding の順が逆になっている点に注意してください。

現段階での結果

再度generateして、生成されたファイルを見てみます。

r3 generate -a
generating cars/ca
generating cars/fr
generating cars/generic_intl
generating cars/jp
generating cars/us
generating cookery/ca
generating cookery/fr
generating cookery/generic_intl
generating cookery/jp
generating cookery/us
generating generic_product/ca
generating generic_product/fr
generating generic_product/generic_intl
generating generic_product/jp
generating generic_product/us
generating wine/ca
generating wine/fr
generating wine/generic_intl
generating wine/jp
generating wine/us
  • $R3HOME/htdocs/cars/ca/index.html
Container: Container
Header: Header
Core Branding: Core Branding Cars Site Branding: Cars Site Branding
Cars Navigation: Cars Navigation Content: Canadian Ford Cars
  • $R3HOME/htdocs/cars/fr/index.html
Container: Container
Header: Header
Core Branding: Core Branding Cars Site Branding: Cars Site Branding
Cars Navigation: Cars Navigation Content: Peugeot
  • $R3HOME/htdocs/cars/jp/index.html
Container: Container
Japanese Header: Japanese Header
Cars Site Branding: Cars Site Branding Core Branding: Core Branding
Cars Navigation: Cars Navigation Content: Nissan Micra
  • $R3HOME/htdocs/cars/us/index.html
Container: Container
Header: Header
Core Branding: Core Branding Cars Site Branding: Cars Site Branding
Cars Navigation: Cars Navigation Content: Ford Cars
  • $R3HOME/htdocs/cookery/ca/index.html
Container: Container
Header: Header
Core Branding: Core Branding Cookery Site Branding: Cookery Site Branding
cookery Navigation: Cookery Navigation Content: Cookery in CA
  • $R3HOME/htdocs/cookery/fr/index.html
Container: Container
Header: Header
Core Branding: Core Branding Cookery Site Branding: Cookery Site Branding
cookery Navigation: Cookery Navigation Content: Cookery en Francais
  • $R3HOME/htdocs/cookery/jp/index.html
Container: Container
Japanese Header: Japanese Header
Cookery Site Branding: Cookery Site Branding Core Branding: Core Branding
cookery Navigation: Cookery Navigation Content: Japanese Cookery
  • $R3HOME/htdocs/cookery/us/index.html
Container: Container
Header: Header
Core Branding: Core Branding Cookery Site Branding: Cookery Site Branding
cookery Navigation: Cookery Navigation Content: Cookery in the USA
  • $R3HOME/htdocs/wine/ca/index.html
Container: Container
Header: Header
Core Branding: Core Branding Cookery Site Branding: Cookery Site Branding
Wine Navigation: Wine Navigation Content: US Wine (california is nice)
  • $R3HOME/htdocs/wine/fr/index.html
Container: Container
Header: Header
Core Branding: Core Branding Cookery Site Branding: Cookery Site Branding
Wine Navigation: Wine Navigation Content: Wine en Francais
  • $R3HOME/htdocs/wine/jp/index.html
Container: Container
Japanese Header: Japanese Header
Cookery Site Branding: Cookery Site Branding Core Branding: Core Branding
Wine Navigation: Wine Navigation Content: Japanese Wine
  • $R3HOME/htdocs/wine/us/index.html
Container: Container
Header: Header
Core Branding: Core Branding Cookery Site Branding: Cookery Site Branding
Wine Navigation: Wine Navigation Content: US Wine (california is nice)

以下の点に注意してみてください。

  • 各プロダクト×各intlのContentが、個別に特殊化した内容になっていること (車なら、プジョーとか日産とか)
  • 各プロダクトのナビゲージョンとサイトブランディングが、それぞれ、"Wine Navigation" などと、各プロダクト毎で統一のものになっていること。
  • 各プロダクトのintl=jpのページのヘッダが、Japanese Headerになっていて、且つ、コアブランディングとサイトブランディングが他intlと並びが逆になっていること

次は、Translation(翻訳)に入っていきます。