ScrumもどきPlugin開発記その3
今回はTracScrumHalfのメインページを作成して、ナビゲーションメニューに追加する。
メインページの中身はとりあえずテキトーで。
例によってTiming and Estimating Pluginを参考にする。
Component追加
src/scrumhalf/scrumhalf.py
import re from genshi.builder import tag from trac.core import * from trac.web import IRequestHandler from trac.web.chrome import INavigationContributor, ITemplateProvider, \ add_stylesheet class ScrumHalf(Component): implements(INavigationContributor, IRequestHandler, ITemplateProvider) def __init__(self): pass # INavigationContributor methods def get_active_navigation_item(self, req): return 'scrumhalf' def get_navigation_items(self, req): yield ('mainnav', 'scrumhalf', tag.a('scrumhalf', href=req.href.scrumhalf())) # IRequestHandler methods def match_request(self, req): return re.match(r'/scrumhalf(?:_trac)?(?:/.*)?$', req.path_info) def process_request(self, req): add_stylesheet(req, 'static/css/scrumhalf.css') return 'scrumhalf.html', {}, None # ITemplateProvider methods def get_templates_dirs(self): from pkg_resources import resource_filename return [resource_filename(__name__, 'templates')] def get_htdocs_dirs(self): from pkg_resources import resource_filename return [('static', resource_filename(__name__, 'htdocs'))]
今回実装した拡張ポイントは以下の3つ。
INavigationContributor | ナビゲーションメニューを拡張 |
IRequestHandler | HTTPリクエストを処理するハンドラ |
ITemplateProvider | 独自テンプレートと静的コンテンツの使用 |
以下に各拡張ポイント実装を(分かる範囲で)説明する。
INavigationContributorメソッド実装
# INavigationContributor methods def get_active_navigation_item(self, req): return 'scrumhalf' def get_navigation_items(self, req): yield ('mainnav', 'scrumhalf', tag.a('scrumhalf', href=req.href.scrumhalf()))
get_active_navigation_item | IRequestHandlerがHTTPリクエストを処理すると呼び出される。非選択ハイライト表示する、ナビゲーション項目名を返す。 |
get_navigation_items | 追加するナビゲーション項目を返す。それぞれの項目は(category, name, text)のタプルで返す。 |
このget_navigation_itemsがジェネレータ関数てやつね。つまりナビゲーション項目を複数追加する場合はyieldを複数記述する・・・と。
IRequestHandler実装
# IRequestHandler methods def match_request(self, req): return re.match(r'/scrumhalf(?:_trac)?(?:/.*)?$', req.path_info) def process_request(self, req): add_stylesheet(req, 'static/css/scrumhalf.css') return 'scrumhalf.html', {}, None
match_request | リクエストを処理するかどうかを判定する。 |
process_request | リクエストを処理する。 |
process_requestは、Genshiテンプレート使用の場合(template_name, data, content_type)のタプルを返す。ClearSilverの場合は(template_name, content_type)。
dataは置換するデータのdictionary(今回はナシ)。content_typeは、Noneの場合"text/html"。
add_stylesheetでスタイルシートを追加出来る。
ITemplateProvider実装
# ITemplateProvider methods def get_templates_dirs(self): from pkg_resources import resource_filename return [resource_filename(__name__, 'templates')] def get_htdocs_dirs(self): from pkg_resources import resource_filename return [('static', resource_filename(__name__, 'htdocs'))]
get_templates_dirs | テンプレートを置くディレクトリパスのlist |
get_htdocs_dirs | 静的ファイルを置くディレクトリ。(prefix, abspath)タプルのlist。prefixはアクセスするURLプレフィクス。abspathはディレクトリのローカルファイルシステム絶対パス。 |
テンプレート追加
とりあえず超簡単なテンプレートを。
src/scrumhalf/templates/scrumhalf.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://genshi.edgewall.org/" xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="layout.html" /> <head> <title>Helloworld</title> </head> <body> <div id="ctxtnav" class="nav"></div> <div id="content" class="scrumhalf"> <h1>Scrum Half!!!</h1> <img src="${href.chrome('static/images/chart.png')}"/> </div> </body> </html>
静的ファイル追加
src/scrumhalf/htdocs/images/chart.png
てきとーな画像。
__init__.py追記
__init__.py
# TracScrumHalf module from initenv import * from scrumhalf import *
実行!
Tracdを再起動して、WebAdminからComponentを有効にする。
ナビゲーションメニューから[scrumhalf]をクリック。
おお。でけた。なんかズレとるけど。(^_^;
※画像はダミーです
最終的なフォルダ構成
src │ setup.py │ └─scrumhalf │ initenv.py │ scrumhalf.py │ __init__.py │ ├─htdocs │ ├─css │ │ scrumhalf.css │ │ │ └─images │ chart.png │ └─templates scrumhalf.html
まだまだ分からんことだらけだが・・・少しずつ作ってくよ。