หลังจากเริ่ม code django ไปได้พอสมควร ผมพบมีปัญหาเกี่ยวกับ Template ซึ่งดูแล้วมันขัดแย้งกับ concept DRY(Don't Repeat Yourself) ชอบกล
ผมวาง structure ของ Template ไว้ประมาณนี้นะครับ
base.html
{% include "auth.html" %}
{% block content %}
{% end block %}
auth.html
{% ifequal user None %}
{% include "auth/signin.html" %}
<a href="/signup">Sign Up</a>
{% else %}
{{ user.email }}
<a href="/signout">Sign Out</a>
{% endifequal %}
singin.html
<form action="/signin/" method="post">
{{ signInForm.as_p }}
<input type="submit" value="Submit" />
</form>
ปัญหาคือพอเริ่ม implement หลาย page มากขึ้น ในทุกๆ view ของผม ผมต้อง Repeat code เกี่ยวกับ user เสมอ เช็คว่า login รึยัง ถ้ายังก็ต้องส่ง signInForm มาให้ template
มันน่าจะมีวิธีที่จะ call signInForm จากตัว Template หรือใครมีวิธีอื่นในการแก้ปัญหาแบบนี้มั๊ยครับ
ถ้าอ่านคำถามไม่ผิด เหมือนคุณจะต้องการทำ form login ในทุกหน้าถ้า user ไม่ได้ login แต่ไม่อยากจะ pass signInForm ทุกครั้งใช่ไหมครับ ถ้าเป็นแบบนั้นขอแนะนำให้ใช้ inclusion tag ครับ
วิธีใช้ก็ราวๆ นี้
สร้างไฟล์
app/templatetags/login.py
หน้าตาประมาณสร้าง template ที่
templates/inclusions/login_form.html
(ทำไม prefix 4 spaces แล้วมันไม่ยอม escape form ให้เนี่ย)แล้วเวลาเรียกใช้ก็เช่น base.html
เจ้า variable
user
เนี่ย มันจะส่งไปให้ template ต่อเมื่อใช้RequestContext
เท่านั้น ระวังไว้ให้ดีน่าจะตรงตามที่ต้องการนะครับ
ขอบคุณครับ ก็คิดอยู่เหมือนกันว่าน่าจะต้องสร้าง custom tag จริงๆ จะลองทำตามคำแนะนำ แล้วมาบอกผลนะครับ ^^
ปรากฎว่าใช้ได้ผล! ขอบคุณมากครับ :)
ผมทำไม่ได้ครับ ไม่รู้ว่าวางไฟล์ไม่ถูกที่หรือเปล่า
ผมว่างไฟล์แบบนี้
ไฟล์ check_login.py
from django import template register = template.Library() @register.inclusion_tag('login_or_user.html') def show_user_or_login(user): logged_in = user.is_logged_in() return {'logged_in':logged_in}
แล้วก็ base.html... {% load check_login %} {% show_user_or_login user %} ...
ผมหาดูตัวอย่างบางที่ก็ไม่มี {% load %} นะครับ ไม่รู้ว่าใช้สาเหตุหรือเปล่าขอบคุณครับ
Directory แบบนั้นต้องใช้
@register.inclusion_tag('inclusion/login_or_user.html')
ครับ@login_require
def xxxx():
....