DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Which Is Better for IoT: Azure RTOS or FreeRTOS?
  • RAML vs. OAS: Which Is the Best API Specification for Your Project?
  • What to Pay Attention to as Automation Upends the Developer Experience
  • Top Six React Development Tools

Trending

  • Which Is Better for IoT: Azure RTOS or FreeRTOS?
  • RAML vs. OAS: Which Is the Best API Specification for Your Project?
  • What to Pay Attention to as Automation Upends the Developer Experience
  • Top Six React Development Tools
  1. DZone
  2. Coding
  3. Languages
  4. Putting breakpoints to HTML templates in Python

Putting breakpoints to HTML templates in Python

Mikko Ohtamaa user avatar by
Mikko Ohtamaa
·
May. 17, 13 · Interview
Like (0)
Save
Tweet
Share
5.01K Views

Join the DZone community and get the full member experience.

Join For Free

Python offers manydifferenttemplate engines for web application development to turn your view logic to HTML code on the server and then send the resulting HTML code to a web browser. When you are dealing with complex page templates, especially when using third party libraries, it often gets confusing what template context variables are available and what they have eaten.  In this case, the best method of debugging is to insert a breakpoint into your page template and inspect the variables in runtime context. This very useful “advanced” debugging method is not known to many people, especially if they come from the background where command-line debugging tools have not been the norm.

Table Of Content

1. Python debugging

2. Setting a breakpoint in Django templates

3. Other templating engines

1. Python debugging

Python offers pdb command-line debugger out of the box. I recommend to use more advanced version ipdb, which comes with proper command history, colored tracebacks and tab completion / arrow key support (though there seems to be an issue using ipdb with multithreaded / autoreloading programs). There also exist more GUIful, but still terminal based, pudb. Eclipse + PyDev offer remote debugging support with full GUI.

Read some command-line debugging tutorials if you are not familiar with the concept. Especially how to inspect local variables with commands of locals(), dir(object), for i in dict.items(): print i come to hand.

2. Setting a breakpoint in Django templates

Here is an example how to create a breakpoint tag for Django templates and then go around and debug your templates. In the example, I debug the field rendering look of django-crispy-forms.

First we need to create a custom Django template tag invoking pdb, because you cannot run arbitrary Python snippets directly from Django templates. The code here is based on the example on djangosnippets.org.

templatetags/debug.py

# -*- coding: utf-8 -*-
#
# http://djangosnippets.org/snippets/1550/
#

import pdb as pdb_module

from django.template import Library, Node

register = Library()

class PdbNode(Node):

    def render(self, context):
        pdb_module.set_trace()
        return ''

@register.tag
def pdb(parser, token):
    return PdbNode()

Then we use this tag our template:

{% load crispy_forms_field %}
{% load debug %}

{% if field.is_hidden %}
    {{ field }}
{% else %}

    <div>
        <div>
            {{ field.long_help }}
            {% pdb %}
        </div>
    </div>
{% endif %}

We run Django normally with manage.py runserver and encounter this breakpoint when rendering a template.

Screen Shot 2013-05-16 at 9.36.06 AM

Now we can go around and see what variables are avaialble in the template and what they have eaten.

(Pdb) locals().keys()
['self', 'context']
(Pdb) context.__class__
<class 'django.template.context.RequestContext'>

Ok, so we have available template variables in a local variable called context (makes sense, we are now in our templatetag.py code).

(Pdb) for i in dir(context): print i
...
_reset_dicts
autoescape
current_app
dicts
get
has_key
new
pop
push
render_context
update
use_l10n
use_tz

There seems to be a way to access all template variables:

(Pdb) for d in context.dicts: print d.keys()
[]
['csrf_token']
['request']
['perms', 'user']
['debug', 'sql_queries']
['LANGUAGES', 'LANGUAGE_BIDI', 'LANGUAGE_CODE']
['MEDIA_URL']
['STATIC_URL']
['TIME_ZONE']
['messages']
['downtime']
['block']
['flat_attrs', 'inputs', 'csrf_token', 'form_id', 'form_error_title', 
'form_action', 'error_text_inline', 'html5_required', 'help_text_inline', 
'formset_error_title', 'form_style', 'form_method', 'form_show_errors', 
'is_formset', 'form_tag', 'attrs', 'form_attrs', 'form_class']

Now we can see what come through to our template as the field and widget in the field rendering loop.

(Pdb) context["field"]
<django.forms.forms.BoundField object at 0x1038ae590>

(Pdb) for i in context["field"].__dict__.items(): print i
('html_initial_name', u'initial-ad-xxx_type')
('form', <xxx.Form object at 0x103064c10>)
('html_name', 'ad-xxx_type')
('html_initial_id', u'initial-ad-id_ad-xxx_type')
('label', u'Foobar')
('field', <django.forms.fields.TypedChoiceField object at 0x103062e50>)
('help_text', '')
('name', 'xxx_type')

And after you see this, you can figure out if your data is coming through the templating stack and is it coming through correctly and what you need to do in order to bend it to your will.

3. Other templating engines

See also an example for Chameleon templates. Unfortunately Plone, out of the box, cannot support this debugging method due to the security.




Template HTML Python (language)

Published at DZone with permission of Mikko Ohtamaa, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Which Is Better for IoT: Azure RTOS or FreeRTOS?
  • RAML vs. OAS: Which Is the Best API Specification for Your Project?
  • What to Pay Attention to as Automation Upends the Developer Experience
  • Top Six React Development Tools

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: