4
\$\begingroup\$

I created a reusable function for changing block name in Djago templates. I want to know if the code is good or is there any probable issues in it. I developed the function as a hack for the following issue.

Template Code

{% extends base_name %}

{% block main-contents %}

    <h2>{{ message_heading }}</h2>

    <div class="alert alert-{{ box_color|default:"info" }}">
        {{ message }}

        {% if btn_1_text and btn_1_url %}
            <a href="{{ btn_1_url }}" class="btn btn-{{ btn_1_color }}">{{ btn_1_text }}</a>
        {% endif %}

        {% if btn_2_text and btn_2_url %}
            <a href="{{ btn_2_url }}" class="btn btn-{{ btn_2_color }}">{{ btn_2_text }}</a>
        {% endif %}

    </div>

{% endblock %}

Function to change block name

def change_block_names(template, change_dict):
    """
    This function will rename the blocks in the template from the
    dictionary. The keys in th change dict will be replaced with
    the corresponding values. This will rename the blocks in the 
    extended templates only.
    """

    extend_nodes = template.nodelist.get_nodes_by_type(ExtendsNode)
    if len(extend_nodes) == 0:
        return

    extend_node = extend_nodes[0]
    blocks = extend_node.blocks
    for name, new_name in change_dict.items():
        if blocks.has_key(name):
            block_node = blocks[name]
            block_node.name = new_name
            blocks[new_name] = block_node
            del blocks[name]


tmpl_name = 'django-helpers/twitter-bootstrap/message.html'
tmpl1 = loader.get_template(tmpl_name)
change_block_names(tmpl1, {'main-contents': 'new-main-contents'})
return HttpResponse(tmpl.render(Context()))

This function seems to work for my issue. But I don't know if this breaks any of the Django's functionality. Can anyone verify this and give me some advice?

\$\endgroup\$
1
  • \$\begingroup\$ have you tried running django's unit tests? is there a unit test for templates for dealing with similar issues and can you write your own? That's the only thing I can think of judging from this code,. \$\endgroup\$ – Old account Jul 16 '13 at 17:17
2
\$\begingroup\$

This seems valid, and I don't think it should mess up Django's functionality. Some improvements are possible.


This is not Pythonic:

if len(extend_nodes) == 0:
    return

Write like this:

if not extend_nodes:
    return

This is not Pythonic:

    if blocks.has_key(name):
        # ...

Write like this:

    if name in blocks:
        # ...

But...

You're not supposed to do this. You haven't explained why you want to change template block names on the fly. And I cannot think of a legitimate use case. It's inefficient to do this operation on the fly, for every page load. What you should really do instead is update the template files in your project, do the necessary renames once and save it, so that you don't need this unnecessary extra operation. The end result will be more efficient, and more robust. Updating all files in your project is possible with a little scripting.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.