views:

743

answers:

3

I'm having an issue with django templates at the moment. I have 3 template files basically:

  • Base
  • story_list
  • story_detail

Story_list and _detail extend Base, and that works perfectly fine. However, list and detail share some code that extend the base template for my sidebar. I'm basically repeating a chunk of code in both templates, and the programmer in me says that's just wrong. There has to be a better way, I'm sure of it. I've tried includes, however I have in the included file:

{% block item %}
    content stuff
{% endblock %}

for about 3 blocks. The problem is that none of that is being picked up/rendered. If I include the file in a block section that extends base, then it dumps everything properly, but if I don't include it in a block, I get nothing. Is SSI the way to go? I toyed with that, but that didn't seem to work properly either. Any help is appreciated.

+4  A: 

If there is common code between the story templates that isn't needed site-wide, I'd create a story_base (extending the original base) and have my story templates extend that.

jpwatts
A: 

You have an {% include %} tag for this.

S.Lott
Yeah, as noted above, it isn't working how I envisioned it would.
f4nt
"If I include the file in a block section that extends base, then it dumps everything properly" Sounds like it works. What am I missing?
S.Lott
+12  A: 

Generally, using includes is not the answer with Django templates. Let me answer your question on several fronts.

First, let me address the sidebar.

  • Are nearly all the common pages going to be using that sidebar? Put it in Base. Don't override those sidebar blocks (i.e. don't write them at all in your Story_* templates).

  • Is this sidebar unique to the Story_* templates? Make another template called, say, Story_base and extend that. This is akin to making an abstract superclass in Java. (Answer was in my head, but wording was mercilessly ripped off from jpwatts.)

Next, let me address template inheritance. Say you have a template named Story_list that extends Base. At this point, after just putting {% extends "Base" %}, Story_list is exactly Base. Anything else you put in Story_list is ignored, because the template is already complete. The only thing you can do now is override blocks that have been defined in Base.

Finally, let me address includes. Try to always avoid them. Other templating engines, such as PHP, seem to encourage using includes. However, this can lead to less manageable templates in the long run. It's slightly harder to glance at an included snippet and immediately ascertain its place in your template hierarchy. They're also harder to refactor into the template hierarchy, especially if you include them at several levels (once in Base, twice in Story_base, once in some of the Story_*, etc.).

Wesley
The sidebar is common to all pages. I currently have them in base, and extend that out in each template. The extension is the exact same code in each child template though. That's what I'm trying to avoid. Can I do that when I have to render to these certain templates? Basically, the sidebar needs certain variables in order to be complete. That's the part I guess I'm not comprehending. Thanks for the explanation and time.
f4nt
When you render your child template Story_*, imagine that you are making a copy of Base, replacing all the content in the blocks with the blocks defined in Story_*, and THEN filling in the values of the variables. If your Base has a sidebar with a {{ my_page_name }} variable, and you render Story_list with my_page_name = "STORY_LIST", then you will see "STORY_LIST" in the sidebar.
Wesley
I feel like an idiot now.. but thank you! :)
f4nt
Only those who don't ask questions are real idiots :P You're welcome. (Hmm, I better post a question on SO soon...)
Wesley