1

I cannot get the contents of an inclusion_tag to display. I am not getting an errors so i know that the tag is registering and I am almost certain that it is loading correctly. The tag is created in crudapp/templatetags/crudapp_tags.py

from django import template
register = template.Library()

@register.inclusion_tag("forum.html")
def results(poll):
    form = 'blah'
    return {'form': form}

templates/forum.html

  {% extends 'index.html' %}
{% load crudapp_tags %}
{% results poll %}
<p>aaa</p>
{% block homepage %}
<p>bbb</p> <!-- Only this displays -->
{% if form %}
<p>Form exists</p>
{% endif %}
{% for item in form %}
<p>This is {{ item }}</p>
{% endfor %}
<div>
  <p>{% if user.is_authenticated %}Add a New Topic: <a href="{% url 'topic_form' %}"><span class="glyphicon glyphicon-plus"></span></a>{% endif %}</p>
</div>
<div>
  <p>{{ totalposts.count }} posts, {{ totaltopics.count }} topics, {{ totalusers.count }} users, {{ totalviews.numviews}} views</p>
</div>
{% endblock %}

The file set up is as follows,

enter image description here

Shane G
  • 3,129
  • 10
  • 43
  • 85
  • 1
    Something here doesn't make sense; your inclusion tag is rendering a template that is using the tag itself. – Daniel Roseman May 23 '16 at 12:39
  • Also the `templates` directory should be inside your app directory instead of the root of the project, unless you have explicitly told Django to look there. – solarissmoke May 23 '16 at 12:40
  • I think you have misunderstood what an inclusion tag does. An inclusion tag renders *another* template. Since you have `{% results poll %}` outside of a block, the result of the tag will never be displayed. Maybe you want an [assignment tag](https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/#assignment-tags) instead (In Django 1.9 you can use simple tag instead of assignment tag). – Alasdair May 23 '16 at 12:40
  • @solarissmoke So I can't use this tag to display 'blah' in any template, it must be a template in the app. That means I need to create a new template directory in my app called crudapp. At the moment I have all my templates in the project directory. – Shane G May 23 '16 at 12:47
  • @Alasdair yes you are probably right that I don't get the concept of inclusion tags. I thought it was a way of getting context into a template without using a url. And this tag could be repeatedly used in other templates. – Shane G May 23 '16 at 12:52
  • @DanielRoseman so should the inclusion tag be in index.html and not used in forum.html ? I can not find any example of inclusion tags which shows how to use them instead they just show how to register the tag. – Shane G May 23 '16 at 12:55

1 Answers1

3

If you are using an inclusion tag, then the tag renders another template. You need to move the code that uses form out of forum.html and into a new template, e.g. results.html

results.html

{% if form %}
<p>Form exists</p>
{% endif %}
{% for item in form %}
<p>This is {{ item }}</p>
{% endfor %}

Then change your tag to use this template

@register.inclusion_tag("results.html")
def results(poll):
    form = 'blah'
    return {'form': form}

Finally, since you are extending a template, you need to move then tag into a block, otherwise the result won't be used.

{% block homepage %}
{% results poll %}
...
{% endblock %}

If you want to add an item to the template context instead of rendering another template, then you want a simple tag instead.

@register.simple_tag
def fetch_result():
    result = ['foo', 'bar']
    return result

Then in your template:

{% fetch_result as result %}

{% for item in result %}
<p>This is {{ item }}</p>
{% endfor %}

The {% fetch_result as result %} works for simple tags in Django 1.9+. In earlier versions, you want an assignment tag.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • when you say an 'item' do you mean just one string or could that still be the result of a query, which is what I would like it to be later on. But for now I just wanted to simplify it and get 'blah' into the template. – Shane G May 23 '16 at 13:25
  • If you are using the simple tag, the result can be any object you like. You used a string `'blah'`, I changed it to a list `['foo', 'blah']` because it makes a bit more sense to loop over a list in the template. It can be a queryset if you want. – Alasdair May 23 '16 at 13:29
  • Should the templates here be in a templates directory in the app crudapp even though I have specificied in settings.py that templates are where they are in the file set up shown in the question? settings.py looks like this, TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, "templates")],............ – Shane G May 23 '16 at 13:29
  • Using Django 1.9 by the way. – Shane G May 23 '16 at 13:32
  • As long as Django can find your templates, I wouldn't worry too much about the template location at the moment, it's a separate question. – Alasdair May 23 '16 at 13:32
  • So crduapp_tags.py is from django import template register = template.Library() @register.inclusion_tag("results.html") def results(poll): form = 'blah' return {'form': form} – Shane G May 23 '16 at 13:50
  • and templates/results.html is not in an app template directory but in the templates directory and is {% extends 'index.html' %} {% load crudapp_tags %} {% block test %} {% if form %}

    Form exists

    {% endif %} {% for item in form %}

    This is {{ item }}

    {% endfor %} {% endblock %}
    – Shane G May 23 '16 at 13:51
  • then in index.html I have put, {% block test %} {% results poll %} {% endblock %} – Shane G May 23 '16 at 13:51
  • Oh actually it is working now, thank you very much. I was tsuck on this for days. Great, thanks, – Shane G May 23 '16 at 13:53
  • The results.html should be like in my answer. It doesn't need to load tags or extend other templates. If you use `{% block test %}`, it will only work if you have the same block in the template you are extending. – Alasdair May 23 '16 at 13:54
  • Sorry I can't vote you up I need 15 reps to do that. – Shane G May 23 '16 at 14:02
  • Don't worry about the upvote. Please [accept the answer](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) if it has solved your question. It would be a good idea to go through your other questions, and accept other answers as well. – Alasdair May 23 '16 at 14:04