ydm / django-sameas

Django application that provides you with an easy-to-use template tag that replicates a block.
GNU Lesser General Public License v3.0
4 stars 5 forks source link

Must {% load sameastags %} in root template! #4

Open natevw opened 10 years ago

natevw commented 10 years ago

t_base_base.html:

{# load sameastags #}

<title>{% block title %}{% endblock %}</title>
{% block body %}{% endblock %}

t_base.html:

{% extends "frontend/t_basebase.html" %}
{% load sameastags %}

{% block title %}{% block subtitle %}{% endblock %}{% endblock %}

{% block body %}
<h1>{% sameas title %}</h1>
{% endblock %}

t_page.html

{% extends "frontend/t_base.html" %}

{% block subtitle %}THING{% endblock %}

If you leave the sameastags commented out in t_base_base.html, even though it doesn't directly use the sameas tag, you get:

KeyError at /tmp/t_derive.html u'sameas_title'

There seems to be a bit more at play here with context pushing/popping, but I suspect the main trouble stems from the lack of this plugin's BlockNode override when rendering the parent templates.

ydm commented 10 years ago

Thanks for pointing this! I'll examine the problem later this month.

natevw commented 10 years ago

Thanks! I did notice this bit in the Custom template tags docs:

Variable scope in context Any variable set in the context will only be available in the same block of the template in which it was assigned. This behavior is intentional; it provides a scope for variables so that they don’t conflict with context in other blocks.

I spent some time in the source debugging this and some related issues, but I really haven't fully grokked the implications, or why "sameas" is currently working across blocks in certain circumstances.

natevw commented 9 years ago

I think I've got a better understanding of this now:

So given all that, to share nested blocks between parent blocks you have to do something like this:

base template (or parent block) container

{% load sameastags %}
{% block parent %}
<!-- {% block reused_block %}{% endblock %} {# have to render here in parent #} -->
{% block container_one %}{% endblock %}
{% block container_two %}{% endblock %}
{% endblock %}

inheriting template

{% load sameastags %}
{% block container_one %}One reuses: {% sameas reused_block %}{% endblock %}
{% block container_two %}Two reuses: {% sameas reused_block %}{% endblock %}

The container has to both load the sameas library and to render the reused block to set the cached contents "low enough" down in the rendering context stack. If container_one tried to render the block itself, it would be stored but only until that block "closed", then it would be missing for container_two.

You might be able to fix this by "manually" storing the rendered contents farther down in the block stack — but be careful since the lowest level might be shared between threads/page renders (I could be mistaken?).