Jinja: دعم المتغيرات المتداخلة

تم إنشاؤها على ٧ ديسمبر ٢٠١٦  ·  7تعليقات  ·  مصدر: pallets/jinja

لقد كنت أبحث في الوثائق والمقالات المختلفة عبر الإنترنت ولم أجد أي إشارة إلى وجود متغيرات متداخلة ، لذلك أقوم بفتح طلب ميزة. يمكن أن يساعد ذلك في العديد من المشاريع من خلال السماح بإجراء مكالمات متغيرة أكثر تعقيدًا وتلقائية.

يمكن تعريف المتغير العادي على النحو التالي:

{{ variable }}

قد يكون من المفيد السماح باستخدام معلومات ديناميكية من متغير آخر لملء اسم متغير آخر.

{{ variable{{ generated_var }} }}

حالة الاستخدام الخاصة بي هي مع Ansible. أحصل على قائمة بأجهزة واجهة الشبكة من متغير واحد (ansible_interfaces). ثم يمكنني استخدام هذا للإشارة إلى المعلومات من متغير آخر (ansible_eth0 ، على سبيل المثال). هنا إطار أساسي لما تحاول تحقيقه.

{% for interface in ansible_interfaces %}
IPADDR{{ loop.index }}={{ ansible_{{ interface }}.ipv4.address }}
NETMASK{{ loop.index }}={{ ansible_{{ interface }}.ipv4.netmask }}
{% endfor %}

Jinja2 لا يحب ذلك عندما يقدم لأنه يشتكي من الأقواس الإضافية الموجودة. للحصول على خيارات حول كيفية تنفيذ ذلك ، كنت أفكر على غرار إحدى هاتين الفكرتين المختلفتين.

(1) السماح بالتوسع المتغير. هذا هو بالضبط ما كنت أعرضه سابقًا ؛ السماح بتحليل المتغيرات من الداخل إلى الخارج.

(2) أضف مرشحًا لتحويل سلسلة إلى اسم متغير.

{% for interface in ansible_interfaces %}
{% set interface_string="ansible_%s.ipv4.address"|format(interface) %}
IPADDR{{ loop.index }}={{ interface_string|variable }}
NETMASK{{ loop.index }}={{ interface_string|variable }}
{% endfor %}

إليك بعض التعليمات البرمجية التقريبية (غير العاملة) توضح الفكرة الثانية.

# vim jinja2/jinja2/filters.py
<strong i="21">@environmentfilter</strong>
def do_variable(environment, s):
    string_to_variable = "{{ %s }}" % s
    return environment.from_string(string_to_variable).render()

من الناحية المثالية ، سيكون الخيار 1 أقل تعقيدًا من حيث استخدام المستخدم النهائي. اسمحوا لي أن أعرف أفكارك حول هذا الموضوع. هذه هي المرة الأولى التي أبحث فيها في رمز Jinja2 ولكني أرغب في المساهمة مرة أخرى إذا كانت هناك حاجة إلى أي مساعدة مع الكود.

التعليق الأكثر فائدة

http://serverfault.com/questions/762079/how-to-loop-through-interface-facts

يبدو أنه يمكنك القيام بذلك:

{{ hostvars[inventory_hostname]['ansible_%s' | format(interface)].ipv4.address }}

أنا قوي جدًا: -1: على أسماء المتغيرات. عادةً ما تكون علامة على بنية سيئة إذا كان التطبيق لا يوفر قائمة بيانات مناسبة إذا كنت بحاجة إلى الوصول إليها عن طريق مفتاح ديناميكي أو تكرارها. FWIW ، أعتقد أن هذا hostvars deb هذا قبيح إلى حد ما مقارنة بأسماء واجهة تعيين لبيانات الواجهة. سأفتح مشكلة مع Ansible ، أقترح تغيير تلك القائمة إلى dict. نظرًا لأن التكرار على الإملاء يعطيك مفاتيحه ، فقد لا يكون حتى غير متوافق مع الوراء إذا قاموا بتغييره إلى إملاء ...

ال 7 كومينتر

http://serverfault.com/questions/762079/how-to-loop-through-interface-facts

يبدو أنه يمكنك القيام بذلك:

{{ hostvars[inventory_hostname]['ansible_%s' | format(interface)].ipv4.address }}

أنا قوي جدًا: -1: على أسماء المتغيرات. عادةً ما تكون علامة على بنية سيئة إذا كان التطبيق لا يوفر قائمة بيانات مناسبة إذا كنت بحاجة إلى الوصول إليها عن طريق مفتاح ديناميكي أو تكرارها. FWIW ، أعتقد أن هذا hostvars deb هذا قبيح إلى حد ما مقارنة بأسماء واجهة تعيين لبيانات الواجهة. سأفتح مشكلة مع Ansible ، أقترح تغيير تلك القائمة إلى dict. نظرًا لأن التكرار على الإملاء يعطيك مفاتيحه ، فقد لا يكون حتى غير متوافق مع الوراء إذا قاموا بتغييره إلى إملاء ...

أنا أوافق بنسبة 100 ٪ على أن العرض الداخلي للحصول على أسماء متغيرة * N هو فكرة سيئة .

ومع ذلك ، فقد جئت إلى هنا للبحث عن حل لتداخل العرض الخارجي وانتهى بي الأمر باستكشاف الحل بنفسي. هل يوجد دعم لمثل هذا الشيء؟ هل إضافة مرشح nested_render مفيد أم ضار لأنه من المحتمل أن يربك الناس؟

المتغيرات المتداخلة ستحل مشكلة مع WTForms ، حيث يشبه البناء
{{ form.playername(value="{{ currentname }}") }}
سيكون أوضح كثيرًا من أي حل آخر وجدته.

{{ form.playername(value=currentname) }} يفعل ذلك. ولكن لمعلوماتك ، يجب عليك تمرير البيانات الحالية إلى مُنشئ النموذج وعدم الإزعاج بها في القوالب على الإطلاق

آه ، الأمر بهذه البساطة! انتهى بي الأمر باستخدام Javascript لتعيين القيمة من متغير currentname. عندما أقوم بتعيين القيمة الافتراضية في كائن النموذج في كود Python ، لا يتم تحديثها.

قم بالمرور بـ #pocoo على IRC وقم باختبار اتصالي هناك (الأمر بعيد جدًا هنا) ويمكنني إخبارك بكيفية القيام بذلك بشكل صحيح.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات