1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 | from django import template
from django.utils.safestring import mark_safe
import random
import re
"""
Example Usage in the template:
<p>{{ email|hide_email }}<br />
{{ email|hide_email:"Contact Me" }}<br />
{% hide_email "name@example.com" %}<br />
{% hide_email "name@example.com" "John Smith" %}</p>
{{ 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:
<noscript>(Javascript must be enabled to see this e-mail address)</noscript>
<script type="text/javascript">// <![CDATA[
document.write('<a href="mai'+'lto:john@example.com">John Smith</a>')
// ]]></script>
"""
# 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'<a href="mai\'+\'lto:%s">%s</a>' % (encode_string(email), encode_string(name))
return u"\n<noscript>(Javascript must be enabled to see this e-mail address)</noscript>\n" \
+'<script type="text/javascript">// <![CDATA['+"\n \
\tdocument.write('%s')\n \
\t// ]]></script>\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 = '<a href="mailto:([\.\w-]+@[\w-]+\.[\w-]+)">([^<]+)</a>'
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)
|
Comments