{"id":166544,"date":"2025-07-14T09:00:00","date_gmt":"2025-07-14T07:00:00","guid":{"rendered":"https:\/\/gtechgroup.it\/blog\/creare-widget-personalizzati-elementor-guida-sviluppatori\/"},"modified":"2026-05-25T10:00:00","modified_gmt":"2026-05-25T08:00:00","slug":"creare-widget-personalizzati-elementor-guida-sviluppatori","status":"publish","type":"post","link":"https:\/\/gtechgroup.it\/blog\/creare-widget-personalizzati-elementor-guida-sviluppatori\/","title":{"rendered":"Creare Widget Personalizzati per Elementor: Guida Sviluppatori"},"content":{"rendered":"<h2>Creare Widget Personalizzati per Elementor: Guida Sviluppatori<\/h2>\n<p>Elementor offre decine di widget predefiniti, ma in alcuni casi le esigenze specifiche di un progetto richiedono funzionalita che nessun widget standard puo fornire. In questi casi, la soluzione e <strong>creare un widget personalizzato<\/strong>. Elementor mette a disposizione una API solida e ben documentata che permette agli sviluppatori PHP di estendere il page builder con widget su misura, perfettamente integrati nel pannello di controllo visuale.<\/p>\n<p>Questa guida e rivolta a sviluppatori con conoscenze di <strong>PHP, HTML e CSS<\/strong>. Se non sei uno sviluppatore ma hai bisogno di widget personalizzati per il tuo progetto, il nostro team di <a href=\"https:\/\/gtechgroup.it\/realizzazione-siti-web\/\">realizzazione siti web<\/a> puo creare soluzioni su misura per le tue esigenze.<\/p>\n<h2>Architettura dei Widget di Elementor<\/h2>\n<p>Ogni widget di Elementor e una <strong>classe PHP<\/strong> che estende la classe base <code>Widget_Base<\/code>. La struttura segue un pattern chiaro e prevedibile:<\/p>\n<ul>\n<li><strong>Metadati del widget<\/strong>: nome, titolo, icona, categoria<\/li>\n<li><strong>Controlli<\/strong>: i campi di configurazione che appaiono nel pannello laterale (testo, colore, tipografia, immagine, ecc.)<\/li>\n<li><strong>Rendering<\/strong>: la funzione che genera il codice HTML visibile nel frontend<\/li>\n<li><strong>Template di anteprima<\/strong>: il JavaScript che genera la anteprima in tempo reale nel builder (opzionale)<\/li>\n<\/ul>\n<h3>File System<\/h3>\n<p>La struttura consigliata per un plugin che contiene widget personalizzati:<\/p>\n<pre><code>my-elementor-widgets\/\n\u251c\u2500\u2500 my-elementor-widgets.php       (file principale del plugin)\n\u251c\u2500\u2500 widgets\/\n\u2502   \u251c\u2500\u2500 cta-box.php                (widget CTA Box)\n\u2502   \u251c\u2500\u2500 team-member.php            (widget Team Member)\n\u2502   \u2514\u2500\u2500 pricing-table.php          (widget Pricing Table)\n\u251c\u2500\u2500 assets\/\n\u2502   \u251c\u2500\u2500 css\/\n\u2502   \u2502   \u2514\u2500\u2500 widgets.css            (stili dei widget)\n\u2502   \u2514\u2500\u2500 js\/\n\u2502       \u2514\u2500\u2500 widgets.js             (script dei widget)\n\u2514\u2500\u2500 readme.txt<\/code><\/pre>\n<h2>Registrare il Plugin e i Widget<\/h2>\n<p>Il file principale del plugin deve registrare i widget con Elementor attraverso il hook appropriato:<\/p>\n<pre><code>&lt;?php\n\/**\n * Plugin Name: My Elementor Widgets\n * Description: Widget personalizzati per Elementor\n * Version: 1.0.0\n * Requires PHP: 7.4\n *\/\n\nif ( ! defined( ABSPATH ) ) exit;\n\nfunction register_custom_widgets( $widgets_manager ) {\n    require_once __DIR__ . \/widgets\/cta-box.php;\n    $widgets_manager-&gt;register( new CTA_Box_Widget() );\n}\nadd_action( elementor\/widgets\/register, register_custom_widgets );<\/code><\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/gtechgroup.it\/blog\/wp-content\/uploads\/2026\/05\/editor-widgets.png\" alt=\"Pannello widget di Elementor che mostra i widget personalizzati nella categoria dedicata\" \/><\/p>\n<h2>La Classe Widget_Base: Metodi Fondamentali<\/h2>\n<p>Ogni widget personalizzato deve implementare almeno questi metodi:<\/p>\n<h3>get_name()<\/h3>\n<p>Restituisce il <strong>nome tecnico<\/strong> del widget (slug unico, senza spazi, in minuscolo). Questo identificativo viene usato internamente da Elementor:<\/p>\n<pre><code>public function get_name() {\n    return cta_box;\n}<\/code><\/pre>\n<h3>get_title()<\/h3>\n<p>Restituisce il <strong>titolo leggibile<\/strong> del widget come appare nel pannello:<\/p>\n<pre><code>public function get_title() {\n    return CTA Box Personalizzato;\n}<\/code><\/pre>\n<h3>get_icon()<\/h3>\n<p>Restituisce la <strong>classe della icona<\/strong> visualizzata nel pannello widget. Puoi usare qualsiasi classe Eicons (il set di icone di Elementor) o Font Awesome:<\/p>\n<pre><code>public function get_icon() {\n    return eicon-call-to-action ;\n}<\/code><\/pre>\n<h3>get_categories()<\/h3>\n<p>Definisce in quale <strong>categoria<\/strong> del pannello appare il widget. Puoi usare categorie esistenti o crearne di personalizzate:<\/p>\n<pre><code>public function get_categories() {\n    return [ general  ];\n}<\/code><\/pre>\n<p>Categorie predefinite disponibili: <code>basic<\/code>, <code>pro-elements<\/code>, <code>general<\/code>, <code>theme-elements<\/code>, <code>woocommerce-elements<\/code>.<\/p>\n<h2>register_controls(): Creare i Campi di Configurazione<\/h2>\n<p>Il metodo <code>register_controls()<\/code> definisce tutti i campi che appaiono nel pannello laterale quando il widget viene selezionato. Elementor offre decine di tipi di controllo:<\/p>\n<h3>Controlli di Base<\/h3>\n<ul>\n<li><strong>TEXT<\/strong>: campo di testo singola riga<\/li>\n<li><strong>TEXTAREA<\/strong>: area di testo multiriga<\/li>\n<li><strong>WYSIWYG<\/strong>: editor visuale completo (TinyMCE)<\/li>\n<li><strong>NUMBER<\/strong>: campo numerico con min\/max\/step<\/li>\n<li><strong>URL<\/strong>: campo URL con opzioni per target e nofollow<\/li>\n<li><strong>SWITCHER<\/strong>: toggle on\/off<\/li>\n<li><strong>SELECT<\/strong>: menu a discesa con opzioni predefinite<\/li>\n<li><strong>SELECT2<\/strong>: menu a discesa con ricerca e selezione multipla<\/li>\n<\/ul>\n<h3>Controlli di Stile<\/h3>\n<ul>\n<li><strong>COLOR<\/strong>: selettore colore con supporto per i Global Colors<\/li>\n<li><strong>SLIDER<\/strong>: cursore numerico con unita di misura (px, em, {6fb8dad3a9c483f1a21adb5997a0bd0fb65a4b2f8344003d223c5d2f2542798c}, vw)<\/li>\n<li><strong>DIMENSIONS<\/strong>: quattro campi collegati per padding\/margin\/border-radius<\/li>\n<li><strong>TYPOGRAPHY<\/strong>: controllo completo della tipografia (font family, size, weight, transform, line-height, letter-spacing)<\/li>\n<li><strong>TEXT_SHADOW<\/strong>: ombra del testo<\/li>\n<li><strong>BOX_SHADOW<\/strong>: ombra del box<\/li>\n<li><strong>BORDER<\/strong>: tipo, larghezza e colore del bordo<\/li>\n<li><strong>BACKGROUND<\/strong>: sfondo classico o gradiente<\/li>\n<\/ul>\n<h3>Controlli Media<\/h3>\n<ul>\n<li><strong>MEDIA<\/strong>: selettore immagine dalla libreria media<\/li>\n<li><strong>GALLERY<\/strong>: selettore galleria di immagini<\/li>\n<li><strong>ICONS<\/strong>: selettore icona (Font Awesome, Eicons, SVG)<\/li>\n<\/ul>\n<h3>Esempio Completo di register_controls()<\/h3>\n<pre><code>protected function register_controls() {\n    \/\/ SEZIONE CONTENUTO\n    $this-&gt;start_controls_section(\n        content_section ,\n        [\n            label  =&gt; Contenuto,\n            tab   =&gt; ElementorControls_Manager::TAB_CONTENT,\n        ]\n    );\n\n    $this-&gt;add_control(\n        title ,\n        [\n            label        =&gt; Titolo,\n            type         =&gt; ElementorControls_Manager::TEXT,\n            default     =&gt; Titolo CTA,\n            placeholder =&gt; Inserisci il titolo,\n        ]\n    );\n\n    $this-&gt;add_control(\n        description ,\n        [\n            label    =&gt; Descrizione ,\n            type     =&gt; ElementorControls_Manager::TEXTAREA,\n            default =&gt; Descrizione della call to action.,\n            rows    =&gt; 5,\n        ]\n    );\n\n    $this-&gt;add_control(\n        button_text,\n        [\n            label    =&gt; Testo Pulsante ,\n            type     =&gt; ElementorControls_Manager::TEXT,\n            default =&gt; Scopri di piu,\n        ]\n    );\n\n    $this-&gt;add_control(\n        button_url ,\n        [\n            label        =&gt; Link Pulsante ,\n            type         =&gt; ElementorControls_Manager::URL,\n            placeholder =&gt; https:\/\/tuosito.it,\n            default     =&gt; [ url  =&gt; # ],\n        ]\n    );\n\n    $this-&gt;add_control(\n        image ,\n        [\n            label    =&gt; Immagine ,\n            type     =&gt; ElementorControls_Manager::MEDIA,\n            default =&gt; [\n                url  =&gt; ElementorUtils::get_placeholder_image_src(),\n            ],\n        ]\n    );\n\n    $this-&gt;end_controls_section();\n\n    \/\/ SEZIONE STILE\n    $this-&gt;start_controls_section(\n        style_section ,\n        [\n            label  =&gt; Stile ,\n            tab   =&gt; ElementorControls_Manager::TAB_STYLE,\n        ]\n    );\n\n    $this-&gt;add_control(\n        title_color,\n        [\n            label      =&gt; Colore Titolo,\n            type       =&gt; ElementorControls_Manager::COLOR,\n            selectors =&gt; [\n                {{WRAPPER}} .cta-title  =&gt; color: {{VALUE}},\n            ],\n        ]\n    );\n\n    $this-&gt;add_group_control(\n        ElementorGroup_Control_Typography::get_type(),\n        [\n            name      =&gt; title_typography,\n            label     =&gt; Tipografia Titolo,\n            selector =&gt; {{WRAPPER}} .cta-title ,\n        ]\n    );\n\n    $this-&gt;end_controls_section();\n}<\/code><\/pre>\n<h2>render(): Generare il Codice HTML<\/h2>\n<p>Il metodo <code>render()<\/code> genera il codice HTML che viene visualizzato nel frontend del sito. Qui accedi ai valori impostati nei controlli tramite <code>$this-&gt;get_settings_for_display()<\/code>:<\/p>\n<pre><code>protected function render() {\n    $settings = $this-&gt;get_settings_for_display();\n    $target   = $settings[button_url ][is_external ] ?  target=\"_blank\" : ;\n    $nofollow = $settings[button_url ][nofollow] ?  rel=\"nofollow\" : ;\n\n    echo &lt;div class=\"cta-box\"&gt;;\n    if ( ! empty( $settings[image ][url ] ) ) {\n        echo &lt;img src=\" . esc_url( $settings[image ][url ] ) . \" alt=\"Screenshot della dashboard WordPress con il plugin configurato\" class=\"cta-image\" \/&gt;;\n    }\n    echo &lt;h3 class=\"cta-title\"&gt; . esc_html( $settings[title ] ) . &lt;\/h3&gt;;\n    echo &lt;p class=\"cta-desc\"&gt; . esc_html( $settings[description ] ) . &lt;\/p&gt;;\n    if ( ! empty( $settings[button_url ][url ] ) ) {\n        echo &lt;a href=\" . esc_url( $settings[button_url ][url ] ) . \" . $target . $nofollow .  class=\"cta-btn\"&gt;;\n        echo esc_html( $settings[button_text] );\n        echo &lt;\/a&gt;;\n    }\n    echo &lt;\/div&gt;;\n}<\/code><\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/gtechgroup.it\/blog\/wp-content\/uploads\/2026\/05\/settings-features.png\" alt=\"Funzionalita avanzate di Elementor per lo sviluppo di widget personalizzati\" \/><\/p>\n<h2>content_template(): Anteprima Live nel Builder<\/h2>\n<p>Il metodo <code>content_template()<\/code> e opzionale ma fortemente consigliato. Genera la anteprima in tempo reale nel builder usando la sintassi <strong>Backbone.js<\/strong> (template JavaScript). Senza questo metodo, Elementor deve fare una chiamata AJAX al server per ogni modifica, rallentando la esperienza di editing:<\/p>\n<pre><code>protected function content_template() {\n    ?&gt;\n    &lt;div class=\"cta-box\"&gt;\n        &lt;# if ( settings.image.url ) { #&gt;\n            &lt;img src=\"{{ settings.image.url }}\" alt=\"Screenshot della dashboard WordPress con il plugin configurato\" class=\"cta-image\" \/&gt;\n        &lt;# } #&gt;\n        &lt;h3 class=\"cta-title\"&gt;{{{ settings.title }}}&lt;\/h3&gt;\n        &lt;p class=\"cta-desc\"&gt;{{{ settings.description }}}&lt;\/p&gt;\n        &lt;# if ( settings.button_url.url ) { #&gt;\n            &lt;a href=\"{{ settings.button_url.url }}\" class=\"cta-btn\"&gt;\n                {{{ settings.button_text }}}\n            &lt;\/a&gt;\n        &lt;# } #&gt;\n    &lt;\/div&gt;\n    &lt;?php\n}<\/code><\/pre>\n<p>Nota la differenza di sintassi: <code>{{ }}<\/code> per i valori con escape e <code>{{{ }}}<\/code> per i valori senza escape (HTML grezzo).<\/p>\n<h2>Caricare CSS e JavaScript<\/h2>\n<p>Se il tuo widget richiede fogli di stile o script personalizzati, registrali nei metodi dedicati:<\/p>\n<pre><code>public function get_style_depends() {\n    return [ my-widget-styles ];\n}\n\npublic function get_script_depends() {\n    return [ my-widget-scripts ];\n}<\/code><\/pre>\n<p>Registra gli asset nel file principale del plugin:<\/p>\n<pre><code>function register_widget_assets() {\n    wp_register_style( my-widget-styles, plugins_url( assets\/css\/widgets.css, __FILE__ ) );\n    wp_register_script( my-widget-scripts, plugins_url( assets\/js\/widgets.js, __FILE__ ), [ jquery ], 1.0.0, true );\n}\nadd_action( wp_enqueue_scripts, register_widget_assets );<\/code><\/pre>\n<h2>Categorie Personalizzate<\/h2>\n<p>Per organizzare i tuoi widget in una categoria dedicata nel pannello:<\/p>\n<pre><code>function add_custom_widget_category( $elements_manager ) {\n    $elements_manager-&gt;add_category(\n        my-custom-widgets,\n        [\n            title  =&gt; I Miei Widget,\n            icon   =&gt; fa fa-plug,\n        ]\n    );\n}\nadd_action( elementor\/elements\/categories_registered , add_custom_widget_category );<\/code><\/pre>\n<h2>Pacchettizzare come Plugin<\/h2>\n<p>Una volta sviluppati e testati i widget, pacchettizza il tutto come un <strong>plugin WordPress standard<\/strong>:<\/p>\n<ol>\n<li>Aggiungi le intestazioni corrette nel file principale del plugin<\/li>\n<li>Verifica che Elementor sia attivo prima di registrare i widget (controlla <code>did_action( elementor\/loaded  )<\/code>)<\/li>\n<li>Gestisci la compatibilita con le versioni di Elementor (controlla <code>ELEMENTOR_VERSION<\/code>)<\/li>\n<li>Aggiungi un file <code>readme.txt<\/code> se intendi distribuirlo<\/li>\n<li>Crea un file ZIP per la distribuzione<\/li>\n<\/ol>\n<h2>Conclusione su Creare Widget Personalizzati per<\/h2>\n<p>Creare widget personalizzati per Elementor e un processo strutturato che richiede conoscenze di PHP e comprensione della architettura del page builder. Una volta padroneggiata la API, le possibilita sono <strong>praticamente illimitate<\/strong>: puoi creare widget per qualsiasi esigenza, da semplici box informativi a integrazioni complesse con API esterne.<\/p>\n<p>Se hai bisogno di widget personalizzati per il tuo progetto ma non hai le competenze di sviluppo necessarie, <a href=\"https:\/\/gtechgroup.it\/contatti\/\">contattaci<\/a> per una consulenza tecnica.<\/p>\n<h2>Guide Correlate della Serie Elementor \u2014 Leggi anche Creare Widget Personalizz<\/h2>\n<ul>\n<li><a href=\"https:\/\/gtechgroup.it\/blog\/elementor-custom-css-codice-personalizzato-sviluppatori\/\">CSS Personalizzato in Elementor: Guida Completa<\/a><\/li>\n<li><a href=\"https:\/\/gtechgroup.it\/blog\/elementor-sezioni-container-flexbox-migrazione-nuovo-sistema\/\">Da Sezioni a Container Flexbox: Migrazione<\/a><\/li>\n<li><a href=\"https:\/\/gtechgroup.it\/blog\/elementor-theme-builder-header-footer-template-personalizzati\/\">Theme Builder: Header, Footer e Template Globali<\/a><\/li>\n<li><a href=\"https:\/\/gtechgroup.it\/blog\/elementor-role-manager-gestire-accessi-permessi-utenti\/\">Role Manager: Gestire Accessi e Permessi<\/a><\/li>\n<li><a href=\"https:\/\/gtechgroup.it\/blog\/come-installare-elementor-wordpress-guida-principianti\/\">Guida Completa a Elementor: Come Funziona<\/a><\/li>\n<\/ul>\n<h3>Migliora il Tuo Sito WordPress<\/h3>\n<p>Scopri le nostre guide complete sugli altri plugin essenziali per WordPress:<\/p>\n<ul>\n<li><a href=\"https:\/\/gtechgroup.it\/blog\/wp-rocket-installare-configurare-wordpress\/\">Come Installare e Configurare WP Rocket<\/a><\/li>\n<li><a href=\"https:\/\/gtechgroup.it\/blog\/come-installare-configurare-seopress-wordpress-guida\/\">Come Installare e Configurare SEOPress<\/a><\/li>\n<li><a href=\"https:\/\/gtechgroup.it\/blog\/cf7-installare-configurare-wordpress\/\">Come Installare e Configurare Contact Form 7<\/a><\/li>\n<li><a href=\"https:\/\/gtechgroup.it\/blog\/installare-attivare-updraftplus-wordpress\/\">Come Installare e Configurare UpdraftPlus<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Creare Widget Personalizzati per Elementor: Guida Sviluppatori Elementor offre decine di widget predefiniti, ma in alcuni casi le esigenze specifiche di un progetto richiedono funzionalita&hellip;<\/p>\n","protected":false},"author":2,"featured_media":168081,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_titles_title":"Creare Widget Personalizzati per Elementor [2026]","_seopress_titles_desc":"Come creare widget personalizzati per Elementor con PHP e JavaScript. Struttura, controlli, rendering e best practice.","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"","_seopress_redirections_param":"","_seopress_redirections_type":0,"_seopress_analysis_target_kw":"Creare Widget Personalizzati Elementor:","footnotes":""},"categories":[61],"tags":[2643,2645,2560,2644],"class_list":["post-166544","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-wordpress","tag-elementor-custom-widget","tag-elementor-developer","tag-sviluppo-elementor","tag-widget-personalizzati"],"_links":{"self":[{"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts\/166544","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/comments?post=166544"}],"version-history":[{"count":0,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts\/166544\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/media\/168081"}],"wp:attachment":[{"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/media?parent=166544"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/categories?post=166544"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gtechgroup.it\/blog\/wp-json\/wp\/v2\/tags?post=166544"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}