From redaxo-yform
Guides YForm email templates with REX_YFORM_DATA placeholders, tpl2email form actions, programmatic PHP sending, attachments, and substitution troubleshooting.
How this skill is triggered — by the user, by Claude, or both
Slash command
/redaxo-yform:yform-email-templatesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
YForm ships its own email-template system, separate from REDAXO's content. Templates live under **YForm → Email Templates** in the backend with a key, subject, plain-text body, optional HTML body, and From/To metadata.
YForm ships its own email-template system, separate from REDAXO's content. Templates live under YForm → Email Templates in the backend with a key, subject, plain-text body, optional HTML body, and From/To metadata.
Inside a template body or subject, reference form fields with:
REX_YFORM_DATA[field="fieldname"]
For choice fields, two extra suffixes give you the human-readable labels instead of the stored values:
REX_YFORM_DATA[field="choice_field_LABELS"] -- choice labels as comma-separated text
REX_YFORM_DATA[field="choice_field_LIST"] -- choice labels with line breaks
Inline PHP also works inside templates:
<?php
if ('REX_YFORM_DATA[field="anrede"]' == 'w') {
echo "Frau";
} else {
echo "Herr";
}
?>
Substitution happens after placeholder replacement, so the literal 'REX_YFORM_DATA[...]' becomes the field value before PHP runs.
tpl2email)$yform->setActionField('tpl2email', [
'template_key', // backend template key
'', // sender email field (or '' to use template's From)
'email', // recipient email field name
]);
In pipe syntax:
action|tpl2email|template_key|email_sender_field|email_recipient_field
The action runs after validation passes. Multiple tpl2email actions per form are allowed (e.g. notify admin + send confirmation to user).
Use this when you need to send a YForm email template from a cronjob, a callback action, or anywhere outside the form lifecycle:
$tpl = rex_yform_email_template::getTemplate('template_key');
if (!$tpl) {
return; // template doesn't exist
}
$values = [
'vorname' => 'Max',
'nachname' => 'Mustermann',
'email' => '[email protected]',
];
foreach ($values as $key => $value) {
foreach (['body', 'body_html', 'subject'] as $part) {
$tpl[$part] = str_replace(
'REX_YFORM_DATA[field="' . $key . '"]',
$value,
$tpl[$part]
);
}
}
$tpl['mail_to'] = '[email protected]';
rex_yform_email_template::sendMail($tpl);
The $tpl array stays mutable up to sendMail() – set mail_from, mail_to, mail_cc, mail_bcc, mail_reply_to, attachments directly before sending.
When a form has an upload field, route the uploaded files into the template attachments:
$yform->setValueField('upload', ['attachment', 'Attachment']);
$yform->setValueField('php', ['php_attach', 'Attach',
'<?php if (isset($this->params["value_pool"]["files"])) {
$this->params["value_pool"]["email_attachments"] =
$this->params["value_pool"]["files"];
} ?>'
]);
$yform->setActionField('tpl2email', ['template_key', '', 'email']);
The php value field re-keys uploads into the email_attachments pool that tpl2email reads.
If the template uses an HTML body, every REX_YFORM_DATA[...] placeholder that contains user input is interpolated raw. Always wrap user-provided strings in HTML-escaping inside the template:
<p>From: <?= rex_escape('REX_YFORM_DATA[field="email"]') ?></p>
For plain-text bodies, escaping is unnecessary but newlines from textareas come through as-is — make sure the template doesn't accidentally HTML-render those.
Create one template per language with a _<clang_code> suffix (e.g. contact_form_de, contact_form_en). Pick the right one in PHP before sending:
$key = 'contact_form_' . rex_clang::getCurrent()->getCode();
$tpl = rex_yform_email_template::getTemplate($key)
?? rex_yform_email_template::getTemplate('contact_form_de'); // fallback
tpl2email that doesn't exist – the action silently fails. Verify the template key in the backend.mail_to from a user-controlled field without validating it as an email – open relay risk.body_html only without a plain-text body – Gmail and several corporate mail filters quarantine messages.npx claudepluginhub friendsofredaxo/claude-marketplace --plugin redaxo-yformSearches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Implements vector databases with Pinecone, Weaviate, Qdrant, Milvus, pgvector for semantic search, RAG, recommendations, and similarity systems. Optimizes embeddings, indexing, and hybrid search.