2014-09-09 2 views
0

어떻게 재귀 적으로을 Jinja2에서 병합 할 수 있습니까? 사용자 정의 필터를 정의하지 않아도됩니까? Jinja2에서 임의의 깊이의 딕트를 병합하십시오.

그래서

{ a: { b: 'ab', d: 'ad'   } } 
+ { a: { b: 'aX',   e: 'ae' } } 

{ a: { b: 'aX', d: 'ad', e: 'ae' } } 

내가 Jinja2에 몇 가지 마 코 템플릿을 마이그레이션하고있어이된다. Mako를 사용하면 작은 파이썬 코드 스 니펫을 사용하여 간단하게 사용할 수 있습니다 ... 사용자 지정 필터를 사용할 수없는 이유는 템플릿 엔진에 사용자 지정 필터를 등록 할 수 없기 때문에 직접 액세스 할 수 없기 때문입니다. null로 설정되어 a에서 중복 키 (b이 우선) 및 제거 키를 무시 a

{%- macro deep_merge(a, b): %} 
    {%- for k,v in b.items(): %} 
    {%- if v is not defined: %} 
     {%- do a.pop(k) %} 
    {%- else: %} 
     {%- if v is mapping: %} 
     {%- if a[k] is not mapping: %} 
      {%- do a.update({ k: { } }) %} 
     {%- endif %} 
     {%- do deep_merge(a[k], v) %} 
     {%- else: %} 
     {%- do a.update({ k: v }) %} 
     {%- endif %} 
    {% endif %} 
    {%- endfor %} 
{%- endmacro %} 

{%- do deep_merge(a, b) %} 

Jinja2 - 코드의이 조각은 재귀 적으로 병합 b :

+0

당신이 돈 같이 "사용자 정의 필터를 등록 할 수 없습니다" ' 템플리트 엔진을 제어 할 수 있습니다. Mako 또는 Jinja의 선택 만 제공하고 Mako/Jinja 코드가 유효한 한 원하는대로 작성할 수 있습니까? –

+0

수정하십시오. 나는 템플릿 엔진을 제어하지 못하기 때문에 어떤 식 으로든 확장 할 수 없다. 그러나 유효한 Jinja2 코드로 간주되는 것은 무엇이든 그것을 먹일 수 있습니다. –

+0

[표현식'do'] (http://jinja.pocoo.org/docs/dev/templates/#expression-statement)에 대한 액세스 권한이 있습니까? –

답변

2

나는 결국 내 문제에 대한 해결책을 발견 b.

1

그것은 추한하지만 상황이 조금 Abby Normal처럼 들린다 :

{# Untested code - may not work #} 
{% macro merge(destination) %} 
{% for provider in varargs %} 
    {% for key, value in provider.items() %} 
     {% if value is mapping %} 
      {% set intermediate = {} %} 
      {% do merge(intermediate, destination.get(key, {}), value) %} 
      {% do destination[key] = intermediate %} 
     {% else %} 
      {% do destination[key] = value %} 
     {% endif %} 
    {% endfor %} 
{% endfor %} 
{% endmacro %} 

그리고 당신은 다음과 같이 사용할 수 있습니다 :

{% set result = {} %} 
{% do merge(result, first_values, second_values) %} 
{# result is now the merger of first_values and second_values #} 
+0

답장을 보내 주셔서 감사합니다. 위의 대답에서 알 수 있듯이 이미 비슷한 해결책을 발견했습니다. 비록 지금 내가 개선 할 수있는 몇 가지를 볼 수있다. –

+0

다행이다. 도움을 청할 수있어서 기쁘다. 내가 대답 할 수있는 대답을 보았을 때 나는 이것을 삭제하려고 유혹에 빠졌지 만, 대체 접근법을 제공하는 것이 도움이 될 것이라고 생각했다 :-) –

+0

예, 대안 항상 좋다 :)'{% - do dict [key] = value %}'문이 나에게 효과적이지 않은 것처럼 당신의 작업을 얻을 수는 없지만 : 진가 구문 오류 : 예상 토큰 '문장의 끝 블록 ','= ''. 그래서 내 솔루션에'dict.update()'를 사용했다. –

관련 문제