2012-04-03 16 views
25

Tôi đang tự hỏi nếu có ai biết làm thế nào để đối phó với những điều sau kỳ quặc mẫu cấu trúc:Django mẫu: khối trọng của trẻ em bao gồm các mẫu thông qua một mẫu mở rộng

### base.html 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> 
<html lang="en"> 

<head> 
    <title> {% block title %} Title of the page {% endblock %} </title> 
</head> 

<body> 
    <header> 
    {% block header %} 
     {% include "base/header.html" %} 
    {% endblock header %} 
    </header> 
    {% block content %}{% endblock %} 
</body> 

</html> 

### base/header.html 
<div id="menu-bar"> 
    {% block nav %} 
    {% include "base/nav.html" %} 
    {% endblock %} 
</div> 

### base/nav.html 
<nav id="menu"> 
    <ul> 
    <li> 
     <a href="/profile/">My Profile</a> 
    </li> 
    <li> 
     <a href="/favs/">My Favorites</a> 
    </li> 
    {% block extra-content %}{% endblock %} 
    </ul> 
</nav> 

Và, trọng tâm của vấn đề:


### app/somepage.html 
{% extends "base.html" %} 
{% block content %} 
    <p>Content is overridden!</p> 
{% endblock %} 

{% block extra-content %} 
    <p>This will not show up, though...</p> 
{% endblock %} 

{% block nav %} 
    <p>Not even this.</p> 
{% endblock %} 

Vấn đề là khi mở rộng mẫu, bạn chỉ có thể ghi đè các khối được khai báo trong phụ huynh chứ không phải bất kỳ phần tử nào.

Tôi cho rằng tôi có thể tạo base.html một khối các khối lồng nhau không được sử dụng bao gồm tất cả các dự phòng trong tương lai, nhưng thậm chí có thể ghi đè đúng cách không? Và đó là cách duy nhất?

Nếu bạn đang tự hỏi tại sao tôi có một luồng công việc bao gồm/mở rộng xung quanh base.html, tôi có nhiều mẫu phụ mà tôi muốn sử dụng trong toàn bộ dự án: Tiêu đề, chân trang, nav, sidebars, vv Tất cả chúng sẽ được cấu trúc nhất quán trên toàn bộ trang web, nhưng trong nhiều trường hợp, toàn bộ phân khu của trang web sẽ chỉ cần một vài trong số các mẫu con đó. Ý tưởng của tôi là xác định các mẫu con trong thư mục templates/base và có các mẫu/base-type1.html, templates/base-type2.html, vv để mở rộng ở các vị trí khác. Mỗi loại sẽ chỉ tham chiếu các mẫu phụ cần thiết và ghi đè lên chúng để đặt nội dung khi cần.

+1

Vâng, sau khi công bố tôi xem [câu hỏi này] (http://stackoverflow.com/questions/9034331/overwriting-a-block-within-an- bao gồm-mẫu-từ-một-mở rộng-mẫu) bật lên trong thanh bên, ngay cả sau khi tìm kiếm kỹ lưỡng tràn ngăn xếp và googling. Tôi hiểu cơ chế của giới hạn này trong django, nhưng con người, những tác động đang gây thất vọng. –

+0

Hoàn toàn cố gắng để đăng bài này như là một câu trả lời, nhưng tài khoản stack mới của tôi thiếu đại diện ... Quên về điều đó. –

+0

Đối với người tìm kiếm trong tương lai: [câu hỏi nói trên] (http://stackoverflow.com/questions/9034331/overwriting-a-block-within-an-included-template-from-an-extended-template) có mẫu mã cơ bản một vài câu trả lời cho thấy chiến lược hữu ích của Marcin. –

Trả lời

5

Bạn có thể giải quyết vấn đề này bằng cách mở rộng các mẫu hiện được bao gồm, sau đó bao gồm tiện ích mở rộng thay vì mẫu cơ sở hiện được bao gồm.

+0

Giải pháp của bạn sẽ hoạt động nếu tôi chỉ có một hệ thống phân cấp tuyến tính của các mẫu, như trong ví dụ về xương trần ở trên. IRL tình huống của tôi là phân cấp nhánh với base.html làm thân cây.Như đã đề cập một thời gian ngắn, nó cũng bao gồm chân trang, thanh bên, v.v. có nghĩa là tôi không thể đơn giản lật hướng bao gồm và mở rộng tiêu đề. –

+0

@ChrisKeele Miễn là bao gồm của bạn là trong một khối, bạn có thể thay thế bao gồm với sự bao gồm của một mẫu có nguồn gốc, do đó, có điều này sẽ làm việc. – Marcin

+0

Vì vậy, nếu tôi đã có một header.html và một footer.html, tôi sẽ làm cho mỗi mở rộng base.html, sau đó trong example.html ... Làm gì? Bao gồm đầu trang và chân trang? Và mở rộng cơ sở trên đầu trang của điều đó? Xin lỗi vì cần làm rõ thêm, nhưng tôi không còn mã ngay bây giờ, và "thay thế bao gồm với việc bao gồm một mẫu có nguồn gốc" là khó cho tôi để tưởng tượng mà không có một sandbox. :) –

23

Nó dường như được ít người biết rằng bạn có thể sử dụng từ khóa with với include để vượt qua biến thành bối cảnh của một mẫu bao gồm - bạn có thể sử dụng nó để xác định bao gồm trong mẫu bao gồm:

# base.html 
<html> 
    <body> 
     {% block header %}{% include "header.html" %}{% endblock %} 
    </body> 
</html> 

# header.html 
# some stuff here 
<div id="header"> 
    <img src="logo.png"> 
    {% include nav_tmpl|default:"navigation.html" %} 
</div> 

# special_page.html (uses other navigation) 
{% extends "base.html" %} 
{% block header %} 
    {% include "header.html" with nav_tmpl="special_nav.html" %} 
    # you might also want to wrap the include in an 'if' tag if you don't want anything 
    # included here per default 
{% endblock %} 

Cách tiếp cận này giúp bạn tiết kiệm ít nhất là từ việc có một tệp bổ sung chỉ với mục đích ghi đè một khối. Bạn cũng có thể sử dụng từ khóa with để chuyển một giá trị thông qua một hệ thống phân cấp lớn hơn bao gồm.

9

Một biến thể terser đến solution proposed by @Bernhard Vallant:

# base.html 
<html> 
    <body> 
     {% block header %}{% include "header.html" %}{% endblock %} 
    </body> 
</html> 

# header.html 
# some stuff here 
<div id="header"> 
    <img src="logo.png"> 
    {% include nav_tmpl|default:"navigation.html" %} 
</div> 

# special_page.html (uses other navigation) 
{% extends "base.html" %} 
{% block header %} 
    {% with nav_tmpl="special_nav.html" %} 
     {{ block.super }} 
    {% endwith %} 
{% endblock %} 
Các vấn đề liên quan