from django import template from django.utils.safestring import mark_safe import random import re """ Example Usage in the template:

{{ email|hide_email }}
{{ email|hide_email:"Contact Me" }}
{% hide_email "name@example.com" %}
{% hide_email "name@example.com" "John Smith" %}

{{ text_block|hide_all_emails|safe }} All hidden emails are rendered as a hyperlink that is protected by javascript and an email and name that are encoded randomly using a hex digit or a decimal digit for each character. Example of how a protected email is rendered: """ # snagged this function from http://www.djangosnippets.org/snippets/216/ def encode_string(value): """ Encode a string into it's equivalent html entity. The tag will randomly choose to represent the character as a hex digit or decimal digit. """ e_string = "" for a in value: type = random.randint(0,1) if type: en = "&#x%x;" % ord(a) else: en = "&#%d;" % ord(a) e_string += en return e_string def HideEmail(email, name=None): name = name or email mailto_link = u'%s' % (encode_string(email), encode_string(name)) return u"\n\n" \ +'\n" % (mailto_link) class HideEmailNode(template.Node): def __init__(self, email, name): self.name = template.Variable(name) self.email = template.Variable(email) def render(self, context): name = self.name.resolve(context) email = self.email.resolve(context) return HideEmail(email, name) def do_hide_email(parser, token): try: format_string = token.split_contents() # if just an email is provided then use the email address as the name if len(format_string) == 2: format_string.append(format_string[1]) except: raise template.TemplateSyntaxError, "'%r' tag requires at least an email address or an email address and a person's name ({% hide_email user@example.com %} or {% hide_email \"user@example.com\" \"John Smith\" %})" % token.contents.split()[0] return HideEmailNode(format_string[1], format_string[2]) def hide_email_filter(email, name=None): name = name or email value = HideEmail(email, name) return mark_safe(value) def hide_all_emails_filter(value): # hide mailto links def mailto_hide_callback(matchobj): return HideEmail(matchobj.group(1), matchobj.group(2)) pattern = '([^<]+)' value = re.sub(pattern, mailto_hide_callback, value) # hyperlink emails and hide them def hide_email_callback(matchobj): return HideEmail(matchobj.group(0), matchobj.group(0)) pattern = "([\.\w-]+@[\w-]+\.[\w-]+)" value = re.sub(pattern, hide_email_callback, value) return mark_safe(value) register = template.Library() register.tag('hide_email', do_hide_email) register.filter('hide_email', hide_email_filter) register.filter('hide_all_emails', hide_all_emails_filter)