Code

Ticket #6932: 6932-template-tag-for-flatpages.diff

File 6932-template-tag-for-flatpages.diff, 8.1 KB (added by Mnewman, 6 years ago)

Patch for a new template tag, this patch also includes tests for flatpages in general (on top of the test for the new code) and documentation

Line 
1Index: django/contrib/flatpages/templatetags/__init__.py
2===================================================================
3Index: django/contrib/flatpages/templatetags/flatpages.py
4===================================================================
5--- django/contrib/flatpages/templatetags/flatpages.py  (revision 0)
6+++ django/contrib/flatpages/templatetags/flatpages.py  (revision 0)
7@@ -0,0 +1,55 @@
8+
9+from django import template
10+from django.contrib.flatpages.models import FlatPage
11+from django.utils.translation import ugettext as _
12+from django.conf import settings
13+
14+register = template.Library()
15+
16+class FlatpageNode(template.Node):
17+    def __init__(self, context_name, starts_with=None):
18+        self.context_name, self.starts_with = context_name, starts_with
19+        if self.starts_with:
20+            self.starts_with = template.Variable(starts_with)
21+        self.flatpages = FlatPage.objects.filter(sites__id=settings.SITE_ID)
22+       
23+    def render(self, context):
24+        if self.starts_with:
25+            self.flatpages = self.flatpages.filter(\
26+                url__startswith=self.starts_with.resolve(context))
27+        context[self.context_name] = self.flatpages
28+        return ''
29+
30+
31+def get_flatpages(parser, token):
32+    """
33+    Template tag that returns flatpages availible on the site.   
34+    An optional argument, 'starts_with', can be applied only return pages
35+    whose urls start with that base url. This can be a variable or a string,
36+    it resolves from context.
37+   
38+    Syntax is {% get_flatpages ['url_starts_with'] as context_name %}
39+    example:
40+    {% get_flatpages '/about/' as about_pages %}
41+    {% for page in about_pages %}...{% endfor %}
42+    """
43+    bits = token.split_contents()
44+    if len(bits) is 3:
45+        if bits[1] != 'as':
46+            raise template.TemplateSyntaxError, _("%s expects a syntax of %s "
47+                "['url_starts_with'] as context_name" % (bits[0], bits[0]))
48+        return FlatpageNode(bits[2])
49+    elif len(bits) is 4:
50+        if bits[2] != 'as':
51+            raise template.TemplateSyntaxError, _("%s expects a syntax of %s "
52+                "['url_starts_with'] as context_name" % (bits[0], bits[0]))
53+        return FlatpageNode(bits[3], bits[1])
54+    else:
55+        raise template.TemplateSyntaxError, _("%s expects a syntax of %s "
56+            "['url_starts_with'] as context_name" % (bits[0], bits[0]))
57+
58+
59+register.tag('get_flatpages', get_flatpages)
60+
61+
62+
63Index: tests/regressiontests/flatpages/views.py
64===================================================================
65--- tests/regressiontests/flatpages/views.py    (revision 0)
66+++ tests/regressiontests/flatpages/views.py    (revision 0)
67@@ -0,0 +1 @@
68+# Create your views here.
69Index: tests/regressiontests/flatpages/__init__.py
70===================================================================
71Index: tests/regressiontests/flatpages/tests.py
72===================================================================
73--- tests/regressiontests/flatpages/tests.py    (revision 0)
74+++ tests/regressiontests/flatpages/tests.py    (revision 0)
75@@ -0,0 +1,82 @@
76+from django.test import TestCase
77+from django.contrib.flatpages.models import FlatPage
78+from django.contrib.sites.models import Site
79+
80+current_site = Site.objects.get_current()
81+
82+
83+class FlatpageTest(TestCase):
84+    """Test for contrib.flatpages"""
85+    # Site.objects.clear_cache()
86+
87+   
88+    def setUp(self):
89+       
90+        page = FlatPage(
91+            url='/page1/',
92+            title='Some page',
93+            content="<p>Some text that shouldn't be automatcially escaped</p>",
94+            registration_required=False,
95+            )
96+        page.save()
97+        page.sites.add(current_site)
98+        page.save()
99+       
100+        registrationPage = FlatPage(
101+            url='/registered/',
102+            title='register for this page',
103+            content="great you are registered",
104+            registration_required=True,
105+            )
106+        registrationPage.save()
107+        registrationPage.sites.add(current_site)
108+        registrationPage.save()
109+       
110+        fallbackPage = FlatPage(
111+            url='/accounts/login/',
112+            title='This page should not be seen',
113+            content=" ",
114+            registration_required=True,
115+            )
116+        fallbackPage.save()
117+        fallbackPage.sites.add(current_site)
118+        fallbackPage.save()
119+       
120+    def testPage(self):
121+        page = self.client.get('/page1/')
122+        self.failUnlessEqual(page.status_code, 200)
123+        self.assertContains(page, "<p>Some text that shouldn't be automatcially escaped</p>")
124+       
125+    def testRegistration(self):
126+        registrationPage = self.client.get('/registered/')
127+        self.assertRedirects(registrationPage, '/accounts/login/?next=/registered/', target_status_code=302)
128+       
129+    def testFallback(self):
130+        fallbackPage = self.client.get('/accounts/login/')
131+        self.assertNotContains(fallbackPage, 'This page should not be seen', status_code=302)
132+       
133+    def testTag(self):
134+        from django import template
135+        # because of the way flatpages are loaded in the tests this is the
136+        # equivilent of {% load flatpages %}
137+        template.add_to_builtins('django.contrib.flatpages.templatetags.flatpages')
138+        t = template.Template("""{% get_flatpages as flatpages %}
139+{% for page in flatpages %}
140+{{ page.title }}
141+{% endfor %}
142+
143+{% get_flatpages '/registered/' as registered_pages %}
144+{% for page in registered_pages %}
145+{{ page.title }}
146+{% endfor %}
147+
148+{% get_flatpages some_var as registered_pages %}
149+{% for page in registered_pages %}
150+{{ page.title }}
151+{% endfor %}""")
152+        r = t.render(template.Context({'some_var':'/accounts/'}))
153+        self.assertEquals(r,
154+            """\n\nThis page should not be seen\n\nSome page\n\nregister""" +\
155+            """ for this page\n\n\n\n\nregister for this page\n\n\n\n\n""" +\
156+            """This page should not be seen\n""")
157+
158+
159Index: tests/regressiontests/flatpages/models.py
160===================================================================
161--- tests/regressiontests/flatpages/models.py   (revision 0)
162+++ tests/regressiontests/flatpages/models.py   (revision 0)
163@@ -0,0 +1 @@
164+# Create your models here.
165Index: tests/regressiontests/flatpages/templates/flatpages/default.html
166===================================================================
167--- tests/regressiontests/flatpages/templates/flatpages/default.html    (revision 0)
168+++ tests/regressiontests/flatpages/templates/flatpages/default.html    (revision 0)
169@@ -0,0 +1,10 @@
170+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
171+    "http://www.w3.org/TR/REC-html40/loose.dtd">
172+<html>
173+<head>
174+<title>{{ flatpage.title }}</title>
175+</head>
176+<body>
177+{{ flatpage.content }}
178+</body>
179+</html>
180Index: docs/flatpages.txt
181===================================================================
182--- docs/flatpages.txt  (revision 7698)
183+++ docs/flatpages.txt  (working copy)
184@@ -134,3 +134,38 @@
185 
186 .. _automatic HTML escaping: ../templates/#automatic-html-escaping
187 
188+
189+Getting a list of Flatpages in your Templates
190+=============================================
191+
192+**New in Django development version**
193+
194+The Flatpages contrib app also comes with a template tag. From your templates
195+you can access this tag via {% load flatpages %} and you get access to a
196+get_flatpages tag that returns flatpages availible on the site.   
197+An optional argument, 'starts_with', can be applied only return pages
198+whose urls start with that base url. This can be a variable or a string,
199+it resolves from context.
200+
201+Syntax is {% get_flatpages ['url_starts_with'] as context_name %}
202+example:
203+
204+    {% get_flatpages '/about/' as about_pages %}
205+    <ul>
206+        {% for page in about_pages %}
207+            <li><a href="{{ page.url }}">{{ page.title }}</a></li>
208+        {% endfor %}
209+    </ul>
210+
211+
212+If you wish to filter flatpages out by registration required, you can place an
213+if statment around your for loop:
214+
215+    {% get_flatpages '/contact/' as contact_pages %}
216+    {% for page in contact_pages %}
217+        {% if not user.is_authenticated and page.registration_required %}
218+            <h3><a href="{{page.url}}">{{page.title}}</a></h3>
219+        {% endif %}
220+    {% endfor %}
221+
222+