RadiantCMS Extensions

Creating Radiant Extensions
この文書は、Radiant CMS の Extension についての、本家のチュートリアルを私、flyman が勝手に邦訳したものです。
これは、私自身がチュートリアルに沿ってエクステンションを作成するにあたり、原文のままでは進めにくいと感じたために書いたものです。すなわち、私自身は Radiant CMS についても、エクステンションについても、全くの素人です。
また、和訳内容についてもかなり適当ですので、一度原文を読まれることをお勧めします。
また、これは私的な用途のために邦訳したもので、本家にお断りはしておらず、著作権法上、問題があるかも知れません (関連するドキュメンツを含めて、MITライセンスだそうですが、これが[associated documentation files]に含まれるかは、微妙、かも)。

2007/08/02 flyman

Radiant Extensions を作る

Radiant 0.6 で、もっともエキサイティングな側面は、エクステンションのサポートが追加されたことです。Radiant が "けば立っていない" コンテンツ・マネジメント・システムである一方、他のシステムでは Radiant にはない多くの機能がサポートされていました。私は Radiant をクリーンかつシンプルに保つことで、簡単に学べ、簡単にサポートできるように努めてきました。問題は、私が"けば"だと考える機能と絶対必要と考える機能が、皆さんの考えと一致しないということでした。エクステンションは、皆さんにこの問題を解決する機会を提供します。

エクステンションを使うことで、あなたは Radiant のほとんど全ての部分をカスタマイズすることが出来ます。そして、Radiant が Ruby on Rails で作られているため、エクステンションの製作は普通の Ruby on Rails アプリの製作と同じくらいに簡単です。

このチュートリアルで、私はあなたが初めてのエクステンション製作を始める助けになりたいと思っています。ここでは、以下の項目を扱います。

  • extension generators の使用
  • カスタム model と controller の製作
  • extension migrations の使用
  • カスタム tags の製作

以降、あなたが既に最新の Radiant gems をパソコンにインストールしており、Ruby on Rails の基本的な事柄を理解しているものと仮定します。もしあなたが今まで Ruby on Rails を使用したことがないなら、先に Rolling with Rails チュートリアル (Part I, II, & III) に目を通してください。

新しいプロジェクトを作る

では、テストプロジェクトを作りましょう。コマンドプロンプトを開き、適当なディレクトリに "cd" して下さい。新しいプロジェクトを作るために `radiant` コマンドを実行します。


% radiant -d sqlite3 path/to/new/project

見ての通り、私はデータベースエンジンに SQLite 3 を使用しています。しかし、あなたは MySQL や PostgreSQL を選んでも構いません。

`radiant` コマンドは私たちの新しいプロジェクトの骨組みを作成し、以下のインストラクションを表示します。


== Installation and Setup

Once you have extracted the files into the directory where you would like to
install Radiant:

1. Create the MySQL/PostgreSQL/SQLite databases for your Web site. You only
   need to create the "production" database, but you may also want to create
   the "development" and "test" databases if you are developing extensions
   or running tests.

2. Edit config/database.yml to taste.

3. Run the database bootstrap rake task:

     % rake production db:bootstrap

   (If you would like bootstrap your development database run `rake
   development db:bootstrap`.)

4. Start it like a normal Rails application. To test execute:

     % script/server -e production

   And open your Web browser on port 3000 (http://localhost:3000). The
   administrative interface is available at /admin/. By default the bootstrap
   rake task creates a user called "admin" with a password of "radiant".

When using Radiant on a production system you may also need to set permissions
on the public and cache directories so that your Web server can access those
directories with the user that it runs under.

Once you've installed Radiant on your own Web site, be sure to add your name
and Web site to the list of radiant users:

http://dev.radiantcms.org/radiant/wiki/RadiantUsers

もしあなたがデータベースエンジンとして SQLite 3 を選んだなら、このチュートリアルのステップ1と2は無視できます。それ以外の場合は、 development、production、test の各環境用にデータベースを作成し、環境に応じて “config/database.yml” を修正します。


% rake db:bootstrap
% rake production db:bootstrap

両データベースの bootstrap を実行したら続きを行う前に、コマンドラインからテストサーバーを production モードで起動して、サイトが正しく動作しているか確認しましょう。


% script/server -e production

“http://localhost:3000/admin/” に接続し、ログインして全てがちゃんと動作しているか確認します。

ログインしたら、上右角にある“Extensions”リンクをクリックして、インストールされているエクステンションを確認します。

Radiant には、現在 “Markdown”と“Textile”という2種類のプリインストールエクステンションが含まれています。エクステンション画面では、エクステンションを有効/無効にしたり、関連する情報を確認できます。

コンソールに戻り、Ctrl+C を押してテストサーバーを停止しましょう。

エクステンションを作る

では、初めてのエクステンションを作りましょう。これから私たちが作るエクステンションは、Webサイトのリンク集の管理を楽にする、というものです。新しいエクステンションを作るには、extension generator を使用します。コマンドのフォーマットは次の通りです。


script/generate extension ExtensionName

私たちのエクステンションの名前は LinkRoll です。コマンドプロンプトに、次のように入力します。


% script/generate extension LinkRoll

以下のように表示されるはずです。


  create  vendor/extensions/link_roll/app/controllers
  create  vendor/extensions/link_roll/app/helpers
  create  vendor/extensions/link_roll/app/models
  create  vendor/extensions/link_roll/app/views
  create  vendor/extensions/link_roll/db/migrate
  create  vendor/extensions/link_roll/lib/tasks
  create  vendor/extensions/link_roll/test/fixtures
  create  vendor/extensions/link_roll/test/functional
  create  vendor/extensions/link_roll/test/unit
  create  vendor/extensions/link_roll/README
  create  vendor/extensions/link_roll/Rakefile
  create  vendor/extensions/link_roll/link_roll_extension.rb
  create  vendor/extensions/link_roll/lib/tasks/link_roll_extension_tasks.rake
  create  vendor/extensions/link_roll/test/test_helper.rb
  create  vendor/extensions/link_roll/test/functional/link_roll_extension_test.rb

見ての通り、extension generator は vendor/extensions/link_roll フォルダ内に、エクステンションの骨組みを作ってくれます。私たちが作ろうとしているエクステンションは全て link_roll フォルダに収まっています。これを別のプロジェクトで使うには、link_roll フォルダをそのプロジェクトの vendor/extensions にコピーするだけです。

“link_roll_extension.rb”ファイルを開いてみましょう。以下のようになっているはずです。


class LinkRollExtension < Radiant::Extension
  version "1.0" 
  description "Describe your extension here" 
  url "http://yourwebsite.com/link_roll" 

  # define_routes do |map|
  #   map.connect 'admin/link_roll/:action', :controller => 'admin/link_roll'
  # end

  def activate
    # admin.tabs.add "Link Roll", "/admin/link_roll", :after => "Layouts", :visibility => [:all]
  end

  def deactivate
    # admin.tabs.remove "Link Roll" 
  end

end

では、 LinkRollExtension の属性を編集しましょう。属性は class 定義の先頭部分にあります。始めに、“description”属性を次のように変更します。

"Allows you to add a link roll to your Web site."

“url”属性を次のように書き換えます。

"http://dev.radiantcms.org/radiant/browser/trunk/extensions/link_roll/"

他の二つの属性についても後で処理します。今は、再びサーバーを起動しましょう。


% script/server -e production

ブラウザで“http://localhost:3000/admin/”を開き、ログインします。上右角の“Extensions”リンクをクリックします。エクステンションのリストに“Link Roll”エクステンションがあるはずです。

注記と関連Webサイトの属性値が変更した通りになっていることを確認して下さい。

Model の生成

コマンドプロンプトに戻り、最初の model を作成しましょう。Ctrl+C を押してサーバーを停止させ、次のように打ちます。


script/generate extension_model LinkRoll Link title:string url:string description:text

次のように出力されるはずです。


exists  app/models/
exists  test/unit/
exists  test/fixtures/
create  app/models/link.rb
create  test/unit/link_test.rb
create  test/fixtures/links.yml
exists  db/migrate
create  db/migrate/001_create_links.rb

見ての通り、extension_model generator には幾つかの引数があります。“LinkRoll”は model を追加する対象のエクステンション名です。“Link”は新しい model の名称です。残りのパラメータは、新しい model の、属性:タイプ 形式の属性です。

コマンドの出力を見ると、次のものが生成されたことが判ります。

  • the file for the Link model
  • the unit test
  • the links fixture
  • the migration

migration ファイル(“vendor/link_roll/db/migrate/001_create_links.rb”)を開きます。以下のようになっているはずです。


class CreateLinks < ActiveRecord::Migration
  def self.up
    create_table :links do |t|
      t.column :title, :string
      t.column :url, :string
      t.column :description, :text
    end
  end

  def self.down
    drop_table :links
  end
end

Links model オブジェクトに関連した“links”テーブルを作成する migration の準備が出来ていることが判ります。また、Links modelの属性が extension_model generator で設定した通りに反映されていることが確認出来ます。

では、この model の migration を実行しましょう (development と production 両データベースで実行します)。


% rake db:migrate:extensions
% rake production db:migrate:extensions

(Note: 今は、以下は無視して結構です。しかし、後でデータベースを extension schema の特定バージョン (例えば、以前のバージョンに戻す) に migrate したいときには、以下の例のように、生成された migration タスクを使用する必要があります。)


% rake production radiant:extensions:link_roll:migrate VERSION=0

バージョンナンバーは、あなたの エクステンションの migration (ファイル) に対応します。schema_info テーブルのものではありません。

Controller を生成する

では、私たちの リンクロール用に所定の model オブジェクトをセットアップしましょう。関連する controller を作ります。次のコマンドを実行して下さい。


script/generate extension_controller LinkRoll admin/links   

次のように出力されます。


  create  app/controllers/admin
  create  app/helpers/admin
  create  app/views/admin/links
  create  test/functional/admin
  create  app/controllers/admin/links_controller.rb
  create  test/functional/admin/links_controller_test.rb
  create  app/helpers/admin/links_helper.rb

コマンドの出力から、以下のものが生成されているのが判ります。

  • the Admin::LinksController
  • the link controller helper
  • the functional test for the controller
  • the folder for the link controller views

また、LinksController が Admin module 内にありまが、これは LinksController が admin インターフェースの一部だからです。

では、controller ファイル (“vendor/extensions/link_roll/app/controllers/admin/links_controller.rb”) を開いてみましょう。以下のようになっているはずです。


  class Admin::LinksController < ApplicationController
    # Remove this line if your controller should only be accessible to users
    # that are logged in:
    no_login_required
  end

これは links の admin controller なので、no_login_required の行は削除します。この例題では、scaffolding を利用して簡易エディットインターフェースを生成させますが、通常の Ruby on Rails アプリを作るときのように、あなた自身の action や関連する view を作るのに何の制限もありません。

Rails に、Link model オブジェクトに scaffold を使用することを伝えるために、LinksController に、以下の行を書き加えます。


scaffold :link

あなたの LinksController は、次のようになっているはずです。


class Admin::LinkController < ApplicationController
  scaffold :link
end

admin インターフェースに LinkController を表示させるためには、残りあと2ステップです。まず、controller のための経路定義が必要です。次に、admin インターフェースに、関連するタブを追加する必要があります。

そのためには、再び extension の主ファイル (“vendor/extensions/link_roll/link_roll_extension.rb”) を開きます。define_routes ブロックを変更して、以下のようにします。


define_routes do |map|
  map.connect 'admin/links/:action', :controller => 'admin/link'
end

activate メソッドを以下のように変更します。


def activate
  admin.tabs.add "Links", "/admin/links", :before => "Layouts" 
end

また、deactivate メソッドは以下のように書き換えます。


def deactivate
  admin.tabs.remove "Links" 
end

通常の Rails アプリの routes.rb ファイルと同じように、define_routes ブロックにはいくつでも経路の指定を定義できます。

activate および deactivate メソッドは、エクステンションが有効化または無効化されたときに呼ばれます。通常、これらのイベントはアプリケーションが起動したときや、エクステンションが admin インターフェースで無効化されたときに走ります。“Layouts”タブの前に“Links”タブを追加するためのメソッドも使用します。

LinkRollExtension クラスは次のようになっているはずです。


class LinkRollExtension < Radiant::Extension
  version "1.0" 
  description "Allows you to add a link roll to your Web site." 
  url "http://dev.radiantcms.org/radiant/browser/trunk/extensions/link_roll/" 

  define_routes do |map|
    map.connect 'admin/links/:action', :controller => 'admin/links'
  end

  def activate
    admin.tabs.add "Links", "/admin/links", :before => "Layouts" 
  end

  def deactivate
    admin.tabs.remove "Links" 
  end

end

links controller とエクステンションファイルを正しく設定したら、admin インターフェースを使用して、新しいリンクを作成したり変更したり出来るようになったはずです。それを確かめるため、起動してみましょう。


% script/server -e production

ブラウザで“http://localhost:3000/admin”へ行きます。ログインして新しくできた“Links”タブをクリックします。新しく出来たリンクロールを編集するための、機能の整ったエディタインターフェースが表示されます (殆どの機能は、Rails 組み込みの足場によって提供されています)。少しインターフェースを試してみましょう。あなたの リンクロールに、いつくかりリンクを追加してみて下さい。どのような関連で動作するのか、感触をつかんで下さい。

カスタムタグを作る

これで、私たちは admin インターフェースでリンクを作成、追加する簡単な方法を手に入れたので、Webサイトに私たちのリンクロールからリンク集を表示させるためのカスタムタグを いくつか作りましょう。では、始めましょう。

あなたのエクステンションの“app/models”ディレクトリに、新しく“link_roll_tags.rb”というファイルを作り、以下のコードを追加します。


module LinkRollTags
  include Radiant::Taggable

  tag 'links' do |tag|
    tag.expand
  end

  tag 'links:each' do |tag|
    result = []
    Link.find(:all, :order => 'title ASC').each do |link|
      tag.locals.link = link
      result << tag.expand
    end
    result
  end

  tag 'links:each:link' do |tag|
    link = tag.locals.link
    %{<a href="#{link.url}" title="#{link.description}">#{link.title}</a>}
  end
end

上記 LinkRollTags モジュールは、素敵な Radiant::Taggable をインクルードしています。これは素晴らしい“tag”クラスメソッドを追加します。これで私たちはモジュールに自分のタグを定義することが出来ます。

タグはエクステンションが有効化されたときに定義されるので、エクステンションの主ファイル (“link_roll_extension.rb”) に切り替え、“activate”メソッドに以下の行を追加して下さい。


Page.send :include, LinkRollTags

Link モジュールにタグを3つ定義しました。このチュートリアルでは、Radius tag DSL の内部動作までは踏み込みません (興味のある方は、こちらをお読み下さい。Radius Quickstart guide)。しかし、上で定義したタグを使用するには十分でしょう。これで、page、layout または snippet の中に以下の様にタグを記述して使用することが出来ます。


<ul>
<r:links:each>
  <li><r:link /></li>
</r:links:each>
</ul>

以下のような出力が得られます。

これで、上記のコードを使用して、あなたのブログでお気に入りサイトのリストを管理することが出来ます。

むすび

これで Creating Radiant Extensions チュートリアルはおしまいです。あなたが、Radiant extensions で出来る沢山のことの感触を掴めたなら幸いです。勿論、このチュートリアルの LinkRoll extension は、あなたが誇りに思えるほどに真に磨き上げられた状態にするまでには、やるべき事はたくさんあります。けれど私は、あなたがここから始めるのに十分な、幸先の良いスタートを示せたものと思います。





サイト名: flyman のおもちゃ箱   http://www.kestrel.jp
この記事のURL:   http://www.kestrel.jp/modules/tinyd04/index.php?id=5