Anonymous avatar Anonymous committed 7cbcba4

[svn] port mail_to and related tests from rails.

hex encoding was implemented and tested differently, it may not work
100% correctly. The javascript encoding is better anyway, it encodes
any cc and bcc addresses as well.

Comments (0)

Files changed (2)

tests/test_url.py

         self.assertEqual("<a href=\"http://www.example.com\" onclick=\"if (confirm('Are you serious?')) { f = document.createElement('form'); document.body.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit(); };return false;\">Hello</a>",
                link_to("Hello", "http://www.example.com", post=True, confirm="Are you serious?"))
     
+    def test_mail_to(self):
+        self.assertEqual('<a href="mailto:justin@example.com">justin@example.com</a>', mail_to("justin@example.com"))
+        self.assertEqual('<a href="mailto:justin@example.com">Justin Example</a>', mail_to("justin@example.com", "Justin Example"))
+        self.assertEqual('<a class="admin" href="mailto:justin@example.com">Justin Example</a>',
+                         mail_to("justin@example.com", "Justin Example", class_="admin"))
+
+    def test_mail_to_with_javascript(self):
+        self.assertEqual("<script type=\"text/javascript\">\n//<![CDATA[\neval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%4d%79%20%65%6d%61%69%6c%3c%2f%61%3e%27%29%3b'))\n//]]>\n</script>", mail_to("me@domain.com", "My email", encode = "javascript"))
+
+    def test_mail_to_with_options(self):
+        self.assertEqual('<a href="mailto:me@example.com?cc=ccaddress%40example.com&amp;body=This%20is%20the%20body%20of%20the%20message.&amp;subject=This%20is%20an%20example%20email&amp;bcc=bccaddress%40example.com">My email</a>',
+            mail_to("me@example.com", "My email", cc="ccaddress@example.com",
+                    bcc="bccaddress@example.com", subject="This is an example email",
+                    body="This is the body of the message."))
+
+    def test_mail_to_with_img(self):
+        self.assertEqual('<a href="mailto:feedback@example.com"><img src="/feedback.png" /></a>',
+                        mail_to('feedback@example.com', '<img src="/feedback.png" />'))
+
+    def test_mail_to_with_hex(self):
+        self.assertEqual('<a href="mailto:%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d">My email</a>',
+                        mail_to("me@domain.com", "My email", encode = "hex"))
+
+    def test_mail_to_with_replace_options(self):
+        self.assertEqual('<a href="mailto:wolfgang@stufenlos.net">wolfgang(at)stufenlos(dot)net</a>',
+                        mail_to("wolfgang@stufenlos.net", None, replace_at="(at)", replace_dot="(dot)"))
+        self.assertEqual('<a href="mailto:%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d">me(at)domain.com</a>',
+                        mail_to("me@domain.com", None, encode="hex", replace_at="(at)"))
+        self.assertEqual('<a href="mailto:%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d">My email</a>',
+                        mail_to("me@domain.com", "My email", encode="hex", replace_at="(at)"))
+        self.assertEqual('<a href="mailto:%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d">me(at)domain(dot)com</a>', mail_to("me@domain.com", None, encode="hex", replace_at="(at)", replace_dot="(dot)"))
+        self.assertEqual("<script type=\"text/javascript\">\n//<![CDATA[\neval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%4d%79%20%65%6d%61%69%6c%3c%2f%61%3e%27%29%3b'))\n//]]>\n</script>",
+                        mail_to("me@domain.com", "My email", encode="javascript", replace_at="(at)", replace_dot="(dot)"))
 
 if __name__ == '__main__':
     suite = [unittest.makeSuite(TestURLHelper)]
     for testsuite in suite:
-        unittest.TextTestRunner(verbosity=1).run(testsuite)
+        unittest.TextTestRunner(verbosity=1).run(testsuite)

webhelpers/rails/urls.py

 URL Helpers
 """
 import cgi
+import urllib
 
 from webhelpers.util import html_escape
 
 def post_javascript_function():
     return "f = document.createElement('form'); document.body.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit();"
 
+
+def mail_to(email_address, name=None, cc=None, bcc=None, subject=None, body=None, replace_at=None, replace_dot=None, encode=None, **html_options):
+    """
+      Creates a link tag for starting an email to the specified <tt>email_address</tt>, which is also used as the name of the
+      link unless +name+ is specified. Additional HTML options, such as class or id, can be passed in the <tt>html_options</tt> hash.
+      
+      You can also make it difficult for spiders to harvest email address by obfuscating them.
+      Examples:
+        >>> mail_to("me@domain.com", "My email", encode = "javascript")  # =>
+        <script type="text/javascript" language="javascript">eval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%4d%79%20%65%6d%61%69%6c%3c%2f%61%3e%27%29%3b'))</script>
+      
+        >>> mail_to("me@domain.com", "My email", encode = "hex")  # =>
+        <a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">My email</a>
+      
+      You can also specify the cc address, bcc address, subject, and body parts of the message header to create a complex e-mail using the
+      corresponding +cc+, +bcc+, +subject+, and +body+ keyword arguments. Each of these options are URI escaped and then appended to
+      the <tt>email_address</tt> before being output. <b>Be aware that javascript keywords will not be escaped and may break this feature
+      when encoding with javascript.</b>
+      Examples:
+        >>> mail_to("me@domain.com", "My email", cc="ccaddress@domain.com", bcc="bccaddress@domain.com", subject="This is an example email",
+            body= "This is the body of the message.")   # =>
+        <a href="mailto:me@domain.com?cc="ccaddress@domain.com"&bcc="bccaddress@domain.com"&body="This%20is%20the%20body%20of%20the%20message."&subject="This%20is%20an%20example%20email">My email</a>
+    """
+    extras = {}
+    for key, option in ('cc', cc), ('bcc', bcc), ('subject', subject), ('body', body):
+        if option:
+            extras[key] = option
+    options_query = urllib.urlencode(extras).replace("+", "%20")
+
+    email_address_obfuscated = email_address
+    if replace_at:
+        email_address_obfuscated = email_address_obfuscated.replace('@', replace_at)
+    if replace_dot:
+        email_address_obfuscated = email_address_obfuscated.replace('.', replace_dot)
+
+    if encode=='hex':
+        email_address = ''.join(['%%%x' % ord(x) for x in email_address])
+
+    url = 'mailto:' + email_address
+    if options_query:
+        url += '?' + options_query
+    html_options['href'] = url
+
+    tag = tags.content_tag('a', name or email_address_obfuscated, **html_options)
+
+    if encode =='javascript':
+        tmp = "document.write('%s');" % tag
+        string = ''.join(['%%%x' % ord(x) for x in tmp])
+        return javascript_tag("eval(unescape('%s'))" % string)
+    else : 
+        return tag
+    
+
 __all__ = ['url', 'link_to', 'button_to', 'link_to_unless_current', 'link_to_unless', 'link_to_if',
-           'current_page', 'current_url']
+           'current_page', 'current_url', 'mail_to']
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.