Get template name in template tag (Django)

Is there a way to get the name of the template (when parsed) in the template tag? I read the search and found nothing, only this previous post Getting the template name in the django template

which doesn't help me much, since the answer depends on the settings .DEBUG is true, which in my case cannot be.

I don’t know where to start, so any suggestion is welcome :)

EDIT

So basically I want to create a plug-in tag that checks the Tag object when rendering, this will be the source of the tag object

class Tag(models.Model): template = models.CharFIeld(max_length=50) name = models.CharField(max_length=100) plugins = models.ForeignKey(PluginBase) 

if theres is a tag object, then it displays all objects of the plugin, if it does not create a tag object unique to the name specified in the template tag and template name, if it is not possible to get the name of the template, then I guess I can just make it unique to name. The whole tag looks like a placeholder, for those familiar with django-cms

+7
source share
2 answers

You may be able to do this using the context processor, but I'm not sure if they have access to the template name.

What will be done to make a wrapper for your rendering calls. Suppose you are currently doing the following:

 from django.shortcuts import render def index(request): return render(request, 'app/index.html', { 'foo': 'bar', }) 

If you create your own wrapper for this, you can add the template name to the dictionary before the actual rendering:

 from django.shortcuts import render def myrender(request, template, dictionary): dictionary.update({'template_name': template}) return render(request, template, dictionary) 

Then, in your views, change it as follows (if you saved the above function in myutils.py and it is available in your path):

 #from django.shortcuts import render <- delete this line from myutils import myrender as render def index(request): return render(request, 'app/index.html', { 'foo': 'bar', }) 

Now all your render calls will update the dictionary with the template name. In any template, just use {{ template_name }} to get the name. Of course, you can also update another rendering function, for example, render_to_response and so on.

Also, import myrender as render may or may not confuse you later because it is named as a Django function ... if so, just import it without " as render " and replace all render calls with myrender . Personally, I would prefer this, as this makes it a replacement for existing rendering functions.

+2
source

Looking at the source, while the Template object gains access to the template name (via .name ), this value is also never passed to the Parser object and, therefore, is not available for template tags.

There are various ways to make the template name available to the template itself (by adding it to the context), but not in the template tags.

As Daniel Roseman said in the comments, if you can clarify what you are actually trying to achieve, there may be a better way to achieve what you want. Do not be offended, but it looks like it might be an XY problem.


Of academic interest, I had a quick violin to see if this was possible. As far as I can see, this is possible, but not without a change or a monkey fixing the source of django.

Note. The following is not a recommended solution and just hints at what might be required for the actual work. Do not use for production code.

By changing django.template.base.py with the following changes, we will add the .template_name attribute to the parser object, making it available for template tags.

To verify this, I defined the following tag, which simply returns the name of the template in the header:

 from django.template.base import Node, Library register = Library() class TemplateNameNode(Node): def __init__(self, template_name): self.name = template_name def render(self, context): return self.name.upper() @register.tag def caps_template_name(parser, token): return TemplateNameNode(parser.template_name) 

and the following template:

 {% load mytags %} Template name in caps: {% caps_template_name %} 

This seems to work when testing in ./manage.py shell :

 >>> from django.template import loader, Context >>> t = loader.get_template("test.html") >>> t.render(Context({})) u'\nTemplate name in caps: TEST.HTML\n' 

While this works, I have to reiterate that manually fixing the django source will never be a good solution and is subject to all kinds of misfortunes when switching to different versions.

+3
source

All Articles