Jinja: 2.9 الانحدار عند تخصيص متغير داخل حلقة

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

2.9:

>>> jinja2.Template('{% set a = -1 %}{% for x in range(5) %}[{{ a }}:{% set a = x %}{{ a }}] {% endfor %}{{ a }}').render()
u'[:0] [:1] [:2] [:3] [:4] -1'

2.8:

>>> jinja2.Template('{% set a = -1 %}{% for x in range(5) %}[{{ a }}:{% set a = x %}{{ a }}] {% endfor %}{{ a }}').render()
u'[-1:0] [0:1] [1:2] [2:3] [3:4] -1'

ذكرت في الأصل على IRC:

يبدو أن التغيير في نطاق jinja2 يؤثر علي ، وأنا غير متأكد من الإصلاح الصحيح. تكمن المشكلة تحديدًا في تخصيص العام هنا: https://github.com/kennethlove/alex-gaynor-blog-design/blob/551172/templates/archive.html#L13 -L24

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

changed_from_last جيدًا - على الأقل من الناحية الوظيفية ، الاسم نفسه محرج بعض الشيء IMO. ربما فقط changed سيكون واضحًا بما فيه الكفاية؟

أعتقد أن العنصر الأول سيُعتبر دائمًا "متغيرًا" بغض النظر عن ماهيته؟ إذا لم يكن هذا السلوك مناسبًا لشخص ما ، فيمكنه دائمًا إضافة شيك not loop.first أي حال.

ال 65 كومينتر

في حين أن السلوك الحالي غير صحيح ، إلا أن السلوك القديم غير صحيح بالتأكيد أيضًا. لم يكن الغرض من العلامة {% set %} تجاوز النطاقات الخارجية. أنا مندهش من حدوث ذلك في بعض الحالات. لست متأكد ماذا افعل هنا.

السلوك الذي أفترض أنه كان صحيحًا هو ناتج مثل [-1:0] [-1:1] [-1:2] [-1:3] [-1:4] -1 .

في هذه الحالة المحددة ، قمت بحلها بإعادة كتابتها لاستخدام groupby .

لدي شعور بأن هذه حالة استخدام شائعة إلى حد ما - أيضًا أشياء مثل {% set found = true %} في حلقة ثم التحقق منها بعد ذلك. من المؤكد أنه من المحتمل أن يكسر الأشياء للناس عندما يتوقف هذا عن العمل ...

لقد صدمت من هذا العمل من قبل. هل هذا دائما يعمل؟

على ما يبدو نعم:

>>> import jinja2
>>> jinja2.__version__
'2.0'
>>> jinja2.Template('{% for x in range(5) %}[{{ a }}:{% set a = x %}{{ a }}] {% endfor %}{{ a }}').render()
u'[:0] [0:1] [1:2] [2:3] [3:4] '

رائعة. لأن المشكلة هنا هي أن هذا ليس سليمًا على الإطلاق. ما المتغير الذي من المفترض أن يتجاوزه؟ ماذا لو كان هناك نطاق وظيفي بينهما. على سبيل المثال: ماكرو أو شيء من هذا القبيل. ليس لدي أي فكرة عن كيفية دعم هذا الآن.

حسنًا ، ربما يشبه نطاق بيثون بافتراض عدم استخدام nonlocal )؟ على سبيل المثال ، لا تسمح بتجاوز شيء محدد في نطاق خارجي (على سبيل المثال ، إذا كان هناك ماكرو في المنتصف) ولكن هل تسمح بتجاوزه بخلاف ذلك؟

على ما يبدو قبل أن يتم اكتشاف ذلك بخطأ في تأكيد القالب:

>>> Template('{% set x = 0 %}{% for y in [1, 2, 3] recursive %}{{ x }}{% set x = y %}{% endfor %}').render()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
jinja2.exceptions.TemplateAssertionError: It's not possible to set and access variables derived from an outer scope! (affects: x (line 1)

يبدو أن السلوك مختلف مع / بدون تكراري (2.8.1 يعطيني خطأ UnboundLocalError مع عودي و '012' بدون)

يجب حل الخطأ المحلي غير المنضم على المستوى الرئيسي.

لست متأكدًا من كيفية التقدم هنا. أنا حقا لا أحب أنه كان من الممكن على ما يبدو القيام بهذا النوع من الأشياء.

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

تم إرسالها إلى هذه المشكلة (انظر # 656) بعد أن أدى هذا التغيير إلى تفجير قالب مدونتي عند الترقية من v.2.8.1 إلى v2.9.4.

كنت أستخدمه لتتبع ما إذا كانت أجزاء مختلفة من البيانات تتغير بين تكرار الحلقة. تمكنت من إصلاحه لأنني كتبت رمز القالب الأصلي (انظر https://github.com/MinchinWeb/seafoam/commit/8eb760816a06e4f0382816f82586204d1e7734fd و https://github.com/MinchinWeb/seafoam/commit/89d555dbd6a2f2543) شك في أنني كنت سأكون قادرة على خلاف ذلك. من الصعب اتباع الكود الجديد لأن المقارنات تتم الآن في الخط. على سبيل المثال ، الكود القديم الخاص بي (الإصدار 2.8.1):

{%- set last_day = None -%}

{% for article in dates %}
    {# ... #}
    <div class="archives-date">
        {%- if last_day != article.date.day %}
            {{ article.date | strftime('%a %-d') }}
        {% else -%}
            &mdash;
        {%- endif -%}
    </div>
    {%- set last_day = article.date.day %}
{% endfor %}

والكود الجديد ، مع مقارنات مباشرة (v2.9.4):

{% for article in dates %}
    {# ... #}
    <div class="archives-date">
        {%- if ((article.date.day == dates[loop.index0 - 1].date.day) and
                (article.date.month == dates[loop.index0 - 1].date.month) and 
                (article.date.year == dates[loop.index0 - 1].date.year)) %}
                    &mdash;
        {% else -%}
                    {{ article.date | strftime('%a %-d') }}
        {%- endif -%}
    </div>
{% endfor %}

لذلك أردت فقط أن أقول أن "ميزة" (أو "الإختراق"، إذا كنت تفضل ذلك) ويستخدم وغاب بالفعل.

إذا كانت قضايا تحديد النطاق معقدة للغاية بحيث لا يمكن اكتشافها بشكل معقول في الوقت الحالي ، فهل يمكن إضافة شيء (على الأقل) إلى سجل التغيير بحيث لا يعض الأشخاص غير المدركين؟

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

على وجه الخصوص ، ربما نرغب في إضافة شيء مثل هذا ( loop.changed_from_last ):

{% for article in dates %}
    <div class="archives-date">
        {%- if loop.changed_from_last(article.date.day) %}
            {{ article.date | strftime('%a %-d') }}
        {% else -%}
            &mdash;
        {%- endif -%}
    </div>
{% endfor %}

changed_from_last جيدًا - على الأقل من الناحية الوظيفية ، الاسم نفسه محرج بعض الشيء IMO. ربما فقط changed سيكون واضحًا بما فيه الكفاية؟

أعتقد أن العنصر الأول سيُعتبر دائمًا "متغيرًا" بغض النظر عن ماهيته؟ إذا لم يكن هذا السلوك مناسبًا لشخص ما ، فيمكنه دائمًا إضافة شيك not loop.first أي حال.

ربما يحتوي previous_context فقط على السياق السابق بالكامل ، بدلاً من محاولة تحديد ما سيفعله المستخدمون به.

فقط previous أو prev ؟ يبدو "السياق" محيرًا إلى حد ما في هذا السياق (لا يقصد التورية)

..... والآن يمكنني بالفعل تخيل شخص ما يطلب next : /

أو ربما بيان صريح للكتابة خارج النطاق: set_outer أو شيء من هذا القبيل.

كنت أفكر في هذا:

class LoopContextBase(object):

    def __init__(self, recurse=None, depth0=0):
        ...
        self._last_iteration = missing

    def changed(self, *value):
        if self._last_iteration != value:
            self._last_iteration = value
            return True
        return False

davidism لا يمكننا عمل set_outer بدون كسر نظام تحديد النطاق بالكامل. هذا من شأنه أن يفسد الأمر برمته.

نعم ، برزت أن هذا سيكون هو الحال. أتوقع "ماذا لو أردت معرفة ما إذا كانت القيمة الحالية أكبر من السابقة" ، أو شيء مشابه. لكني أحب طريقة changed أيضًا.

كنقطة بيانات إضافية ، فقد سقطت على قدمي في حالة أحتاج فيها إلى إدخال فئة خاصة في HTML الذي تم إنشاؤه ، ولكن فقط للعنصر الأول من القائمة المتكررة التي لا تحتوي أيضًا على مجموعة خصائص محددة. لا يمكنني تعديل البيانات المتكررة. لا يمكنني استخدام loop.first (بقدر ما أحب ذلك) أو المقارنة مع أي شيء من العنصر الأخير لأفعل ما أحتاج إلى القيام به هنا بشكل موثوق ، مما أدى إلى تجربة البنية الشريرة التي عملت بشكل مثالي (ولم يكن واضحًا بالنسبة لي أنني كنت أسيء استخدام الخلل).

بالإضافة إلى ذلك ، فإنني أقدم إمكانات الامتداد من خلال المكونات الإضافية لجهات خارجية وليس لدي طريقة لمراقبة كيفية قيام المؤلفين ببناء قوالبهم ، مما يتسبب في حدوث كسر مفاجئ للمستخدمين النهائيين بعد التحديث إلى Jinja 2.9+. لقد قمت بتثبيت أحدث إصدار 2.8 الآن في برنامجي لهذه المسألة لتبقى متوافقة مع الإصدارات السابقة (كما وعد مخطط الإصدار الخاص بي) ، حتى أجد طريقة لجعل المؤلفين يقومون بتحديث قوالبهم.

هل يمكن لشخص ما أن يوضح لماذا لا تعمل نطاقات jinja2 تمامًا كما يعمل Python؟ على سبيل المثال ، تتوافق قوالب jinja2 مع وحدات python ، وتتوافق وحدات الماكرو مع الوظائف (ولها نطاقها الخاص) ، لأن الحلقات ليس لها نطاقها الخاص وما إلى ذلك. بينما يقول mitsuhiko إن jinja 2.8 وما دونه كان به الكثير من أخطاء النطاق ، كان من البديهي بالنسبة لي فهم كيفية عمل النطاق.

بالنسبة لمبرمجي لغة Python ، فإن السلوك من أول مشاركة (Jinja 2.8) واضح. ينطبق الشيء نفسه على https://github.com/pallets/jinja/issues/660 ، لا أفهم لماذا يجب أن تنفذ مكتبة python سلوك جافا سكريبت (أنا أتفهم أن معالجة Python للعلامات الافتراضية ليست مثالية ، لكن أي مطور Python يدرك منه).

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

أيضا من فضلك لا تأخذ تعليقي سلبيا ، أنا ممتن جدا ل jinja.

roganov بعض الملاحظات حول هذا:

هل يمكن لشخص ما أن يوضح لماذا لا تعمل نطاقات jinja2 تمامًا مثل عمل python

نظرًا لأن نطاق Python سيء حقًا في رأيي ، لا سيما في القوالب لأنه يمكنك بسهولة تجاوز المعلومات المهمة عن طريق الخطأ.

بينما يقول mitsuhiko إن jinja 2.8 وما دونه كان به الكثير من أخطاء النطاق ، كان من البديهي بالنسبة لي فهم كيفية عمل النطاق.

لاحظ أن هذا كان استثناءً بسبب خطأ وأنه يعمل فقط في بعض المواقف المحدودة وعن طريق الصدفة البحتة. كان لدى Jinja دائمًا نفس قواعد تحديد النطاق الموثقة ولم يتم توثيق هذا السلوك

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

لقد قمت بتحسين المستندات بالفعل قبل بضعة أيام لهذا الغرض

ماذا لو كانت هناك طريقة لتمرير متغير بشكل صريح إلى حلقة؟ ربما بناء جملة مثل هذا (استعارة من مرشحات النص):

{%- set last_day = None -%}

{% for article in dates | pass_variable ( last_day ) %}
    {# ... #}
    <div class="archives-date">
        {%- if last_day != article.date.day -%}
            {{ article.date | strftime('%a %-d') }}
        {%- else %}
            &mdash;
        {% endif -%}
    </div>
    {%- set last_day = article.date.day %}
{% endfor %}

أو هل هناك طريقة لعمل شيء مشابه لـ scoped كما ينطبق حاليًا على وحدات الماكرو؟


هناك حالة استخدام أخرى تتمثل في الحفاظ على نوع من العداد بين الحلقات. على سبيل المثال ، كم مجموع الصفوف؟ كم عدد الصفوف التي تلبي بعض المعايير؟ إجمالي بعض الخصائص للصفوف المحددة (لطباعة صف إجمالي)؟

لن يكون بناء جملة عامل التصفية ممكنًا هنا نظرًا لأن المرشحات ممكنة بالفعل على الملف القابل للتكرار.

يمكن أن تكون البنية المحتملة لهذا الذي لا يبدو سيئًا كما يلي:

{% for article in dates with last_day %}

خاصة وأن with يقوم بالفعل بفحص الأشياء في Jinja عند استخدامه على سبيل المثال {% with %} . OTOH ، هنا سيكون العكس لأنه مع الكتل تفتح نطاقًا جديدًا ، لا تجعل متغيرات النطاق الخارجي سهلة الوصول ..

لست متأكدًا مما إذا كانت هذه ميزة يحتاجها Jinja أم لا.

لن يغير أي بناء جملة هذا لأنه سيظل يفسد قواعد تحديد النطاق. لا يمكنك القيام بذلك باستخدام نظام التجميع الحالي أو نظام تتبع الهوية. حتى لو كان يعمل مع هذه الحالة البسيطة ، فماذا يحدث إذا كان لدى الشخص حلقة for تساوي recursive . ماذا لو قام شخص ما بتعريف ماكرو في حلقة for. ماذا لو ظهرت كتلة المكالمة في حلقة for.

أعتقد أنه سيكون من المنطقي تقديم كائن عالمي يعمل كمساحة تخزين ويمكن بعد ذلك تعديله بواسطته. على سبيل المثال:

{% set foo = namespace() %}
{% set foo.iterated = false %}
{% for item in seq %}
  {% set foo.iterated = true %}
{% endfor %}

ومع ذلك ، سيتطلب هذا تغيير علامة set أساسي.

mitsuhiko وهذا النوع من الأنماط قيد الاستخدام بالفعل مع علامة do : http://stackoverflow.com/a/4880398/400617

FWIW ، الحل بـ do مروع للغاية. تمامًا مثل الحل الذي يستخدمه الأشخاص في Python 2 عندما يحتاجون إلى nonlocal ...

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

اختراق آخر (قبيح) هو استخدام قائمة وإلحاق وفرقعة: http://stackoverflow.com/a/32700975/4276230

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

{% set list = "" %}
{% for name in names %}
{% if name.last is defined %}
{% set list = list + name.last + " " %}
{% if loop.last %}
{{ list.split(' ')|unique }}
{% endfor %}

MustafaHosny اللهم امين

{{ names|map(attribute="last")|select|unique }}

على الرغم من أن unique ليس مرشحًا مضمنًا ، يمكنك دائمًا إضافة عامل تصفية آخر يقوم بكل شيء ، نظرًا لأنك تقوم بالفعل بإضافة مرشح unique .

أهلا،
أفهم أن هناك الكثير من الأمثلة "القبيحة" بسبب هذا ، ولكن هل يمكنك تقديم النصيحة لكيفية زيادة متغير في حلقة for في قالب jinja بطريقة أنيقة / صحيحة؟ لأن شفري قد تم كسره أيضًا.

لماذا تحتاج إلى القيام بذلك على الإطلاق؟ أيضا ، يرجى تضمين الرمز الخاص بك.

{% for state in states.sensor -%}
{% if loop.first %}
{% set devnum = 0 %}
{% endif -%}
{%- if state.state == "online" %}
{% set devnum = devnum + 1 %}
{%- endif -%}
{% if loop.last %}
{{ devnum }}
{% endif -%}
{%- endfor -%}

هل يمكنك أن تنصحني بكيفية زيادة متغير في حلقة for في قالب jinja بطريقة أنيقة / صحيحة؟

لم يكن من المفترض أن تفعل (أو أن تكون قادرًا على القيام بذلك) على الإطلاق. لذا فإن الجواب هو لا تفعل ذلك. ومع ذلك ، نحن مهتمون لماذا يبدو أن مؤلفي النماذج بحاجة إلى القيام بذلك.

تعداد Jinja بالفعل الحلقة. {{ loop.index0 }}

davidism أحتاج فقط إلى أولئك الذين

اكتب مرشحًا ينتج عنه مجموعات devnum, sensor بالطريقة التي تريدها تمامًا. أو احسبها في Python وقم بتمريرها إلى القالب. أو استخدم المثال أدناه. هذا ينطبق على كل الأمثلة الأخرى التي رأيتها.

Molodax يمكنك القيام بذلك:

{{ states.sensor|selectattr('state', 'equalto', 'online')|sum }}

ألم تقصد |count ؟

آسف نعم العد.

mitsuhiko ، أشكركم على دعمكم ، للأسف ، لا يعمل.
ربما تم تنفيذ jinja2 (الفلاتر) مع بعض القيود في مشروع يستخدم ( مساعد منزلي ). لكنها عملت مع الكود الذي قدمته من قبل. شفقة.

مرحبا يا رفاق. أنت تسأل عن رمز على سبيل المثال يعمل تحت 2.8 ، لذا فإليك لي:

{% set count = 0 %}
{% if 'anchors' in group_names %}
nameserver 127.0.0.1
{% set count = count+1 %}
{% endif %}
{% for resolver in resolvers %}
{% if count < 3 %}
{% if resolver|ipv6 and ansible_default_ipv6.address is defined %}
nameserver {{ resolver }}
{% set count = count+1 %}
{% elif resolver|ipv4 and ansible_default_ipv4.address is defined %}
nameserver {{ resolver }}
{% set count = count+1 %}
{% endif %}
{% endif %}
{% endfor %}

لا أعرف كيف يمكنني القيام بذلك بدون متغير "عدد" عام يمكنني الرجوع إليه في حلقتين منفصلتين. هل لديك أي اقتراحات تسمح لهذا العمل تحت كل من 2.8 و 2.9؟

davidism حلك رائع لكني أحاول تحقيق ذلك.
قم بإنشاء قائمتين على النحو التالي

{% set list1 = name|default()|map(attribute="last")|select|list %}
{% set list2 = name|default()|map(attribute="age")|select|list %}

ثم قم بدمجها في list3 ، والتي يجب أن تبدو كما يلي ثم تطبق في النهاية (مرشح غير مرئي) فريد على list3
آخر 1 سنة
آخر عامين 2
آخر 3 سنوات 3
آخر 4 سنوات
5 سنوات من العمر
آخر 6 سنوات

من ما جمعته لا تعمل الخريطة مع سمات متعددة # 554
أنا أستخدم jinja2 عبر ansible ولذا فإن إضافة فعل شيء في Python مسبقًا ليس فكرة جيدة بالنسبة لي.

@ pujan14aabdnn @ Molodax هل جاء هذا النمط من وثائق Ansible الرسمية ، أم أنه شيء توصلت إليه أو وجدته في مكان آخر؟ في كلتا الحالتين ، قد يكون من الأسهل إبلاغ Ansible بهذا الأمر ، نظرًا لأنهم يفهمون كيفية استخدام منتجهم ويمكنهم التوصل إلى حلول أكثر صلة.

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

إذا لم يكن موثقًا رسميًا ، فأنا أميل أكثر لإغلاق هذا كما كان في الأصل. سأعيد التأكيد على أن Ansible قد تكون قادرة على مساعدتك أكثر في هذا الصدد.

davidism لقد لعبت مع الحلقات في جديد jinja 2.9 .
هنا مثال.

{% for name in names %}
{% if loop.first %}
{% set list = "" %}
{% endif %}
{% if name.first is defined and name.last is defined and not name.disabled %}
{% set list = list + name.first|string + "-" + name.last|string %}
{% if loop.last %}
{% for item in list.split(' ')|unique %}
{{ item }}
{% endfor %}
{% else %}
{% set list = list + " " %}{% endif %}
{% endif %}
{% endfor %}

قد لا تكون هذه هي أفضل طريقة للقيام بذلك ولكن هنا من فهمي أنا لا أخالف أي قواعد تحديد النطاق.

كانت هذه المشكلة في 2.8 وما فوقها

هنا تذهب حالة الاختبار:

import unittest
from jinja2 import Template

TEMPLATE1 = """{% set a = 1 %}{% for i in items %}{{a}},{% set a = a + 1 %}{% endfor %}"""

class TestTemplate(unittest.TestCase):

  def test_increment(self):
    items = xrange(1,10)
    expected='%s,' % ','.join([str(i) for i in items])
    t = Template(TEMPLATE1)
    result = t.render(items=items)
    self.assertEqual(expected,result)

unittest.main()

استخدم loop.index بدلاً من ذلك.

أعتقد أن توفير الوصول إلى قيمة الحلقة السابقة من خلال سمة الكائن loop هو الحل الوحيد الجيد لذلك. لقد اكتشفت للتو هذا المقتطف في مشروعنا والذي لا يمكن حله بمجرد التحقق مما إذا كان الكائن الأخير مختلفًا عن الكائن الحالي كما أن groupby لا يعمل هناك لأنه أكثر من مجرد وصول إلى عنصر / سمة تافهة للحصول على المفتاح :

{% set previous_date = none %}
{% for item in entries -%}
    {% set date = item.start_dt.astimezone(tz_object).date() %}
    {% if previous_date and previous_date != date -%}
        ...
    {% endif %}
    {% set previous_date = date %}
{%- endfor %}

نعم هذا يبدو كفكرة

ماذا عن إضافة أساليب set(key, value) و get(key) إلى كائن الحلقة؟ ثم يمكن للأشخاص تخزين ما يريدون عبر الحلقة.

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

davidismThiefMaster كنت أفكر في مجرد وجود كائن التخزين المتاحة. مثله:

{% set ns = namespace() %}
{% set ns.value = 42 %}
...{% set ns.value = 23 %}

من الواضح أنه لا يمكن تعيين السمات في الوقت الحالي ولكن يمكن تمديدها بسهولة. نظرًا لعدم حدوث إعادة تعيين إلى مساحة الاسم نفسها ، فهذا آمن تمامًا للتنفيذ.

يبدو الأمر جيدًا بالنسبة لي ، إنه نفس الحل مثل nonlocal لـ Py 2. بدلاً من ذلك ، قم بإعداد loop.ns تلقائيًا ، على الرغم من أن ذلك لن يكون متاحًا خارج الحلقة.

ما لا يعجبني في مساحة الاسم هو أنه سيكون من المغري جدًا أن تفعل {% set obj.attr = 42 %} مع obj لشيء ليس namespace() - شيء أعتقد أنه لا يجب أن يعمل .

بخلاف ذلك ، تبدو فكرة مثيرة للاهتمام ، على الرغم من أنني أعتقد أن previtem / nextitem / changed() تغطية الحالات "البسيطة" بشكل رائع بدون "ضجيج" الاضطرار إلى تحديد كائن جديد في النموذج.

ThiefMaster لن يعمل. الطريقة التي أرى بها هذا العمل هي أن تعيينات السمات تمر عبر رد اتصال على البيئة مما يسمح فقط بإجراء تعديلات على كائنات مساحة الاسم.

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

ما زلت حذرة بعض الشيء من الأشياء التي قد يفعلها الناس ...

{% macro do_stuff(ns) %}
    {% set ns.foo %}bar{% endset %}
    {% set ns.bar %}foobar{% endset %}
{% endmacro %}

{% set ns = namespace() %}
{{ do_stuff(ns) }}

في الواقع ، أعتقد أن كتلة جديدة مثل {% namespace ns %} سيكون من الأفضل تعريفها بدلاً من المتغير القابل للاستدعاء - لا يبدو المتغير المسمى namespace شيئًا من غير المحتمل أن يتم تمريره إلى قالب ، وأثناء من المحتمل أن يمنعك ببساطة من استخدام ميزة مساحة الاسم في هذا القالب (تمامًا مثل التظليل في Python) ، يبدو الأمر متسخًا بعض الشيء ...

هل لديك حل بديل لهذه المشكلة أم يتعين علينا انتظار previtem / nextitem في 2.9.6؟
بعض قوالب مكدس الملح الخاصة بي معطلة الآن.

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

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

قفل هذا لأن كل ما يجب أن يقال قد قيل. راجع # 676 و # 684 للإصلاحات التي يتم النظر فيها حاليًا.

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