Sunday, March 29, 2009

Brave?

I did what I suspect was a fairly brave thing at PyCon. I attended an Open Spaced entitled "Is This Pythonic?" No one else was willing to put their code in front of the Python core developers (Jack Diederich and Moshe Zadka), so I offered up on of the files from my PyShards project. Now, keep in mind that I only decided that Python would be my language of Primacy about 6 months before writing the file that they reviewed. I tend to use the common subset of programming language features so that I can hop back and forth between programming languages without making my brain explode. Nonetheless, I wanted to see what it would take to make my code acceptable to the most pedantic of Python programmers, so I volunteered.

Check out the result:

http://jackdied.blogspot.com/2009/03/is-this-pythonic.html

Jack could not pythonicify the code to his satisfaction without relying on newer and trunk Python features. At the time of his writing, he was still not satisfied with his result.

It was an interesting, if not a bit nerve racking, exercise.

Sunday, March 22, 2009

Django templating

One of my contacts, John, wrote me yesterday, asking for some conceptual help with the Django templating system. I broke down template inheritance for him, using the following very simple example.

I told John...


I typically use Django's template inheritance in this way. A base page handles most of the boiler plate stuff and then I specialize in the inherited pages. URLs and the views (python functions) also get involved.

Here's a super simple page. (Imagine that each code snippet lives in its own file.) This one is base.html.


<html>
<body>
Part One
Part Two
</body>
</html>


I need two more things to display a page using the Django system, the URI routing expression in urls.py and a view. (I'm sure you get this, but to be clear I just want to call out all of the parts.)

The URI expression:


(r'^base$', base_function),


base_function is the view function, typically defined in another file. Something like this will display the page without really doing anything fancy with data.



def base_function(request):
return render_to_response("base.html")



From a browser, you go to /base/, and you see...
Part One Part Two

Now you want to either extend or replace a section of the template. First, let's extend. We modify the original template and add markers for the areas we will be extending or replacing.

<html>
<body>
{% block one %} Part One{% endblock %}
{% block two %} Part Two{% endblock %}
</body>
</html>

Suppose you just want to just change the second block. So you create a file called mod2.html.

{% extends "base.html" %}
{% block two %} A different thing to render in Part Two{% endblock %}

You add another URL expression in urls.py. So now it looks like...

(r'^base$', base_function),
(r'^mod2$', mod_alt_two_function),

and you add a second view function...



def mod_alt_two_function(request):
return render_to_response("mod2.html")



From a browser, you go to /mod2/, and you see...
Part One A different thing to render in Part Two

A third view might replace the first and second section....

(r'^base$', base_function),
(r'^mod2$', mod_alt_two_function),
(r'^all$', all_mod_function),




def all_mod_function(request):
return render_to_response("all.html")



{% extends "base.html" %}
{% block one %} Much different than
{% endblock %}
{% block two %} the original{% endblock %}

Producing this when you hit /all/ in the browser:

Much different than
the original

So that's the basics with template inheritance. You can also just include chunks of other templates by including them right in the middle of the page. And you can wrap the includes in logic, so that based upon the data you are passing to the template from the view function, you can make decisions about what to include. Here is a small snippet from one of my pages that includes one of four different HTML template 'chunks' based upon the values of the variables "result.format" and "result.render_hint".




{% ifequal result.format 'pipe' %}
{% ifequal result.render_hint 'email' %}
{% include 'email_result.html' %}
{% endifequal %}
{% ifnotequal result.render_hint 'email' %}
{% include 'table_properties.html' %}
{% endifnotequal %}
{% endifequal %}
{% ifequal result.format 'text' %}
{% include 'text_result.html' %}
{% endifequal %}
{% ifequal result.format 'tag' %}
{% include 'tag.html' %}
{% endifequal %}