Catalyst

Jesse Sheidlowerさんの許可を得て、翻訳を公開しております。なお、この翻訳は、under same terms of Perl itselfで、配布可能です。

原文はこちら: Catalyst

目次

Catalyst

Jesse Sheidlower
June 02, 2005

Web frameworks are an area of significant interest at the moment. Now that we've all learned the basics of web programming, we're ready to get the common stuff out of the way to concentrate on the task at hand; no one wants to spend time rewriting the same bits of glue to handle parameter processing, request dispatching, and the like.

Web フレームワークは、目下、重要な関心を集めている分野です。現在、みんなWebプログラミングの基礎を学んでしまって、 今は目前にある仕事に集中するやりかたではなく、共通のものを得る時期です; もう誰も、パラメタの処理、リクエストの振り分け、そういったものをするための、 同じような、ちっぽけな糊のようなものを書き換えるのに時間を浪費したくありません。

A model currently favored for web applications is MVC, or Model-View-Controller. This design pattern, originally from Smalltalk, supports the separation of the three main areas of an application--handling application flow (Controller), processing information (Model), and outputting results (View)--so that it is possible to change or replace any one without affecting the others.

現在、 Web アプリケーションで好まれているモデルは、MVC、Model-View-Controllerです。 このデザインターンは、もともとはSmalltalkからきており、Mode、 View、 Controllerの3つの主要な部分 --アプリケーションフロー(Controller)、情報の処理(Model)、結果の表示(View) -- を分割することに対応しています。こうすることで、他への影響なしに、何にでも変更、置換することができます。

Catalyst is a new MVC framework for Perl. It is currently under rapid development, but the core API is now stable, and a growing number of projects use it. Catalyst borrows from other frameworks, such as Ruby on Rails and Apache Struts, but its main goal is to be a flexible, powerful, and fast framework for developing any type of web project in Perl. This article, the first of a series of two, introduces Catalyst and shows a simple application; a later article will demonstrate how to write a more complex project.

Catalyst は新しいPerlのMVCフレームワークです。現在、急速に開発されていますが、 コアのAPIは安定しています。それに、Catalyst を使うプロジェクトの数も増えつつあります。 Catalyst は他のフレームワーク - Ruby on RailsやApache Strutsのような - から借りています。 ですが、Catalyst のメインゴールは、Perlで作られるどのようなタイプのWebプロジェクトの開発にも使える、 柔軟性があり、強力な、速いフレームワークです。 この記事は、2つのシリーズの1つ目です。Catalystの紹介と簡単なアプリケーションを見せます; 後の記事ではもっと複雑なプロジェクトの書き方をデモするでしょう。

▲ to Top

インスピレーションを受けたもの

Catalyst grew out of Maypole, an MVC framework developed by Simon Cozens (and discussed last year on Perl.com; see "Rapid Web Application Development with Maypole," for example). Maypole works well for typical CRUD (Create, Retrieve, Update, Delete) databases on the Web. It includes a variety of useful methods and prewritten templates and template macros that make it very easy to set up a powerful web database. However, it focuses so strongly on CRUD that it is less flexible for other tasks. One of the goals of Catalyst is to provide a framework well suited for any web-related project.

Catalyst は、Maipole、Simon Cozensによって開発されたMVCフレームワーク、Maypole ( Perl.comで昨年議論されました; "Rapid Web Application Development with Maypole," 参照) 、から大きくなりました。Maypoleは、Webのデータベースの典型的なCRUD(Create, Retrieve, Update, Delete)で、うまく動きます。 Maypoleは、たくさんの有益なメソッドと既存のテンプレートと強力なWebデータベースをセットアップするのをとても簡単にするテンプレートマクロがあります。 ですが、MaypoleはCRUDに強く焦点が当てられており、他の仕事に関しては柔軟性が低くなっています。 Catalystのゴールの1つは、どのようなWebに関連するプロジェクトにでもうまく合う、フレームワークを提供することです。

Ruby on Rails was another inspiration; this popular system has done much to promote interest in the Ruby programming language. Features we borrowed from RoR are the use of helper scripts to generate application components and the ability to have multiple controllers in a single application. Both RoR and Struts allow the use of forwarding within applications, which also proved useful for Catalyst.

Ruby on Rails は、もうひとつのインスピレーションを受けたものです; この人気のあるシステムは、プログラミング言語Rubyに多くの関心を集めさせました。 RoRから借りた特徴は、アプリケーションのコンポーネントを生成する、ヘルパースクリプトと 1つのアプリケーションに複数のControllerを持つことできるところです。 RoRとStrutsは両方とも、アプリケーション内で転送(forwarding)を使うとができます。 転送は、Catalystにとっても有益だと分かりました。

▲ to Top

特徴

スピード

We planned Catalyst as an enterprise-level framework, able to handle a significant load. It makes heavy use of caching. Catalyst applications register their actions in the dispatcher at compile time, making it possible to process runtime requests quickly, without needing elaborate checks. Regex dispatches are all precompiled. Catalyst builds only the structures it needs, so there are no delays to generate (for example) unused database relations.

Catalystはエンタープライズレベルの、かなりの負荷を扱うことができるフレームワークとして計画されています。 エンタープライズレベルのフレームワークは、キャッシングを頻繁に使います。Catalystのアプリケーションは、 コンパイル時にディスパッチャーにアクションを登録します。このことで実行時のリクエストを、複雑なチェックなしに素早く処理できます。 正規表現のディスパッチは全てプリコンパイルされます。 Catalystは必要とする構造だけを作ります。ですので、(例えば)データベース関係を使わないものを作るのに遅れはありません。

▲ to Top

簡易性

コンポーネント

Catalyst has many prebuilt components and plugins for common modules and tasks. For example, there are View classes available for Template Toolkit, HTML::Template, Mason, Petal, and PSP. Plugins are available for dozens of applications and functions, including Data::FormValidator, authentication based on LDAP or Class::DBI, several caching modules, HTML::FillInForm, and XML-RPC.

Catalystには、共通のモジュールと仕事用に、あらかじめコンポーネントやプラグインがあります。 例えば、ViewクラスにはTemplate ToolkitやHTML::TemplateやMason、Petal、PSPなどを利用できます。 プラグインで何十ものアプリケーションと機能を使えます。 Data::FormValidator、 LDAPベースの認証とかClass::DBI、 複数のキャッシングモジュール, HTML::FillInForm、 XML-RPCなどを含みます。

Catalyst supports component auto-discovery; if you put a component in the correct place, Catalyst will find and load it automagically. Just place a Catalog controller in /AppName/Controller/Catalog.pm (or, in practice, in the shortened /AppName/C/Catalog.pm); there's no need to use each item. You can also declare plugins in the application class with short names, so that:

Catalystは、コンポーネントのオートディスカバリーをサポートします; コンポーネントを正しい場所に置けば、Catalystは、自動的にそれを見付けて、読み込みます。 /AppName/Controller/Catalog.pm(または、実際には、略して /AppName/C/Catalog.pm) に、カタログコントローラを置けばいいだけです; それぞれのものをuseする必要はありません。 また、短い名前でアプリケーションクラスのプラグインを宣言できます。 次のようにします:

use Catalyst qw/Email Prototype Textile/;

will load Catalyst::Plugin::Email, Catalyst::Plugin::Prototype, and Catalyst::Plugin::Textile in one shot.

Catalyst::Plugin::EmailCatalyst::Plugin::Prototypeと とCatalyst::Plugin::Textileを一回でロードします。

開発

Catalyst comes with a built-in lightweight HTTP server for development purposes. This runs on any platform; you can quickly restart it to reload any changes. This server functions similarly to production-level servers, so you can use it throughout the testing process--or longer; it's a great choice if you want to deliver a self-contained desktop application. Scalability is simple, though: when you want to move on, it is trivial to switch the engine to use plain CGI, mod_perl1, mod_perl2, FastCGI, or even the Zeus web server.

Catalystは開発手段にライトウェイトなHTTPサーバが組み込まれています。 このサーバはどんなプラットフォームでも動きます; なんらかの変更をリロードするために、 すぐにリスタートできます(訳註:最新版は変更を自動で読み取り、読み直しますので、リスタートしなくていいです)。 このサーバの機能は製品レベルのサーバに近いです。 これをテストのプロセスで使えますし、また、もっと長く使うこともできます; 内蔵タイプのデスクトップアプリケーションを供給しようとしたいなら、このサーバを使うのは良い選択でしょう。 とはいえ、拡張するのは簡単です。: 移行したくなっても、ただのCGIを使うエンジン、mod_perl1mod_perl2、 FastCGI、Zeus web server でも、 変更するのは、取るに足らないことです。

Debugging (Figure 1) and logging (Figure 2) support is also built-in. With debugging enabled, Catalyst sends very detailed reports to the error log, including summaries of the loaded components, fine-grained timing of each action and request, argument listings for requests, and more. Logging works by using the the Catalyst::Log class; you can log any action for debugging or information purposes by adding lines like:

デバッギング (Figure 1) と ロギング (Figure 2) サポートもまた組み込まれています。 デバッギングを有効にすると、Catalystは、エラーログにとても詳細なレポートを送ります。 ロードされたコンポーネントのサマリや、それぞれのアクションとリクエストのきめこまかいタイミング、 リクエストの引数のリスト、その他多くのものを含みます。 Catalyst::Log クラスでロギングを動かしています; デバッギングのためや目的の情報を得るために、以下のような行を追加することで、どんなアクションも記録できます。

$c->log->info("We made it past the for loop");
$c->log->debug( $sql_query );

Log screenshot
Figure 1. Logging

Crashes will display a flashy debug screen showing details of relevant data structures, software and OS versions, and the line numbers of errors.

クラッシュすると、関連するデータ構造、ソフトウェア、OSのバージョン、エラーの行数を、派手なデバッグスクリーンに表示します。

Debug screenshot
Figure 2. Debugging

Helper scripts, generated with Template Toolkit, are available for the main application and most components. These allow you to quickly generate starter code (including basic unit tests) for the application framework. With a single line, you can create a Model class based on Class::DBI that pulls in the appropriate Catalyst base model class, sets up the pattern for the CDBI configuration hash, and generates a perldoc skeleton.

ヘルパースクリプト - Template Toolkitで生成された - は、メインのアプリケーションとほとんどのコンポーネントで利用できます。 ヘルパースクリプトで、アプリケーションフレームワークの最初のコードをすぐに生成できます(基本的なユニットテストも含みます)。 一行で、適切なCatalystのベースModelクラスを引き入れた、 Class::DBI をベースとした Model クラスを作れます。 CDBIの設定ハッシュをセットアップし、perldocスケルトンを作ります。

▲ to Top

柔軟性

Catalyst allows you to use multiple models, views, and controllers--not just as an option when setting up an application, but as a totally flexible part of an application's flow. You can mix and match different elements within the same application or even within the same method. Want to use Class::DBI for your database storage and LDAP for authentication? You can have two models. Want to use Template Toolkit for web display and PDF::Template for print output? No problem. Catalyst uses a simple building-block approach to its add-ins: if you want to use a component, you say so, and if you don't say so, Catalyst won't use it. With so many components and plugins available, based on CPAN modules, it's easy to use what you want, but you don't have to use something you don't need. Catalyst features advanced URL-to-action dispatching. There are multiple ways to map a URL to an action (that is, a Catalyst method), depending on your requirements. First, there is literal dispatching, which will match a specific path:

Catalyst は複数のModel、View、 Controller を扱えます -- アプリケーションのセットアップ時のオプションとしてだけでなく、アプリケーションのフローの全体的に柔軟な部分としても。 同じアプリケーション内、同じメソッド内に、違った要素をミックスしマッチすることができます。 データベースストレージにClass::DBIと、認証のために、LDAPを使いたい? 両方のモデルを使えます。Webの表示にTemplate Toolkitを使い、プリント用の出力に PDF::Templateを使いたい? 何の問題もありません。 Catalystは、簡単なbuilding-blockアプローチをCatalystのアドインに使っています: コンポーネントを使いたければ、そう言えばいい、また、そう言わなければ、 Catalystは使おうとしません。利用可能なたくさんのコンポーネントとプラグイン - CPANモジュールをベースとしている - で、簡単に望むものを使うことができます。 ですが、必要でないものを使う必要はありません。 Catalyst features advanced URL-to-action dispatching. There are multiple ways to map a URL to an action (that is, a Catalyst method), depending on your requirements. First, there is literal dispatching, which will match a specific path: Catalystは、先進の URL-to-action ディスパッチを備えています。 URLとアクションのマッピングには複数のやりかたがあります(that is, a Catalyst method)。 あなたがどうしたいかに依ります。まず、文字どおりのディスパッチ、特定のパスにマッチするものは:

package MyApp::C::Quux;

# http://localhost:3000/foo/bar/yada だけにマッチ
sub baz : Path('foo/bar/yada') { }

A top-level, or global, dispatch matches the method name directly at the application base:

トップレベル、または、グローバルは、アプリケーションベースでメソッド名に直接マッチします:

package MyApp::C::Foo;

# http://localhost:3000/bar にのみマッチ
sub bar : Global { }

A local, or namespace-prefixed, dispatch acts only in the namespace derived from the name of your Controller class:

ローカル、または、namespace-prefixedのディスパッチは、 Controllerクラスの名前から由来する名前空間でのみ動きます。

package MyApp::C::Catalog::Product;

# http://localhost:3000/catalog/product/buy にマッチ
sub buy : Local { }

package MyApp::C::Catalog::Order;

# http://localhost:3000/catalog/order/review にマッチ
sub review : Local { }

The most flexible is a regex dispatch, which acts on a URL that matches the pattern in the key. If you use capturing parentheses, the matched values are available in the $c->request->snippets array.

一番柔軟性が高いのは、正規表現によるディスパッチです。 キーのパターンにマッチするURLで動きます。 パーレンをキャプチャリングするのに使う(訳注: /([a-z]+)(\d+)/ から、$1, $2など を使う)なら、 マッチした値は、$c->request->snippetsの配列から利用できます。

package MyApp::C::Catalog;

# http://localhost:3000/item23/order189 にマッチ
sub bar : Regex('^item(\d+)/order(\d+)$') { 
   my ( $self, $c ) = @_;
   my $item_number  = $c->request->snippets->[0];
   my $order_number = $c->request->snippets->[1];
   # ...    
}

The regex will act globally; if you want it to act only on a namespace, use the name of the namespace in the body of the regex:

正規表現はグローバルに動きます; 名前空間でのみ動かしたければ、正規表現に名前空間の名前を使ってください:

sub foo : Regex('^catalog/item(\d+)$') { # ...

Finally, you can have private methods, which are never available through URLs. You can only reach them from within the application, with a namespace-prefixed path:

最後に、プライベートメソッドを持つことができます。これは、URLには決して使われません。 アプリケーション内からのみ、namespace-prefixed なパスで使うことができます:

package MyApp::C::Foo;
# matches nothing, and is only available via $c->forward('/foo/bar').
sub bar : Private { }

A single Context object ($context, or more usually as its alias $c) is available throughout the application, and is the primary way of interacting with other elements. Through this object, you can access the request object ($c->request->params will return or set parameters, $c->request->cookies will return or set cookies), share data among components, and control the flow of your application. A response object contains response-specific information ($c->response->status(404)) and the Catalyst::Log class is made directly available, as shown above. The stash is a universal hash for sharing data among application components:

1つのContext オブジェクト($context, または、 普通は $c) がアプリケーションを通して使用できます。主に他の要素に相互に作用するために使います。 このオブジェクトを通して、リクエストオブジェクト($c->request->params がパラメータを返す/セットします、 $c->request->cookies がクッキーを返す/セットします)、 コンポーネント間でデータを共有し、アプリケーションのフローをコントロールします。 レスポンスオブジェクトは、レスポンスに特化した情報を含みます ($c->response->status(404))、また、既に見た、Catalyst::Log クラス が直接に利用可能です. stash は、ユニバーサルなハッシュで、 アプリケーションのコンポーネントでデータを共有するためのものです:

$c->stash->{error_message} = "You must select an entry";

# TT のテンプレートで:
[% IF error_message %]
   <h3>[% error_message %]</h3>
[% END %]

Stash values go directly into the templates, but the entire context object is also available:

Stash の値はテンプレートに直接に入ります。 ですが、全てのコンテキストオブジェクトもまた利用可能です:

<h1>[% c.config.name %]</h1>

To show a Mason example, if you want to use Catalyst::View::Mason:

Masonの例を見るために, Catalyst::View::Masonが欲しければ:

% foreach my $k (keys $c->req->params) {
  param: <% $k %>: value: <% $c->req->params->{$k} %>
% }
▲ to Top

サンプルアプリケーション: 30行のコードで、MiniMojo, Ajax-Based Wiki

Now that you have a sense of what Catalyst is, it's time to look at what it can do. The example application is MiniMojo, a wiki based on Ajax, which is a JavaScript framework that uses the XMLHttpRequest object to create highly dynamic web pages without needing to send full pages back and forth between the server and client.

もう、Catalystが何かわかりましたね。何ができるかを見てみましょう。 アプリケーション例は、MiniMojoです。AjaxのWikiです。 XMLHttpRequestを使ったJavaScriptのフレームワークで、サーバ、クライアント間で前後にページを送る必要のない、 高度に動的なWebページを作ります。

Remember that from the Catalyst perspective, Ajax is just a case of sending more text to the browser, except that this text is in the form of client-side JavaScript that talks to the server, rather than a boilerplate copyright notice or a navigation sidebar. It makes no difference to Catalyst.

Catalystの観点から、Ajaxが、国防省共通契約書版権情報とかナビゲーションサイドバーとかではなく、 サーバと通信するクライアントサイドJavaScriptのフォームにテキストがあることを除いて、 より多くのテキストをブラウザに送る1ケースであることを覚えていてください。 このことはCatalystに重要ではありません。

▲ to Top

インストール

Catalyst has a relatively large number of requirements; most, however, are easy to install, along with their dependencies, from CPAN. The following list should take care of everything you need for this project:

Catalyst 必要なモジュールが比較的たくさんあります; ですが、 ほとんどは簡単にCPANから依存性に沿ってインストールできます。 下のリストで、このプロジェクトに必要なものが揃います。

▲ to Top

アプリケーションのスケルトンの作成

Run this command:

このコマンドを実行:

$ catalyst.pl MiniMojo
$ cd MiniMojo

You've just created the skeleton for your entire application, complete with a helper script keyed to MiniMojo to generate individual classes, basic test scripts, and more.

アプリケーション全体のスケルトンができあがりました。 それぞれのクラスを作るための、MiniMojoをキーとするヘルパースクリプト、 基本的なテストスクリプト、その他多くのものが揃っています。

Run the built-in server:

ビルトインサーバの起動:

$ script/minimojo_server.pl

MiniMojo is already running, though it isn't doing much just yet. (You should have received a web page consisting solely of the text "Congratulations, MiniMojo is on Catalyst!") Press Ctrl-C to stop the server.

MiniMojo はもう動いています、ですが、まだ多くのことはしません。 (単に"Congratulations, MiniMojo is on Catalyst!"というWebページだけです) Ctrl-Cを押して、サーバを止めましょう。

▲ to Top

Application Classに基本的なメソッドを追加

Add a private end action to your application class, lib/MiniMojo.pm, by editing the new file:

プライベートなend アクションをアプリケーションクラス、lib/MiniMojo.pmに追加します。 その新しいファイルを編集します:

sub end : Private {
    my ( $self, $c ) = @_;
    $c->forward('MiniMojo::V::TT') unless $c->res->output;
}

Catalyst automatically calls the end action at the end of a request cycle. It's one of four built-in Private actions. It's a typical pattern in Catalyst to use end to forward the application to the View component for rendering, though if necessary you could do it yourself (for example, if you want to use different Views in the same application--perhaps one to generate web pages with Template Toolkit and another to generate PDFs with PDF::Template).

Catalyst は、リクエストサイクルの最後に自動的にendを呼びます。これは、4つのビルトインアクションの1つです。 レンダリングのためにViewコンポーネントにアプリケーションをフォーワードするのに、endを使うのは、Catalystの典型的なパターンです。 ですが、必要なら、自分でそれを行うこともできます(例えば、同じアプリケーションで違うViewを使いたい--たぶん、一方で Tempalte Toolkit で Webページを生成し、 他方でPDF::Templateで、PDFを生成するような場合)。

Replace the existing, helper-generated default action in the same class with:

ヘルパースクリプトが作った アプリケーションクラスのdefaultアクションを置き換えます:

sub default : Private {
    my ( $self, $c ) = @_;
    $c->forward('/page/show');
}

In case the client has specified no other appropriate action, this will forward on to the page controller's show method. As Private actions, nothing can call these from outside the application. Any method from within the application can call them. The default action is another built-in Private action, along with begin, auto, and end. Again, Catalyst calls them automatically at relevant points in the request cycle.

クライアントが他の適当なアクションを何も指定しなければ、 ページコントローラのshowメソッドにフォーワードします。 プライベートアクションは、アプリケーションの外側から呼び出すことはできません。 アプリケーションないの度のメソッドもこれらを呼ぶことができます。 defaultアクションは、beginautoendと同様に、 別のプライベートアクションです。 Catalystは、リクエストサイクルで関連のある箇所で自動的にそれらを呼び出します。

▲ to Top

Model(SQLite データベース)のセットアップとヘルパースクリプトによるModelクラスの生成

Next, create a file, minimojo.sql, that contains the SQL for setting up your page table in SQLite.

次に、minimojo.sqlというファイルを作ります。 SQLiteにpageテーブルをセットアップするSQLです。

-- minimojo.sql
CREATE TABLE page (
    id INTEGER PRIMARY KEY,
    title TEXT,
    body TEXT
);

Create a database from it, using the sqlite command-line program:

これから、データベースを作成します。sqliteコマンドラインプログラムを使います:

$ sqlite minimojo.db < minimojo.sql

Depending on your setup, it might be necessary to call this as sqlite3.

セットアップによって、 sqlite3として、コマンドを呼び出す必要があるかもしれません.

Use the helper to create model classes and basic unit tests (Figure 3 shows the results):

ヘルパースクリプトでModelクラスと基本のユニットテストを作ります(Figure 3に結果があります):

$ script/minimojo_create.pl model CDBI CDBI dbi:SQLite:/path/to/minimojo.db

Model-creation screenshot
Figure 3. Creating the model

The minimojo_create.pl script is a helper that uses Template Toolkit to automate the creation of particular modules. The previous command creates a model (in contrast to a controller or a view) called CDBI.pm, using the CDBI helper, setting the connection string to dbi:SQLite:/path/to/minimojo.db, the database you just created. (Use the appropriate path for your system.) The helper will write the models into lib/MiniMojo/M/. There are various options for the helper scripts; the only requirement is the type and the name. (You can create your own modules from scratch, without using the helper.)

The minimojo_create.pl スクリプトはTemplate Toolkitを使ったヘルパーで、 特定のモジュールの作成を自動化します。前のコマンドは(ControllerやViewとではなく)、CDBI.pmと呼ばれるModelを作ります。 CDBIヘルパーを使い、dbi:SQLite:/path/to/minimojo.dbの、先ほど作ったデータベースへの接続文字列をセットします。 (自分のシステムに合ったパスを使ってください)。 ヘルパーは、 lib/MiniMojo/M/にModelを書きます。 ヘルパースクリプトにはさまざまなオプションがあります; 必須はタイプと名前だけです。(ヘルパーを使わずに、スクラッチから自分のモジュールを作ることもできます)

▲ to Top/a>

Viewのセットアップ(Template::Toolkit) とヘルパースクリプトによるViewクラスの作成

ヘルパースクリプトによるViewクラスの作成:

$ script/minimojo_create.pl view TT TT

View classes go into lib/MiniMojo/V/.

Viewクラスはlib/MiniMojo/V/にできあがります。

ヘルパースクリプトによるControllerクラスの作成:

Create a controller class called Page with the helper:

ヘルパースクリプトによりPageControllerクラスを作ります:

$ script/minimojo_create.pl controller Page

Controller classes live in lib/MiniMojo/C/.

lib/MiniMojo/C/にControllerクラスが入ります。

Add a show action to lib/MiniMojo/C/Page.pm:

lib/MiniMojo/C/Page.pmshowアクションを追加します:

sub show : Regex('^(\w+)\.html$') {
    my ( $self, $c ) = @_;
    $c->stash->{template} = 'view.tt';
    # $c->forward('page');
}

The Regex dispatch matches a page in foo.html, where foo is any sequence of word characters. This sequence is available in the $context->request->snippets array, where the page action uses it to display an existing page or to create a new one. The rest of this action sets the appropriate template and sends the application to the page action. (Leave the forward command commented out until you have written the page action.)

Regexディスパッチがfoo.htmlのページにマッチします (fooは、どんな順番の単語の文字列配列でも構いません)。 この順番は$context->request->snippets 配列から利用できます。 pageアクションは存在するページを表示するか、新しいものを作るのに使われます。 このアクションの残りでは、適当なテンプレートをセットし、アプリケーションに、 pageアクションを送ります。(pageアクションを書くまで、 forwardをコメントしたままにしておきます)

Restart the server with $ script/minimojo_server.pl and point a web browser to http://localhost:3000/show/ to see the debug screen (you don't yet have the template that show is trying to send people to).

サーバを $ script/minimojo_server.pl で、リスタートし、http://localhost:3000/show/ をWebブラウザーでみると、デバッグスクリーンが表示されます (show が使おうとしたテンプレートは、まだ用意されていないので)

root/view.ttを作ります:

<html>
    <head><title>MiniMojo</title></head>
    <body>
        <h1>MiniMojo is set up!</h1>
    </body>
</html>

Test again by killing the server with Ctrl-C and restarting it, and go to http://localhost:3000/show/. You should see the page you just defined.

Ctrl-Cでサーバを殺して、リスタートし、 http://localhost:3000/show/を見てみます。今作ったページが見られるはずです。

▲ to Top

表示と編集のコードの追加

Modify the application class lib/MiniMojo.pm to include the Prototype and Textile plugins:

PrototypeTextile プラグインを使うために、 アプリケーションクラスのlib/MiniMojo.pmを変更しましょう:

use Catalyst qw/-Debug Prototype Textile/;

Note that you can use the plugins by specifying their base names; Catalyst figures out what you mean without making you use Catalyst::Plugin::Prototype.

ベースの名前を指定することで、プラグイン使うことができるのに注意してください; Catalystは、Catalyst::Plugin::Prototypeを使わなくても、意図するものの見当を付けます。

Modify the page controller, lib/MiniMojo/C/Page.pm, to add page-view and editing code:

page Controller、 lib/MiniMojo/C/Page.pmを修正します。 ページViewと、編集のコードを追加します:

sub page : Private {
    my ( $self, $c, $title ) = @_;
    $title ||= $c->req->snippets->[0] || 'Frontpage';
    my $query = { title => $title };
    $c->stash->{page} = MiniMojo::M::CDBI::Page->find_or_create($query);
}

The private page method sets a title--whether passed in to it, taken from the snippets array (that matches the regex in show), or defaulting to "Frontpage." The $query variable holds a hashref used for Class::DBI's find_or_create method, seeding the stash for the page variable with the result of this CDBI query. At the end of the method, control flow returns to the calling method.

プライベートなpage メソッドでタイトルをセットします -- (show内の正規表現にマッチした)snippets 配列から取得されればそれを、 そうでなければ、 "Frontpage"がデフォルトとしてタイトルに使われます。 $query変数は、Class::DBIfind_or_create メソッドで使われる ハッシュリファレンスを持ちます。CDBIクエリの結果と一緒にpage変数を埋めます。 メソッドの終わりに、コントロールフローは、呼び出すメソッドを返します。

Now uncomment the $c->forward('page'); line in the show action.

showアクション中の$c->forward('page');をコメントを外します。

sub edit : Local {
    my ( $self, $c, $title ) = @_;
    $c->forward('page');
    $c->stash->{page}->body( $c->req->params->{body} )
      if $c->req->params->{body};
    my $body = $c->stash->{page}->body || 'Just type something...';
    my $html = $c->textile->process($body);

    my $base = $c->req->base;
    $html    =~ s{(?<![\?\\\/\[])(\b[A-Z][a-z]+[A-Z]\w*)}
                 {<a href="$base$1.html">$1</a>}g;

    $c->res->output($html);
}

The edit method first forwards the action off to page, so that the stash's page object contains the result of the CDBI query. If there is a value for body, it will use this; otherwise "Just type something..." is the default. The code then processes the body with Textile, which converts plain text to HTML, and then runs the body through a regex to convert camel-case text into links, with the URL base taken from the Catalyst request object. Finally, it outputs the HTML.

edit メソッドは、まずpageにアクションをフォーワードします。 stashの pageオブジェクトはCDBIクエリの結果を含んでいます。 bodyのための値があれば、それを使います; そうでなければ、"Just type something..." がデフォルトです。 コードは、bodyをTextileで処理します。これは、プレインテキストをHTMLに変換します。 Catalystリクエストオブジェクトから受け取ったURLベースで、 camel-caseテキストをリンクに変換する正規表現をbodyに通します。 最後に、HTMLを出力します。

▲ to Top

AjaxでWikiをセットアップする

Modify root/view.tt to include Ajax code:

root/view.tt を変更し、Ajax codeを含めます:

<html>
     <head><title>MiniMojo</title></head>
     [% c.prototype.define_javascript_functions %]
     [% url = base _ 'page/edit/' _ page.title %]
     <body Onload="new Ajax.Updater( 'view',  '[% url %]' )">
         <h1>[% page.title %]</h1>
         <div id="view"></div>
         <textarea id="editor" rows="24" cols="80">[% page.body %]</textarea>
         [% c.prototype.observe_field( 'editor', {
             url => url,
             with => "'body='+value",
             update => 'view' }
         ) %]
     </body>
</html>

その行:

[% c.prototype.define_javascript_functions %]

includes the whole prototype.js library in a script block. Note that the prototype plugin is available in the context object.

scriptブロックにすべてのprototype.js をインクルードします。 prototypeがコンテキストオブジェクトで使えることに注意してください。

セクション

[% url = base _ 'page/edit/' _ page.title %] 
<body Onload="new Ajax.Updater( 'view',  '[% url %]' )">
<h1>[% page.title %]</h1>
<div id="view"></div>

constructs the Ajax URL and updates the view div when loading the page.

ページをロードするときに、Ajax URLを組み立て、view、divをアップデートします。

最後に:

<textarea id="editor" rows="24" cols="80">[% page.body %]</textarea>
    [% c.prototype.observe_field( 'editor', {
        url => url,
        with => "'body='+value",
        update => 'view' }
    ) %]

periodically checks the textarea for changes and makes an Ajax request on demand.

定期的に textarea を、変更があるかチェックし、デーモンでAjaxリクエストを作ります。

That's it! Now you can re-run the server and your wiki is up and running (Figure 4). To use the wiki, simply start typing in the textarea. As you type, the wiki will regularly echo your entry above, passing it through the formatter. When you type something in camel case, it will automatically create a link you can click to go to the new page.

これ迄! サーバを再起動すれば、Wikiは動いています(Figure 4). Wikiを使うためには、textareaにタイプするだけです。 タイプ通りに、wikiは、定期的に上textareaの上に、フォーマッターを通して、エントリーを表示します。 キャメルケースで何かを書けば、自動的にリンクが作られて、クリックして、新しいページへ行くことができます。

screenshot of the running wiki
Figure 4. The running wiki

Enjoy your new Catalyst-powered Ajax wiki!

Catalyst-powered Ajax wikiを楽しんでください!

▲ to Top

リソース

For more information, see the Catalyst documentation, in particular the Catalyst::Manual::Intro module, which gives a thorough introduction to the framework. There are two Catalyst mailing lists, a general list and a developer list. The best place to discuss Catalyst, though, is the #catalyst IRC channel at irc.perl.org. The Catalyst home page is currently just a collection of a few links, but we will extend it in the near future.

詳しくは、Catalystのドキュメントを見てください、特に、Catalyst::Manual::Intro moduleは、 フレームワークの詳細なイントロダクションです。 メーリングリストが2つあります、Catalyst mailing lists。 一般向けのものと、開発者向けのものです。Catalystについて議論する一番の場所は、 irc.perl.orgにある、IRCの#catalystチャンネルです。 Catalyst home pageは現在は、少ないリンク集になっています。 近い将来、拡張するでしょう。

Thanks to Catalyst lead developer Sebastian Riedel for help with this article and, of course, for Catalyst itself.

Catalystのリードディベロッパーの Sebastian Riedelに、この記事を書くために助けてもらいました。感謝します。 そして、もちろん、Catalyst自身にも。

▲ to Top

翻訳について

翻訳者: Ktat
連絡先: ktat.is@gmail.com

▲ to Top