Django snippet: Template

以下代碼節錄自 [url=http://djangobook.com/en/2.0/]Django Book[/url] - Chapter 4 & 9

# Missing comma!
TEMPLATE_DIRS = (
'/home/django/mysite/templates'
)


dynamic path, more flexible and decoupled
import os.path
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)


locals() trick
It returns a dictionary mapping all local variable names to their values, where “local” means all variables that have been defined within the current scope.
def current_datetime(request):
current_date = datetime.datetime.now()
return render_to_response('current_datetime.html', locals())


include Template Tag
# mypage.html
<html>
<body>
{% include "includes/nav.html" %}
<h1>{{ title }}</h1>
</body>
</html>

# includes/nav.html
<div id="nav">
You are in: {{ current_section }}
</div>


Template Inheritance
base template
# base template
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>My helpful timestamp site</h1>
{% block content %}{% endblock %}
{% block footer %}
<hr>
<p>Thanks for visiting my site.</p>
{% endblock %}
</body>
</html>

# extend template
{% extends "base.html" %}

{% block title %}The current time{% endblock %}

{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}


Default TEMPLATE_CONTEXT_PROCESSORS
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
)


disable auto-escaping for an individual variable
This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}


disable auto-escaping for template block
{% autoescape off %}
Hello {{ name }}
{% endautoescape %}


template loading: TEMPLATE_LOADERS
django.template.loader.get_template(template_name)
django.template.loader.select_template(template_name_list)
# If the template doesn’t exist, a TemplateDoesNotExist exception will be raised


template loader
django.template.loaders.filesystem.load_template_source
#This loader loads templates from the filesystem, according to TEMPLATE_DIRS. It is enabled by default.

django.template.loaders.app_directories.load_template_source
#This loader loads templates from Django applications on the filesystem. For each application in INSTALLED_APPS, the loader looks for a templates subdirectory. If the directory exists, Django looks for templates there.

django.template.loaders.eggs.load_template_source
#This loader is just like app_directories, except it loads templates from Python eggs rather than from the filesystem. This loader is disabled by default; you’ll need to enable it if you’re using eggs to distribute your application. (Python eggs are a way of compressing Python code into a single file.)


[size=large]Extending the Template System[/size]
[b]Writing Custom Template Filters[/b]
from django import template
register = template.Library()

def cut(value, arg):
"Removes all values of arg from the given string"
return value.replace(arg, '')

def lower(value): # Only one argument.
"Converts a string into all lowercase"
return value.lower()

register.filter('cut', cut)
register.filter('lower', lower)

# in template:
# {{ somevariable|cut:" " }}


Python 2.4 above
from django import template
register = template.Library()

@register.filter(name='cut')
def cut(value, arg):
return value.replace(arg, '')

@register.filter
def lower(value):
return value.lower()


[b]Writing Custom Template Tags[/b]
from django import template
register = template.Library()

def do_current_time(parser, token):
try:
# split_contents() knows not to split quoted strings.
tag_name, format_string = token.split_contents()
except ValueError:
msg = '%r tag requires a single argument' % token.split_contents()[0]
raise template.TemplateSyntaxError(msg)
return CurrentTimeNode(format_string[1:-1])

import datetime

class CurrentTimeNode(template.Node):
def __init__(self, format_string):
self.format_string = str(format_string)

def render(self, context):
now = datetime.datetime.now()
return now.strftime(self.format_string)

register.tag('current_time', do_current_time)

# python 2.4 above
@register.tag(name="current_time")
def do_current_time(parser, token):
# ...


[b]Setting a Variable in the Context[/b]
class CurrentTimeNode2(template.Node):
def __init__(self, format_string):
self.format_string = str(format_string)

def render(self, context):
now = datetime.datetime.now()
context['current_time'] = now.strftime(self.format_string)
return ''
# in template:
# {% current_time2 "%Y-%M-%d %I:%M %p" %}
# <p>The time is {{ current_time }}.</p>


[b]Setting a Variable in the Context - cleaner solution[/b]
# in template:
# {% get_current_time "%Y-%M-%d %I:%M %p" as my_current_time %}
# <p>The current time is {{ my_current_time }}.</p>

import re
class CurrentTimeNode3(template.Node):
def __init__(self, format_string, var_name):
self.format_string = str(format_string)
self.var_name = var_name

def render(self, context):
now = datetime.datetime.now()
context[self.var_name] = now.strftime(self.format_string)
return ''

def do_current_time(parser, token):
# This version uses a regular expression to parse tag contents.
try:
# Splitting by None == splitting by spaces.
tag_name, arg = token.contents.split(None, 1)
except ValueError:
msg = '%r tag requires arguments' % token.contents[0]
raise template.TemplateSyntaxError(msg)

m = re.search(r'(.*?) as (\w+)', arg)
if m:
fmt, var_name = m.groups()
else:
msg = '%r tag had invalid arguments' % tag_name
raise template.TemplateSyntaxError(msg)

if not (fmt[0] == fmt[-1] and fmt[0] in ('"', "'")):
msg = "%r tag's argument should be in quotes" % tag_name
raise template.TemplateSyntaxError(msg)

return CurrentTimeNode3(fmt[1:-1], var_name)


[b]Parsing Until Another Template Tag[/b]
# in template:
# {% comment %}

def do_comment(parser, token):
nodelist = parser.parse(('endcomment',))
parser.delete_first_token()
return CommentNode()

class CommentNode(template.Node):
def render(self, context):
return ''


[b]Parsing Until Another Template Tag and Saving Contents[/b]
# in template:
# {% upper %}
This will appear in uppercase, {{ user_name }}.
# {% endupper %}

def do_upper(parser, token):
nodelist = parser.parse(('endupper',))
parser.delete_first_token()
return UpperNode(nodelist)

class UpperNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist

def render(self, context):
output = self.nodelist.render(context)
return output.upper()

[i]For more examples of complex rendering, see the source code for {% if %}, {% for %}, {% ifequal %}, and {% ifchanged %}. They live in django/template/defaulttags.py[/i]

[b]Shortcut for Simple Tags[/b]
def current_time(format_string):
try:
return datetime.datetime.now().strftime(str(format_string))
except UnicodeEncodeError:
return ''

register.simple_tag(current_time)

# python 2.4 above
@register.simple_tag
def current_time(token):
# ...


[b]Inclusion Tags[/b]
# inclusion tag using in template:
# {% books_for_author author %}

# template using by inclusion tag:
# <ul>
# {% for book in books %}
# <li>{{ book.title }}</li>
# {% endfor %}
# </ul>

def books_for_author(author):
books = Book.objects.filter(authors__id=author.id)
return {'books': books}

register.inclusion_tag('book_snippet.html')(books_for_author)

# python 2.4 above
@register.inclusion_tag('book_snippet.html')
def books_for_author(author):
# ...


[b]Inclusion tags access to values from the parent template’s context[/b]
@register.inclusion_tag('link.html', takes_context=True)
def jump_link(context):
return {
'link': context['home_link'],
'title': context['home_title'],
}

# in link.html
# Jump directly to <a href="{{ link }}">{{ title }}</a>.

# tag usage:
# {% jump_link %}


[b]Writing Custom Template Loaders[/b]
[code="Python"][/code]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值