Login

Avoid widows using a template filter

Author:
jcroft
Posted:
February 25, 2007
Language:
Python
Version:
Pre .96
Tags:
filter widows templatetag typography shauninman widont
Score:
28 (after 34 ratings)

Support good typography! Avoid widows!

"Widows" are single words that end up on their own line, thanks to automatic line-breaks. This is an no-no in graphic design, and is especially unsightly in headers and other short bursts of text. This filter automatically replaces the space before the last word of the passed value with a non-breaking space, ensuring there is always at least two words on any given line. Usage is like so:

{{ blog.entry.headline|widont }}

It's a simple tag, but good typography is one of the hallmarks of a well-designed site that separates it from amateurish counterparts.

Note: The idea and name "widont" is copped directly from Shaun Inman, who wrote a similar feature for WordPress.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from django.template import Library, Node

register = Library()

def widont(value):
    bits = value.rsplit(' ', 1)
    try:
        widowless = bits[0] + " " + bits[1]
        return widowless
    except:
        return value

register.filter(widont)

More like this

Comments

obeattie (on February 27, 2007):
<p>Thanks for this - looks like this could prove very useful!</p>

#

paching (on March 1, 2007):
<p>Nice little trick I didn't know about! Just a couple notes;</p> <p>If there happens to be an HTML tag such as a link on the last word, this would break it. However for simple headers, I suppose this isn't a problem. In my own code I'm putting this inside a text conversion function where I'm already keeping track of tags, anyway :)</p> <p>Also, it could be implemented as a simple one-liner:</p> <pre>return '&nbsp;'.join(value.rsplit(' ', 1)) </pre>

#

obeattie (on March 11, 2007):
<p>Just one little gotcha...</p> <p>The template should ensure that it is using a string... so Line 6 should read:</p> <p>bits = str(value).rsplit(' ', 1)</p> <p>Therefore, if an object which is not a string is passed to it, it's string method will be called to ensure that the filter will work as intended.</p> <p>Otherwise, this is brilliant!</p>

#

amr-mostafa (on April 22, 2007):
<p>Nice one! Thanks</p>

#

Please login first before commenting.