Word-boundary-aware string truncation template filter

This is a custom template filter that allows you to truncate a string to a maximum of num characters, but respecting word boundaries. So, for example, if string = "This is a test string.", then {{ string|truncatechars:12 }} would give you "This is a..." instead of "This is a te".

fromdjango.templateimportLibraryfromdjango.utils.encodingimportforce_unicodefromdjango.utils.functionalimportallow_lazyfromdjango.template.defaultfiltersimportstringfilterregister=Library()deftruncate_chars(s,num):""" Template filter to truncate a string to at most num characters respecting word boundaries. """s=force_unicode(s)length=int(num)iflen(s)>length:length=length-3ifs[length-1]==' 'ors[length]==' ':s=s[:length].strip()else:words=s[:length].split()iflen(words)>1:delwords[-1]s=u' '.join(words)s+='...'returnstruncate_chars=allow_lazy(truncate_chars,unicode)deftruncatechars(value,arg):""" Truncates a string after a certain number of characters, but respects word boundaries. Argument: Number of characters to truncate after. """try:length=int(arg)exceptValueError:# If the argument is not a valid integer.returnvalue# Fail silently.returntruncate_chars(value,length)truncatechars.is_safe=Truetruncatechars=stringfilter(truncatechars)register.filter(truncatechars)