10
Rendererをカスタマイズす @moriyoshit For Pylonsはっかそん 2014.11

Pyramidのrendererをカスタマイズする

Embed Size (px)

Citation preview

Page 1: Pyramidのrendererをカスタマイズする

Rendererをカスタマイズする

@moriyoshit

For Pylonsはっかそん 2014.11

Page 2: Pyramidのrendererをカスタマイズする

自己紹介

• Pylonsはっかそん初めてです

• 仕事でPyramidを2年ほど…

Page 3: Pyramidのrendererをカスタマイズする

動機

• Requestによってレンダリングするテンプレートを変えたい

• Virtual hostみたいなものを想定

• それたぶんpyramid_layoutでできるよ?

• Exception viewはどうする?

• Requestに含まれる情報からレンダリングに必要な情報を作ってテンプレートに渡したい

• たとえば、CSSや画像へのパスなど

• これは BeforeRender event で inject してもいいけど、レンダリングの文脈でやりたい

Page 4: Pyramidのrendererをカスタマイズする

add_view

permissionattrmapperhttp_cachePredicates

request_type / request_method / request_param / xhr / containment / wrapper / accept / header / context / decorator / match_param / check_csrf / effective_principals / physical_path

Pyramidのレンダリングのしくみ

View Deriver

RendererHelper

route_name

renderer

Create

Parameters

Create

(caller package)

Parameters

Page 5: Pyramidのrendererをカスタマイズする

Pyramidのレンダリングのしくみ

Predicated view

Auth debug view

Secured view

Wrapped view

HTTP cached view

Rendered view

Mapped view

User-supplied view callable

View Deriver

Page 6: Pyramidのrendererをカスタマイズする

Pyramidのレンダリングのしくみclass ViewDeriver(object):

def __init__(self, **kw):self.kw = kwself.registry = kw['registry']self.authn_policy =

self.registry.queryUtility(IAuthenticationPolicy)self.authz_policy =

self.registry.queryUtility(IAuthorizationPolicy)self.logger = self.registry.queryUtility(IDebugLogger)

def __call__(self, view):return self.attr_wrapped_view(

self.predicated_view(self.authdebug_view(

self.secured_view(self.owrapped_view(

self.http_cached_view(self.decorated_view(

self.rendered_view(self.mapped_view(

view)))))))))

Page 7: Pyramidのrendererをカスタマイズする

Pyramidのレンダリングのしくみ

Rendered view

Mapped view

User-supplied view callable

RendererHelper

IRendererFactory

IRenderer

Dict-like

Lookup

IResponse

Create

Passing self as IRenderInfo

Page 8: Pyramidのrendererをカスタマイズする

add_viewでの挙動

if isinstance(renderer, string_types):renderer = renderers.RendererHelper(

name=renderer, package=self.package,registry = self.registry)

渡されたrendererがstring typeであればRendererHelperでくるむそうでなければ、RendererHelperとしてそのままViewDeriverに渡す

Page 9: Pyramidのrendererをカスタマイズする

カスタマイズポイント• IRenderFactoryを登録する (add_renderer)

• レンダラのルックアップ方法に縛られる• 拡張子• フルマッチ

• カスタムレンダラにconfiguration時にパラメータを渡す術がない

• RendererHelperを直接add_viewのrendererとして渡す

• RendererHelperのコンストラクタに渡すべきconfig.packageとconfig.registryは別途取得しておかないといけない

• @view_config decorator と相性が悪すぎる

Page 10: Pyramidのrendererをカスタマイズする

結局どうしているか

• ILateBoundRendererHelperというインターフェイスを勝手に定義、コンストラクタでpackageとregistryを渡すのではなくて後からvenusianのscan時にbindできるようにした

• bind(package, registry)

• 上記のインターフェイスに対応したadd_viewとしてadd_lbr_viewというdirectiveを追加w

• add_lbr_viewに対応した@lbr_view_configを作った