
🛠️ Kohandatud Elementori vidinad: täistsükkel pluginast juhtelementideni
Teemavärskendus lõhkus kohandatud ploki, mis kuvas avalehel pakkumisi. Kõlab tuttavalt? Kood elab failis functions.php, stiilid on laiali paisatud failis style.css ja JS-i töötleja on naelutatud faili footer.php külge. Vaheta teemat või tee suurem Elementori uuendus ja pead kõik selle nullist uuesti kokku panema.
Probleem pole selles, et „kood on halb". Probleem on selles, et see elab vales kohas. Teemasse topitud kohandatud muudatused on sellega püsivalt seotud: teisele saidile ülekandmine on võimatu, vigade silumine on piinarikas ja varade tingimuslik laadimine puudub.
Õige lähenemine on pakendada kohandatud vidin eraldi pluginana. Just seda soovitab ametlik Elementori dokumentatsioon igasuguste mittetriviaalsete kohanduste puhul. Koodi isoleeritus, teemasõltumatus, korralik versioonihaldus ja JS-i laadimine ainult vidinat sisaldavatel lehtedel. Selles juhendis kogu tsükkel: pluginastruktuurist kuni töötava vidinani koos reaalajas toimetamisega, praegusel Elementori API-l (3.x/4.x).

💡 Kiirülevaade:
- Registreeri vidina jaoks eraldi plugin, isoleeri kood teemast lõplikult.
- Ehita põhiklass koos ühilduvuskontrollidega: Elementor aktiivne, versioon mitte madalam kui 3.5, PHP alates 7.4.
- Loo vidinaklass: laienda
Widget_Base, defineeriregister_controls()ja renderdusmeetod. - Ühenda reaalajas tekstiredaktor
add_inline_editing_attributes()ja Backbone'i malli kaudu. - Lisa kohandatud väljad: pildivalija meediateegist, rippmenüüd, nupugrupid, tüpograafia.
- Haagi JavaScripti töötleja
elementor/frontend/initkülge, mis on igasuguse kliendiloogika sisenemispunkt.
Pluginastruktuur ja põhiklass
Loome plugina Elementor Awesomesauce. Minimaalne failistruktuur:
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
Peamine pluginifail, standardne WordPressi päis pluss laaduriklass koos ühilduvuskontrollidega. See on täpselt see struktuur, mida kirjeldatakse Elementori esimese lisamooduli juhendis. Allolev kood töötab Elementor 3.5+ ja Elementor 4.x versioonides: meetodid ilma iganenud _ eesliiteta, konstandid kaasaegsete PHP versioonide jaoks.
Lisa see kood faili elementor-awesomesauce.php. Fail peaks asuma kaustas /wp-content/plugins/elementor-awesomesauce/. Enne aktiveerimist tee täielik saidi varukoopia.
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();
Mis siin oluline on. Konstant MINIMUM_ELEMENTOR_VERSION, 3.5.0. Sellest versioonist alates hakkasid kehtima uued konventsioonid konksude ja meetodite nimetamiseks ilma _ eesliiteta. Elementor 4.x (praegune versioon 2026. aasta juuni seisuga) puhul töötab see sama kood muudatusteta, vidinate API 4.x-s ei katkenud. PHP, minimaalselt 7.4, kuid praktikas on 8.x juba de facto standard. Klass on deklareeritud kui final: see on sisenemispunkt, sellest ei ole vaja pärida.
Pluginaklass: singleton ja vidina registreerimine
Fail plugin.php, singleton, mis laadib JS-varasid ja registreerib vidina konksu elementor/widgets/register kaudu. See on peamine muudatus võrreldes vanade juhenditega: konks elementor/widgets/widgets_registered kuulutati iganenuks alates versioonist 3.5.0, meetod register_widget_type() asendati meetodiga register().
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();
Märkus: register_widgets aktsepteerib parameetrit $widgets_manager. Uues konksus antakse haldur otse kaasa, mitte ei hangita läbi ElementorPlugin::instance()->widgets_manager. Puhtam ja ilma lisaimportimiseta.
Vidinaklass: pärilus, juhtelemendid ja renderdus
Fail widgets/awesomesauce.php, plugina süda. Laienda Widget_Base, defineeri nimi, pealkiri, ikoon ja kategooria. Meetod register_controls() lisab kolm tekstivälja: üherealine, mitmerealine ja WYSIWYG. Meetod render() väljastab märgendi esiküljel ja content_template() defineerib Backbone'i malli reaalajas eelvaate jaoks redaktoris.
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 }
Mis on muutunud võrreldes aegunud juhenditega. Meetodid register_controls() ja content_template() kirjutatakse ilma _ eesliiteta, see on muudatus alates Elementor 3.1-st. render() väljundis kasuta print_render_attribute_string() ja print_unescaped_setting() otse echo asemel, see on kaasaegne lähenemine, mida soovitatakse alates Elementor 3.x-st ja mis töötab 4.x-s. Ikoon asendati fa fa-pencil-ilt (Font Awesome 4, eemaldatud tuumikust) eicon-pencil-iga Elementori enda komplektist.
Kohandatud väljad: meedia, valikud, tüpograafia
Tekstiväljad ei piira võimalusi. Vaatleme nelja juhtelemendi tüüpi, mis katavad enamiku reaalseid stsenaariume.
Meediaväli
Controls_Manager::MEDIA lisab standardse pildivaliku WordPressi meediateegist. Utils::get_placeholder_image_src() meetod töötab praegustes versioonides ja pakub halli kohatäidet, kui pilti pole valitud.
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 );
Ripploend
Controls_Manager::SELECT, valik eelnevalt määratud väärtustest. Allpool on näide pealkirja HTML-sildi kohta:
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 );
Nupugrupp
Controls_Manager::CHOOSE kuvab visuaalseks valikuks ikoonide rea. Ikoonid, ainult eicon-* komplektist, mitte 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 );
Tüpograafia grupijuhtelemendi kaudu
Tüpograafia grupijuhtelement pakub täiskomplekti: font, suurus, tähevahe, paksus, kõik koos responsiivsete murdepunktidega. Täpsemalt Group_Control_Typography dokumentatsioonis. Võtmepunkt: Scheme_Typography on alates Elementor 3.x-st aegunud, ära seda kasuta. Selle asemel kas lingi globaalsete stiilidega või jäta scheme võti täielikult välja.
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 );
Miks plugin, mitte functions.php
Kohandatud vidin teemas töötab. Kuid ainult seni, kuni teemat vahetad. Eraldi pluginaga saad kolm olulist eelist:
- Tingimuslik laadimine. Elementor kutsub
widget_scriptsvälja ainult siis, kui vidin on lehel tegelikult kuvatud, mitte kogu saidi ulatuses. Kümnete vidinatega projektide puhul on see märgatav kokkuhoid HTTP-päringutes. - Isolatsioon. PHP loogika, CSS ja JS ei segune teemaga. Vea leidmine ja parandamine võtab minuteid, mitte tunde
functions.php2000 rea sees tuhnides. - Ülekantavus. Aktiveeri plugin teisel saidil ja vidin töötab. Pole vaja kopeerimist ja käsitsi teede muutmist.

Video: otseesitlus tühjast pluginast töötava vidinani
Teooria on hea, kuid koodi tegevuses nägemine on kiirem. Selles 30-minutilises juhendis läbib autor kogu protsessi: tühjast kaustast kuni juhtelementide ja renderdusega vidinani.
⁉️🤔 Korduma kippuvad küsimused
Miks vidin Elementori paneelis ei ilmu?
Esmalt kontrolli registreerimise konksu. Alates Elementor 3.5-st kasutatakse
elementor/widgets/register(mitteelementor/widgets/widgets_registered, see on aegunud). Teiseks:register_controls()meetod peab olema ilma_eesliiteta. Kolmandaks:get_categories()peab tagastama massiivi olemasoleva kategooriaga,'general'töötab alati. Neljandaks: tühjenda WordPressi vahemälu pärast plugina aktiveerimist.
Mis vahe on print_render_attribute_string() ja otsese echo vahel render() meetodis?
print_render_attribute_string()rakendab automaatselt atribuutide filtreid, sealhulgas inline editing ja Elementori andmeatribuute. Otseneechoneid andmeid ei paku, inline editing lihtsalt ei aktiveeru. Seadete väärtuste väljastamiseks kasutaprint_unescaped_setting(), see käsitleb korrektselt escapingut kontrollerite sees.
Kas saab hakkama ilma eraldi JS-failita?
Jah, kui vidin renderdab ainult PHP märgendit ilma interaktiivsuseta. Kuid niipea kui ilmuvad sliderid, animatsioonid, AJAX-laadimine või igasugune kliendipoolne dünaamika, on JS kohustuslik. Isegi minimaalne handler (nagu ülaltoodud näites) annab sisenemispunkti tulevase loogika jaoks, ilma et peaks hiljem registreerimist ümber kirjutama.
Kas nimeruum on pluginas kohustuslik?
Formaalselt ei ole. Kuid ilma nimeruumita riskid klassinimede konfliktiga mõne teise plugina või teemaga, nimed nagu
PluginvõiWidgetpole kaugeltki unikaalsed. Tootmiskeskkonnas on see kohustuslik. PrefiksElementorAwesomesauceWidgetstagab praktiliselt unikaalsuse.
Kuidas uuendada vana vidinat, mis on kirjutatud aegunud juhendite järgi?
Migratsiooniplaan on kirjeldatud Elementori ametlikus aegumiste juhendis: (1) nimeta ümber
_eesliitega meetodid,_register_controls()→register_controls(),_content_template()→content_template(); (2) asenda konkselementor/widgets/registervastu ja registreerimismeetod$manager->register()vastu; (3) asendafa fa-*ikoonideicon-*vastu, eemaldaScheme_Typography. Pärast muudatusi tõstaMINIMUM_ELEMENTOR_VERSIONpraegusele versioonile ja testi vidinat kolmel tasandil: redaktori paneel, live preview, frontend.
Mida teha vanade vidinatega: migratsiooniplaan praegusele API-le
Kui sul on juba kohandatud vidinaid, mis on kirjutatud 2019-2021 juhendite järgi, ära satu paanikasse. Elementor säilitab tagasiühilduvuse aegumise handleritega kuni 8 põhiversiooni ulatuses. Kuid parem on kood uuendada nüüd, enne kui aegumisteated muutuvad fataalseteks vigadeks.
Migratsiooni kontrollnimekiri:
- **Meetodid ilma
_: kõikjal, kus näed_register_controlsja_content_template, eemalda eesliide. - Registreerimise konks:
elementor/widgets/widgets_registered→elementor/widgets/register. - Registreerimismeetod:
$manager->register_widget_type()→$manager->register(). - Ikoonid:
fa fa-*→eicon-*(Elementori loomulik komplekt) võidashicons-*(WordPressi komplekt). - Tüpograafia:
Scheme_Typography→ kas globaalsed stiilid läbi'global' => [...]või otseväärtused ilmaschemevõtmeta.
Pärast muudatusi testi vidinat kolmel tasandil: kas kontrollerite paneel avaneb redaktoris, kas live preview töötab (Backbone mall), kas frontend renderdub vigadeta. Ja pea meeles kuivkäivitust enne tootmiskeskkonda paigaldamist: Elementor jätab katkised kontrollerid vaikimisi vahele ilma tervet lehte kokku jooksutamata, seega visuaalne kontroll on kohustuslik.
Vana kood functions.php-s või plugin nullist: mida valida
Kui alustad uut projekti, siis ainult plugin. Ühtegi argumenti functions.php "poolt" pole enam alles: isegi 20-realise mikrovidina puhul tasub plugina struktuur end ära juba esimese teemauuendusega.
Kui sul on juba töötav kood teemas, eralda see pluginasse järgmise refaktoreerimise käigus. Protsess on lihtne: loo kaust ja plugina põhifail vastavalt ülaltoodud struktuurile, liiguta vidina klass widgets/ kausta, seadista registreerimine läbi elementor/widgets/register ja testi staging-keskkonnas. Praktikas võtab see tüüpilise vidina puhul 15-20 minutit.
Alusta selle juhendi baasklassist, kopeeri põhifail ja plugin.php skelett, asenda vidina nimi enda omaga. Ja kui küsimusi tekib, vaata Widgets sektsiooni saidil developers.elementor.com: see katab meedia renderdamist, kordusväljadega töötamist ja väljundi optimeerimist.



