The Django Book Chapter 9 - Django Workshop - Taipei.py

84
Advanced Templates 2013-07-23. Django Workshop.

description

Reviewing Chapter 9: Advanced Templates in The Django Book.

Transcript of The Django Book Chapter 9 - Django Workshop - Taipei.py

Page 1: The Django Book Chapter 9 - Django Workshop - Taipei.py

Advanced Templates2013-07-23. Django Workshop.

Page 2: The Django Book Chapter 9 - Django Workshop - Taipei.py

About me

• TP (@uranusjr)

• RTFD

• Find me anywhere

Page 3: The Django Book Chapter 9 - Django Workshop - Taipei.py

Language Review

{% if is_logged_in %}!

Thanks for logging in!!

{% else %}!

Welcome to {{ website_name }}.!

{% endif %}

Page 4: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template tags

{% if is_logged_in %}!

Thanks for logging in!!

{% else %}!

Welcome to {{ website_name }}.!

{% endif %}

Page 5: The Django Book Chapter 9 - Django Workshop - Taipei.py

Variables

{% if is_logged_in %}!

Thanks for logging in!!

{% else %}!

Welcome to {{ website_name }}.!

{% endif %}

Page 6: The Django Book Chapter 9 - Django Workshop - Taipei.py

Language Review

• Variables come from a context

• Dictionary-like name-value mapping

• A context is rendered by the template

• Variable replacement

• Template tag execution

Page 7: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template

__init__(self, string)

render(self, context)

format string

context

rendered value

text file

dict object

Page 8: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.shortcuts import render_to_response!!def view_1(request):! context_dict = {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR'],! 'message': 'I am view 1.'! }! return render_to_response('template1.html',! context_dict)!!def view_2(request):! context_dict = {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR'],! 'message': 'I am the second view.'! }! return render_to_response('template2.html',! context_dict)

Page 9: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.shortcuts import render_to_response!!def view_1(request):! context_dict = {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR'],! 'message': 'I am view 1.'! }! return render_to_response('template1.html',! context_dict)!!def view_2(request):! context_dict = {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR'],! 'message': 'I am the second view.'! }! return render_to_response('template2.html',! context_dict)

Page 10: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.template import loader, Context!!def view_1(request):! context_dict = {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR'],! 'message': 'I am view 1.'! }! t = loader.get_template('template1.html')! context = Context(context_dict)! return t.render(context)!!def view_2(request):! context_dict = {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR'],! 'message': 'I am the second view.'! }! t = loader.get_template('template2.html')! context = Context(context_dict)! return t.render(context)

Page 11: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.template import loader, Context!!def view_1(request):! context_dict = {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR'],! 'message': 'I am view 1.'! }! t = loader.get_template('template1.html')! context = Context(context_dict)! return t.render(context)!!def view_2(request):! context_dict = {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR'],! 'message': 'I am the second view.'! }! t = loader.get_template('template2.html')! context = Context(context_dict)! return t.render(context)

Page 12: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.template import loader, Context!!def render_it(template, context_dict):! context_dict.update({! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR']! })! return template.render(Context(context_dict))!!def view_1(request):! t = loader.get_template('template1.html')! context_dict = {'message': 'I am view 1.'}! return render_it(t, context_dict)!!def view_2(request):! t = loader.get_template('template2.html')! context_dict = {! 'message': 'I am the second view.'! }! return render_it(t, context_dict)

Page 13: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.template import loader, Context!!def render_it(template, context_dict):! context_dict.update({! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR']! })! return template.render(Context(context_dict))!!def view_1(request):! t = loader.get_template('template1.html')! context_dict = {'message': 'I am view 1.'}! return render_it(t, context_dict)!!def view_2(request):! t = loader.get_template('template2.html')! context_dict = {! 'message': 'I am the second view.'! }! return render_it(t, context_dict)

Page 14: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.template import loader, RequestContext!!def custom_proc(request):! return {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR']! }!!def view_1(request):! t = loader.get_template('template1.html')! context = RequestContext(! request, {'message': 'I am view 1.'},! processors=[custom_proc]! )! return t.render(context)!!def view_2(request):! t = loader.get_template('template2.html')! context = RequestContext(! request, {'message': 'I am the second view.'},! processors=[custom_proc]! )! return t.render(context)

Page 15: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.template import loader, RequestContext!!def custom_proc(request):! return {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR']! }!!def view_1(request):! t = loader.get_template('template1.html')! context = RequestContext(! request, {'message': 'I am view 1.'},! processors=[custom_proc]! )! return t.render(context)!!def view_2(request):! t = loader.get_template('template2.html')! context = RequestContext(! request, {'message': 'I am the second view.'},! processors=[custom_proc]! )! return t.render(context)

Page 16: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.template import loader, RequestContext!!def custom_proc(request):! return {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR']! }!!def view_1(request):! t = loader.get_template('template1.html')! context = RequestContext(! request, {'message': 'I am view 1.'},! processors=[custom_proc]! )! return t.render(context)!!def view_2(request):! t = loader.get_template('template2.html')! context = RequestContext(! request, {'message': 'I am the second view.'},! processors=[custom_proc]! )! return t.render(context)

Page 17: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.shortcuts import render_to_response!from django.template import RequestContext!!def custom_proc(request):! return {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR']! }!!def view_1(request):! context = RequestContext(request, processors=[custom_proc])! return render_to_response(! 'template1.html',! {'message': 'I am view 1.'},! context_instance=context! )!!def view_2(request):! context = RequestContext(request, processors=[custom_proc])! return render_to_response(! 'template2.html',! {'message': 'I am the second view.'},! context_instance=context! )

Page 18: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.shortcuts import render_to_response!from django.template import RequestContext!!def custom_proc(request):! return {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR']! }!!def view_1(request):! context = RequestContext(request, processors=[custom_proc])! return render_to_response(! 'template1.html',! {'message': 'I am view 1.'},! context_instance=context! )!!def view_2(request):! context = RequestContext(request, processors=[custom_proc])! return render_to_response(! 'template2.html',! {'message': 'I am the second view.'},! context_instance=context! )

Page 19: The Django Book Chapter 9 - Django Workshop - Taipei.py

TEMPLATE_CONTEXT_PROCESSORS = (! 'django.contrib.auth.context_processors.auth',! 'django.core.context_processors.debug',! 'django.core.context_processors.i18n',! 'django.core.context_processors.media',! 'django.core.context_processors.static',! 'django.core.context_processors.tz',! 'django.contrib.messages.context_processors.messages',! 'myapp.views.custom_proc'!)

settings.py

Page 20: The Django Book Chapter 9 - Django Workshop - Taipei.py

TEMPLATE_CONTEXT_PROCESSORS = (! 'django.contrib.auth.context_processors.auth',! 'django.core.context_processors.debug',! 'django.core.context_processors.i18n',! 'django.core.context_processors.media',! 'django.core.context_processors.static',! 'django.core.context_processors.tz',! 'django.contrib.messages.context_processors.messages',! 'myapp.views.custom_proc'!)

settings.py

Page 21: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.shortcuts import render_to_response!from django.template import RequestContext!!def custom_proc(request):! return {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR']! }!!def view_1(request):! context = RequestContext(request)! return render_to_response(! 'template1.html',! {'message': 'I am view 1.'},! context_instance=context! )!!def view_2(request):! context = RequestContext(request)! return render_to_response(! 'template2.html',! {'message': 'I am the second view.'},! context_instance=context! )

Page 22: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.shortcuts import render_to_response!from django.template import RequestContext!!def custom_proc(request):! return {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR']! }!!def view_1(request):! context = RequestContext(request)! return render_to_response(! 'template1.html',! {'message': 'I am view 1.'},! context_instance=context! )!!def view_2(request):! context = RequestContext(request)! return render_to_response(! 'template2.html',! {'message': 'I am the second view.'},! context_instance=context! )

Page 23: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.shortcuts import render!!def custom_proc(request):! return {! 'app': 'My app',! 'user': request.user,! 'ip_address': request.META['REMOTE_ADDR']! }!!def view_1(request):! return render(! 'template1.html',! {'message': 'I am view 1.'}! )!!def view_2(request):! return render(! 'template2.html',! {'message': 'I am the second view.'}! )

Page 24: The Django Book Chapter 9 - Django Workshop - Taipei.py

Custom Processors

• Do one thing and do it well

• Pick your variable names

• Context keys are global

• General import conventions apply

Page 25: The Django Book Chapter 9 - Django Workshop - Taipei.py

• Breaking down render_to_response

• RequestContext and context processors

• TEMPLATE_CONTEXT_PROCESSORS

• django.shortcuts.render

Summary

Page 26: The Django Book Chapter 9 - Django Workshop - Taipei.py

HTML Escaping

• Variable values are escaped by default

• {{ something|safe }}

• {% autoescape off %} Not escaped: {{ something }} {% endautoescape %}!

• Literals in tags/filters are not escaped

• {{ escaped|default:'1 < 2' }}

Page 27: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template Loading

• django.template.loader

• get_template(template_name)

• select_template(template_names)!

• TemplateDoesNotExist!

• TEMPLATE_DIRS!

• TEMPLATE_LOADERS

Page 28: The Django Book Chapter 9 - Django Workshop - Taipei.py

PROJECT_ROOT = …!!!TEMPLATE_DIRS = (! os.path.join(PROJECT_ROOT, 'templates'),! os.path.join(PROJECT_ROOT, 'other_templates')!)!!TEMPLATE_LOADERS = (! 'django.template.loaders.filesystem.Loader',! 'django.template.loaders.app_directories.Loader',! # 'django.template.loaders.eggs.Loader',!)

Page 29: The Django Book Chapter 9 - Django Workshop - Taipei.py

1

2

3

• Loader order

• Path order

• Third-party apps will be searched

• App directory search order is undefined

Page 30: The Django Book Chapter 9 - Django Workshop - Taipei.py

Questions?

Page 31: The Django Book Chapter 9 - Django Workshop - Taipei.py
Page 32: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template Tags

Page 33: The Django Book Chapter 9 - Django Workshop - Taipei.py

Before We Start...

• This is a HUGE topic

• Read the documentation

• Learn how others do it

• Template processing is string manipulation

• Slow, period

• No fancy things unless necessary

Page 34: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template Library

Page 35: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template Library

Page 36: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template Library

Name matters

Page 37: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template Library

Don’t forget this

Page 38: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template Library

Naming is important

Page 39: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template Filter

• Takes one or zero arguments

• Always returns something

• Fails silently

Page 40: The Django Book Chapter 9 - Django Workshop - Taipei.py

{{ value|upper }}!!{{ value|add:arg }}

Page 41: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!!register = template.Library()!!!def upper(value):! """Converts a string into all uppercase."""! return value.upper()!!!def add(value, arg):! """Adds the arg to the value."""! return int(value) + int(arg)

Page 42: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!!register = template.Library()!!!def upper(value):! """Converts a string into all uppercase."""! return value.upper()!!!def add(value, arg):! """Adds the arg to the value."""! return int(value) + int(arg)

Page 43: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!!register = template.Library()!!!def upper(value):! """Converts a string into all uppercase."""! return value.upper()!!!def add(value, arg):! """Adds the arg to the value."""! return int(value) + int(arg)!!!register.filter('upper', upper)!register.filter('add', add)

Page 44: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!!register = template.Library()[email protected](name='upper')!def upper(value):! """Converts a string into all uppercase."""! return value.upper()[email protected](name='add')!def add(value, arg):! """Adds the arg to the value."""! return int(value) + int(arg)!

Page 45: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!!register = template.Library()[email protected]!def upper(value):! """Converts a string into all uppercase."""! return value.upper()[email protected]!def add(value, arg):! """Adds the arg to the value."""! return int(value) + int(arg)!

Page 46: The Django Book Chapter 9 - Django Workshop - Taipei.py

@register.filter!def upper(value):! """Converts a string into all uppercase."""! return value.upper()[email protected]!def add(value, arg):! """Adds the arg to the value."""! try:! return int(value) + int(arg)! except (ValueError, TypeError):! try:! return value + arg! except Exception:! return '' # Return something

Page 47: The Django Book Chapter 9 - Django Workshop - Taipei.py

@register.filter!def upper(value):! """Converts a string into all uppercase."""! return value.upper() # Let it [email protected]!def add(value, arg):! """Adds the arg to the value."""! try:! return int(value) + int(arg)! except (ValueError, TypeError):! try:! return value + arg! except Exception:! return ''

Page 48: The Django Book Chapter 9 - Django Workshop - Taipei.py

{{ value|upper }}!!{{ value|add:arg }}

Page 49: The Django Book Chapter 9 - Django Workshop - Taipei.py

{% load myapp_tags %}!!{{ value|upper }}!!{{ value|add:arg }}

Page 50: The Django Book Chapter 9 - Django Workshop - Taipei.py

{{ value|date:arg }}

Page 51: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.conf import settings!from django.utils import [email protected]!def date(value, arg=None):! """Formats a date according to the given format."""! if value in (None, ''):! return ''! if arg is None:! arg = settings.DATE_FORMAT! try:! return formats.date_format(value, arg)! except AttributeError:! try:! return format(value, arg)! except AttributeError:! return ''

Page 52: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.conf import settings!from django.utils import [email protected]!def date(value, arg=None):! """Formats a date according to the given format."""! if value in (None, ''):! return ''! if arg is None:! arg = settings.DATE_FORMAT! try:! return formats.date_format(value, arg)! except AttributeError:! try:! return format(value, arg)! except AttributeError:! return ''

Page 53: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.conf import settings!from django.utils import [email protected]!def date(value, arg=None):! """Formats a date according to the given format."""! if value in (None, ''):! return ''! if arg is None:! arg = settings.DATE_FORMAT! try:! return formats.date_format(value, arg)! except AttributeError:! try:! return format(value, arg)! except AttributeError:! return ''

Page 54: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django.conf import settings!from django.utils import [email protected]!def date(value, arg=None):! """Formats a date according to the given format."""! if value in (None, ''):! return ''! if arg is None:! arg = settings.DATE_FORMAT! try:! return formats.date_format(value, arg)! except AttributeError:! try:! return format(value, arg)! except AttributeError:! return ''

Page 55: The Django Book Chapter 9 - Django Workshop - Taipei.py

Return Something

• Not necessarily a string

• Only need to be convertible to a string

• None is converted to 'None', not ''

• I always return strings

Page 56: The Django Book Chapter 9 - Django Workshop - Taipei.py

Template Tags

Compilation function

Template tag node

__init__(self, string)

render(self, context)

template

context

rendered value

Page 57: The Django Book Chapter 9 - Django Workshop - Taipei.py

{% now format_string %}

Page 58: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!from django.template import TemplateSyntaxError!!register = template.Library()[email protected]!def now(parser, token):! bits = token.split_contents()! if len(bits) != 2:! raise TemplateSyntaxError(! "'now' statement takes one argument"! )! format_string = bits[1][1:-1]! return NowNode(format_string)!

Page 59: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!from django.template import TemplateSyntaxError!!register = template.Library()[email protected]!def now(parser, token):! bits = token.split_contents()! if len(bits) != 2:! raise TemplateSyntaxError(! "'now' statement takes one argument"! )! format_string = bits[1][1:-1]! return NowNode(format_string)!

Page 60: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!from django.template import TemplateSyntaxError!!register = template.Library()[email protected]!def now(parser, token):! bits = token.split_contents()! if len(bits) != 2:! raise TemplateSyntaxError(! "'now' statement takes one argument"! )! format_string = bits[1][1:-1]! return NowNode(format_string)!

Page 61: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!from django.template import TemplateSyntaxError!!register = template.Library()[email protected]!def now(parser, token):! bits = token.split_contents()! if len(bits) != 2:! raise TemplateSyntaxError(! "'now' statement takes one argument"! )! format_string = bits[1][1:-1]! return NowNode(format_string)!

Page 62: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!from django.template import TemplateSyntaxError!!register = template.Library()[email protected]!def now(parser, token):! bits = token.split_contents()! if len(bits) != 2:! raise TemplateSyntaxError(! "'now' statement takes one argument"! )! format_string = bits[1][1:-1]! return NowNode(format_string)!

Page 63: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!from django.template import TemplateSyntaxError!!register = template.Library()[email protected]!def now(parser, token):! bits = token.split_contents()! if len(bits) != 2:! raise TemplateSyntaxError(! "'now' statement takes one argument"! )! format_string = bits[1][1:-1]! return NowNode(format_string)!

Page 64: The Django Book Chapter 9 - Django Workshop - Taipei.py

from datetime import datetime!!!class NowNode(Node):! def __init__(self, format_string):! self.format_string = format_string!! def render(self, context):! now = datetime.now()! return now.strftime(self.format_string)

Page 65: The Django Book Chapter 9 - Django Workshop - Taipei.py

from datetime import datetime!!!class NowNode(Node):! def __init__(self, format_string):! self.format_string = format_string!! def render(self, context):! now = datetime.now()! return now.strftime(self.format_string)

Page 66: The Django Book Chapter 9 - Django Workshop - Taipei.py

from datetime import datetime!from django.conf import settings!from django.template.defaultfilters import date!from django.utils import timezone!!!class NowNode(Node):! def __init__(self, format_string):! self.format_string = format_string!! def render(self, context):! if settings.USE_TZ:! tzinfo = timezone.get_current_timezone()! else:! tzinfo = None! return date(! datetime.now(tz=tzinfo),! self.format_string! )

Page 67: The Django Book Chapter 9 - Django Workshop - Taipei.py

from datetime import datetime!from django.conf import settings!from django.template.defaultfilters import date!from django.utils import timezone!!!class NowNode(Node):! def __init__(self, format_string):! self.format_string = format_string!! def render(self, context):! if settings.USE_TZ:! tzinfo = timezone.get_current_timezone()! else:! tzinfo = None! return date(! datetime.now(tz=tzinfo),! self.format_string! )

Page 68: The Django Book Chapter 9 - Django Workshop - Taipei.py

{% inject_now format_string %}!!<p>The time is {{ now }}</p>

Page 69: The Django Book Chapter 9 - Django Workshop - Taipei.py

from django import template!from django.template import TemplateSyntaxError!!register = template.Library()[email protected]!def inject_now(parser, token):! bits = token.split_contents()! if len(bits) != 2:! raise TemplateSyntaxError(! "'inject_now' requires one argument"! )! format_string = bits[1][1:-1]! return InjectNowNode(format_string)!

Page 70: The Django Book Chapter 9 - Django Workshop - Taipei.py

class InjectNowNode(Node):! def __init__(self, format_string):! self.format_string = format_string!! def render(self, context):! if settings.USE_TZ:! tzinfo = timezone.get_current_timezone()! else:! tzinfo = None! context['now'] = date(! datetime.now(tz=tzinfo),! self.format_string! )! return ''

Page 71: The Django Book Chapter 9 - Django Workshop - Taipei.py

class InjectNowNode(Node):! def __init__(self, format_string):! self.format_string = format_string!! def render(self, context):! if settings.USE_TZ:! tzinfo = timezone.get_current_timezone()! else:! tzinfo = None! context['now'] = date(! datetime.now(tz=tzinfo),! self.format_string! )! return ''

Page 72: The Django Book Chapter 9 - Django Workshop - Taipei.py

{% inject_now format_string as var_name %}!!<p>The time now is {{ var_name }}</p>

Page 73: The Django Book Chapter 9 - Django Workshop - Taipei.py

@register.tag!def inject_now(parser, token):! bits = token.split_contents()! if len(bits) != 4:! raise TemplateSyntaxError(! "'inject_now' statement requires form "! "{% inject_now format as var_name %}."! )! format_string = bits[1][1:-1]! var_name = bits[3]! return InjectNowNode(format_string, var_name)

Page 74: The Django Book Chapter 9 - Django Workshop - Taipei.py

@register.tag!def inject_now(parser, token):! error = TemplateSyntaxError(! "'inject_now' statement requires form "! "{% inject_now format as var_name %}."! )! try:! tag_name, arg = token.contents.split(None, 1)! except ValueError:! raise error!! m = re.search(r'(.*?) as (\w+)', arg)! if m:! fmt, var_name = m.groups()! else:! raise error! if not (fmt[0] == fmt[-1] and fmt[0] in ('"', "'")):! raise error!! return InjectNowNode(fmt[1:-1], var_name)

Page 75: The Django Book Chapter 9 - Django Workshop - Taipei.py

class InjectNowNode(Node):! def __init__(self, format_string, var_name):! self.format_string = format_string! self.var_name = var_name!! def render(self, context):! if settings.USE_TZ:! tzinfo = timezone.get_current_timezone()! else:! tzinfo = None! context[self.var_name] = date(! datetime.now(tz=tzinfo),! self.format_string! )! return ''

Page 76: The Django Book Chapter 9 - Django Workshop - Taipei.py

Start-end tags

• parser.parse(end_tags_tuple)!

• Returns a NodeList instance (iterable)

• parser.delete_first_token()

• Deletes next token (i.e. the end token)

Page 77: The Django Book Chapter 9 - Django Workshop - Taipei.py

def do_comment(parser, token):! nodelist = parser.parse(('endcomment',))! parser.delete_first_token()! return CommentNode()!!!class CommentNode(template.Node):! def render(self, context):! return ''

Page 78: The Django Book Chapter 9 - Django Workshop - Taipei.py

def do_comment(parser, token):! nodelist = parser.parse(('endcomment',))! parser.delete_first_token()! return CommentNode()!!!class CommentNode(template.Node):! def render(self, context):! return ''

Page 79: The Django Book Chapter 9 - Django Workshop - Taipei.py

def do_comment(parser, token):! nodelist = parser.parse(('endcomment',))! parser.delete_first_token()! return CommentNode()!!!class CommentNode(template.Node):! def render(self, context):! return ''

Page 80: The Django Book Chapter 9 - Django Workshop - Taipei.py

Shortcuts

• register.simple_tag

• register.inclusion_tag(template)!

• takes_context=True!

• stringfilter

Page 81: The Django Book Chapter 9 - Django Workshop - Taipei.py

Custom Loaders

• implement load_template_source

• Raise TemplateDoesNotExist when appropriate

• Add it to TEMPLATE_LOADERS in settings

Page 82: The Django Book Chapter 9 - Django Workshop - Taipei.py

Standalone Mode

• django.conf.settings.configure()

• I’d just use another template engine

• Jinja2 + Coffin

• Read Appendix D or the docs if you really know what you’re doing

Page 83: The Django Book Chapter 9 - Django Workshop - Taipei.py

Again...

• This is a HUGE topic

• Read the documentation

• Learn how others do it

• Template processing is string manipulation

• Slow, period

• No fancy things unless necessary

Page 84: The Django Book Chapter 9 - Django Workshop - Taipei.py

Questions?