26

I've created a custom tag that I want to use, but Django can't seem to find it. My templatetags directory is set up like this:

pygmentize.py

from pygments import highlight
from pygments.lexers import get_lexer_by_name
from django import template
from pygments.formatters.other import NullFormatter

register = template.Library()

@register.tag(name='code')
def do_code(parser,token):
    code = token.split_contents()[-1]
    nodelist = parser.parse(('endcode',))
    parser.delete_first_token()
    return CodeNode(code,nodelist)

class CodeNode(template.Node):
    def __init__(self,lang,code):
        self.lang = lang
        self.nodelist = code

    def render(self,context):
        code = self.nodelist.render(context)
        lexer = get_lexer_by_name('python')
        return highlight(code,lexer,NullFormatter())

I am trying to use this tag to render code in gameprofile.html.

gameprofile.html

(% load pygmentize %}
{% block content %}
    <title>{% block title %} | {{ game.title }}{% endblock %}</title>
    <div id="gamecodecontainer">
        {% code %}
            {{game.code}}
        {% endcode %}
    </div>
{% endblock content %}

When I navigate to gameprofile.html, I get an error:

Invalid block tag on line 23: 'code', expected 'endblock'. Did you forget to register or load this tag?

Braiam
  • 1
  • 11
  • 47
  • 78
123
  • 8,733
  • 14
  • 57
  • 99
  • does `{% do_code %}{% endcode %}` work? (is it ignoring the name) – Sayse Jan 28 '16 at 07:59
  • I've tried, and `do_code` doesn't work either. – 123 Jan 28 '16 at 08:00
  • Hmm, the only thing that really looks out of place then to me is the fact that you have a block inside of a block... not sure if that would affect things or not (the title). (I could be wrong, I don't think I use any nested blocks) – Sayse Jan 28 '16 at 08:03
  • The title has been there for a while and hans't been a problem. Although there is also a block inside a block for the `{% code %}` section too... – 123 Jan 28 '16 at 08:05
  • Yeah I was referring more to explicitly the `block` tag, again but I guess there could be times when you only want a block to show if another is present... I can't really see any thing wrong with your code here, of course I presume that you've restarted the `runserver` command – Sayse Jan 28 '16 at 08:08
  • Yup, at least a few times. No luck. – 123 Jan 28 '16 at 08:11
  • I'm afraid I can't really see the problem here... the only difference between your code and any of the django source code is that they ignore the `name=` (`.tag('code')` for example), as a simple test you could try just adding a different `simple_tag` or similar and see if that is able to be rendered, it would at least reduce the bug scope from module to node – Sayse Jan 28 '16 at 08:15
  • I've tried changing up the `simple_tag`, but still the same issue unfortunately. – 123 Jan 28 '16 at 08:30
  • I've just read that there is the chance that you're getting a syntax error that is stopping the import without telling you ([source](http://stackoverflow.com/a/8177742/1324033))... You could try changing the code to the [example](https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/#parsing-until-another-block-tag-and-saving-contents) tag code to verify this – Sayse Jan 28 '16 at 08:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/101850/discussion-between-sayse-and-tk-421). – Sayse Jan 28 '16 at 08:48
  • Generally the message "Did you forget to register or load this tag?" is linked with a mispell of a django tag. – Tms91 Mar 28 '20 at 17:49

11 Answers11

20

For Django 2.2 up to 3, you have to load staticfiles in html template first before use static keyword

{% load staticfiles %}
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">

For other versions use static

{% load static %}
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">

Also you have to check that you defined STATIC_URL in setting.py

At last, make sure the static files exist in the defined folder

vipmaa
  • 1,022
  • 16
  • 25
  • 1
    for Django 3.0 this results in the error: django.template.exceptions.TemplateSyntaxError: 'staticfiles' is not a registered tag library. So it seems like "load static" is the correct command at least for Django 3.0+ – David Schumann Aug 18 '20 at 13:09
  • 2
    For Django 3 use only `{% load static %}` – vipmaa Sep 28 '20 at 14:20
17

The error is in this line: (% load pygmentize %}, an invalid tag. Change it to {% load pygmentize %}

Erick M
  • 465
  • 4
  • 9
11
{% load static %}
<img src="{% static "my_app/example.jpg" %}" alt="My image">

in your templates, use the static template tag to build the URL for the given relative path using the configured STATICFILES_STORAGE.

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Abhishek mishra
  • 111
  • 1
  • 2
10

did you try this

{% load games_tags %} 

at the top instead of pygmentize?

losee
  • 2,190
  • 3
  • 29
  • 55
7
{% load static %}

Please add this template tag on top of the HTML or base HTML file

Thomas John
  • 2,138
  • 2
  • 22
  • 38
5

Encountered this same issue but I just added {% load static %} from my extends template and it worked. So in your case if you're trying to load gameprofile.html from a base template you just need to add it like this:

{% extends 'some_base.html' %}
{% block content %}
{% load pygmentize %}
blufang
  • 51
  • 1
  • 4
2

I had the same problem, here's how I solved it. Following the first section of this very excellent Django tutorial, I did the following:

  1. Create a new Django app by executing: python manage.py startapp new_app
  2. Edit the settings.py file, adding the following to the list of INSTALLED_APPS: 'new_app',
  3. Add a new module to the new_app package named new_app_tags.
  4. In a Django HTML template, add the following to the top of the file, but after {% extends 'base_template_name.html' %}: {% load new_app_tags %}
  5. In the new_app_tags module file, create a custom template tag (see below).
  6. In the same Django HTML template, from step 4 above, use your shiney new custom tag like so: {% multiply_by_two | "5.0" %}
  7. Celebrate!

Example from step 5 above:

from django import template

register = template.Library()

@register.simple_tag
def multiply_by_two(value):
    return float(value) * 2.0
MikeyE
  • 1,756
  • 1
  • 18
  • 37
0

The app that contains the custom tags must be in INSTALLED_APPS. So Are you sure that your directory is in INSTALLED_APPS ?

From the documentation:

The app that contains the custom tags must be in INSTALLED_APPS in order for the {% load %} tag to work. This is a security feature: It allows you to host Python code for many template libraries on a single host machine without enabling access to all of them for every Django installation.

bfontaine
  • 18,169
  • 13
  • 73
  • 107
Ahmed Hosny
  • 1,162
  • 10
  • 21
  • The `games` app is included in installed apps. – 123 Jan 28 '16 at 07:45
  • The app that contains the custom tags which here is templatetags – Ahmed Hosny Jan 28 '16 at 07:46
  • I get `ImportError: No module named templatetags` – 123 Jan 28 '16 at 07:48
  • I Think you should put it in installed app as games.templatetags – Ahmed Hosny Jan 28 '16 at 07:55
  • 2
    This is just wrong, there isn't any problem with where the op is storing their template tag and they are not classed as an app – Sayse Jan 28 '16 at 08:00
  • Yes, I've edited my comment therefore. And if you refer that it should not be at the INSTALLED_APPS, I think it is what stated in docummentation [link](https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/) – Ahmed Hosny Jan 28 '16 at 08:03
  • 2
    The only app here is `games` and that must be included because otherwise the actual template the op is trying to render their tag in wouldn't be available. – Sayse Jan 28 '16 at 08:11
  • Yes I know. Mmm, the only thing I'm thinking of now is a name conflict of the templatetag "code". – Ahmed Hosny Jan 28 '16 at 08:21
0

In gameprofile.html please change the tag {% endblock content %} to {% endblock %} then it works otherwise django will not load the endblock and give error.

Biswajit Roy
  • 508
  • 2
  • 7
  • 19
0

Sometimes all you need is to just:

  1. Restart the django server by pressing Ctrl + C

or

  1. Hard reload the page by pressing Shift + Ctrl + R
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Mr Coolman
  • 29
  • 4
-2

You need to change:

{% endblock content %}

to

{% endblock %}
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
steve
  • 171
  • 1
  • 2
  • 10