জিনজা 2 থেকে পাইথন ফাংশনটি কল করুন


144

আমি জিনজা 2 ব্যবহার করছি, এবং আমি একটি সহায়ক হিসাবে পাইথন ফাংশনটি কল করতে চাই, অনুরূপ সিনট্যাক্স ব্যবহার করে যেন আমি ম্যাক্রো কল করছি। জিনজা 2 আমাকে একটি ফাংশন কল করতে বাধা দেওয়ার অভিপ্রায় মনে করে এবং আমি জোর দিয়েছি যে আমি ফাংশনটিকে ম্যাক্রো হিসাবে টেমপ্লেটে অনুলিপি করে নিজেকে পুনরাবৃত্তি করছি।

এটি করার জন্য কোনও সোজা উপায় আছে? এবং, অজগর ফাংশনগুলির পুরো সেটটি আমদানি করার কোনও উপায় আছে এবং জিনজা 2 থেকে এগুলি অ্যাক্সেসযোগ্য রয়েছে, পুরো প্রচুর রিগামরল (যেমন কোনও এক্সটেনশন লেখার) মধ্য দিয়ে না গিয়ে?

উত্তর:


223

যারা ফ্লাস্ক ব্যবহার করছেন তাদের জন্য এটি আপনার __init__.py:

def clever_function():
    return u'HELLO'

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

এবং আপনার টেমপ্লেটে এটিকে কল করুন {{ clever_function() }}


আপনি কি এই জাতীয় একাধিক ফাংশন পাস করতে পারেন?
ffghfgh

6
নতুন সংস্করণগুলিতে (আমি জিনজা ২ ২.৯..6 ব্যবহার করছি) মনে হচ্ছে এটি আরও সহজ কাজ করেছে। আপনি যেমন পরিবর্তনশীল ব্যবহার করবেন তেমন ফাংশনটি ব্যবহার করুন (আরও জটিল পরিস্থিতিতেও এটি কাজ করে):from jinja2 import Template ##newline## def clever_function(): ##newline## return "Hello" ##newline## template = Template("{{ clever_function() }}") ##newline## print(template.render(clever_function=clever_function))
সেমজান ম্যাসিংগার

1
এমনকি 8 বছর পরেও, আপনি যদি ফ্লাস্ক ব্যবহার করছেন তবে এটি সাম্প্রতিক উত্তরগুলির চেয়ে ক্লিয়ার সমাধান হিসাবে মনে হচ্ছে। এবং @ffghfgh থেকে পুরানো প্রশ্নের উত্তর দিতে, হ্যাঁ — আপনি একাধিক ফাংশন পাস করতে পারেন।
কেভিনমাইক

133

দ্রষ্টব্য: এটি ফ্লাস্ক নির্দিষ্ট!

আমি জানি এই পোস্টটি বেশ পুরানো, তবে প্রাসঙ্গিক প্রসেসরের সাহায্যে ফ্লাস্কের নতুন সংস্করণগুলিতে এটি করার আরও ভাল পদ্ধতি রয়েছে।

ভেরিয়েবলগুলি সহজেই তৈরি করা যায়:

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

উপরেরগুলি এর মতো ফ্লাস্কের সাথে জিনজা 2 টেমপ্লেটে ব্যবহার করা যেতে পারে:

{{ 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 %}

4
এই ফাংশনগুলি কোথায় উপস্থিত থাকতে হবে, আর, ভিউ বা ঠিক কোথাও?
নক করুন

3
__init__.pyধরে নিচ্ছি আপনি flask.Flask(__name__)সেখানে ঘোষণা করেছেন।
লিয়াম স্ট্যানলি

6
জিনজা 2 সম্পর্কে জিজ্ঞাসা করা প্রশ্নে ডাউন ভোট দিয়েছে এবং ফ্লাস্ক নির্দিষ্ট answer
এজেপি

13
@ এজেপি এখনও তাত্ত্বিকভাবে প্রশ্নের উত্তর দেয়। সমস্যাটি সমাধানের এটি একমাত্র উপায়, তবে আপনি ফ্লাস্ক ব্যবহার করছেন granted সমস্ত জাভাস্ক্রিপ্ট প্রশ্নের মতো প্রায়শই jQuery এর সাথে বা ছাড়াই বিকল্প দেওয়ার উত্তর দেয় বা পাইথন সম্পর্কে প্রশ্নগুলি পাইথন 2 এবং 3 উভয়ের উত্তর দেয় The (পাই 2 সম্পর্কে একটি প্রশ্নের বিপরীতে একটি পাই 3 উত্তর বাদ দেওয়া হবে)। এই উত্তরটি আমাকে সাহায্য করেছিল।
জেরোমেজ

2
খুব সহায়ক, এবং ঠিক আমি যা খুঁজছিলাম। জিনজা 2 একটি ওয়েব কাঠামোর অংশ এবং এটি যেমন ব্যাক-এন্ডের থেকে সম্পূর্ণ স্বতন্ত্র নয়। আমি পাইথন এবং এই পোস্টের সাথে জাজানো এবং ফ্লাস্ক দুটিতেই কাজ করি, পাশাপাশি এখানকার অন্যান্যরাও আমার পক্ষে প্রাসঙ্গিক। কোনও প্রশ্নের অতিরিক্ত উল্লেখ করার চেষ্টা করা আমার মতে অপ্রয়োজনীয়ভাবে অস্পষ্ট হওয়ার মতো ক্ষতিকারক।

76

আমি মনে করি জিনজা ইচ্ছাকৃতভাবে কোনও টেম্পলেটের মধ্যে 'স্বেচ্ছাসেবক' অজগর চালানো কঠিন করে তুলেছে। এটি মতামতটি কার্যকর করার চেষ্টা করে যে টেমপ্লেটগুলিতে কম যুক্তি যুক্তি একটি ভাল জিনিস good

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

5
আমি এটিও আবিষ্কার করেছি - আপনি এর মতো কিছু ব্যবহার করে একটি মডিউল যুক্ত করতে পারেন: import utils.helpers env.globals['helpers'] = utils.helpers
লি

@Lee। হ্যাঁ, আপনি নেমস্পেস (মডিউল), ফাংশন, শ্রেণীর উদাহরণ ইত্যাদি 'ইনজেক্ট' করতে পারেন এটি দরকারী তবে মাকোর মতো অন্যান্য টেম্পলেট ইঞ্জিনগুলির মতো নমনীয় নয়। এখনও, জিনজার অন্যান্য ভাল পয়েন্ট আছে। উত্তরটি যদি সহায়তা করে তবে আমি কৃতজ্ঞ হব :)
রব কাউ

আমার অ্যাপ্লিকেশন ইঞ্জিন প্রকল্পটি করার সময় আমার জন্য কৌতুকটি করেছে (ওয়েবঅ্যাপ 2 এবং জিনজা 2) ধন্যবাদ
সোজন ভি জোসে

@ রবকউই অভিধান env.globals এ চতুর_ফাংশন যুক্ত করার পরে, কীভাবে কোনও টেমপ্লেট থেকে ফাংশনটি কল করতে পারে।
জর্জে বিদিনহা

1
সুতরাং, {{ clever_function('a', 'b') }}
রব কাউই

41
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

আপনি ম্যাট্রোস্কিনের উত্তর অনুসারে ক্ষেত্রগুলিতে ফাংশনটি দিতে পারেন

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

আউটপুট দেবে:

Hey, my name is Jay Kay

জিনজা 2 সংস্করণ 2.7.3 এর সাথে কাজ করে

এবং আপনি যদি কোনও ডেকরেটার চান তবে ব্রুনো ব্রোনোস্কির উত্তরটিtemplate.globals পরীক্ষা করে নেওয়ার বিষয়ে সংজ্ঞা নির্ধারণের কাজগুলি সহজ করতে পারেন


8
সম্ভবত কারণ আপনি অন্য সবার
উত্তরকে অগ্রাহ্য করেছেন

13
@ বারোকো কোভেসেভ এটি একটি ভাল কারণ নয়। আমি কেবল ২ টি উত্তর দিয়েছিলাম; জিনজা 2 এর চেয়ে ফ্ল্যাস্ক সম্পর্কে উত্তরগুলি দেওয়া হয়েছিল। যদি তারা তাদের উত্তরগুলি বিষয়বস্তুতে থাকতে এবং জিনজা 2 সম্পর্কে সম্পাদনা করতে চায় তবে আমি তাদের ভোট দিয়ে দেব।
এজেপি

টিএক্স @ বারকো কোভেসেভ :)
এজেপি

1
আমি এই উত্তরের একটি ফাংশন সাজসজ্জার সংস্করণ তৈরি করেছি। এটি বর্তমানে 0 টি ভোট দিয়ে নীচে: - ( stackoverflow.com/a/47291097/117471
ব্রুনো Bronosky

2
@ ব্রুনো ব্রোনোস্কি সুন্দর ভোট দিয়েছেন :) ... এটিকে আরও দশক দিন এবং এটি আমার চেয়েও বেশি হতে পারে: পি ... যদিও
ঝাঁকুনি

25

আমি @ এজেপির উত্তরটি পছন্দ করি । আমি প্রচুর ফাংশন দিয়ে শেষ না হওয়া পর্যন্ত এটি ভারব্যাটিম ব্যবহার করেছি। তারপরে আমি পাইথন ফাংশন ডেকরেটারে স্যুইচ করেছি ।

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__!


1
এটি অত্যন্ত সুন্দর। আপনি যখন অজগরটিতে কোনও ফাংশন টিকাশ করেন তা স্বয়ংক্রিয়ভাবে ফাংশনটির নামটি টীকাটির ফাংশনে পাস করে?
মিউট্যান্ট_সিটি

@ মিউট্যান্ট_সিটি, হ্যাঁ পাইথন ফাংশন ডেকরেটার লিঙ্কটি পড়ুন। দুর্দান্ত জিনিস!
ব্রুনো ব্রোনোস্কি

1
@ ব্রুনো ব্রোনোস্কি পাইথন সাজসজ্জার ক্ষেত্রেও বুদ্ধিমান এবং পরিষ্কার ব্যবহারের দুর্দান্ত প্রদর্শন। দুর্দান্ত পোস্ট!
dreftymac

1
কি দুর্দান্ত বাস্তবায়ন!
ফিলিপ ওগার

16

সরকারী দস্তাবেজগুলিতে বা স্ট্যাক ওভারফ্লোতে এ জাতীয় সহজ উপায়টি কখনও দেখেনি, তবে এটি পেয়ে আমি অবাক হয়ে গিয়েছিলাম:

# 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})

এই উত্তরটি এখন পর্যন্ত সেরা ইমো। সমস্ত ফাংশনটি পাইথনের প্রথম শ্রেণির নাগরিক হওয়ার পরে আপনি কোনও মান পাস করার ঠিক একই পদ্ধতিতে ফাংশনটি টেম্পলেটটিতে পাস করেন :)
মার্ক কর্টিংক

8

আপনার প্রধান কোডের সাথে টেমপ্লেটটি সংযুক্ত করতে ল্যাম্বডা ব্যবহার করুন

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

তারপরে আপনি টেম্পলেটে বিনষ্টভাবে ফাংশনটি কল করতে পারেন

{{clever_function(value)}}

1
ল্যাম্বদা ফাংশনগুলির চতুর ব্যবহার।

23
@ ডিওডিমিডিয়া: না তা নয়। এটি সম্পূর্ণ অপ্রয়োজনীয়। কেবলমাত্র ফাংশন হ্যান্ডেলটি নিজেই পাস করুন: চতুর_ফাংশন = চালাক_ফানশন
ভিজুল্ট

@ অ্যাজভুল্ট আমি দেখছি। আমি কীভাবে মিস করব? যে পরিষ্কার করার জন্য ধন্যবাদ!

6

জিনজা ২ থেকে পাইথন ফাংশনটি কল করতে, আপনি কাস্টম ফিল্টারগুলি ব্যবহার করতে পারেন যা গ্লোবালগুলির মতো একইভাবে কাজ করে: http://jinja.pocoo.org/docs/dev/api/#writing-filters

এটি বেশ সহজ এবং দরকারী। MyTemplate.txt ফাইলটিতে আমি লিখেছি:

{{ data|pythonFct }}

এবং একটি অজগর লিপি:

import jinja2

def pythonFct(data):
    return "This is my data: {0}".format(data)

input="my custom filter works!"

loader = jinja2.FileSystemLoader(path or './')
env = jinja2.Environment(loader=loader)
env.filters['pythonFct'] = pythonFct
result = env.get_template("myTemplate.txt").render(data=input)
print(result)

5

পাইথন ফাংশনগুলির একটি সম্পূর্ণ সেট আমদানির কোনও উপায় আছে এবং সেগুলি জিনজা 2 থেকে অ্যাক্সেসযোগ্য?

হ্যাঁ আছে, উপরের অন্যান্য উত্তর ছাড়াও, এটি আমার পক্ষে কাজ করে।

একটি ক্লাস তৈরি করুন এবং এটি সম্পর্কিত পদ্ধতিগুলি সহ পপুলেট করুন

class Test_jinja_object:

    def __init__(self):
        self.myvar = 'sample_var'

    def clever_function (self):
        return 'hello' 

তারপরে আপনার ভিউ ফাংশনে আপনার শ্রেণীর একটি উদাহরণ তৈরি করুন এবং রেন্ডার_টেমপ্লেট ফাংশনটির জন্য প্যারামিটার হিসাবে ফলস্বরূপ বস্তুটি আপনার টেমপ্লেটে পাস করুন

my_obj = Test_jinja_object()

এখন আপনার টেমপ্লেটে, আপনি জিনজার মতো ক্লাসের পদ্ধতিগুলি কল করতে পারেন

{{ my_obj.clever_function () }}

সমতুল্য এবং সামান্য সহজ উপায়: মডিউলে টেম্পলেটগুলির জন্য সমস্ত ফাংশন রাখুন, সেই মডিউলটি আমদানি করুন এবং এটি টেমপ্লেট গ্লোবাল হিসাবে যুক্ত করুন। মডিউল হ'ল একটি অবজেক্ট যা এতে ফাংশন রয়েছে :) (তবে পদ্ধতিগুলি নয় - স্ব পরমের প্রয়োজন নেই এবং কোনও শ্রেণীর পুনর্নির্মাণের প্রয়োজন নেই!)
Éric আরাউজো

@ এরিকআরাউজো যদি কেবলমাত্র এক বা দুটি টেম্পলেটগুলিতে আমার সমস্ত ফাংশনের সেট প্রয়োজন হয় তবে কী হবে। এছাড়াও, যদি আমার বিভিন্ন জিঞ্জাস টেম্পলেটগুলিতে পাইথন ফাংশনের বিভিন্ন সেট প্রয়োজন হয়? আপনি কি তাদের ক্লাসে পদ্ধতি হিসাবে রাখার পরিবর্তে কেবলমাত্র প্রয়োজনীয় পদ্ধতিতে ক্লাসগুলি পাস করার পরিবর্তে তাদের সমস্তকে টেমপ্লেট গ্লোবাল হিসাবে আমদানি করে কার্যকর বিবেচনা করতে পারেন?
কুডেহেনবু ওলুওয়পোনলে

কেবলমাত্র নির্দিষ্ট টেম্পলেটগুলিতে ব্যবহার করতে, আমি সেই টেমপ্লেটগুলি ব্যবহার করে এমন দর্শনগুলি দ্বারা পুনরায় ফিরে আসা টেম্পলেট প্রসঙ্গ ডিকটিতে কেবল ফাংশন (বা ফাংশনযুক্ত একটি মডিউল) যুক্ত করব।
এরিক আরাউজো

3

সমস্ত বিল্টিন ফাংশন আমদানি করতে আপনি ব্যবহার করতে পারেন:

app.jinja_env.globals.update(__builtins__)

যোগ .__dict__পর __builtins__যদি এই কাজ করে না।

জন 32323 এর উত্তরের ভিত্তিতে ।


2

আপনি যদি এটি জাঙ্গো দিয়ে করছেন, আপনি কেবল প্রসঙ্গটি সহ ফাংশনটি পাস করতে পারেন:

context = {
    'title':'My title',
    'str': str,
}
...
return render(request, 'index.html', context)

এখন আপনি strjinja2 টেমপ্লেটে ফাংশনটি ব্যবহার করতে সক্ষম হবেন


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.