Skip to content

feat: Rich text editor integration for Global Variables & Shortcodes plugins #756

@cp-bwg

Description

@cp-bwg

Summary

Adds rich text editor integration (Quill + TinyMCE) for the Global Variables plugin (PR #743) and a new Shortcodes plugin. This implements Part 2 (Rich Text Inline Tokens) from #719, which was explicitly planned as a follow-up in the original PR.

What This Enables

Global Variables — Editor Integration

  • Quill: Custom VariableBlot renders {variable_key} tokens as styled blue chips in the editor
  • TinyMCE: tinymce.PluginManager.add() registers a "Var" toolbar button with chip rendering
  • Searchable picker dropdown fetches variables from /api/global-variables
  • Token↔chip roundtrip: chips in editor → {key} in database → chips on reload
  • Existing {key} text auto-converted to chips on content load

Shortcodes Plugin (New)

  • [[shortcode_name param="value"]] syntax with registered handler functions
  • Handler registry with built-in handlers: current_date, phone_link, cta_button, plan_count, provider_rating
  • Server-side resolution via content:read hook (priority 60, runs after variables at 50)
  • Full CRUD admin page with handler status badges and live preview
  • Quill integration: purple ShortcodeBlot chips + "SC" toolbar button
  • TinyMCE integration: PluginManager-based button with chip rendering

Shared Editor Utilities

  • quill-shared.ts — Quill constructor Proxy (injects custom formats), searchable picker dropdown, enhancer polling framework
  • tinymce-shared.ts — PluginManager approach (the official TinyMCE plugin API), picker dropdown, chip CSS injection into editor iframe
  • admin-template.ts — Shared HTML wrapper with Tailwind + HTMX + CSRF auto-injection

Enhanced Admin Pages

  • Both plugins have full CRUD admin pages (add, inline edit, delete, toggle active/inactive)
  • "Rich Text Editor Integration" settings card with toggle + editor auto-detection
  • Warning when no editor plugin is active

Related Issues

Technical Notes

  • Editor scripts are self-contained HTML (styles + scripts) injectable via afterAuth middleware
  • Quill: uses Proxy to patch constructor for custom format whitelisting
  • TinyMCE: uses PluginManager.add() (official API) + server-side HTML replacement to inject button names into toolbar/plugins arrays
  • Both editors support token↔chip serialization (editor DOM → DB tokens → editor DOM)
  • Content resolution: variables (priority 50) → shortcodes (priority 60)
  • Opt-out: ?resolve_variables=false, ?resolve_shortcodes=false

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions