In Django, how to implement boilerplate HTML variables with Dynamic URLs used in templates and DB objects?

313 Views Asked by At

In Django, in my DB I've created string variables containing boilerplate HTML with dynamic URLs, and I can't quite get them to work in my templates.

I'm using render_as_template (https://github.com/danielrozenberg/django-render-as-template/blob/master/render_as_template/templatetags/render_as_template.py) so the dynamic URLs work. I tried custom template tags, but when I use those with render_as_template, it fails to load.

I then tried a custom context processor. I created two functions in the context processor, one for hyperlinks, and one for tooltips. I got the tooltips processor to work, but I can only reference them in the template via their number in the auto-generated dict from the queryset.

I did the same with the hyperlink processor, then tried modifying it to use string keys instead of integers, but it doesn't load all of the field. I must be missing something.

custom_tags.py
from django import template
register = template.Library()

@register.simple_tag
def rdo_hyper():
    value = Boilerplate.objects.filter(name='RDO').values_list('hyperlink',flat=True)
    return value[0]
# It's only going to return one field.
# Expected output: <a href="{% url 'guides:rdo' %}" target=”_blank” rel=”noopener noreferrer”>Foobar</a>


# tried a non-DB version, just in case
@register.simple_tag
def rdo_hyper2():
    value = "<a href=\"{% url \'guides:rdo\' %}\" target=\”_blank\” rel=\”noopener noreferrer\”>Foobar</a>"
    return value
# Expected output: <a href="{% url 'guides:rdo' %}" target=”_blank” rel=”noopener noreferrer”>Foobar</a>
custom_context.py
from myapp.apps.wizard.models import Boilerplate

def boilerplate_hyperlink_processor(request):
    boilerplate_hyper = {
        "foo": Boilerplate.objects.filter(name='Aftermarket').values_list('hyperlink',flat=True),
        "bar": Boilerplate.objects.filter(name='Sights').values_list('hyperlink',flat=True)
    }
    return {'boilerplate_hyper': boilerplate_hyper}
# Expected output of boilerplate_hyper.foo: 
#<a href="{% url 'guides:aftermarket' %}" target=”_blank” rel=”noopener noreferrer”>Aftermarket Support</a>
#
# Expected output of boilerplate_hyper.bar: 
# <a href="{% url 'guides:sights' %}" target=”_blank” rel=”noopener noreferrer”>Sights</a>


def boilerplate_tooltip_processor(request):
    boilerplate_tooltip = Boilerplate.objects.values_list('tooltip',flat=True)
    return {'boilerplate_tooltip': boilerplate_tooltip}
# Expected output of boilerplate_tooltip.0: 
#<sup><a href="{% url 'guides:sights' %}" target=”_blank” rel=”noopener noreferrer” data-html="true" class="fas fa-info-circle pr-2" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="Insert helpful tooltip info here.<br/><strong>Click</strong> for more info."></a></sup>
template.html
{% load static %}
{% load custom_tags %}
{% rdo_hyper as rdo_hyper %}
{% rdo_hyper2 as rdo_hyper2 %}
{% load render_as_template %}
...
<html>

{% autoescape off %}

1. {% rdo_hyper %} 
2. {{ rdo_hyper }} 
3. {% rdo_hyper2 %} 
4. {{ rdo_hyper2 }} 
5. {% render_as_template rdo_hyper %} 
6. {{ boilerplate_hyper.foo }} 
7. {% render_as_template boilerplate_hyper.foo %} 
8. {% render_as_template boilerplate_tooltip.0 %}

{% endautoescape %}

{# The hyperlink value is: 
<a href="{% url 'guides:aftermarket' %}" target=”_blank” rel=”noopener noreferrer”>
Aftermarket Support</a> #}

</html>

In template.html, the following occurs:

  1. Renders, but the dynamic URL fails.
  2. Doesn't render the variable at all. Otherwise page loads fine.
  3. Renders, but the dynamic URL fails.
  4. Doesn't render the variable at all. Otherwise page loads fine.
  5. Doesn't render the variable at all. Otherwise page loads fine.
  6. Only renders "Aftermarket Support']>" instead of the full hyperlink field from the DB.
  7. Throws this error:
TemplateSyntaxError:  
In template <unknown source>, error at line 1.
Could not parse the remainder: '\'guides:aftermarket\'' from '\'guides:aftermarket\''
1   <QuerySet ['<a href="{% url \'guides:aftermarket\' %}" target=”_blank” rel=”noopener noreferrer”>Aftermarket Support</a>']>
  1. Works fine.

It's great that {% render_as_template boilerplate_tooltip.0 %} works, but I would much rather reference variables in templates through a string key. After all, the ethos of Django's templating language is that its templates can be read and written by non-programmers. Any ideas?

1

There are 1 best solutions below

0
brized On

I went back to trying custom tags and this seems to work:

custom_tags.py
@register.simple_tag(takes_context=True)
def rdo_hyper2(context):
    value = "<a href=\"{% url \'guides:rdo\' %}\" target=\”_blank\” rel=\”noopener noreferrer\”>Foobar</a>"
    rendered = context.template.engine.from_string(value).render(context)
    return rendered
template.html
{% load custom_tags %}
...
{% rdo_hyper2 %}

When including {% rdo_hyper2 %} or other custom tags inside a DB field, I also have to use {% load custom_tags %} at the top of that field every time or else it throws:

Invalid block tag on line 12: 'rdo_hyper2'. Did you forget to register or load this tag?

Hopefully that's not resource intensive!