[TurboGears] ブログを作成する。その4
注意
この記事は、id:SumiTomohiko:20070118:1169099368の続きです。
その3からの変更点
id:SumiTomohiko:20070118:1169099368のあと、画面のデザインを変更し、記事を編集、削除する機能を追加しました。現在は、以下のような画面になっています。
デザインの変更や、編集、削除の処理自体はたいしたことはないので、説明は省略します。この記事では、ウィジェットを使ったところについて説明します。
ウィジェット
ウィジェットは、ビューの部品です。複数の箇所に存在する同じ部品を、共通化することができます。今回は、記事の登録画面と編集画面にある、記事を入力する以下のフォームを、ウィジェットで共通化します。
ウィジェットは、TurboGears Widget Browserでみることができます。TurboGears Widget Browserは、tg-admin toolboxコマンドを実行した後、http://127.0.0.1:7654/をブラウザで開き、メニューの左下にある"Widget Browser"をクリックすると閲覧できます。TurboGears Widget Browserには様々なウィジェットがありますが、その中のTable Formがもっともイメージに近いので、これを継承して作ることにします。
修正するファイルは、tgdiary/controller.pyです。まず、turbogears.widgetsをimportします。
from turbogears import controllers, expose, widgets
次に、フォームを表すウィジェットを作成します。turbogears.widgets.TableFormを継承します。記事登録画面と編集画面ではフォームを送信するURLが異なるので、コンストラクタのaction変数に送信先を渡すようにします。
class ArticleFormWidget(widgets.TableForm): def __init__(self, action): title_field = widgets.TextField('title', label=u'題名', attrs=dict(size='64')) body_field = widgets.TextArea('body', label=u'本文', rows=16, cols=64) super(ArticleFormWidget, self).__init__('ArticleEditForm', fields=[title_field, body_field], action=action, submit_text=u'送信')
コンストラクタでは最初に、フォームに設置するテキストボックスとテキストエリアを作成します。
テキストボックスを表すクラスは、turbogears.widgets.TextFieldです。TextFieldのコンストラクタの最初の引数は、<input>タグのname属性の値です。これはまた、ウィジェットを表示するときに与えられたオブジェクトの、表示する属性を表します(後述します)。label引数は、テキストボックスの左に表示される文字列です。label引数がない場合は、最初の引数がそのまま表示されます。attrs引数は、それ以外の属性を辞書で与えます。ここでは、size属性を設定しています。
テキストエリアを表すクラスは、turbogears.widgets.TextAreaです。TextFieldと同様に、最初の引数はname属性の値であり、label引数は横に表示される文字列です。rows引数とcols引数は、<textarea>タグのrows属性とcols属性に対応します。
なお、どんなウィジェットがどんなパラメータをとるかは、TurboGears Widget Browserで閲覧できます。
コンストラクタの最後では、親クラス (TableForm) のコンストラクタを呼び出します。<form>タグのname属性の値と、フォームに含まれるTextFieldとTextArea, フォームのaction属性の値、送信ボタンの表示文字列を設定します。
ウィジェットを使うときは、まずコントローラ内でウィジェットを作成します。例えば、記事の編集画面を表示するeditメソッドでは、以下のようになります。上述の通り、コンストラクタにはフォームの送信先URLを与えています。ウィジェットはビューで使用するので、メソッドの戻り値の辞書に含めます。
@expose(template="tgdiary.templates.edit") @identity.require(identity.not_anonymous()) def edit(self, id): # TODO: Validate id and user's id. article = Article.get(id) article_form_widget = ArticleFormWidget('/doedit?id=%s' % id) return dict(article=article, article_form_widget=article_form_widget)
ウィジェットを使うtgdiary/templates/edit.kidでは、以下のように記述します。
${article_form_widget.display(article)}
ウィジェットのオブジェクトのdisplayメソッドを呼び出すだけです。displayメソッドには、ウィジェットで表示するオブジェクトを与えます。このオブジェクトの、TextFieldオブジェクトなどのコンストラクタで指定した属性が、各フィールドに表示されます。
参考文献
id:aodag:20070114:1168796301