From: Stephen Burrows Date: Tue, 30 Nov 2010 15:35:42 +0000 (-0500) Subject: Further polished embedding system - allowed for context-dependent embed nodes to... X-Git-Tag: philo-0.9~24^2~8 X-Git-Url: http://git.ithinksw.org/philo.git/commitdiff_plain/72849b1c135de8c0ad14d2ca881a98fdea279859 Further polished embedding system - allowed for context-dependent embed nodes to be correctly added to the embed context and to correctly render in extending templates even if not within blocks. Added notes to README about how to use philo. Fixed docstring typo for {% node_url %} templatetag. --- diff --git a/README b/README index e718287..90d12c0 100644 --- a/README +++ b/README @@ -3,7 +3,21 @@ Philo is a foundation for developing web content management systems. Prerequisites: * Python 2.5.4+ * Django 1.2+ + * django-mptt 0.4+ * (Optional) django-grappelli 2.0+ * (Optional) recaptcha-django r6 + * (Optional) south 0.7.2+ To contribute, please visit the project website . + +==== +Using philo +==== +After installing philo and mptt on your python path, make sure to complete the following steps: + +1. add 'philo.middleware.RequestNodeMiddleware' to settings.MIDDLEWARE_CLASSES. +2. add 'philo' and 'mptt' to settings.INSTALLED_APPS. +3. include 'philo.urls' somewhere in your urls.py file. +4. Optionally add a root node to your current Site. + +Philo should be ready to go! \ No newline at end of file diff --git a/templatetags/embed.py b/templatetags/embed.py index ef2eeb2..901e163 100644 --- a/templatetags/embed.py +++ b/templatetags/embed.py @@ -61,23 +61,25 @@ class EmbedContext(object): old_extends_node_init = ExtendsNode.__init__ -def get_embed_dict(nodelist): +def get_embed_dict(embed_list, context): embeds = {} - for n in nodelist.get_nodes_by_type(ConstantEmbedNode): - if n.content_type not in embeds: - embeds[n.content_type] = [n] + for e in embed_list: + ct = e.get_content_type(context) + if ct not in embeds: + embeds[ct] = [e] else: - embeds[n.content_type].append(n) + embeds[ct].append(e) return embeds def extends_node_init(self, nodelist, *args, **kwargs): - self.embeds = get_embed_dict(nodelist) + self.embed_list = nodelist.get_nodes_by_type(ConstantEmbedNode) old_extends_node_init(self, nodelist, *args, **kwargs) def render_extends_node(self, context): compiled_parent = self.get_parent(context) + embeds = get_embed_dict(self.embed_list, context) if BLOCK_CONTEXT_KEY not in context.render_context: context.render_context[BLOCK_CONTEXT_KEY] = BlockContext() @@ -90,7 +92,7 @@ def render_extends_node(self, context): # Add the block nodes from this node to the block context # Do the equivalent for embed nodes block_context.add_blocks(self.blocks) - embed_context.add_embeds(self.embeds) + embed_context.add_embeds(embeds) # If this block's parent doesn't have an extends node it is the root, # and its block nodes also need to be added to the block context. @@ -100,10 +102,16 @@ def render_extends_node(self, context): if not isinstance(node, ExtendsNode): blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)]) block_context.add_blocks(blocks) - embeds = get_embed_dict(compiled_parent.nodelist) + embeds = get_embed_dict(compiled_parent.nodelist.get_nodes_by_type(ConstantEmbedNode), context) embed_context.add_embeds(embeds) break - + + # Explicitly render all direct embed children of this node. + if self.embed_list: + for node in self.nodelist: + if isinstance(node, ConstantEmbedNode): + node.render(context) + # Call Template._render explicitly so the parser context stays # the same. return compiled_parent._render(context) @@ -152,7 +160,7 @@ class ConstantEmbedNode(template.Node): try: return template.loader.get_template(template_name) except template.TemplateDoesNotExist: - if not hasattr(self, 'template_name') and settings.TEMPLATE_DEBUG: + if hasattr(self, 'template') and settings.TEMPLATE_DEBUG: # Then it's a constant node. raise return False @@ -201,6 +209,7 @@ class ConstantEmbedNode(template.Node): except (KeyError, IndexError): if settings.TEMPLATE_DEBUG: raise + self.mark_rendered_for(context) return settings.TEMPLATE_STRING_IF_INVALID context.push() @@ -225,13 +234,11 @@ class EmbedNode(ConstantEmbedNode): self.object_pk = object_pk else: self.object_pk = None - self.instance = None if template_name is not None: self.template_name = template_name else: self.template_name = None - self.template = None def get_instance(self, context): if self.object_pk is None: diff --git a/templatetags/nodes.py b/templatetags/nodes.py index 338ac2d..9721ec4 100644 --- a/templatetags/nodes.py +++ b/templatetags/nodes.py @@ -68,7 +68,7 @@ class NodeURLNode(template.Node): @register.tag(name='node_url') def do_node_url(parser, token): """ - {% node_url [for ] [as ] [as ] %} {% node_url with [for ] [as ] %} {% node_url [ [ ...] ] [for ] [as ] %} {% node_url [= [= ...] ] [for ] [as ]%} diff --git a/tests.py b/tests.py index b0f40d5..96ac7b6 100644 --- a/tests.py +++ b/tests.py @@ -39,9 +39,10 @@ class TemplateTestCase(TestCase): expected_invalid_str = 'INVALID' failures = [] - + tests = template_tests.items() + tests.sort() # Run tests - for name, vals in template_tests.items(): + for name, vals in tests: xx, context, result = vals try: test_template = loader.get_template(name) @@ -96,6 +97,13 @@ class TemplateTestCase(TestCase): # Blocks and includes 'block-include01': ('{% extends "simple01" %}{% embed penfield.blog with "embed03" %}{% block one %}{% include "simple01" %}{% embed penfield.blog 1 %}{% endblock %}', {}, "%sSimple%sSimple%s is a lie!" % (blog.title, blog.title, blog.title)), 'block-include02': ('{% extends "simple01" %}{% block one %}{% include "simple04" %}{% embed penfield.blog with "embed03" %}{% include "simple04" %}{% embed penfield.blog 1 %}{% endblock %}', {}, "%sSimple%s%s is a lie!%s is a lie!" % (blog.title, blog.title, blog.title, blog.title)), + + # Tests for more complex situations... + 'complex01': ('{% block one %}{% endblock %}complex{% block two %}{% endblock %}', {}, 'complex'), + 'complex02': ('{% extends "complex01" %}', {}, 'complex'), + 'complex03': ('{% extends "complex02" %}{% embed penfield.blog with "embed01" %}', {}, 'complex'), + 'complex04': ('{% extends "complex03" %}{% block one %}{% embed penfield.blog 1 %}{% endblock %}', {}, '%scomplex' % blog.title), + 'complex05': ('{% extends "complex03" %}{% block one %}{% include "simple04" %}{% endblock %}', {}, '%scomplex' % blog.title), }