Tag pro odkazy na poslání mailu #22
5 changed files with 121 additions and 4 deletions
|
@ -1,6 +1,7 @@
|
|||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% load deadliny %}
|
||||
{% load mail %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
|
@ -14,7 +15,14 @@
|
|||
|
||||
{% if edit %}
|
||||
<p>Řešitelé:
|
||||
{% for r in object.resitele.all %}{{ r }} (<a href="mailto:{{ r.osoba.email }}?subject={{ "Oprava řešení M&M " | urlencode }}{{ object.problem.all.0.hlavni_problem | urlencode }}">{{ r.osoba.email }}</a>){% if forloop.revcounter0 != 0 %}, {% endif %}{% endfor %}
|
||||
{% for r in object.resitele.all %}
|
||||
{{ r }}
|
||||
{# DjangoTemplates neumí spojovat řetězce (https://stackoverflow.com/q/4386168), tak si necháváme vyrobit subject mailu ve view. #}
|
||||
zelvuska marked this conversation as resolved
Outdated
|
||||
({% maillink r.osoba.email to=r.osoba.email subject=predmetmailu %}){% if forloop.revcounter0 != 0 %}, {% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
<p>
|
||||
{% maillink "Poslat mail všem řešitelům" bcc=maily_vsech_resitelu subject=predmetmailu %}
|
||||
</p>
|
||||
{% else %}
|
||||
<p>Řešitelé: {{ object.resitele.all | join:", " }}</p>
|
||||
|
|
|
@ -235,8 +235,12 @@ class DetailReseniView(DetailView):
|
|||
def get_context_data(self, **kw):
|
||||
self.check_access()
|
||||
ctx = super().get_context_data(**kw)
|
||||
hodnoceni = self.aktualni_hodnoceni()
|
||||
ctx["hodnoceni"] = hodnoceni
|
||||
detaily_hodnoceni = self.aktualni_hodnoceni()
|
||||
ctx["hodnoceni"] = detaily_hodnoceni
|
||||
|
||||
# Subject případného mailu (template neumí použitelně spojovat řetězce: https://stackoverflow.com/q/4386168)
|
||||
ctx["predmetmailu"] = "Oprava řešení M&M "+self.reseni.problem.first().hlavni_problem.nazev
|
||||
ctx["maily_vsech_resitelu"] = [y for x in self.reseni.resitele.all().values_list('osoba__email') for y in x]
|
||||
return ctx
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
|
0
various/templatetags/__init__.py
Normal file
0
various/templatetags/__init__.py
Normal file
48
various/templatetags/mail.py
Normal file
48
various/templatetags/mail.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
from django import template
|
||||
from django.utils.safestring import mark_safe
|
||||
from urllib.request import quote as urlencode
|
||||
register = template.Library()
|
||||
|
||||
@register.simple_tag
|
||||
def mailurl(*, subject=None, body=None, to=[], cc=[], bcc=[]):
|
||||
"""Tag na vytváření správně zakódované mailto: adresy
|
||||
|
||||
Ref: RFC 6068, <https://en.wikipedia.org/wiki/Mailto>"""
|
||||
if isinstance(to, str):
|
||||
to = [to]
|
||||
if isinstance(cc, str):
|
||||
cc = [cc]
|
||||
if isinstance(bcc, str):
|
||||
bcc = [bcc]
|
||||
assert isinstance(to, list)
|
||||
assert isinstance(cc, list)
|
||||
assert isinstance(bcc, list)
|
||||
# FIXME: adresa není správně zakódovaná, rozbije se to na adresách s divnými znaky
|
||||
parts = [
|
||||
f'mailto:{str.join(",", to)}',
|
||||
]
|
||||
if len(to) + len(cc) + len(bcc) < 1:
|
||||
raise ValueError('Cannot mail to empty set of people')
|
||||
|
||||
if subject:
|
||||
parts.append(f'subject={urlencode(subject)}')
|
||||
if body:
|
||||
parts.append(f'body={urlencode(body)}')
|
||||
if len(cc) > 0:
|
||||
parts.append(f'cc={str.join(",", cc)}')
|
||||
if len(bcc) > 0:
|
||||
parts.append(f'bcc={str.join(",", bcc)}')
|
||||
|
||||
if len(parts) > 1:
|
||||
url = parts[0] + '?' + str.join('&', parts[1:])
|
||||
else:
|
||||
url = parts[0]
|
||||
return url
|
||||
|
||||
@register.simple_tag
|
||||
def maillink(text, subject=None, body=None, to=[], cc=[], bcc=[], attrs=None):
|
||||
url = mailurl(subject=subject, body=body, to=to, cc=cc, bcc=bcc)
|
||||
if not attrs: attrs = ''
|
||||
mezera = ' '*bool(attrs)
|
||||
full_link = f'<a href="{url}"{mezera}{attrs}>{text}</a>'
|
||||
return mark_safe(full_link)
|
|
@ -1,3 +1,60 @@
|
|||
from django.test import TestCase
|
||||
# TODO: Možná vyrobit separátní soubory v tests/… než mít všechny testy v jednom souboru?
|
||||
from various.templatetags.mail import maillink, mailurl
|
||||
|
||||
# Create your tests here.
|
||||
class MailTagsTest(TestCase):
|
||||
"""Testuje template tagy ohledně mailů."""
|
||||
def test_maillink(self):
|
||||
# Tohle nedává smysl dělit do víc funkcí, bylo by v nich víc boilerplatu než užitečného kódu.
|
||||
self.assertEquals(maillink('Hello', to='some@body.test'), r'<a href="mailto:some@body.test">Hello</a>')
|
||||
self.assertEquals(maillink('Hello', to=['some@body.test']), r'<a href="mailto:some@body.test">Hello</a>')
|
||||
self.assertEquals(
|
||||
maillink('Hello', to=['alice@test.test', 'bob@jinde.test']),
|
||||
r'<a href="mailto:alice@test.test,bob@jinde.test">Hello</a>',
|
||||
)
|
||||
self.assertEquals(
|
||||
maillink('Hello', to='some@body.test', attrs='class="trida" id="id"'),
|
||||
r'<a href="mailto:some@body.test" class="trida" id="id">Hello</a>',
|
||||
)
|
||||
# Následující test toho testuje moc zároveň, měly by předcházet dedikované testy… (kašlu na ně :-P)
|
||||
self.assertEquals(
|
||||
maillink('Text odkazu', to='prijemce@wtf.test', subject="Předmět", body="Čau"),
|
||||
r'<a href="mailto:prijemce@wtf.test?subject=P%C5%99edm%C4%9Bt&body=%C4%8Cau">Text odkazu</a>',
|
||||
)
|
||||
self.assertRaises(ValueError, lambda: maillink('Nemám příjemce'))
|
||||
self.assertRaises(TypeError, lambda: maillink()) # Nemá text, takže to shodí python
|
||||
|
||||
def test_mailurl(self):
|
||||
self.assertEquals(mailurl(to='some@body.test'), r'mailto:some@body.test')
|
||||
self.assertEquals(mailurl(to=['some@body.test']), r'mailto:some@body.test')
|
||||
self.assertEquals(mailurl(to=['alice@test.test', 'bob@jinde.test']), r'mailto:alice@test.test,bob@jinde.test')
|
||||
zelvuska marked this conversation as resolved
Outdated
zelvuska
commented
Není to tohle: https://docs.djangoproject.com/en/3.2/topics/templates/#django.template.loader.render_to_string Není to tohle:
from django.template.loader import render_to_string
https://docs.djangoproject.com/en/3.2/topics/templates/#django.template.loader.render_to_string
zelvuska
commented
Aha, to bere soubor… Aha, to bere soubor…
|
||||
self.assertEquals(
|
||||
mailurl(to='some@body.test', body='Tělo', subject='Předmět'),
|
||||
r'mailto:some@body.test?subject=P%C5%99edm%C4%9Bt&body=T%C4%9Blo',
|
||||
)
|
||||
self.assertRaises(ValueError, lambda: mailurl())
|
||||
|
||||
def test_render_in_template(self):
|
||||
# Pomocná funkce: vykreslí template do stringu
|
||||
# Ref: https://stackoverflow.com/a/1690879
|
||||
def render_template(template, context=None):
|
||||
from django.template import Template, Context
|
||||
context = context or {}
|
||||
context = Context(context)
|
||||
return Template(template).render(context)
|
||||
|
||||
template = (
|
||||
r'{% load mail %}'
|
||||
# TODO: Vyzkoušet i víc adresátů. (Nepamatuji si z hlavy syntaxi…)
|
||||
r'{% maillink "Text" to="alice@test.test" subject="Oprava řešení" %}'
|
||||
)
|
||||
self.assertEquals(
|
||||
render_template(template),
|
||||
r'<a href="mailto:alice@test.test?subject=Oprava%20%C5%99e%C5%A1en%C3%AD">Text</a>',
|
||||
)
|
||||
|
||||
mailurltemplate = (
|
||||
r'{% load mail %}'
|
||||
r'{% mailurl to="alice@test.test" subject="Čau Alice" %}'
|
||||
)
|
||||
self.assertEquals(render_template(mailurltemplate), r'mailto:alice@test.test?subject=%C4%8Cau%20Alice')
|
||||
|
|
Loading…
Reference in a new issue
Přemýšlím, jestli to nechce komentář, proč máme
mailsubject
generovaný ve view, když je to prakticky čistě prezentační záležitost… Názory?A možná v template komentář, kde se vzal mailsubject / co to je?
Template IMHO spíš komentář nepotřebuje. Je to evidentně subject mailu, a věci se typicky berou v kontextu (a v development toolbaru by měl být normálně vidět). Ta divná věc je to, že ho bastlíme ve view…
Ale možná by se mohl jmenovat česky, není důvod to tak neudělat (kromě toho, že jsem to nejspíš kódil v tramvaji a tam kódím většinou anglicky :-D)