4

次のような mako テンプレートの小さな階層があります。

base.mako

<h1>${self.view()}</h1>
${listactions(self.mainactions)}
${self.body()}

<%def name="listactions(actions)">
    <ul>
    % for action in actions:
        <li>${action}</li>
    % endfor
    </ul>
</%def>

clientbase.mako

<%inherit file="base.mako"/>
<%def name="view()">Clients</%def>
<%
    mainactions = [request.route_url('clientsnew')]
%>

clientindex.mako

<%inherit file="clientsbase.mako"/>
This is the index

問題は、clientsindex.mako をレンダリングするクライアント インデックス ビューにアクセスしようとすると、エラーAttributeError: Namespace 'self:/base.mako' has no member 'mainactions' が表示されることです。

これを行う適切な方法は何ですか?私は mako のドキュメントを調べましたが、これまでに見つけたのは、モジュール レベルの python ブロックを使用して mainactions を宣言し、次に base.mako で self.attr.mainactions を実行できることです。問題は、このブロック内にあり、リクエスト オブジェクトにアクセスできません。

別の質問があると思います: 私の場合、関数をビュー呼び出し可能オブジェクトとして使用していますが、クライアントに関連するすべてのビューを保持する個別の client.py ビュー ファイルを作成したとしましょう。何らかの方法でclients.pyファイルからコントローラー全体のコンテキスト変数のようなものを設定する方法はありますか? このようにして、各ビューの辞書で返すことなく、テンプレートのコンテキストに mainactions 変数を設定することができます。

4

4 に答える 4

1

これはかなり古い質問ですが、ここでは、うまくいくかもしれないと思います。テンプレートを作成するときは、デフォルトで関数を実際に表示していることに注意してくださいbody()

私の推測では、それmainactionsはのローカル変数として定義されていself.body()ます。しかし、私たちは自分自身にアクセスできるので、すべてがクールです...

だから書く代わりに:

mainactions = [request.route_url('clientsnew')]

あなたは書くことを試みるべきです:

self.mainactions = [request.route_url('clientsnew')]

とはいえ、これはあなたがやりたいことを達成するための本当に良い方法ではありません。もし私があなたなら、defまたはを使ってやりますblock

base.mako

<h1>${self.view()}</h1>
<%block name="mainaction">
</%block>
${self.body()}

<%def name="listactions(actions)">
    <ul>
    % for action in actions:
        <li>${action}</li>
    % endfor
    </ul>
</%def>

clientbase.mako

<%inherit file="base.mako"/>
<%def name="view()">Clients</%def>
<%block name="mainaction"
    ${request.route_url('clientsnew')}
</%block>

残りは変更されません...defの場合は、deffromの親をオーバーライドしてから、必要な場所base.makoを使用しdefます。

それはほとんどそれです。

于 2012-06-27T21:42:41.713 に答える
0

この答えは古いので、あなたがすでにこの問題を解決したかどうかはわかりません。

動作する可能性のある1つの方法は、view()def内でPythonブロックを移動することです。そうすれば、その変数は実際にはbase.makoで呼び出されます。

自分のアプリでview、アプリ全体で必要な一連のコンテキスト変数(view.page、view.perpageなど)を保持するオブジェクトを作成しました。呼び出し可能なすべてのビューで、これを開始しますview(getsからコンテキスト変数を計算します。 post_data、routesなどを自動的に)そしてそれをコンテキスト変数として渡します。したがって、いつでもview.mainactionsを渡すことができ、デフォルトでNoneを維持している限り、アプリでKeyErrorsが発生することはありません。

于 2011-12-13T20:18:27.843 に答える
0

この答えはあなたの「他の質問」に対するものです:)

ビューを Controller クラスのメソッドとして定義できます。このようにして、コントローラー全体の変数出力を共通のメソッドに分解できます。

from pyramid.view import view_config
from myproject.resources import MyResource


class MyController(object):

    def __init__(self, request):
        self.request = request

    def respond(self, additionalVars):
        additionalVars['myCommonVar1'] = 'common value'
        return additionalVars

    @view_config(
        context='myproject.resources:MyResource',
        request_method='GET',
        renderer='one.mak')
    def get_one(self):
        return self.respond({'var2':'sth'})

    @view_config(
        context='myproject.resources:MyResource',
        name = 'two',
        request_method='GET',
        renderer='two.mak')
    def get_two(self):
        return self.respond({'var3':'sth else'})
于 2012-09-12T07:51:41.677 に答える
0

うーん...私は長い間パイロンに何も書いていませんし、それをチェックするためのパイロンのインストールもしていません。next.mainactionsしかし、代わりに書いてみてself.mainactions、何が起こるか見てください。

于 2011-04-06T14:19:19.997 に答える