Darstellung
Elementor widget
Phase 10 registers the Elementor widget ad-form. The editor canvas never executes the form (content_template placeholder). Frontend output reuses [ad_form] / FormRenderer.
Requires Elementor 3.5+ (elementor/widgets/register). The plugin stays fully usable without Elementor.
Widget
| Key | Value |
|---|---|
| Name | ad-form |
| Title | AD Form |
| Icon | eicon-form-horizontal |
| Category | ad-form |
| Control | form_id (SELECT of published forms) |
ElementorIntegration hooks elementor/loaded, then registers the category, widget and editor assets. Core never type-hints Elementor classes. FormWidget extends Widget_Base only after that class exists.
render() calls Shortcode::render( [ 'id' => $formId, 'source' => 'elementor' ] ). Empty form_id or a missing form returns an empty string. Elementor supplies the widget wrapper.
Entry source stored on submissions is elementor.
Editor
PHP SELECT of published forms (same catalogue as GET /forms/picker). content_template shows a placeholder or a preview card (title + note). The live form is not mounted in the panel or canvas.
Inline config window.adFormElementor:
json
{
"canEditForms": true,
"formsUrl": "…/wp-admin/admin.php?page=ad-form-forms",
"forms": { "1": "Contact" }
}Editor CSS/JS: assets/elementor/css/editor.css, assets/elementor/js/editor.js (vanilla, not Webpack).
Frontend assets
Frontend\Assets::detect_from_query() treats _elementor_data containing "widgetType":"ad-form" as a present form so CSS can print in wp_head. Widget render() still calls mark_form_present() / enqueue(); print_late in wp_footer covers late Elementor output.
PHP
Dingfelder\AdForm\Elementor\ElementorIntegrationDingfelder\AdForm\Elementor\FormWidgetDingfelder\AdForm\Elementor\ElementorServiceProvider
Picker reuse: Form::to_picker_array() / Permissions::pick_forms() (REST, Gutenberg). The widget loads options through FormService in PHP.
Next
Phase 12: form templates.