Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get request context in Advanced custom template tags

In Django simple and inclusion template tags allow getting the request context with

@register.simple_tag(takes_context=True)

Official documentation for custom template tags - inclusion tags.

However, for custom tags, I don't see how this is done.

What I am trying to do is extend the i18n {% trans %} tag, to look for translation in the database first, before using gettext. I need access to the request.Language from the custom template tag.

like image 829
uri.lazar Avatar asked Sep 02 '18 13:09

uri.lazar


People also ask

How do I access the current context of a template tag?

If your template tag needs to access the current context, you can use the takes_context argument when registering your tag: Note that the first argument must be called context. For more information on how the takes_context option works, see the section on inclusion tags. If you need to rename your tag, you can provide a custom name for it:

How does takes_context work with template tags?

If you specify takes_context in creating a template tag, the tag will have no required arguments, and the underlying Python function will have one argument – the template context as of when the tag was called.

How do I define a custom template tag?

Thus, to define a custom template tag, you specify how the raw template tag is converted into a Node (the compilation function), and what the node’s render () method does.

How do I call a custom tag without any arguments?

Then, any time you want to use that custom tag, load its library and call it without any arguments, like so: Note that when you’re using takes_context=True, there’s no need to pass arguments to the template tag. It automatically gets access to the context. The takes_context parameter defaults to False.


1 Answers

From the Django doc of custom template tags, it's also possible to add takes_context for customs tags

import datetime
from django import template

register = template.Library()


@register.simple_tag(takes_context=True)
def current_time(context, format_string):

    #use "context" variable here
    return datetime.datetime.now().strftime(format_string)


I'm not sure how to override the existing tag at this particular scenario :(
Anyway, what I'm suggesting is, create a simple_tag that takes the context and do your logic inside the tag and return the translation text from DB. If it's not in DB, return a boolean False. Now in template, check these thing using if tag.

from django import template

register = template.Library()


@register.simple_tag(takes_context=True)
def is_db_available(context):
    # access your context here and do the DB check and return the translation text or 'False'
    if translation_found_in_DB:
        return "Some translation text"
    return False

and in template

{% load custom_tags %}
{% load i18n %}
{% is_db_available as check %} 
{% if check %}  <!-- The if condition  -->
    {{ check }}
{% else %}
    {% trans "This is the title." %} <!-- Calling default trans tag  -->
{% endif %}
like image 82
JPG Avatar answered Nov 14 '22 23:11

JPG