feat: markdown in email body for mailing and transactional
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
{{ form_row(form.headline) }}
|
||||
{{ form_row(form.body) }}
|
||||
|
||||
{{ include('_partials/_markdown_hint.html.twig') }}
|
||||
|
||||
<div class="bg-gray-100 rounded-md p-4 text-sm">
|
||||
<div class="font-bold pb-2">
|
||||
Verfügbare Platzhalter
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
{% if text.headline is not empty %}
|
||||
<h1 class="text-xl font-bold pb-2">{{ text.headline | raw }}</h1>
|
||||
{% endif %}
|
||||
{# The paragraphs come from the mail body, where email/layout.html.twig styles every
|
||||
<p> with padding-bottom:16px - pb-4 is the same spacing, so the preview matches. #}
|
||||
<div class="[&>p]:pb-4 [&_a]:underline">
|
||||
{# .mail-body carries the spacing and list styling of email/layout.html.twig, so this
|
||||
pane and the mailing pane both show what the mail will look like. #}
|
||||
<div class="mail-body">
|
||||
{{ text.bodyHtml | raw }}
|
||||
</div>
|
||||
<p>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<div class="pb-4">
|
||||
<span class="font-bold">Betreff:</span> {{ subject }}
|
||||
</div>
|
||||
{# App\Email\MailBodyRenderer escaped everything before it introduced a tag, which is what
|
||||
makes |raw safe here - see the contract on that class. #}
|
||||
<div class="mail-body border border-gray-200 rounded-md p-4">
|
||||
{{ bodyHtml | raw }}
|
||||
<p>
|
||||
<span class="btn inline-block">Zum Portal</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="pt-4 text-sm text-gray-500">
|
||||
Platzhalter sind mit deinem eigenen Namen gefüllt, beim Versand steht dort der Name der
|
||||
jeweiligen Person. Logo und Fußzeile der E-Mail sind hier nicht abgebildet.
|
||||
</div>
|
||||
@@ -27,29 +27,64 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{# the draft is parked on every keystroke so that a trip to the filter and back keeps it,
|
||||
hx-trigger replaces htmx' default submit trigger, the preview button still posts natively #}
|
||||
{{ form_start(form, { 'attr': {
|
||||
'hx-post': path('app_admin_teamer_mailing_draft'),
|
||||
'hx-trigger': 'input changed delay:500ms',
|
||||
'hx-swap': 'none',
|
||||
} }) }}
|
||||
<div class="flex flex-col space-y-4 pb-4 max-w-3xl">
|
||||
{{ form_row(form.subject) }}
|
||||
{{ form_row(form.message) }}
|
||||
</div>
|
||||
{# One request per keystroke parks the draft - so that a trip to the filter and back
|
||||
keeps it - and answers with the preview, which is why the response is swapped into
|
||||
the pane instead of being thrown away. hx-trigger replaces htmx' default submit
|
||||
trigger, the "Vorschau an mich senden" button still posts natively.
|
||||
|
||||
<div class="pb-8 max-w-3xl text-sm text-gray-500">
|
||||
<div class="pb-2">
|
||||
Platzhalter für Betreff und Nachricht, sie werden beim Senden pro Person ersetzt:
|
||||
Deliberately without htmx' "changed" modifier: it compares the listening element's
|
||||
.value between events, and a <form> has none, so every event compares undefined to
|
||||
undefined and the request is never sent. The 500ms delay is what keeps the typing
|
||||
from flooding the route. #}
|
||||
{{ form_start(form, { 'attr': {
|
||||
'id': 'mailing-form',
|
||||
'hx-post': path('app_admin_teamer_mailing_draft'),
|
||||
'hx-trigger': 'input delay:500ms',
|
||||
'hx-target': '#mailing-preview',
|
||||
'hx-swap': 'innerHTML',
|
||||
'hx-indicator': '#mailing-preview-indicator',
|
||||
} }) }}
|
||||
<div class="grid lg:grid-cols-2 gap-8 items-start">
|
||||
<div>
|
||||
<div class="flex flex-col space-y-4 pb-4">
|
||||
{{ form_row(form.subject) }}
|
||||
{{ form_row(form.message) }}
|
||||
</div>
|
||||
|
||||
<div class="pb-6">
|
||||
{{ include('_partials/_markdown_hint.html.twig') }}
|
||||
</div>
|
||||
|
||||
<div class="pb-8 text-sm text-gray-500">
|
||||
<div class="pb-2">
|
||||
Platzhalter für Betreff und Nachricht, sie werden beim Senden pro Person ersetzt:
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{% for placeholder, label in placeholders %}
|
||||
<span class="inline-flex items-center space-x-1 py-1 px-2 bg-gray-50 border border-gray-200 rounded">
|
||||
<code>{{ placeholder }}</code>
|
||||
<span>{{ label }}</span>
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{% for placeholder, label in placeholders %}
|
||||
<span class="inline-flex items-center space-x-1 py-1 px-2 bg-gray-50 border border-gray-200 rounded">
|
||||
<code>{{ placeholder }}</code>
|
||||
<span>{{ label }}</span>
|
||||
</span>
|
||||
{% endfor %}
|
||||
|
||||
<div class="lg:sticky lg:top-4">
|
||||
<div class="font-bold pb-2">
|
||||
Vorschau
|
||||
</div>
|
||||
<div class="relative">
|
||||
<div id="mailing-preview">
|
||||
{{ include('admin/teamer/_mailing_preview.html.twig', preview) }}
|
||||
</div>
|
||||
{# Deliberately a sibling of the swap target, not a child: hx-swap replaces
|
||||
the target's contents, which would carry the indicator away with them. #}
|
||||
<div class="htmx-indicator absolute inset-0 bg-white/75 flex items-center justify-center"
|
||||
id="mailing-preview-indicator">
|
||||
{{ include('_partials/_spinner.html.twig', { 'class': 'w-8 h-8' }) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user