2009-12-12 4 views
20

에 인수를 전달 나는 렌더링 할 때장고 : 부모 템플릿

project 
- main_templates (including nav bar) 
-- app1 
--- app1_base_template 
--- app1_templates 
-- app2 
--- app2_base_template 
--- app2_templates 

그래서, app2_templates main_template를 확장하는 app2_base_template 확장이 스타일의 템플릿을 가지고있다.

내가해야 할 일은 app2의 템플릿이 렌더링 될 때 (사용자 위치를 보여주기 위해) 해당 탐색 항목을 굵게 표시하는 것입니다.

가장 쉬운 방법은 {% block xxx %} 부분에 변수를 전달하는 것입니다. 이것이 가능합니까?

다른 일반적인 방법에는 어떤 것이 있습니까?

+0

이 내용을 확인하셨습니까? http://stackoverflow.com/questions/1024168/django-is-there-a-better-way-to-bold-the-current-page-link – rinti

+2

CSS 솔루션은 유지 관리가 매우 어려워서 정보를 추가해야합니다. 3 개의 다른 장소. – Boris

답변

41

{% with %} 템플릿 태그를 사용해 보셨습니까?

{% block content %} 
    {% with 'myvar' as expectedVarName %} 
    {{block.super}} 
    {% endwith %} 
{% endblock content %} 
+0

죄송합니다. 이것은 base.html에 있고,'block.super'는 navbar를 가리키고 있습니다 ...? 나는 나의베이스에 * 포함 된 내 navbar를 가지고있다. * 나의 'block content' ... 이것이 작동하도록 어떻게 설정되어야 하는가? – Pureferret

+3

재미있는 해킹이지만 완전한 해결책은 아닙니다. 상위 템플릿은 대부분 이것이 {{% block content %}}로 둘러싸여 야하며, 이렇게하면'content' 내부의 다른 블록을 덮어 쓰지 못하게됩니다. – Kos

+0

Django 1.11+에서 구문이 변경되었습니다 (이전 버전이 여전히 지원 되더라도) : https : //docs.djangoproject.com/en/1.11/ref/templates/builtins/#with. {% with 'myvar'with expectedVarName % } => {% with expectedVarName = 'myvar'%} – ThePhi

2

상위 템플릿의 변수가 자동으로 하위 범위에 포함됩니다. 제목에 부모에게 변수를 전달하려는 경우 템플릿에서 변수를 정의 할 수 없으므로 의미가 없습니다. 상위 변수와 하위 변수 모두에 변수가 필요하면 변수를 뷰에 선언하십시오.

8

템플릿 상속 트리 위로 변수를 전달하는 직접적인 방법은 없습니다. 사람들이 현재 페이지를 강조 표시하는 탐색 모음을 구현하는 방법은 종종 사이트 자체의 특성에 맞게 조정됩니다. 낮은 기술은 접근

탭이 활성화되어 있는지를 나타내는 템플릿 컨텍스트에서 변수를 전달

: 그건 내가 두 가지 일반적인 방법을 본 적이 말했다

# in views.py 
def my_view(request): 
    return render_to_response('app2_template.html', {"active_tab": "bar"}, 

<!-- Parent template --> 
<div id="navigation"> 
    <a href="/foo" {% ifequal active_tab "foo" %}class="active"{% endifequal %}>Foo</a> 
    <a href="/bar" {% ifequal active_tab "bar" %}class="active"{% endifequal %}>Bar</a> 
</div> 

높은 -tech 방식

내비게이션 막대를 렌더링하려면 custom template tag을 구현하십시오. 태그가 활성화 된 섹션을 나타내는 변수를 가지고 있습니다

<!-- Parent template --> 

<div id="navigation">{% block mainnav %}{% endblock %}</div> 

<!-- any child template --> 
{% load my_custom_nav_tag %} 
{% block mainnav %}{% my_custom_nav_tag "tab_that_is_active" %}{% endblock %} 

당신은 거의 거기에서 미친 갈 수 있습니다. 누군가가 이미 djangosnippets.org에서 당신을 위해 일할 무언가를 구현했다는 것을 알 수 있습니다.

+0

+1 하이테크 접근법. 몇 가지 조사를 해보고, 어떤 파일에 대한 정교화 및 참조를 통해 향후 어떤 사람들을 도울 수있게 만들었습니다. – SpiRail

1

슬프게도 나는 깨끗한 방법을 찾을 수 없습니다.

각 응용 프로그램의 base.html에 태그를 넣어 최대 종료 : (.. 주요 탐색을위한 응용 프로그램의 기본에 의해 실제로 내가 사용하는이 한 세트의 응용 프로그램의 탐색 모음을위한 앱 페이지에서 설정 한)

<span class="main_nav_bar_hint" id="2"></span> 

그리고 프로젝트 JQuery와 마법의 비트 base.html 해킹의 비트,하지만 쉽게 이해하고 내가 한 번만 더 많은 애플 리케이션이 추가 논리적 변경해야하는이 방법

$(document).ready(function() { $("#nav_menu_" + $(".main_nav_bar_hint").attr("id")).removeClass("normal").addClass("selected"); }) 

그것.

2

템플릿 포함에 args를 전달할 수 없다는 것은 장고 템플릿 시스템의 많은 실패 중 하나입니다.

나는 거의 동일한 문제를 다루어야했다. 부모 템플릿이 포맷/강조 표시를 다르게하기 위해 깊이 중첩 된 템플릿이 필요했다.

가능한 해결책 :

  1. 계층 구조에 당신이 위치에 따라 값의 수를 설정하는 "슈퍼 컨텍스트"루틴을 사용합니다. 나는. super_context = MySuperContext (요청, 기타, 값 등), 여기서 super_context는 뷰 (또는 RequestContext)로 전달하는 dict입니다. 이것은 가장 장고 thnonic (?) 접근법이지만, 그것은 프리젠 테이션 로직이 나에게 잘못된 생각으로 되돌아 간다는 것을 의미합니다.

  2. expr 템플릿 태그를 사용하여 하위 템플릿의 값을 설정하십시오. 참고 : 이것은 {% include %} 템플릿이 포함되기 전에 평가되어야하기 때문에 템플릿을 사용할 때만 작동합니다. {% extends %}는 하위 템플릿의 첫 번째 것이어야하기 때문에이를 수행 할 수 없습니다.

  3. 템플릿으로 전환하십시오. 최소한이 작업을 수행해야하는보기가 필요합니다.

이 값을 일단

는이 같은 일을 할 수 설정 :

<div class="foo{% if foo_active%}_active{%endif%}"> stuff </div> 

이는 경우는 "foo_active"활성화되지와의 사업부 클래스 "foo는"합니다. 스타일은 맛있지 만 계피를 너무 많이 첨가하지 마십시오. :-)

2

나는 (예, 그것은 말장난 ... 당신에게 완벽한 이해가되지 것입니다 내가 당신을 말하지 않는 한 유사한 잘못을 ... 맥락에서 자렛 하디의 "낮은 기술"접근 방식을 찍은 I nav를하고있는 것이 아니라 어느 버튼이 눌러 졌는지 보여주기 위해 버튼의 경계 색을 설정하는 것).

하지만 내 버전은 조금 더 콤팩트라고 생각합니다. 보기에서 하나의 간단한 컨텍스트 변수 활성 막대를 정의하는 대신 사전을 반환하지만 항상 하나의 키 - 값 쌍만 사용합니다. activebar = { 'foo': '활성'}.

그런 다음 템플릿에서 나는 class = "{{activebar.foo}}"를 foo 앵커에 작성하고 그에 따라 다른 앵커에 작성합니다. activebar.foo만이 "active"값을 가지도록 정의 된 경우 bar anchor의 activebar.bar는 아무 작업도 수행하지 않습니다. 어쩌면 "자동으로 실패 함"이 적절한 장고 이야기 일 수 있습니다. 그리고 밥은 당신의 삼촌입니다.

편집 : 죄송합니다 ... 며칠이 지났습니다. 위에서 작성한 내용이 나에게 도움이되었지만 대상으로 새 창으로 앵커를 navbar에 넣으면 문제가 발생했습니다. 이상한 결함의 원인 인 것 같았습니다. Firefox의 새 창 (Firefox의 탭)을 클릭 한 다음 새 창을 시작한 창으로 돌아간 후 Navbar 아래에있는 표시가 비어있게되었습니다. 아무 것도 클릭하지 않고 탐색 바의 항목 위에 커서를 놓습니다. 스크롤 막대를 움직여 화면 다시 그리기를 강제해야했습니다 (페이지 다시로드는 아니지만 화면 다시 그리기가 포함되어 있기 때문에 너무 효과적이었습니다).

나는 왜 그런 일이 일어날지를 파악하기에는 너무 많은 멍청하다. 어떻게 든 사라진 문제를 일으키는 다른 일을했을 수도 있습니다. 그러나 ... 나는 나를 위해 완벽하게 작동하는 더 단순한 접근법을 발견했습니다. 내 상황에 따라 뷰에서 시작되는 모든 하위 템플릿은 연관된 navbar 항목을 "활성"으로 표시해야합니다. 사실, 그 navbar 항목은 자식 템플릿을 시작한 뷰를 시작한 항목입니다. 일반적인 거래입니다.

내 솔루션 --- 예를 들어 "로그인"navbar 항목을 가져와 봅시다 --- 로그인 양식이 포함 된 하위 템플릿에 넣으십시오.

{% block login %}active{% endblock %} 

나는 제목 블록 아래에 그것을 넣어하지만 배치가 중요 할 생각하지 않습니다. 아이 템플릿을 렌더링 할 때 따라서

<li class="{% block login %}{% endblock %}"><a href="/mysite/login">Login</a></li> 

: 그리고 여기, 음 ... 내가 넣어 로그인 메뉴 바 항목의 앵커를 둘러싸고있는 리튬 태그, 네비게이션 바의 정의를 포함하는 부모 템플릿에 코드입니다 부모는 로그인 navbar 항목을 활성화 된 것으로 표시하고 Bob은 여전히 ​​삼촌입니다.

위에서 설명한 사전 접근 방식은 모두 동일한 하위 템플릿에있는 버튼 중 어떤 줄이 눌 렸는지 표시하는 것이 었습니다. 그것은 여전히 ​​저에게 효과적입니다. 하나의 하위 템플릿 만 관련되어 있기 때문에, 내 환경에서 navbar에 대한 새로운 메소드가 어떻게 작동하는지 보지 못합니다. navbars 뷰에 대한 새로운 메소드가 포함되어 있지 않습니다. 더 간단 해!