[python] jinja2에서 파이썬 함수 호출

jinja2를 사용하고 있으며 매크로를 호출하는 것과 유사한 구문을 사용하여 파이썬 함수를 도우미로 호출하고 싶습니다. jinja2는 함수 호출을 막기위한 의도로 보이며 함수를 템플릿에 매크로로 복사하여 반복 할 것을 주장합니다.

이 작업을 수행하는 간단한 방법이 있습니까? 그리고 전체 파이썬 함수를 가져 와서 많은 확장 기능을 작성하는 등 리가 마롤을 거치지 않고 jinja2에서 액세스 할 수있는 방법이 있습니까?



답변

플라스크를 사용하는 사람들은 이것을 다음에 넣으십시오 __init__.py.

def clever_function():
    return u'HELLO'

app.jinja_env.globals.update(clever_function=clever_function)

템플릿에서 {{ clever_function() }}


답변

참고 : 이것은 플라스크 전용입니다!

이 게시물이 상당히 오래되었다는 것을 알고 있지만 컨텍스트 프로세서를 사용하여 최신 버전의 Flask 에서이 작업을 수행하는 더 좋은 방법이 있습니다.

변수를 쉽게 만들 수 있습니다 :

@app.context_processor
def example():
    return dict(myexample='This is an example')

위와 같이 Flask를 사용하는 Jinja2 템플릿에서 사용할 수 있습니다.

{{ myexample }}

(어떤 출력 This is an example)

본격적인 기능뿐만 아니라 :

@app.context_processor
def utility_processor():
    def format_price(amount, currency=u'€'):
        return u'{0:.2f}{1}'.format(amount, currency)
    return dict(format_price=format_price)

위와 같이 사용하면 위와 같습니다.

{{ format_price(0.33) }}

(통화 기호와 함께 입력 가격을 출력하는 경우)

또는 플라스크에 구운 진자 필터를 사용할 수 있습니다 . 예 : 데코레이터 사용 :

@app.template_filter('reverse')
def reverse_filter(s):
    return s[::-1]

또는 데코레이터없이 수동으로 기능을 등록하십시오.

def reverse_filter(s):
    return s[::-1]
app.jinja_env.filters['reverse'] = reverse_filter

위의 두 가지 방법으로 적용된 필터는 다음과 같이 사용할 수 있습니다.

{% for x in mylist | reverse %}
{% endfor %}


답변

jinja가 의도적으로 템플릿 내에서 ‘임의’파이썬을 실행하는 것을 어렵게 만듭니다. 템플릿의 로직이 적을수록 좋다는 견해를 강요합니다.

Environment인스턴스 내에서 글로벌 네임 스페이스를 조작 하여 함수에 대한 참조를 추가 할 수 있습니다. 템플릿을로드 하기 전에 수행해야합니다 . 예를 들면 다음과 같습니다.

from jinja2 import Environment, FileSystemLoader

def clever_function(a, b):
    return u''.join([b, a])

env = Environment(loader=FileSystemLoader('/path/to/templates'))
env.globals['clever_function'] = clever_function


답변

from jinja2 import Template

def custom_function(a):
    return a.replace('o', 'ay')

template = Template('Hey, my name is {{ custom_function(first_name) }} {{ func2(last_name) }}')
template.globals['custom_function'] = custom_function

Matroskin의 답변 에 따라 필드에서 기능을 제공 할 수도 있습니다

fields = {'first_name': 'Jo', 'last_name': 'Ko', 'func2': custom_function}
print template.render(**fields)

출력합니다 :

Hey, my name is Jay Kay

Jinja2 버전 2.7.3에서 작동

브루노 브로 노 스키의 답변template.globals확인하면서 데코레이터가 함수를 쉽게 정의 할 수있게 하려면


답변

@AJP의 답변이 마음에 듭니다 . 나는 많은 기능으로 끝날 때까지 그것을 그대로 사용했습니다. 그런 다음 Python 함수 데코레이터 로 전환했습니다 .

from jinja2 import Template

template = '''
Hi, my name is {{ custom_function1(first_name) }}
My name is {{ custom_function2(first_name) }}
My name is {{ custom_function3(first_name) }}
'''
jinga_html_template = Template(template)

def template_function(func):
    jinga_html_template.globals[func.__name__] = func
    return func

@template_function
def custom_function1(a):
    return a.replace('o', 'ay')

@template_function
def custom_function2(a):
    return a.replace('o', 'ill')

@template_function
def custom_function3(a):
    return 'Slim Shady'

fields = {'first_name': 'Jo'}
print(jinga_html_template.render(**fields))

좋은 기능에는 __name__!


답변

공식 문서 나 스택 오버플로에서 그런 간단한 방법을 보지 못했지만 이것을 발견했을 때 놀랐습니다.

# jinja2.__version__ == 2.8
from jinja2 import Template

def calcName(n, i):
    return ' '.join([n] * i)

template = Template("Hello {{ calcName('Gandalf', 2) }}")

template.render(calcName=calcName)
# or
template.render({'calcName': calcName})


답변

람다를 사용하여 템플릿을 기본 코드에 연결

return render_template("clever_template", clever_function=lambda x: clever_function x)

그런 다음 템플릿에서 함수를 완벽하게 호출 할 수 있습니다.

{{clever_function(value)}}