`
vitojeng
  • 浏览: 20545 次
  • 性别: Icon_minigender_1
  • 来自: TW
社区版块
存档分类
最新评论

Django snippet: Template

阅读更多
以下代碼節錄自 Django Book - 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.)


Extending the Template System
Writing Custom Template Filters
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()


Writing Custom Template Tags
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):
    # ...


Setting a Variable in the Context
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>


Setting a Variable in the Context - cleaner solution
# 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)


Parsing Until Another Template Tag
# 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 ''


Parsing Until Another Template Tag and Saving Contents
# 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()

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

Shortcut for Simple Tags
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):
    # ...


Inclusion Tags
# 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):
    # ...


Inclusion tags access to values from the parent template’s context
@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 %}


Writing Custom Template Loaders


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics