Template tag to create mailto links with options

  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
124
125
from django import template
from django.template import Node, NodeList, TemplateSyntaxError

register = template.Library()

class MailtoNode(Node):
    '''
        Node for mailto tag
    '''    
    def __init__(self, nodelist, email, subject, cc_list, bcc_list):
        self.nodelist = nodelist
        self.email=template.Variable(email)
        
        self.subject_words=None
        if subject is not None:
            if subject[0] == subject[-1] and subject[0] in ('"', "'"):
                subject=subject[1:-1]
            self.subject_words=[template.Variable(subject_word[2:-2]) if subject_word[0:2] == "{{" and subject_word[-2:] == "}}" else subject_word for subject_word in subject.split(" ")]
            
        self.cc_list=None
        if cc_list is not None:
            if cc_list[0] == cc_list[-1] and cc_list[0] in ('"', "'"):
                self.cc_list=cc_list[1:-1]
            else:
                self.cc_list=template.Variable(cc_list)

        self.bcc_list=None
        if bcc_list is not None:
            if bcc_list[0] == bcc_list[-1] and bcc_list[0] in ('"', "'"):
                self.bcc_list=bcc_list[1:-1]
            else:
                self.bcc_list=template.Variable(bcc_list)

    def render(self, context):
        try:
            email=self.email.resolve(context)
        except:
            email=self.email
            
        additional='?'
        if self.subject_words is not None:
            subject_words_expanded=[]
            for word in self.subject_words:
                word_expanded=''
                try:
                    word_expanded = word.resolve(context)
                except: 
                    word_expanded = word
                # Mailto links sometimes truncates the URI if there is an ampersand in the string somewhere
                subject_words_expanded.append(str(word_expanded).replace('&', '%26').replace('&','%26'))
            additional += 'subject=%s&' % " ".join(subject_words_expanded)
    
        if self.cc_list is not None:
            try:
                cc_list=self.cc_list.resolve(context)
                if isinstance(cc_list, list):
                    cc_list=",".join(cc_list)
            except:
                cc_list=self.cc_list
            additional += 'cc=%s&' % (cc_list)
            
        if self.bcc_list is not None:
            try:
                bcc_list=self.bcc_list.resolve(context)
                if isinstance(bcc_list, list):
                    bcc_list=",".join(bcc_list)
            except:
                bcc_list=self.bcc_list
            additional += 'bcc=%s&' % (bcc_list)
           
        nodelist_expanded=[]
        for node in self.nodelist:
            try:
                nodelist_expanded.append(node.render(context))
            except:
                nodelist_expanded.append(node)
        linktext=' '.join(nodelist_expanded)
            
        return '<a href="mailto:%s%s">%s</a>' % (email, additional[0:-1], linktext)

@register.tag
def mailto(parser, token):
    '''
        Custom template tag to create complete mailto links.
        
        Format:
        
        {% mailto email subject comma_separated_cc_list comma_separated_bcc_list %}link content{% endmailto %}
        
        Where:  email is the recipient (only required field; string or context variable)
                subject is the subject for the email (optional; string containing context variables with no {{}}.)
                cc is the comma separated list of carbon copied (optional; will also accept a variable containing a string or python list)
                bcc is the comma separated list of blind carbon copied (optional; will also accept a variable containing a string or a python list)
        
        Examples: 
            {% mailto 'blah@blah.com' 'subject line' 'nancy@blah.com, joe@blah.com' 'secret@blah.com' %}link text{% endmailto %}
        Produces:
            <a href="mailto:blah@blah.com?subject=subject line&cc=nancy@blah.com, joe@blah.com&bcc=secret@blah.com">link text</a>
    
        Examples: 
            {% mailto context.var.email 'subject for user.get_full_name' context.var.cc 'secret@blah.com' %}link text{% endmailto %}
            Where context.var.email has joedoe@doeloop.com, context.var.cc has janedoe@doeloop.com, and current user is jimmy
        Produces:
            <a href="mailto:joedoe@doeloop.com?subject=subject for jimmy&cc=janedoe@doeloop.com&bcc=secret@blah.com">link text</a>
    '''
    tokenlist = token.split_contents()
    if len(tokenlist) < 2:
        raise TemplateSyntaxError("'%s' takes at least one argument"
                                  " (the email recipient)" % tokenlist[0])
    
    email=tokenlist[1]
    subject=None
    if len(tokenlist) >= 3:
        subject = tokenlist[2]
    cc_list=None
    if len(tokenlist) >= 4:
        cc_list=tokenlist[3]
    bcc_list=None
    if len(tokenlist) == 5:
        bcc_list=tokenlist[4]
    
    nodelist = parser.parse(('endmailto',))
    parser.delete_first_token()
    
    return MailtoNode(nodelist, email, subject, cc_list, bcc_list)

More like this

  1. Encode emails as URIs by fahhem 3 years, 8 months ago
  2. Paginator TemplateTag by trbs 6 years ago
  3. Recurse template tag for Django by Zarin 6 years, 2 months ago
  4. Protect anti robots template tag by marinho 5 years, 11 months ago
  5. favicon Template Tag by benjy_mouse 4 years, 2 months ago

Comments

(Forgotten your password?)