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 '%s' % (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: link text 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: link text ''' 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)