
🛠️ Mukautetut Elementor-widgetit: koko sykli liitännäisestä ohjaimiin
Teeman päivitys rikkoi mukautetun lohkon, joka näytti kampanjoita etusivulla. Kuulostaako tutulta? Koodi asuu functions.php-tiedostossa, tyylit on levitelty style.css-tiedostoon ja JavaScript-käsittelijä on naulattu footer.php-tiedostoon. Vaihda teemaa tai tee iso Elementor-päivitys, ja joudut kasaamaan kaiken tämän uudelleen alusta.
Ongelma ei ole siinä, että "koodi on huonoa". Ongelma on siinä, että se sijaitsee väärässä paikassa. Teemaan ahdetut mukautetut muokkaukset on sidottu siihen pysyvästi: siirtäminen toiselle sivustolle on mahdotonta, virheiden jäljitys on tuskallista ja resurssien ehdollinen lataaminen puuttuu kokonaan.
Oikea lähestymistapa on paketoida mukautettu widget erilliseksi lisäosaksi. Juuri tätä virallinen Elementor-dokumentaatio suosittelee kaikkiin ei-triviaaleihin mukautuksiin. Koodin eristys, teemariippumattomuus, asianmukainen versiointi ja JavaScriptin lataaminen vain sivuilla, joilla widget on. Tässä oppaassa käydään läpi koko sykli: lisäosan rakenteesta toimivaan widgetiin, jossa on inline-muokkaus, nykyisellä Elementor-rajapinnalla (3.x/4.x).

💡 Pikaopas:
- Rekisteröi widgetille erillinen lisäosa, eristä koodi teemasta lopullisesti.
- Rakenna pääluokka yhteensopivuustarkistuksilla: Elementor aktiivinen, versio vähintään 3.5, PHP versiosta 7.4 alkaen.
- Luo widget-luokka: laajenna
Widget_Base, määritteleregister_controls()ja renderöintimetodi. - Kytke inline-tekstimuokkaus
add_inline_editing_attributes()-metodin ja Backbone-pohjan avulla. - Lisää mukautettuja kenttiä: kuvanvalinta mediakirjastosta, pudotusvalikoita, painikeryhmiä, typografiaa.
- Kiinnitä JavaScript-käsittelijä
elementor/frontend/init-tapahtumaan, joka on lähtökohta kaikelle asiakaspuolen logiikalle.
Lisäosan rakenne ja pääluokka
Luomme Elementor Awesomesauce -lisäosan. Minimaalinen tiedostorakenne:
1 elementor-awesomesauce/ 2 ├── elementor-awesomesauce.php ← entry point 3 ├── plugin.php ← plugin singleton class 4 ├── widgets/ 5 │ └── awesomesauce.php ← widget class 6 └── assets/ 7 └── js/ 8 └── awesomesauce.js ← frontend JS handler
Päälisäosatiedosto, vakio WordPress-otsikko sekä lataajaluokka yhteensopivuustarkistuksilla. Tämä on juuri se rakenne, joka on kuvattu Elementorin ensimmäisen lisäosan oppaassa. Alla oleva koodi toimii Elementor 3.5+:ssa ja Elementor 4.x:ssä: metodit ilman vanhentunutta _-etuliitettä, vakiot moderneille PHP-versioille.
Lisää tämä koodi tiedostoon elementor-awesomesauce.php. Tiedoston tulee sijaita polussa /wp-content/plugins/elementor-awesomesauce/. Ennen aktivointia ota täysi varmuuskopio sivustosta.
1 <?php 2 /** 3 * Plugin Name: Elementor Awesomesauce 4 * Description: Custom Elementor widget with live editing of text, images and styles. 5 * Plugin URI: https://techblog.sdstudio.top/ 6 * Version: 1.0.0 7 * Author: TechBlog SD Studio 8 * Text Domain: elementor-awesomesauce 9 */ 10 11 if ( ! defined( 'ABSPATH' ) ) exit; 12 13 final class Elementor_Awesomesauce { 14 15 const VERSION = '1.0.0'; 16 const MINIMUM_ELEMENTOR_VERSION = '3.5.0'; 17 const MINIMUM_PHP_VERSION = '7.4'; 18 19 public function __construct() { 20 add_action( 'init', array( $this, 'i18n' ) ); 21 add_action( 'plugins_loaded', array( $this, 'init' ) ); 22 } 23 24 public function i18n() { 25 load_plugin_textdomain( 'elementor-awesomesauce' ); 26 } 27 28 public function init() { 29 if ( ! did_action( 'elementor/loaded' ) ) { 30 add_action( 'admin_notices', array( $this, 'admin_notice_missing_main_plugin' ) ); 31 return; 32 } 33 34 if ( ! version_compare( ELEMENTOR_VERSION, self::MINIMUM_ELEMENTOR_VERSION, '>=' ) ) { 35 add_action( 'admin_notices', array( $this, 'admin_notice_minimum_elementor_version' ) ); 36 return; 37 } 38 39 if ( version_compare( PHP_VERSION, self::MINIMUM_PHP_VERSION, '<' ) ) { 40 add_action( 'admin_notices', array( $this, 'admin_notice_minimum_php_version' ) ); 41 return; 42 } 43 44 require_once( 'plugin.php' ); 45 } 46 47 public function admin_notice_missing_main_plugin() { 48 if ( isset( $_GET['activate'] ) ) { 49 unset( $_GET['activate'] ); 50 } 51 $message = sprintf( 52 esc_html__( '"%1$s" requires "%2$s" to be installed and activated.', 'elementor-awesomesauce' ), 53 '<strong>' . esc_html__( 'Elementor Awesomesauce', 'elementor-awesomesauce' ) . '</strong>', 54 '<strong>' . esc_html__( 'Elementor', 'elementor-awesomesauce' ) . '</strong>' 55 ); 56 printf( '<p>%1$s</p>', $message ); 57 } 58 59 public function admin_notice_minimum_elementor_version() { 60 if ( isset( $_GET['activate'] ) ) { 61 unset( $_GET['activate'] ); 62 } 63 $message = sprintf( 64 esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'elementor-awesomesauce' ), 65 '<strong>' . esc_html__( 'Elementor Awesomesauce', 'elementor-awesomesauce' ) . '</strong>', 66 '<strong>' . esc_html__( 'Elementor', 'elementor-awesomesauce' ) . '</strong>', 67 self::MINIMUM_ELEMENTOR_VERSION 68 ); 69 printf( '<p>%1$s</p>', $message ); 70 } 71 72 public function admin_notice_minimum_php_version() { 73 if ( isset( $_GET['activate'] ) ) { 74 unset( $_GET['activate'] ); 75 } 76 $message = sprintf( 77 esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'elementor-awesomesauce' ), 78 '<strong>' . esc_html__( 'Elementor Awesomesauce', 'elementor-awesomesauce' ) . '</strong>', 79 '<strong>' . esc_html__( 'PHP', 'elementor-awesomesauce' ) . '</strong>', 80 self::MINIMUM_PHP_VERSION 81 ); 82 printf( '<p>%1$s</p>', $message ); 83 } 84 } 85 86 new Elementor_Awesomesauce();
Mikä tässä on tärkeää. Vakio MINIMUM_ELEMENTOR_VERSION, 3.5.0. Tästä versiosta alkaen tulivat voimaan uudet käytännöt koukkujen ja metodien nimeämiselle ilman _-etuliitettä. Elementor 4.x:lle (nykyinen versio kesäkuussa 2026) tämä sama koodi toimii ilman muutoksia, widget-rajapintaa ei rikottu 4.x:ssä. PHP, vähintään 7.4, mutta käytännössä 8.x on jo de facto -standardi. Luokka on määritelty final: tämä on sisääntulopiste, siitä ei tarvitse periä.
Lisäosaluokka: singleton ja widgetin rekisteröinti
Tiedosto plugin.php, singleton, joka lataa JavaScript-resurssit ja rekisteröi widgetin elementor/widgets/register-koukun kautta. Tämä on tärkein muutos verrattuna vanhoihin oppaisiin: elementor/widgets/widgets_registered-koukku julistettiin vanhentuneeksi versiosta 3.5.0 alkaen, register_widget_type()-metodi korvattiin register()-metodilla.
1 <?php 2 namespace ElementorAwesomesauce; 3 4 use Elementor\Plugin as ElementorPlugin; 5 6 class Plugin { 7 8 private static $_instance = null; 9 10 public static function instance() { 11 if ( is_null( self::$_instance ) ) { 12 self::$_instance = new self(); 13 } 14 return self::$_instance; 15 } 16 17 public function widget_scripts() { 18 wp_register_script( 19 'elementor-awesomesauce', 20 plugins_url( '/assets/js/awesomesauce.js', __FILE__ ), 21 [ 'jquery' ], 22 false, 23 true 24 ); 25 } 26 27 private function include_widgets_files() { 28 require_once( __DIR__ . '/widgets/awesomesauce.php' ); 29 } 30 31 public function register_widgets( $widgets_manager ) { 32 $this->include_widgets_files(); 33 $widgets_manager->register( new \ElementorAwesomesauceWidgets\Awesomesauce() ); 34 } 35 36 public function __construct() { 37 add_action( 'elementor/frontend/after_register_scripts', [ $this, 'widget_scripts' ] ); 38 add_action( 'elementor/widgets/register', [ $this, 'register_widgets' ] ); 39 } 40 } 41 42 Plugin::instance();
Huomaa: register_widgets ottaa vastaan $widgets_manager-parametrin. Uudessa koukussa hallinnoija välitetään suoraan, ei haettuna ElementorPlugin::instance()->widgets_manager-kutsulla. Siistimpää ja ilman ylimääräistä tuontia.
Widget-luokka: periytyminen, säätimet ja renderöinti
Tiedosto widgets/awesomesauce.php, lisäosan sydän. Laajenna Widget_Base, määrittele nimi, otsikko, kuvake ja kategoria. register_controls()-metodi lisää kolme tekstikenttää: yksirivinen, monirivinen ja WYSIWYG. render()-metodi tulostaa merkinnän julkisella puolella, ja content_template() määrittelee Backbone-pohjan live-esikatselua varten editorissa.
1 <?php 2 namespace ElementorAwesomesauceWidgets; 3 4 use Elementor\Widget_Base; 5 use Elementor\Controls_Manager; 6 7 if ( ! defined( 'ABSPATH' ) ) exit; 8 9 class Awesomesauce extends Widget_Base { 10 11 public function get_name() { 12 return 'awesomesauce'; 13 } 14 15 public function get_title() { 16 return __( 'Awesomesauce', 'elementor-awesomesauce' ); 17 } 18 19 public function get_icon() { 20 return 'eicon-pencil'; 21 } 22 23 public function get_categories() { 24 return [ 'general' ]; 25 } 26 27 public function get_keywords() { 28 return [ 'awesomesauce', 'custom', 'demo' ]; 29 } 30 31 protected function register_controls() { 32 $this->start_controls_section( 33 'section_content', 34 [ 35 'label' => __( 'Content', 'elementor-awesomesauce' ), 36 ] 37 ); 38 39 $this->add_control( 40 'title', 41 [ 42 'label' => __( 'Title', 'elementor-awesomesauce' ), 43 'type' => Controls_Manager::TEXT, 44 'default' => __( 'Title', 'elementor-awesomesauce' ), 45 ] 46 ); 47 48 $this->add_control( 49 'description', 50 [ 51 'label' => __( 'Description', 'elementor-awesomesauce' ), 52 'type' => Controls_Manager::TEXTAREA, 53 'default' => __( 'Description', 'elementor-awesomesauce' ), 54 ] 55 ); 56 57 $this->add_control( 58 'content', 59 [ 60 'label' => __( 'Content', 'elementor-awesomesauce' ), 61 'type' => Controls_Manager::WYSIWYG, 62 'default' => __( 'Content', 'elementor-awesomesauce' ), 63 ] 64 ); 65 66 $this->end_controls_section(); 67 } 68 69 protected function render() { 70 $settings = $this->get_settings_for_display(); 71 72 $this->add_inline_editing_attributes( 'title', 'none' ); 73 $this->add_inline_editing_attributes( 'description', 'basic' ); 74 $this->add_inline_editing_attributes( 'content', 'advanced' ); 75 ?> 76 <div class="elementor-awesomesauce"> 77 <h2 <?php $this->print_render_attribute_string( 'title' ); ?>> 78 <?php $this->print_unescaped_setting( 'title' ); ?> 79 </h2> 80 <div <?php $this->print_render_attribute_string( 'description' ); ?>> 81 <?php $this->print_unescaped_setting( 'description' ); ?> 82 </div> 83 <div <?php $this->print_render_attribute_string( 'content' ); ?>> 84 <?php $this->print_unescaped_setting( 'content' ); ?> 85 </div> 86 </div> 87 <?php 88 } 89 90 protected function content_template() { 91 ?> 92 <# 93 view.addInlineEditingAttributes( 'title', 'none' ); 94 view.addInlineEditingAttributes( 'description', 'basic' ); 95 view.addInlineEditingAttributes( 'content', 'advanced' ); 96 #> 97 <div class="elementor-awesomesauce"> 98 <h2 {{{ view.getRenderAttributeString( 'title' ) }}}>{{{ settings.title }}}</h2> 99 <div {{{ view.getRenderAttributeString( 'description' ) }}}>{{{ settings.description }}}</div> 100 <div {{{ view.getRenderAttributeString( 'content' ) }}}>{{{ settings.content }}}</div> 101 </div> 102 <?php 103 } 104 }
Mikä on muuttunut vanhentuneisiin oppaisiin verrattuna. Metodit register_controls() ja content_template() kirjoitetaan ilman _-etuliitettä, tämä on muutos Elementor 3.1:stä lähtien. Tulostuksessa render()-metodissa käytä print_render_attribute_string()- ja print_unescaped_setting()-funktioita suoran echon sijaan, mikä on moderni, Elementor 3.x:stä lähtien suositeltu ja 4.x:ssä toimiva lähestymistapa. Kuvake vaihdettu fa fa-pencil-kuvakkeesta (Font Awesome 4, poistettu ytimestä) Elementorin oman kuvakesetin eicon-pencil-kuvakkeeseen.
Mukautetut kentät: media, valintalistat, typografia
Tekstikentät eivät rajoita mahdollisuuksia. Käymme läpi neljä ohjaintyyppiä, jotka kattavat useimmat todelliset tilanteet.
Mediakenttä
Controls_Manager::MEDIA lisää vakioidun kuvanvalinnan WordPressin mediakirjastosta. Utils::get_placeholder_image_src()-metodi toimii nykyisissä versioissa ja tarjoaa harmaan paikkamerkkikuvan, jos kuvaa ei ole valittu.
1 $this->add_control( 2 'mask_image', 3 [ 4 'label' => __( 'Mask Image', 'elementor-awesomesauce' ), 5 'type' => Controls_Manager::MEDIA, 6 'default' => [ 7 'url' => \Elementor\Utils::get_placeholder_image_src(), 8 ], 9 ] 10 );
Pudotusvalikko
Controls_Manager::SELECT, valinta ennalta määritellyistä arvoista. Alla on esimerkki otsikon HTML-tagille:
1 $this->add_control( 2 'title_tag', 3 [ 4 'label' => __( 'Title HTML Tag', 'elementor-awesomesauce' ), 5 'type' => Controls_Manager::SELECT, 6 'default' => 'h2', 7 'options' => [ 8 'h1' => 'H1', 9 'h2' => 'H2', 10 'h3' => 'H3', 11 'h4' => 'H4', 12 ], 13 ] 14 );
Painikeryhmä
Controls_Manager::CHOOSE näyttää rivin kuvakkeita visuaalista valintaa varten. Kuvakkeet, vain eicon-*-setistä, ei fa fa-*:
1 $this->add_control( 2 'text_align', 3 [ 4 'label' => __( 'Alignment', 'elementor-awesomesauce' ), 5 'type' => Controls_Manager::CHOOSE, 6 'options' => [ 7 'left' => [ 8 'title' => __( 'Left', 'elementor-awesomesauce' ), 9 'icon' => 'eicon-text-align-left', 10 ], 11 'center' => [ 12 'title' => __( 'Center', 'elementor-awesomesauce' ), 13 'icon' => 'eicon-text-align-center', 14 ], 15 'right' => [ 16 'title' => __( 'Right', 'elementor-awesomesauce' ), 17 'icon' => 'eicon-text-align-right', 18 ], 19 ], 20 'default' => 'center', 21 'toggle' => true, 22 ] 23 );
Typografia ryhmäohjaimen kautta
Typografian ryhmäohjain tarjoaa täyden valikoiman: fontti, koko, kirjainväli, lihavointi, kaikki responsiivisilla taittopisteillä. Lisätietoja Group_Control_Typography-dokumentaatiossa. Avainkohta: Scheme_Typography on ollut vanhentunut Elementor 3.x:stä lähtien, älä käytä sitä. Sen sijaan joko linkitä globaaleihin tyyleihin tai jätä scheme-avain kokonaan pois.
1 use Elementor\Group_Control_Typography; 2 3 $this->add_group_control( 4 Group_Control_Typography::get_type(), 5 [ 6 'name' => 'content_typography', 7 'label' => __( 'Typography', 'elementor-awesomesauce' ), 8 'selector' => '{{WRAPPER}} .elementor-awesomesauce', 9 'fields_options' => [ 10 'letter_spacing' => [ 11 'range' => [ 12 'min' => 0, 13 'max' => 100, 14 ], 15 ], 16 ], 17 ] 18 );
Miksi lisäosa eikä functions.php
Teemaan tehty mukautettu widget toimii. Mutta vain siihen asti, kunnes vaihdat teemaa. Erillisessä lisäosassa saat kolme tärkeää etua:
- Ehdollinen lataus. Elementor kutsuu
widget_scripts-metodia vain, kun widget todella näytetään sivulla, ei koko sivustolla. Projekteissa, joissa on kymmeniä widgettejä, tämä tarkoittaa huomattavaa säästöä HTTP-pyynnöissä. - Eristäminen. PHP-logiikka, CSS ja JS eivät sekoitu teeman kanssa. Vian löytäminen ja korjaaminen vie minuutteja, ei tunteja
functions.php-tiedoston 2000 rivin läpikäymistä. - Siirrettävyys. Aktivoi lisäosa toisella sivustolla, widget toimii. Ei kopioi-liitä-toimintoa ja manuaalista polkujen muokkausta.

Video: live-esittely tyhjästä lisäosasta toimivaksi widgetiksi
Teoria on hyvä, mutta koodin näkeminen toiminnassa on nopeampaa. Tässä 30 minuutin oppaassa tekijä käy läpi koko prosessin: tyhjästä kansiosta widgetiksi, jossa on ohjaimet ja renderöinti.
⁉️🤔 Usein kysytyt kysymykset
Miksi vimpain ei näy Elementor-paneelissa?
Tarkista ensin rekisteröintikoukku. Elementor 3.5:stä lähtien käytetään
elementor/widgets/register(eielementor/widgets/widgets_registered, se on vanhentunut). Toiseksi:register_controls()-metodissa ei saa olla_-etuliitettä. Kolmanneksi:get_categories()-metodin on palautettava taulukko, jossa on olemassa oleva kategoria,'general'toimii aina. Neljänneksi: tyhjennä WordPressin välimuisti lisäosan aktivoinnin jälkeen.
Mitä eroa on print_render_attribute_string()-funktiolla ja suoralla echo-komennolla render()-metodissa?
print_render_attribute_string()lisää automaattisesti attribuuttisuodattimet, mukaan lukien inline-muokkauksen ja Elementorin data-attribuutit. Suoraechoei tarjoa tätä dataa, jolloin inline-muokkaus ei yksinkertaisesti aktivoidu. Asetusarvojen tulostamiseen käytäprint_unescaped_setting(), joka käsittelee escapauksen oikein kontrollien sisällä.
Pärjääkö ilman erillistä JS-tiedostoa?
Kyllä, jos vimpain pelkästään renderöi PHP-merkkauksen ilman interaktiivisuutta. Mutta heti kun mukaan tulee liukusäätimiä, animaatioita, AJAX-latausta tai mitä tahansa asiakaspään dynamiikkaa, JS on pakollinen. Jopa minimaalinen käsittelijä (kuten yllä olevassa esimerkissä) tarjoaa aloituspisteen tulevalle logiikalle ilman, että rekisteröintiä tarvitsee kirjoittaa myöhemmin uusiksi.
Onko nimiavaruus pakollinen lisäosassa?
Muodollisesti ei. Mutta ilman nimiavaruutta riskinä on luokkanimien törmäys toisen lisäosan tai teeman kanssa, nimet kuten
PlugintaiWidgeteivät ole läheskään uniikkeja. Tuotantokäytössä pakollinen. EtuliiteElementorAwesomesauceWidgetstakaa käytännössä uniikkiuden.
Miten päivitetään vanha vimpain, joka on kirjoitettu vanhentuneiden oppaiden mukaan?
Migraatiosuunnitelma on kuvattu virallisessa Elementorin vanhentumisoppaassa: (1) nimeä uudelleen metodit, joissa on
_-etuliite,_register_controls()→register_controls(),_content_template()→content_template(); (2) vaihda koukku muotoonelementor/widgets/registerja rekisteröintimetodi muotoon$manager->register(); (3) vaihdafa fa-*-ikoniteicon-*-ikoneiksi, poistaScheme_Typography. Muokkausten jälkeen nostaMINIMUM_ELEMENTOR_VERSIONnykyiseen ja testaa vimpain kolmella tasolla: editoripaneeli, live-esikatselu, frontend.
Mitä tehdä vanhoille vimpaimille: migraatiosuunnitelma nykyiseen APIin
Jos sinulla on jo mukautettuja vimpaimia, jotka on kirjoitettu vuosien 2019-2021 oppaiden mukaan, älä hätäänny. Elementor ylläpitää taaksepäin yhteensopivuutta vanhentumiskäsittelijöillä jopa 8 pääversion ajan. Mutta koodi on parempi päivittää nyt, ennen kuin vanhentumisilmoitukset muuttuvat vakaviksi virheiksi.
Migraation tarkistuslista:
- **Metodit ilman
_: kaikkialla, missä näet_register_controlsja_content_template, poista etuliite. - Rekisteröintikoukku:
elementor/widgets/widgets_registered→elementor/widgets/register. - Rekisteröintimetodi:
$manager->register_widget_type()→$manager->register(). - Ikonit:
fa fa-*→eicon-*(Elementorin natiivi sarja) taidashicons-*(WordPressin sarja). - Typografia:
Scheme_Typography→ joko globaalit tyylit'global' => [...]-rakenteella tai suorat arvot ilmanscheme-avainta.
Muutosten jälkeen testaa vimpain kolmella tasolla: avautuuko kontrollipaneeli editorissa, toimiiko live-esikatselu (Backbone-pohja), renderöityykö frontend ilman virheitä. Ja muista kuivaharjoittelu ennen tuotantoon vientiä: Elementor ohittaa rikkinäiset kontrollit hiljaisesti kaatamatta koko sivua, joten visuaalinen varmistus on pakollinen.
Vanha koodi functions.php:ssä vai lisäosa alusta alkaen: kumpi valita
Jos aloitat uuden projektin, vain lisäosa. functions.php:n puolesta ei ole enää mitään perusteita: jopa 20 rivin mikrovimpaimen kohdalla lisäosarakenne maksaa itsensä takaisin ensimmäisen teemapäivityksen yhteydessä.
Jos sinulla on jo toimivaa koodia teemassa, siirrä se lisäosaan seuraavan refaktoroinnin yhteydessä. Prosessi on suoraviivainen: luo kansio ja päälisäosatiedosto yllä olevan rakenteen mukaisesti, siirrä vimpainluokka hakemistoon widgets/, määritä rekisteröinti elementor/widgets/register-koukun kautta ja testaa staging-ympäristössä. Käytännössä tämä vie 15-20 minuuttia tyypilliseltä vimpaimelta.
Aloita tämän oppaan perusluokasta, kopioi päätiedosto ja plugin.php rungoksi, korvaa vimpaimen nimi omallasi. Ja kun kysymyksiä herää, tarkista Widgets-osio osoitteessa developers.elementor.com: se kattaa median renderöinnin, toistokenttien kanssa työskentelyn ja tulosteen optimoinnin.



