2006-12-06 03:48:46 +08:00
# -*- coding: utf-8 -*-
2006-08-27 21:59:47 +08:00
from django . conf import settings
if __name__ == ' __main__ ' :
# When running this file in isolation, we need to set up the configuration
# before importing 'template'.
settings . configure ( )
2007-07-23 12:45:01 +08:00
import os
import unittest
from datetime import datetime , timedelta
2006-08-27 21:59:47 +08:00
from django import template
2008-08-05 22:16:13 +08:00
from django . core import urlresolvers
2006-08-27 21:59:47 +08:00
from django . template import loader
2007-07-23 12:45:01 +08:00
from django . template . loaders import app_directories , filesystem
2007-10-22 01:14:25 +08:00
from django . utils . translation import activate , deactivate , ugettext as _
2007-11-14 20:58:53 +08:00
from django . utils . safestring import mark_safe
2006-08-27 21:59:47 +08:00
from django . utils . tzinfo import LocalTimezone
2007-07-23 12:45:01 +08:00
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
from unicode import unicode_tests
2007-12-03 07:57:22 +08:00
from context import context_tests
2008-05-29 21:11:23 +08:00
2008-06-26 12:25:40 +08:00
try :
from loaders import *
except ImportError :
pass # If setuptools isn't installed, that's fine. Just move on.
2008-05-29 21:11:23 +08:00
2007-11-14 20:58:53 +08:00
import filters
2006-08-27 21:59:47 +08:00
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
# Some other tests we would like to run
__test__ = {
2008-05-29 21:11:23 +08:00
' unicode ' : unicode_tests ,
' context ' : context_tests
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
}
2006-08-27 21:59:47 +08:00
#################################
# Custom template tag for tests #
#################################
register = template . Library ( )
class EchoNode ( template . Node ) :
def __init__ ( self , contents ) :
self . contents = contents
def render ( self , context ) :
return " " . join ( self . contents )
def do_echo ( parser , token ) :
return EchoNode ( token . contents . split ( ) [ 1 : ] )
register . tag ( " echo " , do_echo )
template . libraries [ ' django.templatetags.testtags ' ] = register
#####################################
# Helper objects for template tests #
#####################################
class SomeException ( Exception ) :
silent_variable_failure = True
class SomeOtherException ( Exception ) :
pass
class SomeClass :
def __init__ ( self ) :
self . otherclass = OtherClass ( )
def method ( self ) :
return " SomeClass.method "
def method2 ( self , o ) :
return o
def method3 ( self ) :
raise SomeException
def method4 ( self ) :
raise SomeOtherException
class OtherClass :
def method ( self ) :
return " OtherClass.method "
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
class UTF8Class :
" Class whose __str__ returns non-ASCII data "
2006-12-06 03:48:46 +08:00
def __str__ ( self ) :
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
return u ' ŠĐĆŽćžšđ ' . encode ( ' utf-8 ' )
2006-12-06 03:48:46 +08:00
2006-08-27 21:59:47 +08:00
class Templates ( unittest . TestCase ) :
2007-07-23 12:45:01 +08:00
def test_loaders_security ( self ) :
def test_template_sources ( path , template_dirs , expected_sources ) :
# Fix expected sources so they are normcased and abspathed
expected_sources = [ os . path . normcase ( os . path . abspath ( s ) ) for s in expected_sources ]
# Test app_directories loader
sources = app_directories . get_template_sources ( path , template_dirs )
self . assertEqual ( list ( sources ) , expected_sources )
# Test filesystem loader
sources = filesystem . get_template_sources ( path , template_dirs )
self . assertEqual ( list ( sources ) , expected_sources )
template_dirs = [ ' /dir1 ' , ' /dir2 ' ]
test_template_sources ( ' index.html ' , template_dirs ,
[ ' /dir1/index.html ' , ' /dir2/index.html ' ] )
test_template_sources ( ' /etc/passwd ' , template_dirs ,
[ ] )
test_template_sources ( ' etc/passwd ' , template_dirs ,
[ ' /dir1/etc/passwd ' , ' /dir2/etc/passwd ' ] )
test_template_sources ( ' ../etc/passwd ' , template_dirs ,
[ ] )
test_template_sources ( ' ../../../etc/passwd ' , template_dirs ,
[ ] )
test_template_sources ( ' /dir1/index.html ' , template_dirs ,
[ ' /dir1/index.html ' ] )
test_template_sources ( ' ../dir2/index.html ' , template_dirs ,
[ ' /dir2/index.html ' ] )
test_template_sources ( ' /dir1blah ' , template_dirs ,
[ ] )
test_template_sources ( ' ../dir1blah ' , template_dirs ,
[ ] )
# Case insensitive tests (for win32). Not run unless we're on
# a case insensitive operating system.
if os . path . normcase ( ' /TEST ' ) == os . path . normpath ( ' /test ' ) :
template_dirs = [ ' /dir1 ' , ' /DIR2 ' ]
test_template_sources ( ' index.html ' , template_dirs ,
[ ' /dir1/index.html ' , ' /dir2/index.html ' ] )
test_template_sources ( ' /DIR1/index.HTML ' , template_dirs ,
[ ' /dir1/index.html ' ] )
2006-08-27 21:59:47 +08:00
def test_templates ( self ) :
2007-11-14 20:58:53 +08:00
template_tests = self . get_template_tests ( )
filter_tests = filters . get_filter_tests ( )
2006-08-27 21:59:47 +08:00
2007-11-14 20:58:53 +08:00
# Quickly check that we aren't accidentally using a name in both
# template and filter tests.
2008-06-26 12:30:06 +08:00
overlapping_names = [ name for name in filter_tests if name in template_tests ]
2007-11-14 20:58:53 +08:00
assert not overlapping_names , ' Duplicate test name(s): %s ' % ' , ' . join ( overlapping_names )
template_tests . update ( filter_tests )
# Register our custom template loader.
def test_template_loader ( template_name , template_dirs = None ) :
" A custom template loader that loads the unit-test templates. "
try :
return ( template_tests [ template_name ] [ 0 ] , " test: %s " % template_name )
except KeyError :
raise template . TemplateDoesNotExist , template_name
old_template_loaders = loader . template_source_loaders
loader . template_source_loaders = [ test_template_loader ]
failures = [ ]
tests = template_tests . items ( )
tests . sort ( )
# Turn TEMPLATE_DEBUG off, because tests assume that.
old_td , settings . TEMPLATE_DEBUG = settings . TEMPLATE_DEBUG , False
2008-06-26 12:30:06 +08:00
# Set TEMPLATE_STRING_IF_INVALID to a known string.
2007-11-14 20:58:53 +08:00
old_invalid = settings . TEMPLATE_STRING_IF_INVALID
expected_invalid_str = ' INVALID '
for name , vals in tests :
if isinstance ( vals [ 2 ] , tuple ) :
normal_string_result = vals [ 2 ] [ 0 ]
invalid_string_result = vals [ 2 ] [ 1 ]
if ' %s ' in invalid_string_result :
expected_invalid_str = ' INVALID %s '
invalid_string_result = invalid_string_result % vals [ 2 ] [ 2 ]
template . invalid_var_format_string = True
else :
normal_string_result = vals [ 2 ]
invalid_string_result = vals [ 2 ]
if ' LANGUAGE_CODE ' in vals [ 1 ] :
activate ( vals [ 1 ] [ ' LANGUAGE_CODE ' ] )
else :
activate ( ' en-us ' )
for invalid_str , result in [ ( ' ' , normal_string_result ) ,
( expected_invalid_str , invalid_string_result ) ] :
settings . TEMPLATE_STRING_IF_INVALID = invalid_str
try :
test_template = loader . get_template ( name )
output = self . render ( test_template , vals )
except Exception , e :
if e . __class__ != result :
failures . append ( " Template test (TEMPLATE_STRING_IF_INVALID= ' %s ' ): %s -- FAILED. Got %s , exception: %s " % ( invalid_str , name , e . __class__ , e ) )
continue
if output != result :
failures . append ( " Template test (TEMPLATE_STRING_IF_INVALID= ' %s ' ): %s -- FAILED. Expected %r , got %r " % ( invalid_str , name , result , output ) )
if ' LANGUAGE_CODE ' in vals [ 1 ] :
deactivate ( )
if template . invalid_var_format_string :
expected_invalid_str = ' INVALID '
template . invalid_var_format_string = False
loader . template_source_loaders = old_template_loaders
deactivate ( )
settings . TEMPLATE_DEBUG = old_td
settings . TEMPLATE_STRING_IF_INVALID = old_invalid
self . assertEqual ( failures , [ ] , ' \n ' . join ( failures ) )
def render ( self , test_template , vals ) :
return test_template . render ( template . Context ( vals [ 1 ] ) )
def get_template_tests ( self ) :
2006-08-27 21:59:47 +08:00
# SYNTAX --
# 'template_name': ('template contents', 'context dict', 'expected string output' or Exception class)
2007-11-14 20:58:53 +08:00
return {
### BASIC SYNTAX ################################################
2006-08-27 21:59:47 +08:00
# Plain text should go through the template parser untouched
' basic-syntax01 ' : ( " something cool " , { } , " something cool " ) ,
2007-11-14 20:58:53 +08:00
# Variables should be replaced with their value in the current
# context
2006-08-27 21:59:47 +08:00
' basic-syntax02 ' : ( " {{ headline }} " , { ' headline ' : ' Success ' } , " Success " ) ,
# More than one replacement variable is allowed in a template
' basic-syntax03 ' : ( " {{ first }} --- {{ second }} " , { " first " : 1 , " second " : 2 } , " 1 --- 2 " ) ,
# Fail silently when a variable is not found in the current context
2006-09-04 22:02:11 +08:00
' basic-syntax04 ' : ( " as {{ missing }}df " , { } , ( " asdf " , " asINVALIDdf " ) ) ,
2006-08-27 21:59:47 +08:00
# A variable may not contain more than one word
' basic-syntax06 ' : ( " {{ multi word variable }} " , { } , template . TemplateSyntaxError ) ,
# Raise TemplateSyntaxError for empty variable tags
' basic-syntax07 ' : ( " {{ }} " , { } , template . TemplateSyntaxError ) ,
' basic-syntax08 ' : ( " {{ }} " , { } , template . TemplateSyntaxError ) ,
# Attribute syntax allows a template to call an object's attribute
' basic-syntax09 ' : ( " {{ var.method }} " , { " var " : SomeClass ( ) } , " SomeClass.method " ) ,
# Multiple levels of attribute access are allowed
' basic-syntax10 ' : ( " {{ var.otherclass.method }} " , { " var " : SomeClass ( ) } , " OtherClass.method " ) ,
# Fail silently when a variable's attribute isn't found
2006-09-04 22:02:11 +08:00
' basic-syntax11 ' : ( " {{ var.blech }} " , { " var " : SomeClass ( ) } , ( " " , " INVALID " ) ) ,
2006-08-27 21:59:47 +08:00
# Raise TemplateSyntaxError when trying to access a variable beginning with an underscore
' basic-syntax12 ' : ( " {{ var.__dict__ }} " , { " var " : SomeClass ( ) } , template . TemplateSyntaxError ) ,
# Raise TemplateSyntaxError when trying to access a variable containing an illegal character
' basic-syntax13 ' : ( " {{ va>r }} " , { } , template . TemplateSyntaxError ) ,
' basic-syntax14 ' : ( " {{ (var.r) }} " , { } , template . TemplateSyntaxError ) ,
' basic-syntax15 ' : ( " {{ sp %a m }} " , { } , template . TemplateSyntaxError ) ,
' basic-syntax16 ' : ( " {{ eggs! }} " , { } , template . TemplateSyntaxError ) ,
' basic-syntax17 ' : ( " {{ moo? }} " , { } , template . TemplateSyntaxError ) ,
# Attribute syntax allows a template to call a dictionary key's value
' basic-syntax18 ' : ( " {{ foo.bar }} " , { " foo " : { " bar " : " baz " } } , " baz " ) ,
# Fail silently when a variable's dictionary key isn't found
2006-09-04 22:02:11 +08:00
' basic-syntax19 ' : ( " {{ foo.spam }} " , { " foo " : { " bar " : " baz " } } , ( " " , " INVALID " ) ) ,
2006-08-27 21:59:47 +08:00
# Fail silently when accessing a non-simple method
2006-09-04 22:02:11 +08:00
' basic-syntax20 ' : ( " {{ var.method2 }} " , { " var " : SomeClass ( ) } , ( " " , " INVALID " ) ) ,
2006-08-27 21:59:47 +08:00
2007-04-27 20:16:22 +08:00
# Don't get confused when parsing something that is almost, but not
# quite, a template tag.
' basic-syntax21 ' : ( " a {{ moo % } b " , { } , " a {{ moo % } b " ) ,
' basic-syntax22 ' : ( " {{ moo #} " , { } , " {{ moo #} " ) ,
# Will try to treat "moo #} {{ cow" as the variable. Not ideal, but
# costly to work around, so this triggers an error.
' basic-syntax23 ' : ( " {{ moo #} {{ cow }} " , { " cow " : " cow " } , template . TemplateSyntaxError ) ,
# Embedded newlines make it not-a-tag.
' basic-syntax24 ' : ( " {{ moo \n }} " , { } , " {{ moo \n }} " ) ,
2007-11-29 05:04:05 +08:00
# Literal strings are permitted inside variables, mostly for i18n
# purposes.
' basic-syntax25 ' : ( ' {{ " fred " }} ' , { } , " fred " ) ,
' basic-syntax26 ' : ( r ' {{ " \ " fred \ " " }} ' , { } , " \" fred \" " ) ,
' basic-syntax27 ' : ( r ' {{ _( " \ " fred \ " " ) }} ' , { } , " \" fred \" " ) ,
2007-02-28 04:25:27 +08:00
# List-index syntax allows a template to access a certain item of a subscriptable object.
' list-index01 ' : ( " {{ var.1 }} " , { " var " : [ " first item " , " second item " ] } , " second item " ) ,
# Fail silently when the list index is out of range.
' list-index02 ' : ( " {{ var.5 }} " , { " var " : [ " first item " , " second item " ] } , ( " " , " INVALID " ) ) ,
# Fail silently when the variable is not a subscriptable object.
' list-index03 ' : ( " {{ var.1 }} " , { " var " : None } , ( " " , " INVALID " ) ) ,
# Fail silently when variable is a dict without the specified key.
' list-index04 ' : ( " {{ var.1 }} " , { " var " : { } } , ( " " , " INVALID " ) ) ,
# Dictionary lookup wins out when dict's key is a string.
' list-index05 ' : ( " {{ var.1 }} " , { " var " : { ' 1 ' : " hello " } } , " hello " ) ,
# But list-index lookup wins out when dict's key is an int, which
# behind the scenes is really a dictionary lookup (for a dict)
# after converting the key to an int.
' list-index06 ' : ( " {{ var.1 }} " , { " var " : { 1 : " hello " } } , " hello " ) ,
# Dictionary lookup wins out when there is a string and int version of the key.
' list-index07 ' : ( " {{ var.1 }} " , { " var " : { ' 1 ' : " hello " , 1 : " world " } } , " hello " ) ,
2007-03-30 09:50:06 +08:00
2006-08-27 21:59:47 +08:00
# Basic filter usage
2007-04-27 19:01:45 +08:00
' filter-syntax01 ' : ( " {{ var|upper }} " , { " var " : " Django is the greatest! " } , " DJANGO IS THE GREATEST! " ) ,
2006-08-27 21:59:47 +08:00
# Chained filters
2007-04-27 19:01:45 +08:00
' filter-syntax02 ' : ( " {{ var|upper|lower }} " , { " var " : " Django is the greatest! " } , " django is the greatest! " ) ,
2006-08-27 21:59:47 +08:00
# Raise TemplateSyntaxError for space between a variable and filter pipe
2007-04-27 19:01:45 +08:00
' filter-syntax03 ' : ( " {{ var |upper }} " , { } , template . TemplateSyntaxError ) ,
2006-08-27 21:59:47 +08:00
# Raise TemplateSyntaxError for space after a filter pipe
2007-04-27 19:01:45 +08:00
' filter-syntax04 ' : ( " {{ var| upper }} " , { } , template . TemplateSyntaxError ) ,
2006-08-27 21:59:47 +08:00
# Raise TemplateSyntaxError for a nonexistent filter
2007-04-27 19:01:45 +08:00
' filter-syntax05 ' : ( " {{ var|does_not_exist }} " , { } , template . TemplateSyntaxError ) ,
2006-08-27 21:59:47 +08:00
# Raise TemplateSyntaxError when trying to access a filter containing an illegal character
2007-04-27 19:01:45 +08:00
' filter-syntax06 ' : ( " {{ var|fil(ter) }} " , { } , template . TemplateSyntaxError ) ,
2006-08-27 21:59:47 +08:00
# Raise TemplateSyntaxError for invalid block tags
2007-04-27 19:01:45 +08:00
' filter-syntax07 ' : ( " { % nothing_to_see_here % } " , { } , template . TemplateSyntaxError ) ,
2006-08-27 21:59:47 +08:00
# Raise TemplateSyntaxError for empty block tags
2007-04-27 19:01:45 +08:00
' filter-syntax08 ' : ( " { % % } " , { } , template . TemplateSyntaxError ) ,
2006-08-27 21:59:47 +08:00
# Chained filters, with an argument to the first one
2007-04-27 19:01:45 +08:00
' filter-syntax09 ' : ( ' {{ var|removetags: " b i " |upper|lower }} ' , { " var " : " <b><i>Yes</i></b> " } , " yes " ) ,
2006-08-27 21:59:47 +08:00
2007-11-17 20:11:26 +08:00
# Literal string as argument is always "safe" from auto-escaping..
2007-11-14 20:58:53 +08:00
' filter-syntax10 ' : ( r ' {{ var|default_if_none: " endquote \ " hah " }} ' ,
2007-11-17 20:11:26 +08:00
{ " var " : None } , ' endquote " hah ' ) ,
2006-08-27 21:59:47 +08:00
# Variable as argument
2007-04-27 19:01:45 +08:00
' filter-syntax11 ' : ( r ' {{ var|default_if_none:var2 }} ' , { " var " : None , " var2 " : " happy " } , ' happy ' ) ,
2006-08-27 21:59:47 +08:00
# Default argument testing
2007-04-27 19:01:45 +08:00
' filter-syntax12 ' : ( r ' {{ var|yesno: " yup,nup,mup " }} {{ var|yesno }} ' , { " var " : True } , ' yup yes ' ) ,
2006-08-27 21:59:47 +08:00
2007-04-27 19:01:45 +08:00
# Fail silently for methods that raise an exception with a
# "silent_variable_failure" attribute
' filter-syntax13 ' : ( r ' 1 {{ var.method3 }}2 ' , { " var " : SomeClass ( ) } , ( " 12 " , " 1INVALID2 " ) ) ,
2006-08-27 21:59:47 +08:00
2007-04-27 19:01:45 +08:00
# In methods that raise an exception without a
# "silent_variable_attribute" set to True, the exception propagates
' filter-syntax14 ' : ( r ' 1 {{ var.method4 }}2 ' , { " var " : SomeClass ( ) } , SomeOtherException ) ,
2006-08-27 21:59:47 +08:00
# Escaped backslash in argument
2007-04-27 19:01:45 +08:00
' filter-syntax15 ' : ( r ' {{ var|default_if_none: " foo \ bar " }} ' , { " var " : None } , r ' foo \ bar ' ) ,
2006-08-27 21:59:47 +08:00
# Escaped backslash using known escape char
2007-04-27 19:01:45 +08:00
' filter-syntax16 ' : ( r ' {{ var|default_if_none: " foo \ now " }} ' , { " var " : None } , r ' foo \ now ' ) ,
2006-08-27 21:59:47 +08:00
2006-09-26 15:26:07 +08:00
# Empty strings can be passed as arguments to filters
2007-04-27 19:01:45 +08:00
' filter-syntax17 ' : ( r ' {{ var|join: " " }} ' , { ' var ' : [ ' a ' , ' b ' , ' c ' ] } , ' abc ' ) ,
2006-09-26 15:26:07 +08:00
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 20:11:04 +08:00
# Make sure that any unicode strings are converted to bytestrings
# in the final output.
' filter-syntax18 ' : ( r ' {{ var }} ' , { ' var ' : UTF8Class ( ) } , u ' \u0160 \u0110 \u0106 \u017d \u0107 \u017e \u0161 \u0111 ' ) ,
2006-12-06 03:48:46 +08:00
2007-06-28 02:58:10 +08:00
# Numbers as filter arguments should work
' filter-syntax19 ' : ( ' {{ var|truncatewords:1 }} ' , { " var " : " hello world " } , " hello ... " ) ,
2008-08-16 05:08:11 +08:00
#filters should accept empty string constants
' filter-syntax20 ' : ( ' {{ " " |default_if_none: " was none " }} ' , { } , " " ) ,
2007-06-28 02:58:10 +08:00
2006-10-25 05:30:38 +08:00
### COMMENT SYNTAX ########################################################
' comment-syntax01 ' : ( " { # this is hidden #}hello " , { } , " hello " ) ,
' comment-syntax02 ' : ( " { # this is hidden #}hello { # foo #} " , { } , " hello " ) ,
# Comments can contain invalid stuff.
' comment-syntax03 ' : ( " foo { # { % i f % } #} " , { } , " foo " ) ,
' comment-syntax04 ' : ( " foo { # { % e ndblock % } #} " , { } , " foo " ) ,
' comment-syntax05 ' : ( " foo { # { % s omerandomtag % } #} " , { } , " foo " ) ,
' comment-syntax06 ' : ( " foo { # { % #} " , { } , " foo " ) ,
' comment-syntax07 ' : ( " foo { # % } #} " , { } , " foo " ) ,
' comment-syntax08 ' : ( " foo { # % } #}bar " , { } , " foobar " ) ,
' comment-syntax09 ' : ( " foo { # {{ #} " , { } , " foo " ) ,
' comment-syntax10 ' : ( " foo { # }} #} " , { } , " foo " ) ,
' comment-syntax11 ' : ( " foo { # { #} " , { } , " foo " ) ,
' comment-syntax12 ' : ( " foo { # } #} " , { } , " foo " ) ,
2006-08-27 21:59:47 +08:00
### COMMENT TAG ###########################################################
' comment-tag01 ' : ( " { % c omment % }this is hidden { % e ndcomment % }hello " , { } , " hello " ) ,
' comment-tag02 ' : ( " { % c omment % }this is hidden { % e ndcomment % }hello { % c omment % }foo { % e ndcomment % } " , { } , " hello " ) ,
# Comment tag can contain invalid stuff.
' comment-tag03 ' : ( " foo { % c omment % } { % i f % } { % e ndcomment % } " , { } , " foo " ) ,
' comment-tag04 ' : ( " foo { % c omment % } { % e ndblock % } { % e ndcomment % } " , { } , " foo " ) ,
' comment-tag05 ' : ( " foo { % c omment % } { % s omerandomtag % } { % e ndcomment % } " , { } , " foo " ) ,
### CYCLE TAG #############################################################
' cycle01 ' : ( ' { % c ycle a % } ' , { } , template . TemplateSyntaxError ) ,
' cycle02 ' : ( ' { % c ycle a,b,c as abc % } { % c ycle abc % } ' , { } , ' ab ' ) ,
' cycle03 ' : ( ' { % c ycle a,b,c as abc % } { % c ycle abc % } { % c ycle abc % } ' , { } , ' abc ' ) ,
' cycle04 ' : ( ' { % c ycle a,b,c as abc % } { % c ycle abc % } { % c ycle abc % } { % c ycle abc % } ' , { } , ' abca ' ) ,
' cycle05 ' : ( ' { % c ycle % } ' , { } , template . TemplateSyntaxError ) ,
' cycle06 ' : ( ' { % c ycle a % } ' , { } , template . TemplateSyntaxError ) ,
' cycle07 ' : ( ' { % c ycle a,b,c as foo % } { % c ycle bar % } ' , { } , template . TemplateSyntaxError ) ,
2006-09-21 21:09:00 +08:00
' cycle08 ' : ( ' { % c ycle a,b,c as foo % } { % c ycle foo % } {{ foo }} {{ foo }} { % c ycle foo % } {{ foo }} ' , { } , ' abbbcc ' ) ,
2007-09-14 10:49:21 +08:00
' cycle09 ' : ( " { % f or i in test % } { % c ycle a,b % } {{ i }}, { % e ndfor % } " , { ' test ' : range ( 5 ) } , ' a0,b1,a2,b3,a4, ' ) ,
# New format:
' cycle10 ' : ( " { % c ycle ' a ' ' b ' ' c ' as abc % } { % c ycle abc % } " , { } , ' ab ' ) ,
' cycle11 ' : ( " { % c ycle ' a ' ' b ' ' c ' as abc % } { % c ycle abc % } { % c ycle abc % } " , { } , ' abc ' ) ,
' cycle12 ' : ( " { % c ycle ' a ' ' b ' ' c ' as abc % } { % c ycle abc % } { % c ycle abc % } { % c ycle abc % } " , { } , ' abca ' ) ,
' cycle13 ' : ( " { % f or i in test % } { % c ycle ' a ' ' b ' % } {{ i }}, { % e ndfor % } " , { ' test ' : range ( 5 ) } , ' a0,b1,a2,b3,a4, ' ) ,
' cycle14 ' : ( " { % c ycle one two as foo % } { % c ycle foo % } " , { ' one ' : ' 1 ' , ' two ' : ' 2 ' } , ' 12 ' ) ,
' cycle13 ' : ( " { % f or i in test % } { % c ycle aye bee % } {{ i }}, { % e ndfor % } " , { ' test ' : range ( 5 ) , ' aye ' : ' a ' , ' bee ' : ' b ' } , ' a0,b1,a2,b3,a4, ' ) ,
2006-08-27 21:59:47 +08:00
### EXCEPTIONS ############################################################
# Raise exception for invalid template name
' exception01 ' : ( " { % e xtends ' nonexistent ' % } " , { } , template . TemplateSyntaxError ) ,
# Raise exception for invalid template name (in variable)
' exception02 ' : ( " { % e xtends nonexistent % } " , { } , template . TemplateSyntaxError ) ,
# Raise exception for extra {% extends %} tags
' exception03 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % }2 { % e ndblock % } { % e xtends ' inheritance16 ' % } " , { } , template . TemplateSyntaxError ) ,
# Raise exception for custom tags used in child with {% load %} tag in parent, not in child
' exception04 ' : ( " { % e xtends ' inheritance17 ' % } { % block first % } { % e cho 400 % }5678 { % e ndblock % } " , { } , template . TemplateSyntaxError ) ,
### FILTER TAG ############################################################
' filter01 ' : ( ' { % f ilter upper % } { % e ndfilter % } ' , { } , ' ' ) ,
' filter02 ' : ( ' { % f ilter upper % }django { % e ndfilter % } ' , { } , ' DJANGO ' ) ,
' filter03 ' : ( ' { % f ilter upper|lower % }django { % e ndfilter % } ' , { } , ' django ' ) ,
2007-04-21 12:44:30 +08:00
' filter04 ' : ( ' { % f ilter cut:remove % }djangospam { % e ndfilter % } ' , { ' remove ' : ' spam ' } , ' django ' ) ,
2006-08-27 21:59:47 +08:00
### FIRSTOF TAG ###########################################################
' firstof01 ' : ( ' { % f irstof a b c % } ' , { ' a ' : 0 , ' b ' : 0 , ' c ' : 0 } , ' ' ) ,
' firstof02 ' : ( ' { % f irstof a b c % } ' , { ' a ' : 1 , ' b ' : 0 , ' c ' : 0 } , ' 1 ' ) ,
' firstof03 ' : ( ' { % f irstof a b c % } ' , { ' a ' : 0 , ' b ' : 2 , ' c ' : 0 } , ' 2 ' ) ,
' firstof04 ' : ( ' { % f irstof a b c % } ' , { ' a ' : 0 , ' b ' : 0 , ' c ' : 3 } , ' 3 ' ) ,
' firstof05 ' : ( ' { % f irstof a b c % } ' , { ' a ' : 1 , ' b ' : 2 , ' c ' : 3 } , ' 1 ' ) ,
2007-10-20 23:01:31 +08:00
' firstof06 ' : ( ' { % f irstof a b c % } ' , { ' b ' : 0 , ' c ' : 3 } , ' 3 ' ) ,
' firstof07 ' : ( ' { % f irstof a b " c " % } ' , { ' a ' : 0 } , ' c ' ) ,
' firstof08 ' : ( ' { % f irstof a b " c and d " % } ' , { ' a ' : 0 , ' b ' : 0 } , ' c and d ' ) ,
' firstof09 ' : ( ' { % f irstof % } ' , { } , template . TemplateSyntaxError ) ,
2006-08-27 21:59:47 +08:00
### FOR TAG ###############################################################
' for-tag01 ' : ( " { % f or val in values % } {{ val }} { % e ndfor % } " , { " values " : [ 1 , 2 , 3 ] } , " 123 " ) ,
' for-tag02 ' : ( " { % f or val in values reversed % } {{ val }} { % e ndfor % } " , { " values " : [ 1 , 2 , 3 ] } , " 321 " ) ,
' for-tag-vars01 ' : ( " { % f or val in values % } {{ forloop.counter }} { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " 123 " ) ,
' for-tag-vars02 ' : ( " { % f or val in values % } {{ forloop.counter0 }} { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " 012 " ) ,
' for-tag-vars03 ' : ( " { % f or val in values % } {{ forloop.revcounter }} { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " 321 " ) ,
' for-tag-vars04 ' : ( " { % f or val in values % } {{ forloop.revcounter0 }} { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " 210 " ) ,
2008-01-02 13:01:03 +08:00
' for-tag-vars05 ' : ( " { % f or val in values % } { % i f forloop.first % }f { % e lse % }x { % e ndif % } { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " fxx " ) ,
' for-tag-vars06 ' : ( " { % f or val in values % } { % i f forloop.last % }l { % e lse % }x { % e ndif % } { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " xxl " ) ,
2007-06-08 19:58:03 +08:00
' for-tag-unpack01 ' : ( " { % f or key,value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , " one:1/two:2/ " ) ,
' for-tag-unpack03 ' : ( " { % f or key, value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , " one:1/two:2/ " ) ,
' for-tag-unpack04 ' : ( " { % f or key , value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , " one:1/two:2/ " ) ,
' for-tag-unpack05 ' : ( " { % f or key ,value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , " one:1/two:2/ " ) ,
' for-tag-unpack06 ' : ( " { % f or key value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , template . TemplateSyntaxError ) ,
' for-tag-unpack07 ' : ( " { % f or key,,value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , template . TemplateSyntaxError ) ,
' for-tag-unpack08 ' : ( " { % f or key,value, in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , template . TemplateSyntaxError ) ,
# Ensure that a single loopvar doesn't truncate the list in val.
' for-tag-unpack09 ' : ( " { % f or val in items % } {{ val.0 }}: {{ val.1 }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , " one:1/two:2/ " ) ,
# Otherwise, silently truncate if the length of loopvars differs to the length of each set of items.
' for-tag-unpack10 ' : ( " { % f or x,y in items % } {{ x }}: {{ y }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 , ' carrot ' ) , ( ' two ' , 2 , ' orange ' ) ) } , " one:1/two:2/ " ) ,
' for-tag-unpack11 ' : ( " { % f or x,y,z in items % } {{ x }}: {{ y }}, {{ z }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , ( " one:1,/two:2,/ " , " one:1,INVALID/two:2,INVALID/ " ) ) ,
' for-tag-unpack12 ' : ( " { % f or x,y,z in items % } {{ x }}: {{ y }}, {{ z }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 , ' carrot ' ) , ( ' two ' , 2 ) ) } , ( " one:1,carrot/two:2,/ " , " one:1,carrot/two:2,INVALID/ " ) ) ,
' for-tag-unpack13 ' : ( " { % f or x,y,z in items % } {{ x }}: {{ y }}, {{ z }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 , ' carrot ' ) , ( ' two ' , 2 , ' cheese ' ) ) } , ( " one:1,carrot/two:2,cheese/ " , " one:1,carrot/two:2,cheese/ " ) ) ,
2006-08-27 21:59:47 +08:00
### IF TAG ################################################################
' if-tag01 ' : ( " { % i f foo % }yes { % e lse % }no { % e ndif % } " , { " foo " : True } , " yes " ) ,
' if-tag02 ' : ( " { % i f foo % }yes { % e lse % }no { % e ndif % } " , { " foo " : False } , " no " ) ,
' if-tag03 ' : ( " { % i f foo % }yes { % e lse % }no { % e ndif % } " , { } , " no " ) ,
# AND
' if-tag-and01 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' yes ' ) ,
' if-tag-and02 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' no ' ) ,
' if-tag-and03 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' no ' ) ,
' if-tag-and04 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' no ' ) ,
' if-tag-and05 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False } , ' no ' ) ,
' if-tag-and06 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' bar ' : False } , ' no ' ) ,
' if-tag-and07 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , ' no ' ) ,
' if-tag-and08 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' bar ' : True } , ' no ' ) ,
# OR
' if-tag-or01 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' yes ' ) ,
' if-tag-or02 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' yes ' ) ,
' if-tag-or03 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' yes ' ) ,
' if-tag-or04 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' no ' ) ,
' if-tag-or05 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False } , ' no ' ) ,
' if-tag-or06 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' bar ' : False } , ' no ' ) ,
' if-tag-or07 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , ' yes ' ) ,
' if-tag-or08 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' bar ' : True } , ' yes ' ) ,
# TODO: multiple ORs
# NOT
' if-tag-not01 ' : ( " { % i f not foo % }no { % e lse % }yes { % e ndif % } " , { ' foo ' : True } , ' yes ' ) ,
' if-tag-not02 ' : ( " { % i f not % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , ' no ' ) ,
' if-tag-not03 ' : ( " { % i f not % }yes { % e lse % }no { % e ndif % } " , { ' not ' : True } , ' yes ' ) ,
' if-tag-not04 ' : ( " { % i f not not % }no { % e lse % }yes { % e ndif % } " , { ' not ' : True } , ' yes ' ) ,
' if-tag-not05 ' : ( " { % i f not not % }no { % e lse % }yes { % e ndif % } " , { } , ' no ' ) ,
' if-tag-not06 ' : ( " { % i f foo and not bar % }yes { % e lse % }no { % e ndif % } " , { } , ' no ' ) ,
' if-tag-not07 ' : ( " { % i f foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' no ' ) ,
' if-tag-not08 ' : ( " { % i f foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' yes ' ) ,
' if-tag-not09 ' : ( " { % i f foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' no ' ) ,
' if-tag-not10 ' : ( " { % i f foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' no ' ) ,
' if-tag-not11 ' : ( " { % i f not foo and bar % }yes { % e lse % }no { % e ndif % } " , { } , ' no ' ) ,
' if-tag-not12 ' : ( " { % i f not foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' no ' ) ,
' if-tag-not13 ' : ( " { % i f not foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' no ' ) ,
' if-tag-not14 ' : ( " { % i f not foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' yes ' ) ,
' if-tag-not15 ' : ( " { % i f not foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' no ' ) ,
' if-tag-not16 ' : ( " { % i f foo or not bar % }yes { % e lse % }no { % e ndif % } " , { } , ' yes ' ) ,
' if-tag-not17 ' : ( " { % i f foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' yes ' ) ,
' if-tag-not18 ' : ( " { % i f foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' yes ' ) ,
' if-tag-not19 ' : ( " { % i f foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' no ' ) ,
' if-tag-not20 ' : ( " { % i f foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' yes ' ) ,
' if-tag-not21 ' : ( " { % i f not foo or bar % }yes { % e lse % }no { % e ndif % } " , { } , ' yes ' ) ,
' if-tag-not22 ' : ( " { % i f not foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' yes ' ) ,
' if-tag-not23 ' : ( " { % i f not foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' no ' ) ,
' if-tag-not24 ' : ( " { % i f not foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' yes ' ) ,
' if-tag-not25 ' : ( " { % i f not foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' yes ' ) ,
' if-tag-not26 ' : ( " { % i f not foo and not bar % }yes { % e lse % }no { % e ndif % } " , { } , ' yes ' ) ,
' if-tag-not27 ' : ( " { % i f not foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' no ' ) ,
' if-tag-not28 ' : ( " { % i f not foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' no ' ) ,
' if-tag-not29 ' : ( " { % i f not foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' no ' ) ,
' if-tag-not30 ' : ( " { % i f not foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' yes ' ) ,
' if-tag-not31 ' : ( " { % i f not foo or not bar % }yes { % e lse % }no { % e ndif % } " , { } , ' yes ' ) ,
' if-tag-not32 ' : ( " { % i f not foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' no ' ) ,
' if-tag-not33 ' : ( " { % i f not foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' yes ' ) ,
' if-tag-not34 ' : ( " { % i f not foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' yes ' ) ,
' if-tag-not35 ' : ( " { % i f not foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' yes ' ) ,
# AND and OR raises a TemplateSyntaxError
' if-tag-error01 ' : ( " { % i f foo or bar and baz % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , template . TemplateSyntaxError ) ,
' if-tag-error02 ' : ( " { % i f foo and % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , template . TemplateSyntaxError ) ,
' if-tag-error03 ' : ( " { % i f foo or % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , template . TemplateSyntaxError ) ,
' if-tag-error04 ' : ( " { % i f not foo and % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , template . TemplateSyntaxError ) ,
' if-tag-error05 ' : ( " { % i f not foo or % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , template . TemplateSyntaxError ) ,
### IFCHANGED TAG #########################################################
2008-06-26 12:25:40 +08:00
' ifchanged01 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % e ndfor % } ' , { ' num ' : ( 1 , 2 , 3 ) } , ' 123 ' ) ,
' ifchanged02 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 3 ) } , ' 13 ' ) ,
' ifchanged03 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 1 ) } , ' 1 ' ) ,
' ifchanged04 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % f or x in numx % } { % i fchanged % } {{ x }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 2 , 3 ) , ' numx ' : ( 2 , 2 , 2 ) } , ' 122232 ' ) ,
' ifchanged05 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % f or x in numx % } { % i fchanged % } {{ x }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 1 ) , ' numx ' : ( 1 , 2 , 3 ) } , ' 1123123123 ' ) ,
' ifchanged06 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % f or x in numx % } { % i fchanged % } {{ x }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 1 ) , ' numx ' : ( 2 , 2 , 2 ) } , ' 1222 ' ) ,
' ifchanged07 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % f or x in numx % } { % i fchanged % } {{ x }} { % e ndifchanged % } { % f or y in numy % } { % i fchanged % } {{ y }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 1 ) , ' numx ' : ( 2 , 2 , 2 ) , ' numy ' : ( 3 , 3 , 3 ) } , ' 1233323332333 ' ) ,
2008-06-26 12:30:06 +08:00
' ifchanged08 ' : ( ' { % f or data in datalist % } { % f or c,d in data % } { % i f c % } { % i fchanged % } {{ d }} { % e ndifchanged % } { % e ndif % } { % e ndfor % } { % e ndfor % } ' , { ' datalist ' : [ [ ( 1 , ' a ' ) , ( 1 , ' a ' ) , ( 0 , ' b ' ) , ( 1 , ' c ' ) ] , [ ( 0 , ' a ' ) , ( 1 , ' c ' ) , ( 1 , ' d ' ) , ( 1 , ' d ' ) , ( 0 , ' e ' ) ] ] } , ' accd ' ) ,
2006-12-06 03:48:46 +08:00
2006-11-07 13:36:51 +08:00
# Test one parameter given to ifchanged.
' ifchanged-param01 ' : ( ' { % f or n in num % } { % i fchanged n % }.. { % e ndifchanged % } {{ n }} { % e ndfor % } ' , { ' num ' : ( 1 , 2 , 3 ) } , ' ..1..2..3 ' ) ,
' ifchanged-param02 ' : ( ' { % f or n in num % } { % f or x in numx % } { % i fchanged n % }.. { % e ndifchanged % } {{ x }} { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 2 , 3 ) , ' numx ' : ( 5 , 6 , 7 ) } , ' ..567..567..567 ' ) ,
2006-12-06 03:48:46 +08:00
2006-11-07 13:36:51 +08:00
# Test multiple parameters to ifchanged.
' ifchanged-param03 ' : ( ' { % f or n in num % } {{ n }} { % f or x in numx % } { % i fchanged x n % } {{ x }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 2 ) , ' numx ' : ( 5 , 6 , 6 ) } , ' 156156256 ' ) ,
2006-12-06 03:48:46 +08:00
2006-11-07 13:36:51 +08:00
# Test a date+hour like construct, where the hour of the last day
# is the same but the date had changed, so print the hour anyway.
' ifchanged-param04 ' : ( ' { % f or d in days % } { % i fchanged % } {{ d.day }} { % e ndifchanged % } { % f or h in d.hours % } { % i fchanged d h % } {{ h }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' days ' : [ { ' day ' : 1 , ' hours ' : [ 1 , 2 , 3 ] } , { ' day ' : 2 , ' hours ' : [ 3 ] } , ] } , ' 112323 ' ) ,
2006-12-06 03:48:46 +08:00
2006-11-07 13:36:51 +08:00
# Logically the same as above, just written with explicit
# ifchanged for the day.
' ifchanged-param04 ' : ( ' { % f or d in days % } { % i fchanged d.day % } {{ d.day }} { % e ndifchanged % } { % f or h in d.hours % } { % i fchanged d.day h % } {{ h }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' days ' : [ { ' day ' : 1 , ' hours ' : [ 1 , 2 , 3 ] } , { ' day ' : 2 , ' hours ' : [ 3 ] } , ] } , ' 112323 ' ) ,
2006-08-27 21:59:47 +08:00
2008-07-27 06:09:43 +08:00
# Test the else clause of ifchanged.
' ifchanged-else01 ' : ( ' { % f or id in ids % } {{ id }} { % i fchanged id % }-first { % e lse % }-other { % e ndifchanged % }, { % e ndfor % } ' , { ' ids ' : [ 1 , 1 , 2 , 2 , 2 , 3 ] } , ' 1-first,1-other,2-first,2-other,2-other,3-first, ' ) ,
' ifchanged-else02 ' : ( ' { % f or id in ids % } {{ id }}- { % i fchanged id % } { % c ycle red,blue % } { % e lse % }grey { % e ndifchanged % }, { % e ndfor % } ' , { ' ids ' : [ 1 , 1 , 2 , 2 , 2 , 3 ] } , ' 1-red,1-grey,2-blue,2-grey,2-grey,3-red, ' ) ,
' ifchanged-else03 ' : ( ' { % f or id in ids % } {{ id }} { % i fchanged id % }- { % c ycle red,blue % } { % e lse % } { % e ndifchanged % }, { % e ndfor % } ' , { ' ids ' : [ 1 , 1 , 2 , 2 , 2 , 3 ] } , ' 1-red,1,2-blue,2,2,3-red, ' ) ,
' ifchanged-else04 ' : ( ' { % f or id in ids % } { % i fchanged % }*** {{ id }}* { % e lse % }... { % e ndifchanged % } {{ forloop.counter }} { % e ndfor % } ' , { ' ids ' : [ 1 , 1 , 2 , 2 , 2 , 3 , 4 ] } , ' ***1*1...2***2*3...4...5***3*6***4*7 ' ) ,
2006-08-27 21:59:47 +08:00
### IFEQUAL TAG ###########################################################
' ifequal01 ' : ( " { % i fequal a b % }yes { % e ndifequal % } " , { " a " : 1 , " b " : 2 } , " " ) ,
' ifequal02 ' : ( " { % i fequal a b % }yes { % e ndifequal % } " , { " a " : 1 , " b " : 1 } , " yes " ) ,
' ifequal03 ' : ( " { % i fequal a b % }yes { % e lse % }no { % e ndifequal % } " , { " a " : 1 , " b " : 2 } , " no " ) ,
' ifequal04 ' : ( " { % i fequal a b % }yes { % e lse % }no { % e ndifequal % } " , { " a " : 1 , " b " : 1 } , " yes " ) ,
' ifequal05 ' : ( " { % i fequal a ' test ' % }yes { % e lse % }no { % e ndifequal % } " , { " a " : " test " } , " yes " ) ,
' ifequal06 ' : ( " { % i fequal a ' test ' % }yes { % e lse % }no { % e ndifequal % } " , { " a " : " no " } , " no " ) ,
' ifequal07 ' : ( ' { % i fequal a " test " % }yes { % e lse % }no { % e ndifequal % } ' , { " a " : " test " } , " yes " ) ,
' ifequal08 ' : ( ' { % i fequal a " test " % }yes { % e lse % }no { % e ndifequal % } ' , { " a " : " no " } , " no " ) ,
' ifequal09 ' : ( ' { % i fequal a " test " % }yes { % e lse % }no { % e ndifequal % } ' , { } , " no " ) ,
' ifequal10 ' : ( ' { % i fequal a b % }yes { % e lse % }no { % e ndifequal % } ' , { } , " yes " ) ,
# SMART SPLITTING
' ifequal-split01 ' : ( ' { % i fequal a " test man " % }yes { % e lse % }no { % e ndifequal % } ' , { } , " no " ) ,
' ifequal-split02 ' : ( ' { % i fequal a " test man " % }yes { % e lse % }no { % e ndifequal % } ' , { ' a ' : ' foo ' } , " no " ) ,
' ifequal-split03 ' : ( ' { % i fequal a " test man " % }yes { % e lse % }no { % e ndifequal % } ' , { ' a ' : ' test man ' } , " yes " ) ,
' ifequal-split04 ' : ( " { % i fequal a ' test man ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : ' test man ' } , " yes " ) ,
' ifequal-split05 ' : ( " { % i fequal a ' i \" love \" you ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : ' ' } , " no " ) ,
' ifequal-split06 ' : ( " { % i fequal a ' i \" love \" you ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : ' i " love " you ' } , " yes " ) ,
' ifequal-split07 ' : ( " { % i fequal a ' i \" love \" you ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : ' i love you ' } , " no " ) ,
' ifequal-split08 ' : ( r " { % i fequal a ' I \ ' m happy ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : " I ' m happy " } , " yes " ) ,
' ifequal-split09 ' : ( r " { % i fequal a ' slash \ man ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : r " slash \ man " } , " yes " ) ,
' ifequal-split10 ' : ( r " { % i fequal a ' slash \ man ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : r " slashman " } , " no " ) ,
2007-03-09 14:12:15 +08:00
# NUMERIC RESOLUTION
' ifequal-numeric01 ' : ( ' { % i fequal x 5 % }yes { % e ndifequal % } ' , { ' x ' : ' 5 ' } , ' ' ) ,
' ifequal-numeric02 ' : ( ' { % i fequal x 5 % }yes { % e ndifequal % } ' , { ' x ' : 5 } , ' yes ' ) ,
' ifequal-numeric03 ' : ( ' { % i fequal x 5.2 % }yes { % e ndifequal % } ' , { ' x ' : 5 } , ' ' ) ,
' ifequal-numeric04 ' : ( ' { % i fequal x 5.2 % }yes { % e ndifequal % } ' , { ' x ' : 5.2 } , ' yes ' ) ,
' ifequal-numeric05 ' : ( ' { % i fequal x 0.2 % }yes { % e ndifequal % } ' , { ' x ' : .2 } , ' yes ' ) ,
' ifequal-numeric06 ' : ( ' { % i fequal x .2 % }yes { % e ndifequal % } ' , { ' x ' : .2 } , ' yes ' ) ,
' ifequal-numeric07 ' : ( ' { % i fequal x 2. % }yes { % e ndifequal % } ' , { ' x ' : 2 } , ' ' ) ,
' ifequal-numeric08 ' : ( ' { % i fequal x " 5 " % }yes { % e ndifequal % } ' , { ' x ' : 5 } , ' ' ) ,
' ifequal-numeric09 ' : ( ' { % i fequal x " 5 " % }yes { % e ndifequal % } ' , { ' x ' : ' 5 ' } , ' yes ' ) ,
' ifequal-numeric10 ' : ( ' { % i fequal x -5 % }yes { % e ndifequal % } ' , { ' x ' : - 5 } , ' yes ' ) ,
' ifequal-numeric11 ' : ( ' { % i fequal x -5.2 % }yes { % e ndifequal % } ' , { ' x ' : - 5.2 } , ' yes ' ) ,
' ifequal-numeric12 ' : ( ' { % i fequal x +5 % }yes { % e ndifequal % } ' , { ' x ' : 5 } , ' yes ' ) ,
2006-08-27 21:59:47 +08:00
### IFNOTEQUAL TAG ########################################################
' ifnotequal01 ' : ( " { % i fnotequal a b % }yes { % e ndifnotequal % } " , { " a " : 1 , " b " : 2 } , " yes " ) ,
' ifnotequal02 ' : ( " { % i fnotequal a b % }yes { % e ndifnotequal % } " , { " a " : 1 , " b " : 1 } , " " ) ,
' ifnotequal03 ' : ( " { % i fnotequal a b % }yes { % e lse % }no { % e ndifnotequal % } " , { " a " : 1 , " b " : 2 } , " yes " ) ,
' ifnotequal04 ' : ( " { % i fnotequal a b % }yes { % e lse % }no { % e ndifnotequal % } " , { " a " : 1 , " b " : 1 } , " no " ) ,
### INCLUDE TAG ###########################################################
' include01 ' : ( ' { % i nclude " basic-syntax01 " % } ' , { } , " something cool " ) ,
' include02 ' : ( ' { % i nclude " basic-syntax02 " % } ' , { ' headline ' : ' Included ' } , " Included " ) ,
' include03 ' : ( ' { % i nclude template_name % } ' , { ' template_name ' : ' basic-syntax02 ' , ' headline ' : ' Included ' } , " Included " ) ,
' include04 ' : ( ' a { % i nclude " nonexistent " % }b ' , { } , " ab " ) ,
2007-02-12 08:22:22 +08:00
### NAMED ENDBLOCKS #######################################################
# Basic test
' namedendblocks01 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock second % }_ { % e ndblock first % }3 " , { } , ' 1_2_3 ' ) ,
# Unbalanced blocks
2007-02-13 10:54:17 +08:00
' namedendblocks02 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock first % }_ { % e ndblock second % }3 " , { } , template . TemplateSyntaxError ) ,
2007-02-12 08:22:22 +08:00
' namedendblocks03 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock % }_ { % e ndblock second % }3 " , { } , template . TemplateSyntaxError ) ,
' namedendblocks04 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock second % }_ { % e ndblock third % }3 " , { } , template . TemplateSyntaxError ) ,
' namedendblocks05 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock first % } " , { } , template . TemplateSyntaxError ) ,
# Mixed named and unnamed endblocks
' namedendblocks06 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock % }_ { % e ndblock first % }3 " , { } , ' 1_2_3 ' ) ,
' namedendblocks07 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock second % }_ { % e ndblock % }3 " , { } , ' 1_2_3 ' ) ,
2006-08-27 21:59:47 +08:00
### INHERITANCE ###########################################################
# Standard template with no inheritance
2007-11-15 05:07:27 +08:00
' inheritance01 ' : ( " 1 { % block first % }& { % e ndblock % }3 { % block second % }_ { % e ndblock % } " , { } , ' 1&3_ ' ) ,
2006-08-27 21:59:47 +08:00
# Standard two-level inheritance
' inheritance02 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % }2 { % e ndblock % } { % block second % }4 { % e ndblock % } " , { } , ' 1234 ' ) ,
# Three-level with no redefinitions on third level
' inheritance03 ' : ( " { % e xtends ' inheritance02 ' % } " , { } , ' 1234 ' ) ,
# Two-level with no redefinitions on second level
2007-11-15 05:07:27 +08:00
' inheritance04 ' : ( " { % e xtends ' inheritance01 ' % } " , { } , ' 1&3_ ' ) ,
2006-08-27 21:59:47 +08:00
# Two-level with double quotes instead of single quotes
' inheritance05 ' : ( ' { % e xtends " inheritance02 " % } ' , { } , ' 1234 ' ) ,
# Three-level with variable parent-template name
' inheritance06 ' : ( " { % e xtends foo % } " , { ' foo ' : ' inheritance02 ' } , ' 1234 ' ) ,
# Two-level with one block defined, one block not defined
2007-11-15 05:07:27 +08:00
' inheritance07 ' : ( " { % e xtends ' inheritance01 ' % } { % block second % }5 { % e ndblock % } " , { } , ' 1&35 ' ) ,
2006-08-27 21:59:47 +08:00
# Three-level with one block defined on this level, two blocks defined next level
' inheritance08 ' : ( " { % e xtends ' inheritance02 ' % } { % block second % }5 { % e ndblock % } " , { } , ' 1235 ' ) ,
# Three-level with second and third levels blank
2007-11-15 05:07:27 +08:00
' inheritance09 ' : ( " { % e xtends ' inheritance04 ' % } " , { } , ' 1&3_ ' ) ,
2006-08-27 21:59:47 +08:00
# Three-level with space NOT in a block -- should be ignored
2007-11-15 05:07:27 +08:00
' inheritance10 ' : ( " { % e xtends ' inheritance04 ' % } " , { } , ' 1&3_ ' ) ,
2006-08-27 21:59:47 +08:00
# Three-level with both blocks defined on this level, but none on second level
' inheritance11 ' : ( " { % e xtends ' inheritance04 ' % } { % block first % }2 { % e ndblock % } { % block second % }4 { % e ndblock % } " , { } , ' 1234 ' ) ,
# Three-level with this level providing one and second level providing the other
' inheritance12 ' : ( " { % e xtends ' inheritance07 ' % } { % block first % }2 { % e ndblock % } " , { } , ' 1235 ' ) ,
# Three-level with this level overriding second level
' inheritance13 ' : ( " { % e xtends ' inheritance02 ' % } { % block first % }a { % e ndblock % } { % block second % }b { % e ndblock % } " , { } , ' 1a3b ' ) ,
# A block defined only in a child template shouldn't be displayed
2007-11-15 05:07:27 +08:00
' inheritance14 ' : ( " { % e xtends ' inheritance01 ' % } { % block newblock % }NO DISPLAY { % e ndblock % } " , { } , ' 1&3_ ' ) ,
2006-08-27 21:59:47 +08:00
# A block within another block
' inheritance15 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % }2 { % block inner % }inner { % e ndblock % } { % e ndblock % } " , { } , ' 12inner3_ ' ) ,
# A block within another block (level 2)
' inheritance16 ' : ( " { % e xtends ' inheritance15 ' % } { % block inner % }out { % e ndblock % } " , { } , ' 12out3_ ' ) ,
# {% load %} tag (parent -- setup for exception04)
' inheritance17 ' : ( " { % lo ad testtags % } { % block first % }1234 { % e ndblock % } " , { } , ' 1234 ' ) ,
# {% load %} tag (standard usage, without inheritance)
' inheritance18 ' : ( " { % lo ad testtags % } { % e cho this that theother % }5678 " , { } , ' this that theother5678 ' ) ,
# {% load %} tag (within a child template)
' inheritance19 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % } { % lo ad testtags % } { % e cho 400 % }5678 { % e ndblock % } " , { } , ' 140056783_ ' ) ,
# Two-level inheritance with {{ block.super }}
2007-11-15 05:07:27 +08:00
' inheritance20 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % } {{ block.super }}a { % e ndblock % } " , { } , ' 1&a3_ ' ) ,
2006-08-27 21:59:47 +08:00
# Three-level inheritance with {{ block.super }} from parent
' inheritance21 ' : ( " { % e xtends ' inheritance02 ' % } { % block first % } {{ block.super }}a { % e ndblock % } " , { } , ' 12a34 ' ) ,
# Three-level inheritance with {{ block.super }} from grandparent
2007-11-15 05:07:27 +08:00
' inheritance22 ' : ( " { % e xtends ' inheritance04 ' % } { % block first % } {{ block.super }}a { % e ndblock % } " , { } , ' 1&a3_ ' ) ,
2006-08-27 21:59:47 +08:00
# Three-level inheritance with {{ block.super }} from parent and grandparent
2007-11-15 05:07:27 +08:00
' inheritance23 ' : ( " { % e xtends ' inheritance20 ' % } { % block first % } {{ block.super }}b { % e ndblock % } " , { } , ' 1&ab3_ ' ) ,
2006-08-27 21:59:47 +08:00
# Inheritance from local context without use of template loader
' inheritance24 ' : ( " { % e xtends context_template % } { % block first % }2 { % e ndblock % } { % block second % }4 { % e ndblock % } " , { ' context_template ' : template . Template ( " 1 { % block first % }_ { % e ndblock % }3 { % block second % }_ { % e ndblock % } " ) } , ' 1234 ' ) ,
# Inheritance from local context with variable parent template
' inheritance25 ' : ( " { % e xtends context_template.1 % } { % block first % }2 { % e ndblock % } { % block second % }4 { % e ndblock % } " , { ' context_template ' : [ template . Template ( " Wrong " ) , template . Template ( " 1 { % block first % }_ { % e ndblock % }3 { % block second % }_ { % e ndblock % } " ) ] } , ' 1234 ' ) ,
2008-06-18 20:59:39 +08:00
# Set up a base template to extend
2008-08-31 03:25:40 +08:00
' inheritance26 ' : ( " no tags " , { } , ' no tags ' ) ,
2008-06-18 20:59:39 +08:00
2008-08-31 03:25:40 +08:00
# Inheritance from a template that doesn't have any blocks
' inheritance27 ' : ( " { % e xtends ' inheritance26 ' % } " , { } , ' no tags ' ) ,
2008-07-27 06:09:43 +08:00
2006-08-27 21:59:47 +08:00
### I18N ##################################################################
# {% spaceless %} tag
2007-04-01 09:09:21 +08:00
' spaceless01 ' : ( " { % s paceless % } <b> <i> text </i> </b> { % e ndspaceless % } " , { } , " <b><i> text </i></b> " ) ,
' spaceless02 ' : ( " { % s paceless % } <b> \n <i> text </i> \n </b> { % e ndspaceless % } " , { } , " <b><i> text </i></b> " ) ,
2006-08-27 21:59:47 +08:00
' spaceless03 ' : ( " { % s paceless % }<b><i>text</i></b> { % e ndspaceless % } " , { } , " <b><i>text</i></b> " ) ,
# simple translation of a string delimited by '
' i18n01 ' : ( " { % lo ad i18n % } { % trans ' xxxyyyxxx ' % } " , { } , " xxxyyyxxx " ) ,
# simple translation of a string delimited by "
' i18n02 ' : ( ' { % lo ad i18n % } { % trans " xxxyyyxxx " % } ' , { } , " xxxyyyxxx " ) ,
# simple translation of a variable
2007-11-17 20:12:18 +08:00
' i18n03 ' : ( ' { % lo ad i18n % } { % blocktrans % } {{ anton }} { % e ndblocktrans % } ' , { ' anton ' : ' \xc3 \x85 ' } , u " Å " ) ,
2006-08-27 21:59:47 +08:00
# simple translation of a variable and filter
2007-11-17 20:12:18 +08:00
' i18n04 ' : ( ' { % lo ad i18n % } { % blocktrans with anton|lower as berta % } {{ berta }} { % e ndblocktrans % } ' , { ' anton ' : ' \xc3 \x85 ' } , u ' å ' ) ,
2006-08-27 21:59:47 +08:00
# simple translation of a string with interpolation
' i18n05 ' : ( ' { % lo ad i18n % } { % blocktrans % }xxx {{ anton }}xxx { % e ndblocktrans % } ' , { ' anton ' : ' yyy ' } , " xxxyyyxxx " ) ,
# simple translation of a string to german
' i18n06 ' : ( ' { % lo ad i18n % } { % trans " Page not found " % } ' , { ' LANGUAGE_CODE ' : ' de ' } , " Seite nicht gefunden " ) ,
# translation of singular form
2007-11-18 11:36:03 +08:00
' i18n07 ' : ( ' { % lo ad i18n % } { % blocktrans count number as counter % }singular { % plural % } {{ counter }} plural { % e ndblocktrans % } ' , { ' number ' : 1 } , " singular " ) ,
2006-08-27 21:59:47 +08:00
# translation of plural form
2007-11-18 11:36:03 +08:00
' i18n08 ' : ( ' { % lo ad i18n % } { % blocktrans count number as counter % }singular { % plural % } {{ counter }} plural { % e ndblocktrans % } ' , { ' number ' : 2 } , " 2 plural " ) ,
2006-08-27 21:59:47 +08:00
# simple non-translation (only marking) of a string to german
' i18n09 ' : ( ' { % lo ad i18n % } { % trans " Page not found " noop % } ' , { ' LANGUAGE_CODE ' : ' de ' } , " Page not found " ) ,
# translation of a variable with a translated filter
2008-02-03 09:49:55 +08:00
' i18n10 ' : ( ' {{ bool|yesno:_( " yes,no,maybe " ) }} ' , { ' bool ' : True , ' LANGUAGE_CODE ' : ' de ' } , ' Ja ' ) ,
2006-08-27 21:59:47 +08:00
# translation of a variable with a non-translated filter
' i18n11 ' : ( ' {{ bool|yesno: " ja,nein " }} ' , { ' bool ' : True } , ' ja ' ) ,
# usage of the get_available_languages tag
' i18n12 ' : ( ' { % lo ad i18n % } { % g et_available_languages as langs % } { % f or lang in langs % } { % i fequal lang.0 " de " % } {{ lang.0 }} { % e ndifequal % } { % e ndfor % } ' , { } , ' de ' ) ,
2007-11-17 12:04:12 +08:00
# translation of constant strings
2007-11-17 20:11:26 +08:00
' i18n13 ' : ( ' {{ _( " Password " ) }} ' , { ' LANGUAGE_CODE ' : ' de ' } , ' Passwort ' ) ,
2007-11-17 12:04:12 +08:00
' i18n14 ' : ( ' { % c ycle " foo " _( " Password " ) _( \' Password \' ) as c % } { % c ycle c % } { % c ycle c % } ' , { ' LANGUAGE_CODE ' : ' de ' } , ' foo Passwort Passwort ' ) ,
' i18n15 ' : ( ' {{ absent|default:_( " Password " ) }} ' , { ' LANGUAGE_CODE ' : ' de ' , ' absent ' : " " } , ' Passwort ' ) ,
2007-11-17 20:11:26 +08:00
' i18n16 ' : ( ' {{ _( " < " ) }} ' , { ' LANGUAGE_CODE ' : ' de ' } , ' < ' ) ,
2008-08-16 05:08:11 +08:00
' i18n17 ' : ( ' {{ _( " " ) }} ' , { ' LANGUAGE_CODE ' : ' de ' } , ' ' ) ,
2006-08-27 21:59:47 +08:00
2007-11-17 20:12:18 +08:00
# Escaping inside blocktrans works as if it was directly in the
# template.
2008-08-16 05:08:11 +08:00
' i18n18 ' : ( ' { % lo ad i18n % } { % blocktrans with anton|escape as berta % } {{ berta }} { % e ndblocktrans % } ' , { ' anton ' : ' α & β' } , u ' α & β' ) ,
' i18n19 ' : ( ' { % lo ad i18n % } { % blocktrans with anton|force_escape as berta % } {{ berta }} { % e ndblocktrans % } ' , { ' anton ' : ' α & β' } , u ' α & β' ) ,
2007-11-17 20:12:18 +08:00
2007-07-20 20:15:02 +08:00
### HANDLING OF TEMPLATE_STRING_IF_INVALID ###################################
2006-10-25 05:30:38 +08:00
2006-09-04 22:02:11 +08:00
' invalidstr01 ' : ( ' {{ var|default: " Foo " }} ' , { } , ( ' Foo ' , ' INVALID ' ) ) ,
' invalidstr02 ' : ( ' {{ var|default_if_none: " Foo " }} ' , { } , ( ' ' , ' INVALID ' ) ) ,
' invalidstr03 ' : ( ' { % f or v in var % }( {{ v }}) { % e ndfor % } ' , { } , ' ' ) ,
' invalidstr04 ' : ( ' { % i f var % }Yes { % e lse % }No { % e ndif % } ' , { } , ' No ' ) ,
' invalidstr04 ' : ( ' { % i f var|default: " Foo " % }Yes { % e lse % }No { % e ndif % } ' , { } , ' Yes ' ) ,
2007-05-08 11:36:16 +08:00
' invalidstr05 ' : ( ' {{ var }} ' , { } , ( ' ' , ' INVALID %s ' , ' var ' ) ) ,
' invalidstr06 ' : ( ' {{ var.prop }} ' , { ' var ' : { } } , ( ' ' , ' INVALID %s ' , ' var.prop ' ) ) ,
2006-09-04 22:02:11 +08:00
2006-08-27 21:59:47 +08:00
### MULTILINE #############################################################
' multiline01 ' : ( """
Hello ,
boys .
How
are
you
gentlemen .
""" ,
{ } ,
"""
Hello ,
boys .
How
are
you
gentlemen .
""" ),
### REGROUP TAG ###########################################################
' regroup01 ' : ( ' { % r egroup data by bar as grouped % } ' + \
' { % f or group in grouped % } ' + \
' {{ group.grouper }}: ' + \
' { % f or item in group.list % } ' + \
' {{ item.foo }} ' + \
' { % e ndfor % }, ' + \
' { % e ndfor % } ' ,
{ ' data ' : [ { ' foo ' : ' c ' , ' bar ' : 1 } ,
{ ' foo ' : ' d ' , ' bar ' : 1 } ,
{ ' foo ' : ' a ' , ' bar ' : 2 } ,
{ ' foo ' : ' b ' , ' bar ' : 2 } ,
{ ' foo ' : ' x ' , ' bar ' : 3 } ] } ,
' 1:cd,2:ab,3:x, ' ) ,
# Test for silent failure when target variable isn't found
' regroup02 ' : ( ' { % r egroup data by bar as grouped % } ' + \
' { % f or group in grouped % } ' + \
' {{ group.grouper }}: ' + \
' { % f or item in group.list % } ' + \
' {{ item.foo }} ' + \
' { % e ndfor % }, ' + \
' { % e ndfor % } ' ,
2006-09-04 22:02:11 +08:00
{ } , ' ' ) ,
2006-08-27 21:59:47 +08:00
### TEMPLATETAG TAG #######################################################
' templatetag01 ' : ( ' { % templatetag openblock % } ' , { } , ' { % ' ) ,
' templatetag02 ' : ( ' { % templatetag closeblock % } ' , { } , ' % } ' ) ,
' templatetag03 ' : ( ' { % templatetag openvariable % } ' , { } , ' {{ ' ) ,
' templatetag04 ' : ( ' { % templatetag closevariable % } ' , { } , ' }} ' ) ,
' templatetag05 ' : ( ' { % templatetag % } ' , { } , template . TemplateSyntaxError ) ,
' templatetag06 ' : ( ' { % templatetag foo % } ' , { } , template . TemplateSyntaxError ) ,
' templatetag07 ' : ( ' { % templatetag openbrace % } ' , { } , ' { ' ) ,
' templatetag08 ' : ( ' { % templatetag closebrace % } ' , { } , ' } ' ) ,
' templatetag09 ' : ( ' { % templatetag openbrace % } { % templatetag openbrace % } ' , { } , ' {{ ' ) ,
' templatetag10 ' : ( ' { % templatetag closebrace % } { % templatetag closebrace % } ' , { } , ' }} ' ) ,
2006-10-27 09:58:13 +08:00
' templatetag11 ' : ( ' { % templatetag opencomment % } ' , { } , ' { # ' ) ,
' templatetag12 ' : ( ' { % templatetag closecomment % } ' , { } , ' #} ' ) ,
2006-08-27 21:59:47 +08:00
### WIDTHRATIO TAG ########################################################
' widthratio01 ' : ( ' { % widthratio a b 0 % } ' , { ' a ' : 50 , ' b ' : 100 } , ' 0 ' ) ,
' widthratio02 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 0 , ' b ' : 0 } , ' ' ) ,
' widthratio03 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 0 , ' b ' : 100 } , ' 0 ' ) ,
' widthratio04 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 50 , ' b ' : 100 } , ' 50 ' ) ,
' widthratio05 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 100 , ' b ' : 100 } , ' 100 ' ) ,
# 62.5 should round to 63
' widthratio06 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 50 , ' b ' : 80 } , ' 63 ' ) ,
# 71.4 should round to 71
' widthratio07 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 50 , ' b ' : 70 } , ' 71 ' ) ,
# Raise exception if we don't have 3 args, last one an integer
' widthratio08 ' : ( ' { % widthratio % } ' , { } , template . TemplateSyntaxError ) ,
' widthratio09 ' : ( ' { % widthratio a b % } ' , { ' a ' : 50 , ' b ' : 100 } , template . TemplateSyntaxError ) ,
' widthratio10 ' : ( ' { % widthratio a b 100.0 % } ' , { ' a ' : 50 , ' b ' : 100 } , template . TemplateSyntaxError ) ,
2007-03-28 01:25:56 +08:00
### WITH TAG ########################################################
' with01 ' : ( ' { % with dict.key as key % } {{ key }} { % e ndwith % } ' , { ' dict ' : { ' key ' : 50 } } , ' 50 ' ) ,
' with02 ' : ( ' {{ key }} { % with dict.key as key % } {{ key }}- {{ dict.key }}- {{ key }} { % e ndwith % } {{ key }} ' , { ' dict ' : { ' key ' : 50 } } , ( ' 50-50-50 ' , ' INVALID50-50-50INVALID ' ) ) ,
2007-04-21 12:13:52 +08:00
' with-error01 ' : ( ' { % with dict.key xx key % } {{ key }} { % e ndwith % } ' , { ' dict ' : { ' key ' : 50 } } , template . TemplateSyntaxError ) ,
' with-error02 ' : ( ' { % with dict.key as % } {{ key }} { % e ndwith % } ' , { ' dict ' : { ' key ' : 50 } } , template . TemplateSyntaxError ) ,
2006-08-27 21:59:47 +08:00
### NOW TAG ########################################################
# Simple case
2008-06-26 12:54:10 +08:00
' now01 ' : ( ' { % now " j n Y " % } ' , { } , str ( datetime . now ( ) . day ) + ' ' + str ( datetime . now ( ) . month ) + ' ' + str ( datetime . now ( ) . year ) ) ,
2006-08-27 21:59:47 +08:00
# Check parsing of escaped and special characters
2008-06-26 12:54:10 +08:00
' now02 ' : ( ' { % now " j " n " Y " % } ' , { } , template . TemplateSyntaxError ) ,
# 'now03': ('{% now "j \"n\" Y"%}', {}, str(datetime.now().day) + '"' + str(datetime.now().month) + '"' + str(datetime.now().year)),
# 'now04': ('{% now "j \nn\n Y"%}', {}, str(datetime.now().day) + '\n' + str(datetime.now().month) + '\n' + str(datetime.now().year))
2006-08-27 21:59:47 +08:00
2007-02-13 12:24:58 +08:00
### URL TAG ########################################################
# Successes
2008-06-26 12:54:10 +08:00
' url01 ' : ( ' { % u rl regressiontests.templates.views.client client.id % } ' , { ' client ' : { ' id ' : 1 } } , ' /url_tag/client/1/ ' ) ,
2008-08-31 19:11:20 +08:00
' url02 ' : ( ' { % u rl regressiontests.templates.views.client_action id=client.id,action= " update " % } ' , { ' client ' : { ' id ' : 1 } } , ' /url_tag/client/1/update/ ' ) ,
' url02a ' : ( ' { % u rl regressiontests.templates.views.client_action client.id, " update " % } ' , { ' client ' : { ' id ' : 1 } } , ' /url_tag/client/1/update/ ' ) ,
2008-06-26 12:54:10 +08:00
' url03 ' : ( ' { % u rl regressiontests.templates.views.index % } ' , { } , ' /url_tag/ ' ) ,
' url04 ' : ( ' { % u rl named.client client.id % } ' , { ' client ' : { ' id ' : 1 } } , ' /url_tag/named-client/1/ ' ) ,
' url05 ' : ( u ' { % u rl ме тка _о пе р а то р а v % } ' , { ' v ' : u ' Ω ' } , ' /url_tag/ % D0 % AE % D0 % BD % D0 % B8 % D0 % BA % D0 % BE % D0 % B4/ % CE % A9/ ' ) ,
2008-09-01 01:29:49 +08:00
' url06 ' : ( u ' { % u rl ме тка _о пе р а то р а _2 tag=v % } ' , { ' v ' : u ' Ω ' } , ' /url_tag/ % D0 % AE % D0 % BD % D0 % B8 % D0 % BA % D0 % BE % D0 % B4/ % CE % A9/ ' ) ,
' url07 ' : ( u ' { % u rl regressiontests.templates.views.client2 tag=v % } ' , { ' v ' : u ' Ω ' } , ' /url_tag/ % D0 % AE % D0 % BD % D0 % B8 % D0 % BA % D0 % BE % D0 % B4/ % CE % A9/ ' ) ,
2007-02-13 12:24:58 +08:00
# Failures
2008-06-26 12:54:10 +08:00
' url-fail01 ' : ( ' { % u rl % } ' , { } , template . TemplateSyntaxError ) ,
2008-08-05 22:16:13 +08:00
' url-fail02 ' : ( ' { % u rl no_such_view % } ' , { } , urlresolvers . NoReverseMatch ) ,
' url-fail03 ' : ( ' { % u rl regressiontests.templates.views.client % } ' , { } , urlresolvers . NoReverseMatch ) ,
2007-10-21 23:48:40 +08:00
2008-08-30 03:28:03 +08:00
# {% url ... as var %}
' url-asvar01 ' : ( ' { % u rl regressiontests.templates.views.index as url % } ' , { } , ' ' ) ,
' url-asvar02 ' : ( ' { % u rl regressiontests.templates.views.index as url % } {{ url }} ' , { } , ' /url_tag/ ' ) ,
' url-asvar03 ' : ( ' { % u rl no_such_view as url % } {{ url }} ' , { } , ' ' ) ,
2007-10-21 23:48:40 +08:00
### CACHE TAG ######################################################
2008-06-26 12:54:10 +08:00
' cache01 ' : ( ' { % lo ad cache % } { % c ache -1 test % }cache01 { % e ndcache % } ' , { } , ' cache01 ' ) ,
' cache02 ' : ( ' { % lo ad cache % } { % c ache -1 test % }cache02 { % e ndcache % } ' , { } , ' cache02 ' ) ,
' cache03 ' : ( ' { % lo ad cache % } { % c ache 2 test % }cache03 { % e ndcache % } ' , { } , ' cache03 ' ) ,
' cache04 ' : ( ' { % lo ad cache % } { % c ache 2 test % }cache04 { % e ndcache % } ' , { } , ' cache03 ' ) ,
' cache05 ' : ( ' { % lo ad cache % } { % c ache 2 test foo % }cache05 { % e ndcache % } ' , { ' foo ' : 1 } , ' cache05 ' ) ,
' cache06 ' : ( ' { % lo ad cache % } { % c ache 2 test foo % }cache06 { % e ndcache % } ' , { ' foo ' : 2 } , ' cache06 ' ) ,
' cache07 ' : ( ' { % lo ad cache % } { % c ache 2 test foo % }cache07 { % e ndcache % } ' , { ' foo ' : 1 } , ' cache05 ' ) ,
# Allow first argument to be a variable.
2008-07-27 06:09:43 +08:00
' cache08 ' : ( ' { % lo ad cache % } { % c ache time test foo % }cache08 { % e ndcache % } ' , { ' foo ' : 2 , ' time ' : 2 } , ' cache06 ' ) ,
' cache09 ' : ( ' { % lo ad cache % } { % c ache time test foo % }cache09 { % e ndcache % } ' , { ' foo ' : 3 , ' time ' : - 1 } , ' cache09 ' ) ,
' cache10 ' : ( ' { % lo ad cache % } { % c ache time test foo % }cache10 { % e ndcache % } ' , { ' foo ' : 3 , ' time ' : - 1 } , ' cache10 ' ) ,
2007-10-21 23:48:40 +08:00
2008-06-26 12:33:18 +08:00
# Raise exception if we don't have at least 2 args, first one integer.
2008-06-26 12:54:10 +08:00
' cache11 ' : ( ' { % lo ad cache % } { % c ache % } { % e ndcache % } ' , { } , template . TemplateSyntaxError ) ,
' cache12 ' : ( ' { % lo ad cache % } { % c ache 1 % } { % e ndcache % } ' , { } , template . TemplateSyntaxError ) ,
' cache13 ' : ( ' { % lo ad cache % } { % c ache foo bar % } { % e ndcache % } ' , { } , template . TemplateSyntaxError ) ,
2008-07-27 06:09:43 +08:00
' cache14 ' : ( ' { % lo ad cache % } { % c ache foo bar % } { % e ndcache % } ' , { ' foo ' : ' fail ' } , template . TemplateSyntaxError ) ,
' cache15 ' : ( ' { % lo ad cache % } { % c ache foo bar % } { % e ndcache % } ' , { ' foo ' : [ ] } , template . TemplateSyntaxError ) ,
2006-08-27 21:59:47 +08:00
2008-08-25 12:52:55 +08:00
# Regression test for #7460.
' cache16 ' : ( ' { % lo ad cache % } { % c ache 1 foo bar % } { % e ndcache % } ' , { ' foo ' : ' foo ' , ' bar ' : ' with spaces ' } , ' ' ) ,
2007-11-14 20:58:53 +08:00
### AUTOESCAPE TAG ##############################################
' autoescape-tag01 ' : ( " { % a utoescape off % }hello { % e ndautoescape % } " , { } , " hello " ) ,
' autoescape-tag02 ' : ( " { % a utoescape off % } {{ first }} { % e ndautoescape % } " , { " first " : " <b>hello</b> " } , " <b>hello</b> " ) ,
' autoescape-tag03 ' : ( " { % a utoescape on % } {{ first }} { % e ndautoescape % } " , { " first " : " <b>hello</b> " } , " <b>hello</b> " ) ,
2006-08-27 21:59:47 +08:00
2007-11-14 20:58:53 +08:00
# Autoescape disabling and enabling nest in a predictable way.
' autoescape-tag04 ' : ( " { % a utoescape off % } {{ first }} { % a utoescape on % } {{ first }} { % e ndautoescape % } { % e ndautoescape % } " , { " first " : " <a> " } , " <a> <a> " ) ,
2006-08-27 21:59:47 +08:00
2007-11-14 20:58:53 +08:00
' autoescape-tag05 ' : ( " { % a utoescape on % } {{ first }} { % e ndautoescape % } " , { " first " : " <b>first</b> " } , " <b>first</b> " ) ,
2006-08-27 21:59:47 +08:00
2007-11-14 20:58:53 +08:00
# Strings (ASCII or unicode) already marked as "safe" are not
# auto-escaped
' autoescape-tag06 ' : ( " {{ first }} " , { " first " : mark_safe ( " <b>first</b> " ) } , " <b>first</b> " ) ,
' autoescape-tag07 ' : ( " { % a utoescape on % } {{ first }} { % e ndautoescape % } " , { " first " : mark_safe ( u " <b>Apple</b> " ) } , u " <b>Apple</b> " ) ,
2006-10-25 05:30:38 +08:00
2007-11-17 20:11:26 +08:00
# Literal string arguments to filters, if used in the result, are
# safe.
2007-11-29 09:44:30 +08:00
' autoescape-tag08 ' : ( r ' { % a utoescape on % } {{ var|default_if_none: " endquote \ " hah " }} { % e ndautoescape % } ' , { " var " : None } , ' endquote " hah ' ) ,
# Objects which return safe strings as their __unicode__ method
# won't get double-escaped.
' autoescape-tag09 ' : ( r ' {{ unsafe }} ' , { ' unsafe ' : filters . UnsafeClass ( ) } , ' you & me ' ) ,
' autoescape-tag10 ' : ( r ' {{ safe }} ' , { ' safe ' : filters . SafeClass ( ) } , ' you > me ' ) ,
2006-10-25 05:30:38 +08:00
2007-11-14 20:58:53 +08:00
# The "safe" and "escape" filters cannot work due to internal
# implementation details (fortunately, the (no)autoescape block
# tags can be used in those cases)
' autoescape-filtertag01 ' : ( " {{ first }} { % f ilter safe % } {{ first }} x<y { % e ndfilter % } " , { " first " : " <a> " } , template . TemplateSyntaxError ) ,
}
2006-08-27 21:59:47 +08:00
if __name__ == " __main__ " :
unittest . main ( )