Login

email_links

Author:
sansmojo
Posted:
June 5, 2007
Language:
Python
Version:
.96
Score:
2 (after 2 ratings)

A very basic app centered around a template tag that takes an e-mail address and optional label and returns a link to an e-mail form. This way, you can easily throw e-mail addresses into your template that will automatically link to an e-mail form instead of displaying the e-mail address itself.

The model for this app is extremely simple, with only one field to store the e-mail address. When an e-mail is passed to the email_link template tag, the e-mail address is added to the database if it is not already there. This is stored in the database in order to keep the full e-mail address hidden from the viewer.

To use, simply create an app called 'email_links' (or you can change the name if you also change line 4 of email_extras.py to reflect the change). Then use the models.py and views.py provided. Add a templatetags directory under your app, and add email_extras.py and a blank init.py

In your urls.py, add the following to your urlpatterns (subsitute project_name for your own):

(r'^email/(?P<email_id>[0-9]+)/$', 'project_name.email_links.views.email_form'),

Create two templates: email_links/email_form.html and email_links/thanks.html (the examples here are extremely basic - make them however you want).

Finally, in a template where you want to provide a link to e-mail someone, first load email_extras:

{% load email_extras %}

Then do one of the following: {% email_link "[email protected]" %}

{% email_link "[email protected]" "E-mail someone" %}

Both will create a link to the e-mail form. The first will use mask_email (from the snippet by jkocherhans) to create the link. The second will display the second argument "E-mail someone" in the link.

Also note that I've used the Sites add-on to generate the links, but you can easily change this to suit your needs.

I hope all of this makes sense. I'm a bit tired, but wanted to get this up before bed.

  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
117
118
119
120
121
122
123
### models.py:
from django.db import models

from django.contrib.sites.models import Site

class Email(models.Model):
    """Model to store e-mail addresses linked to from the site."""
    email       = models.EmailField(unique=True)

    def __str__(self):
        return self.email

    def get_absolute_url(self):
        return '/email/%s/' % self.id

    class Admin:
        pass

### views.py:
from django import newforms as forms
from django.core.mail import send_mail
from django.shortcuts import get_object_or_404, render_to_response

from models import Email

class EmailForm(forms.Form):
    name        = forms.CharField(max_length=100)
    email       = forms.EmailField('E-mail address')
    subject     = forms.CharField(max_length=100)
    message     = forms.CharField(widget=forms.Textarea())
    cc_myself   = forms.BooleanField(label='Send a copy of my message to me.', required=False)

def email_form(request, email_id):
    recipient = get_object_or_404(Email, pk=email_id)

    if request.method == 'POST':
        newdata = request.POST.copy()

        form = EmailForm(data=newdata)
        if form.is_valid():
            name        = form.cleaned_data['name']
            email       = form.cleaned_data['email']
            subject     = form.cleaned_data['subject']
            message     = form.cleaned_data['message']
            cc_myself   = form.cleaned_data['cc_myself']

            sender = "%s <%s>" % ( name, email )

            send_mail(subject, message, sender, [recipient.email,], fail_silently=False)

            if cc_myself:
                cc_subject = "Copy of %s" % subject

                send_mail(cc_subject, message, sender, [sender,], fail_silently=False)

            return render_to_response('email_links/thanks.html', { 'email': recipient.email })
    else:
        form = EmailForm()

    return render_to_response('email_links/email_form.html', { 'form': form, 'email': recipient.email })

### templatetags/email_extras.py:
from django.template import Library
from django.contrib.sites.models import Site

from email_links.models import Email

register = Library()

def mask_email(email):
    """
    Mask an email address.
    Credit to jkocherhans (http://www.djangosnippets.org/snippets/79/)
    """
    name, domain = email.split('@')
    if len(name) > 5:
        # show the first 3 characters
        masked_name = name[:3]
    else:
        # just use the 1st character
        masked_name = name[0]
    return "%s...@%s" % ( masked_name, domain )

register.filter('mask_email', mask_email)

def email_link(email, label=None):
    """
    Returns an e-mail link, with an optional label.

    Examples:
        {% email_link email label %}
        {% email_link email %}
    """
    email_object = Email.objects.get_or_create(email=email)[0]
    if label is None:
        label = mask_email(email)
    return '<a href="http://%s%s">%s</a>' % ( Site.objects.get_current().domain, email_object.get_absolute_url(), label )

register.simple_tag(email_link)

### templates/email_links/email_form.html:
"""
<html>
<body>
  <form method="post" action=".">
  <p>Send an e-mail to {{ email|mask_email }}</p>
  <table>
  {{ form }}
  <tr><td colspan="2" align="center"><input type="submit" name="send" value="Send e-mail" /></td></tr>
  </table>
  </form>
</body>
</html>
"""

### templates/email_links/thanks.html:
"""
<html>
<body>
  <h2>Thanks!!</h2>
</body>
</html>
"""

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

amr-mostafa (on June 5, 2007):

Very nice!

It has 1 drawback though, is that e-mail addresses can be harvested by spambots. The masking introduced here only masks the e-mails for the visual eye of the user, but view-source-ing the page would reveal the address.

One way to workaround this is to base64 encode it in the link, and decode it later on the submission. That theoretically hides it from 100% of spambot (I mean who would want to base64 decode every string checking if it's an e-mail or not :P), but to be technically 100% safe, maybe encrypt it with a secret key, (the one in settings.py for example), and decrypt it on submission.

Cheers for the nice piece

#

Please login first before commenting.