Turbogearsプロジェクトのコントローラを考えてみる

ディレクトリ構造から考えてみる

久しくTurbogearsをいじっていなかったのでだいぶ忘れちゃっていますが、とりあえずコントローラを考えてみることにします。コントローラはビューに結構関係していますので、ビューを考えるうちにコントローラを書き換えたり、まぁそういう感じになっちゃうんじゃないでしょうか。なので、とりあえず大枠を考えるといった感じです。

URLとPythonオブジェクトのマッピング

コントローラって何よ、という概念がまだ自分の中にはできあがってないのですが、現時点ではURLとPythonオブジェクトをマッピングするものだ、という理解です(言葉遣いあってるのかな…)。違ってたら是非ご指摘ください(*´Д`)ノ

一般的なwebサイトの場合、URLは例えば以下のようなディレクトリ構造によって決まります。

webサイトのディレクトリ構造

このようなディレクトリ構造の場合、例えばindex.htmlには「http://www.example.com/index.html」というURLによってアクセスすることができますし、snackディレクトリには「http://www.example.com/snack」というURLによってアクセスすることができます。

しかしTurbogearsではこういったディレクトリ構造によるURLではなく、PythonオブジェクトによってURLを決定します。これはCherryPyによって実現されています。ちなみに私はCherry Pieを食べたことはありません。

いろいろな書き方ができるとは思うのですが、個人的には上記のようなディレクトリ構造を念頭に置いてコントローラを作ってみたいと思います。

まずはPythonオブジェクトによってどのようにURLが決定できるのか簡単な例を見てみたいと思います。

class Root(controllers.RootController):
@expose()
def index(self):
return "Hello, world!"

@expose()
def about(self):
return "This is Junksnack Project."

ルートクラスのメソッドとしてindexとaboutを書いてみました。細かい部分はちょっと横に置いておいて、これはディレクトリ構造でいえば、ルートディレクトリの配下にindex.htmlとabout.htmlがあるような感じです。具体的には

  • 「http://www.example.com/index.html」にアクセス→「Hello, world!」が表示される
  • 「http://www.example.com/about.html」にアクセス→「This is Junksnack Project.」が表示される

というような状況を想定すればいいと思います。

ここでは

  • Rootクラス→ルートディレクトリ
  • indexメソッド→index.htmlファイル
  • aboutメソッド→about.htmlファイル

という対応をしています。

つまり、一般的なディレクトリ構造における

  • ディレクトリ→クラス
  • ファイル→メソッド

として実装すればわかりやすいんじゃないかなぁと思います(あくまで一つのアプローチにすぎませんが)。

もちろん必ずそうしなければならないという決まりは全然ありませんし、プロジェクトの内容によってどのレベルでクラス分けをすればよいのかというのは異なってくると思います。しかし今回のプロジェクトの現段階では、個人的な理解のしやすさという意味でこういうやり方を採りたいと思います。

今回のプロジェクトではどんな構造にしようかな

ということで具体的に今回のプロジェクトでは以下のようなディレクトリ構造にしてみたいと思います。

今回のプロジェクトで想定するディレクトリ構造

  • ルートディレクトリ
    • index.html
    • about.html
    • maker1ディレクトリ
      • index.html
      • snack1ファイル
      • snack2ファイル
      • などなど
    • maker2ディレクトリ
    • などなど

つまり、ルートディレクトリ配下にはindex.htmlとabout.htmlファイル、そしてその他にディレクトリとして各メーカディレクトリがあります。各メーカディレクトリ配下にはindex.htmlや、そのメーカが発売しているスナックのファイル(snack1とかsnack2とか)があるという感じです。

ということはコントローラの方はどうなるかといえば(細部は超省略)、

Class Makers():
def index():
def snack():

Class Root():
def index():
def about():

こんな感じでいかがでしょう?

ではとりあえず動的な要素なしで、それぞれのページでPlainTextだけを出力させてみます。

class Makers:
@expose()
def index(self):
return "makers page"

@expose()
def snack(self):
return "This is snack item page."

class Root(controllers.RootController):
makers = Makers()

@expose()
def index(self):
return "top page"

@expose()
def about(self):
return "This is Junksnack Project."

基本的な形

@exposeについて

基本的な形としては

class ClassName:
@expose()
def MethodName(self):
return "Plain Text"

というふうになっています。

@expose()

というのが特徴的で、Python2.4から実装された修飾子(デコレータ)である「@」を使っています。メソッドの直前でこれを書くことによって、外部からこのメソッドにアクセスできることになります(=ブラウザでアクセスできる)。CherryPyではセキュリティのためにデフォルトでは各メソッドにはアクセスできないようになっています。@exposeを明示した場合にのみ、そのメソッドにアクセスできるようになります。

また、デコレータを使わずに

MethodName.exposed = True

と書くこともできます。

すなわち

class ClassName:
@expose()
def MethodName(self):
return "Plain Text"


class ClassName:
def MethodName(self):
return "Plain Text"
MethodName.exposed = True

は同義です。

MakersクラスをRootツリーに組み込む

class Root(controllers.RootController):
makers = Makers()

としてますが、makers = Makers()によってMakersクラスをRootツリーに組み込んでいます。

  • makers→URLで使う名前
  • Makers()→定義したクラス

となります。これがないと例えば「http://www.example.com/makers」にアクセスしてもnot foundになります。

ということで

# Makersクラスを定義します
# 一般的なディレクトリ構造の「makers」フォルダに相当します
# 配下にはindex.htmlやsnack.htmlなどがある、という想定です

class Makers:
# indexメソッドにアクセスできるように@expose()を指定します
@expose()
# indexメソッドを定義します
# index.htmlのようなものだと思えばいいと思います
def index(self):
# ここではとりあえず簡単な文字列を返すことにします
return "makers page"

@expose()
def snack(self):
return "This is a snack item page."

# Rootクラスを定義します
# ルートディレクトリ配下にindex.htmlやabout.htmlがあるという感じです
class Root(controllers.RootController):

# MakersクラスをRootクラスに取り込みます
# これによってhttp://www.example.com/makersのような形で
# Makersクラスの各メソッドにアクセスできるようになります
makers = Makers()

# @expose()を使わずにメソッドにアクセス可能にしてみます
# すなわち「メソッド名.exposed = True」とします
def index(self):
return "top page"
index.exposed = True

@expose()
def about(self):
return "This is Junksnack Project."

これによって以下のような結果(PlainTextの出力)が得られます。

  • http://www.example.com → top page
  • http://www.example.com/index → top page
  • http://www.example.com/about → This is Junksnack Project.
  • http://www.example.com/makers → makers page
  • http://www.example.com/makers/index → makers page
  • http://www.example.com/makers/snack → This is a snack item page.
カテゴリ
Turbogears Turbogears
トラックバック用URL:
http://nagosui.org/Nagosui/COREBlog2/plan-projects-controller/tbping
コメントを追加

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

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

このBlogについて
Plone, Zope, Pythonなどのトピックについてのメモです。
カテゴリ
Plone (98)
Plone Products (23)
COREBlog2 (31)
COREBlog1 (29)
ReadingCOREBlog (7)
Zope (66)
Turbogears (18)
Django (12)
Python (25)
Linux (30)
Nagosui (11)
Design (33)
Misc (48)
moblog (5)
最近のエントリ
Glossy Horizontal Menuを使う nyusuke 2008年11月17日
第3回Python東海終了 nyusuke 2008年11月17日
Universalじゃない件 nyusuke 2008年11月15日
CorruptedErrorが出たので直す nyusuke 2008年11月14日
最近のコメント
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日