2014-02-14 70 views
6

我有一個宏,用於使用debmirror來構建本地存儲庫。如何在Jinja2宏中引發異常?

這裏的代碼片段:

{%- set gnupghome = kwargs.pop('gnupghome', '/root/.gnupg') %} 
{%- set env = { 'GNUPGHOME': gnupghome } %} 
keyring_import: 
    cmd: 
    - run 
{%- if 'keyid' in kwargs and 'keyserver' in kwargs %} 
    {%- set keyid = kwargs.pop('keyid') %} 
    {%- set keyserver = kwargs.pop('keyserver') %} 
    - name: 'gpg --no-default-keyring --keyring {{ gnupghome }}/trustedkeys.gpg --keyserver {{ keyserver }} --recv-keys {{ keyid }}' 
{%- elif 'key_url' in kwargs %} 
    {%- set key_url = kwargs.pop('key_url') %} 
    - name: 'wget -q -O- "{{ key_url }}" | gpg --no-default-keyring --keyring {{ gnupghome }}/trustedkeys.gpg --import' 
{%- endif %} 
    - require: 
     - pkg: wget 
     - pkg: gnupg 

endif關鍵詞,我想用else引發異常,對於如:

無論key_url或兩個密鑰服務器和keyid的需要。

可能嗎?

+3

沒有,Jinja2的不支持引發異常。你可以使用python函數或過濾器,它可以引發異常,但不能在純Jinja中使用。 –

回答

4

這可以在擴展中處理。從https://github.com/duelafn/python-jinja2-apci

# FROM: https://github.com/duelafn/python-jinja2-apci/blob/master/jinja2_apci/error.py 
from jinja2 import nodes 
from jinja2.ext import Extension 
from jinja2.exceptions import TemplateRuntimeError 

class RaiseExtension(Extension): 
    # This is our keyword(s): 
    tags = set(['raise']) 

    # See also: jinja2.parser.parse_include() 
    def parse(self, parser): 
     # the first token is the token that started the tag. In our case we 
     # only listen to "raise" so this will be a name token with 
     # "raise" as value. We get the line number so that we can give 
     # that line number to the nodes we insert. 
     lineno = next(parser.stream).lineno 

     # Extract the message from the template 
     message_node = parser.parse_expression() 

     return nodes.CallBlock(
      self.call_method('_raise', [message_node], lineno=lineno), 
      [], [], [], lineno=lineno 
     ) 

    def _raise(self, msg, caller): 
     raise TemplateRuntimeError(msg) 

傳遞擴展到您的環境:jinja2.Environment(... extensions=[RaiseExtension])然後在模板中使用它:

{%- if 'keyid' in kwargs and 'keyserver' in kwargs %} 
    ... 
{%- else %} 
    {% raise "Either key_url or both keyserver and keyid required." %} 
{% endif %} 
1

院長Serenevy的回答是優雅。這是一個較短的解決方案,它增加了一個全球性的jinja的環境。

def raise_helper(msg): 
    raise Exception(msg) 

env = jinja2.Environment(... 
env.globals['raise'] = raise_helper 

然後在你的模板:

{{ raise("uh oh...") }} 
6

超級快速的解決方法,只要你不介意養ZeroDivisionError:無論你想提高一個例外

插入一個{{ 0/0 }}

3

插入一個{{ "My error explained here"/0 }}表達式。例如

{% if not required_parameter %} 
{{ "required_parameter must be defined."/0 }} 
{% endif %} 

(建立在0/0 zsero的答案)