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)