pyvelm v0.11.0¶
Release date: 2026-05-26
Email templates, a sanitized Html field type, a Word-style TipTap v3
rich editor with CodeMirror HTML source, live Jinja preview against any
record, and a responsive form grid (cols + colspan).
Highlights¶
Email templates (mail.template)¶
Admins edit templates at Settings → Workflows → Email templates. Each
template targets a model and stores a Jinja2 subject + HTML body. Application
code queues rendered mail via MailThread.send_mail() or template.send_mail().
Context in templates:
| Key | Meaning |
|---|---|
object |
Business record (model must match template) |
user |
Current res.users |
company |
Active / default res.company |
ctx |
Extra dict from send_mail(..., extra={}) |
Legacy ${object.name} syntax is rewritten to {{ object.name }}.
Html field + sanitizer¶
Html subclasses Text and runs pyvelm/html_sanitizer.py on every write:
allowlisted tags/attributes, no <script> / <style>, strips event handlers and
javascript: URLs, filters dangerous CSS. The HTML editor widget is the default
for Html fields (no widget="html" needed).
Rich editor (npm bundle)¶
npm run build:editor → pyvelm/static/dist/mail_editor.js (loaded before
Alpine in layouts/main.html).
- Write — TipTap v3 “Simple Editor” (StarterKit, color, highlight, align, image, task list, placeholder) with a ribbon toolbar (Undo / Styles / Font / Paragraph / Insert).
- HTML source — CodeMirror 6 with line wrap and variable autocomplete (Ctrl+Space).
- Preview — sanitized HTML; optional preview with record via
POST /api/mail/templates/previewand a record picker on the Preview tab. - Insert variable — searchable dropdown (type to search when the model has
more than 25 fields); APIs:
GET /api/mail/templates/models,GET /api/mail/templates/variables?model=….
Form layout grid¶
Form arch supports cols (default 2) and per-field colspan / "full".
Sections can override cols. Layout uses .pv-form-grid and CSS custom properties
for responsive behavior: one column on small screens, up to cols on large.
Upgrade¶
pyvelm db migrate— applies base 0.25 → 0.26 (mail.templatetable,mail.message.body_is_html,mail.message.template_id, Admin ACL on templates).- Apps → Sync (or restart your app server) so admin views/menus reload.
- Rebuild static assets if you hack the editor locally:
- Hard-refresh the browser (editor bundle must load before Alpine).
Also in this release¶
- SMTP sends multipart HTML when
body_is_html=True. - Tests —
test_html_sanitizer.py, extendedtest_mail_template.py. - Editor fixes — TipTap instances in a
WeakMap(avoids Alpine Proxy + mismatched ProseMirror transactions);@mousedown.preventon toolbar buttons; tab-awaresyncAll()so Source edits are not overwritten when switching tabs.