Jinja2:编写[不那么]复杂模板的正确方法
Jinja2 : proper way to write [not so] complex template
我正在尝试实现一个简单的日历网页。
我对 Jinja2 很陌生,但我对模板的理解是,应避免在 Python 源代码中编写 HTML 代码,因为模板就是为此目的而设计的。
我面临的问题是我不知道如何为这个项目编写清晰的模板。我想我的项目中存在整体架构问题...
我的页面模板:
{% extends "base.html" %}
{% block title %}The title{% endblock %}
{% block content %}
<h1>Hey</h1>
<p> I'm happy </p>
<div id="calendar">
<table>
<tr>
{% for month in range(1, 13) %}
<td valign="top" align="center">{# html code for a single month goes here... #}</td>
{% endfor %}
</tr>
</table>
</div>
{% endblock %}
每个月的模板是
<table>
<th>{{ month_name }}</th>
{% for day_number in days %}
<tr><td>{{ day_number }}</td><td>{{ weekday }}</td></tr>
{% endfor %}
</table>
最后,我有一个 Python class 日历,基本上提供了帮助函数来计算一个月中的天数:
class Calendar:
def __init__(self, year):
self.year = year
def monthrange(self, month):
nextmonth = month % 12 + 1
nextyear = self.year + 1 if nextmonth == 1 else self.year
firstday = datetime.date(self.year, month, 1)
lastday = datetime.date(nextyear, nextmonth, 1)
return (1, (lastday - firstday).days)
def itermonthdates(self, month):
first, last = self.monthrange(month)
for i in range(first, last + 1):
yield datetime.date(self.year, month, i)
def tohtml(self):
def month_to_html(month):
# !!! This code generate HTML but it should not !!!
s = '<table>\n'
s += '<th>{}</th>'.format(MONTHS[month - 1])
for day in self.itermonthdates(month):
weekday = WEEKDAYS[day.weekday()]
d = {'day': day.day, 'weekday': weekday}
s += '<tr><td>%(day)02d</td><td>%(weekday)s</td></tr>\n' % d
s += '</table>\n'
return s
template_loader = jinja2.FileSystemLoader(searchpath='templates')
template_env = jinja2.Environment(loader=template_loader)
template = template_env.get_template('template.html')
print(template.render(months=[month_to_html(i) for i in range(1, 13)]))
所以这段代码只能部分工作,因为我不知道如何使用 Jinja2 来渲染每个月。
如有任何帮助,我们将不胜感激。
本
我终于认为我得到了你想要的。 不要在Python
中写HTML
。相反,您可以在 Python
中为您的日历创建 logic
,然后将该数据发送到模板以填充 Jinja
。废话不多说,让我们编写一个非常简单的示例。
简单示例
在这里我们将获取要在网页中显示的当前日期。
logic.py
@app.route('/')
def index():
import time
current_time = time.strftime("%d/%m/%Y")
return render_template('template.html', data = current_time)
template.html
{% if data %} # This checks if the variable "data" is set.
<p> {{data}} </p> ## This will output the date here
通过将其应用于您的代码,您可以将任何逻辑数据(这意味着它需要生成 Python
)发送给变量,并通过添加第二个 Jinja
模板将它们发送给 Jinja
=21=] 到 render_template
。希望我这次能理解你的意思。
感谢您的回答。
我以解决方案结束。不知道有没有更好的办法。最后,我将 calendar
对象传递给模板。
页面模板:
{% extends "base.html" %}
{% block title %}The title{% endblock %}
{% block content %}
<h1>Hey</h1>
<p> I'm happy </p>
<div id="calendar">
<table>
<tr>
{% for month in range(1, 13) %}
<td valign="top" align="center">
{% include 'month_template.html' %}
</td>
{% endfor %}
</tr>
</table>
</div>
{% endblock %}
月份模板:
<table>
<th>{{ calendar.month_name(month) }}</th>
{% for day_number, weekday in calendar.itermonthdays(month) %}
<tr><td>{{ day_number }}</td><td>{{ weekday }}</td></tr>
{% endfor %}
</table>
Python脚本:
class Calendar:
def __init__(self, year):
self.year = year
@staticmethod
def month_name(monthid):
return MONTHS[monthid - 1]
def monthrange(self, month):
nextmonth = month % 12 + 1
nextyear = self.year + 1 if nextmonth == 1 else self.year
firstday = datetime.date(self.year, month, 1)
lastday = datetime.date(nextyear, nextmonth, 1)
return (1, (lastday - firstday).days)
def itermonthdates(self, month):
first, last = self.monthrange(month)
for i in range(first, last + 1):
yield datetime.date(self.year, month, i)
def itermonthdays(self, month):
for date in self.itermonthdates(month):
day = '{:02d}'.format(date.day)
weekday = WEEKDAYS[date.weekday()]
yield day, weekday
def tohtml(self):
template_loader = jinja2.FileSystemLoader(searchpath='templates')
template_env = jinja2.Environment(loader=template_loader)
template = template_env.get_template('template.html')
print(template.render(calendar=self))
如果您发现更好的方法,请告诉我。
谢谢。
本
我正在尝试实现一个简单的日历网页。
我对 Jinja2 很陌生,但我对模板的理解是,应避免在 Python 源代码中编写 HTML 代码,因为模板就是为此目的而设计的。
我面临的问题是我不知道如何为这个项目编写清晰的模板。我想我的项目中存在整体架构问题...
我的页面模板:
{% extends "base.html" %}
{% block title %}The title{% endblock %}
{% block content %}
<h1>Hey</h1>
<p> I'm happy </p>
<div id="calendar">
<table>
<tr>
{% for month in range(1, 13) %}
<td valign="top" align="center">{# html code for a single month goes here... #}</td>
{% endfor %}
</tr>
</table>
</div>
{% endblock %}
每个月的模板是
<table>
<th>{{ month_name }}</th>
{% for day_number in days %}
<tr><td>{{ day_number }}</td><td>{{ weekday }}</td></tr>
{% endfor %}
</table>
最后,我有一个 Python class 日历,基本上提供了帮助函数来计算一个月中的天数:
class Calendar:
def __init__(self, year):
self.year = year
def monthrange(self, month):
nextmonth = month % 12 + 1
nextyear = self.year + 1 if nextmonth == 1 else self.year
firstday = datetime.date(self.year, month, 1)
lastday = datetime.date(nextyear, nextmonth, 1)
return (1, (lastday - firstday).days)
def itermonthdates(self, month):
first, last = self.monthrange(month)
for i in range(first, last + 1):
yield datetime.date(self.year, month, i)
def tohtml(self):
def month_to_html(month):
# !!! This code generate HTML but it should not !!!
s = '<table>\n'
s += '<th>{}</th>'.format(MONTHS[month - 1])
for day in self.itermonthdates(month):
weekday = WEEKDAYS[day.weekday()]
d = {'day': day.day, 'weekday': weekday}
s += '<tr><td>%(day)02d</td><td>%(weekday)s</td></tr>\n' % d
s += '</table>\n'
return s
template_loader = jinja2.FileSystemLoader(searchpath='templates')
template_env = jinja2.Environment(loader=template_loader)
template = template_env.get_template('template.html')
print(template.render(months=[month_to_html(i) for i in range(1, 13)]))
所以这段代码只能部分工作,因为我不知道如何使用 Jinja2 来渲染每个月。
如有任何帮助,我们将不胜感激。 本
我终于认为我得到了你想要的。 不要在Python
中写HTML
。相反,您可以在 Python
中为您的日历创建 logic
,然后将该数据发送到模板以填充 Jinja
。废话不多说,让我们编写一个非常简单的示例。
简单示例
在这里我们将获取要在网页中显示的当前日期。
logic.py
@app.route('/')
def index():
import time
current_time = time.strftime("%d/%m/%Y")
return render_template('template.html', data = current_time)
template.html
{% if data %} # This checks if the variable "data" is set.
<p> {{data}} </p> ## This will output the date here
通过将其应用于您的代码,您可以将任何逻辑数据(这意味着它需要生成 Python
)发送给变量,并通过添加第二个 Jinja
模板将它们发送给 Jinja
=21=] 到 render_template
。希望我这次能理解你的意思。
感谢您的回答。
我以解决方案结束。不知道有没有更好的办法。最后,我将 calendar
对象传递给模板。
页面模板:
{% extends "base.html" %}
{% block title %}The title{% endblock %}
{% block content %}
<h1>Hey</h1>
<p> I'm happy </p>
<div id="calendar">
<table>
<tr>
{% for month in range(1, 13) %}
<td valign="top" align="center">
{% include 'month_template.html' %}
</td>
{% endfor %}
</tr>
</table>
</div>
{% endblock %}
月份模板:
<table>
<th>{{ calendar.month_name(month) }}</th>
{% for day_number, weekday in calendar.itermonthdays(month) %}
<tr><td>{{ day_number }}</td><td>{{ weekday }}</td></tr>
{% endfor %}
</table>
Python脚本:
class Calendar:
def __init__(self, year):
self.year = year
@staticmethod
def month_name(monthid):
return MONTHS[monthid - 1]
def monthrange(self, month):
nextmonth = month % 12 + 1
nextyear = self.year + 1 if nextmonth == 1 else self.year
firstday = datetime.date(self.year, month, 1)
lastday = datetime.date(nextyear, nextmonth, 1)
return (1, (lastday - firstday).days)
def itermonthdates(self, month):
first, last = self.monthrange(month)
for i in range(first, last + 1):
yield datetime.date(self.year, month, i)
def itermonthdays(self, month):
for date in self.itermonthdates(month):
day = '{:02d}'.format(date.day)
weekday = WEEKDAYS[date.weekday()]
yield day, weekday
def tohtml(self):
template_loader = jinja2.FileSystemLoader(searchpath='templates')
template_env = jinja2.Environment(loader=template_loader)
template = template_env.get_template('template.html')
print(template.render(calendar=self))
如果您发现更好的方法,请告诉我。
谢谢。
本