Problém / Potreba
Ak ste už dodali webovú stránku na Elementore a klient sa vás opýta: „Chcem widget“ na mieru„ale bez inštalácie 12 doplnkov“, už máte správny reflex: prejdite si kód.
Elementor (Free/Pro) poskytuje dostatočne stabilné API s hookmi a udalosťami na správne prispôsobenie nástroja na tvorbu: pridanie kategórie widgetov, uloženie vlastného widgetu, vloženie ovládacích prvkov, vynútenie predvolených hodnôt, načítanie skriptov iba v prípade potreby a dokonca pridanie dynamického poľa prostredníctvom značky.
Typická obchodná potreba: industrializovať opakovane použiteľné komponenty (výzvy na akciu, autorské rámčeky, produktové listy, tabuľky, bannery GDPR atď.) a zároveň zachovať používateľskú skúsenosť Elementoru. Na konci budete vedieť, ako štruktúrovať čistý a kompatibilný mini-plugin. WordPress 6.9.4+ a PHP 8.1+ a budete mať opakovane použiteľnú základňu pre vaše projekty.
Rýchle zhrnutie
- Vytvorte mini-plugin WordPress (nie je to jednorazový úryvok), ktorý sa integruje s Elementorom bez narušeniaadmin.
- Použite správne hooky Elementoru:
elementor/init,elementor/widgets/register,elementor/elements/categories_registered,elementor/frontend/after_register_scripts. - Pridajte si vlastný widget „Odznak“ (názov + text + farba + ikona) s ovládacími prvkami, bezpečným vykresľovaním a štýlmi.
- Pridajte dynamickú značku (rozšírená možnosť) na vloženie hodnoty z metaúdajov používateľa (napr. pozícia/rola).
- CSS/JS načítajte iba v prípade, že je k dispozícii widget z vášho pluginu (zabráni sa tak „načítaniu všetkého všade“).
Kedy použiť toto riešenie
- Chcete stabilný komponent s rôznymi verziami, ktorý je možné opätovne použiť na viacerých miestach (agentúra, freelancer, tím).
- Musíte sa držať štýlového sprievodcu (farby, typografia, medzery) bez toho, aby ste klientovi nechali 50 „nebezpečných“ možností.
- Potrebujete presné vykresľovanie front-endu bez toho, aby ste sa spoliehali na doplnok tretej strany, ktorý sa môže zmeniť bez varovania.
- Chcete zlepšiť výkon: prvky načítané iba v prípade potreby, žiadny „veľký balík“ widgetov.
- Chcete integrovať dáta WordPressu (meta, možnosti, ACF/Pody atď.) prostredníctvom dynamických značiek.
Kedy toto riešenie NEPOUŽÍVAŤ
- Potreba je čisto vizuálna a príležitostná: a proces Šablóna Elementoru, kontajner a trochu CSS môže stačiť.
- Nemáte kontrolu nad údržbou: vlastný widget znamená dodržiavanie Elementoru (a niekedy aj jeho zastaraných verzií).
- Ak chcete Elementor rozsiahlo „záplatovať“ (napr. upraviť vnútorné správanie editora), zriedkakedy je stabilný. Zvoľte si oficiálne rozšírenia alebo akceptujte určitú mieru technického dlhu.
- Váš klient primárne používa Gutenberg/blocks: v tomto prípade je často vhodnejší vlastný blok (Block API). Pozrite si oficiálnu dokumentáciu: Príručka editora blokov.
Predpoklady / pred začatím
- WordPress 6.9.4+ a PHP 8.1+ (ideálne 8.2/8.3 v roku 2026, ak váš poskytovateľ hostingu dokáže držať krok).
- Elementor je nainštalovaný a aktivovaný (pre tento príklad widgetu postačuje bezplatná verzia). Pre pokročilé dynamické značky sa často používa Elementor Pro, ale vždy, keď je to možné, sa držíme verejných API.
- Pred vykonaním akýchkoľvek zmien je nevyhnutné vytvoriť testovacie prostredie a zálohu. Často som videl úryvky kódu vložené do produkčného prostredia, ktoré spustili fatálnu chybu a zablokovali administrátorské rozhranie.
- Plugin pre protokoly (alebo aspoň
WP_DEBUG_LOG) na čítanie chýb PHP.
Užitočné referencie pre WordPress:
- Príručka pre vývojárov doplnkov
- Jednorazové čísla (zabezpečenie)
- wp_enqueue_script ()
- esc_html()
- Príručka PHP
Naivný prístup (a prečo sa mu vyhnúť)
Klasický prístup: vložiť veľký kus kódu do functions.php témy (často bez podradenej témy), ukladať skripty všade a pri načítaní vytvárať inštancie tried Elementoru.
Typický príklad (anti-vzor)
<?php
// ❌ Exemple volontairement mauvais : ne copiez pas tel quel.
add_action('init', function () {
// ❌ Elementor n'est pas forcément chargé ici, et cette classe peut ne pas exister.
$widgets_manager = ElementorPlugin::instance()->widgets_manager;
require_once __DIR__ . '/widgets/badge.php';
$widgets_manager->register(new My_Badge_Widget());
// ❌ Charge CSS/JS sur toutes les pages, même si le widget n'est pas utilisé.
wp_enqueue_style('my-badge', get_stylesheet_directory_uri() . '/badge.css');
});
Prečo sa to (často) láme
- Načasovanie Elementor v čase ešte nedokončil inicializáciu svojich manažérov
init(v závislosti od verzií/kontextov). - Fatálna chyba ak je Elementor vypnutý,
ElementorPluginneexistuje. - výkon CSS/JS sa načítava všade, vrátane stránok, ktoré nepoužívajú Elementor.
- údržba Kód stratený v téme, nemožné správne verziovať, krehké pri zmene tém.
Správny prístup – podrobný návod
Vytvoríme mini plugin s:
- bootstrap, ktorý kontroluje, či je Elementor aktívny,
- špecializovaná kategória widgetov,
- vlastný widget,
- podmienené zaťaženie majetku,
- voliteľný variant „Dynamický tag“ na ilustráciu pokročilého filtra/registra.
Krok 1 – Vytvorenie doplnku
Vytvorte tento priečinok: wp-content/plugins/bpcab-elementor-hooks/
Potom tento súbor: wp-content/plugins/bpcab-elementor-hooks/bpcab-elementor-hooks.php
Krok 2 – Overenie Bootstrapu + Elementoru
Pripájame náš kód k plugins_loaded potom čakáme elementor/initKľúčový bod: nikdy nevolajte triedy Elementoru, kým nie je plugin pripravený.
Krok 3 – Uložte kategóriu + widget
Elementor sprístupňuje špecializované akcie. V praxi sú tieto stabilné už niekoľko verzií:
elementor/elements/categories_registeredpridať kategóriu,elementor/widgets/registeruložiť widget.
Trvám na tom: vyhnite sa používaniu háčikov „náhodne“ (ako napríklad init ou wp_loaded) na dotyk Elementoru. Problém zriedkakedy pramení z kódu widgetu, ale skôr z okamihu jeho spustenia.
Krok 4 – Načítajte CSS/JS v správnom čase
Majetok sa zaznamenáva prostredníctvom elementor/frontend/after_register_styles / elementor/frontend/after_register_scriptspotom my Enqueue iba ak je widget skutočne vykreslený.
Krok 5 – (Voliteľné) Pridajte dynamickú značku
Ak používate Elementor Pro (alebo ak váš stack podporuje dynamické tagy), vlastný tag je často čistejší ako shortcode. Vy sprístupníte dáta a Elementor sa postará o ich vkladanie do svojich „dynamických“ ovládacích prvkov.
Úplný kód
Skopírujte a vložte všetko nižšie. Plugin je samostatný a widgety môžete pridať neskôr.
Súbor 1 — bpcab-elementor-hooks.php
<?php
/**
* Plugin Name: BPCAB - Personnalisation Elementor par hooks
* Description: Exemple pédagogique : catégorie + widget custom + assets conditionnels + (option) Dynamic Tag.
* Version: 1.0.0
* Requires at least: 6.9
* Requires PHP: 8.1
* Author: BPCAB
* License: GPLv2 or later
*/
declare(strict_types=1);
if (!defined('ABSPATH')) {
exit;
}
final class BPCAB_Elementor_Hooks_Plugin {
public const VERSION = '1.0.0';
public const SLUG = 'bpcab-elementor-hooks';
private static ?self $instance = null;
public static function instance(): self {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
add_action('plugins_loaded', [$this, 'bootstrap']);
}
public function bootstrap(): void {
// Elementor définit généralement ELEMENTOR_VERSION quand il est actif.
if (!defined('ELEMENTOR_VERSION')) {
// Pas d'Elementor : on ne fait rien. Évitez d'afficher une notice agressive en front.
add_action('admin_notices', [$this, 'admin_notice_missing_elementor']);
return;
}
// On attend l'initialisation d'Elementor avant d'appeler ses classes/managers.
add_action('elementor/init', [$this, 'on_elementor_init']);
}
public function admin_notice_missing_elementor(): void {
if (!current_user_can('activate_plugins')) {
return;
}
$plugin_name = esc_html__('BPCAB - Personnalisation Elementor par hooks', 'bpcab');
$message = esc_html__('Elementor doit être activé pour utiliser ce plugin.', 'bpcab');
echo '<div class="notice notice-warning">';
echo '<p><strong>' . $plugin_name . '</strong> — ' . $message . '</p>';
echo '</div>';
}
public function on_elementor_init(): void {
// 1) Catégorie de widgets.
add_action('elementor/elements/categories_registered', [$this, 'register_category']);
// 2) Widgets.
add_action('elementor/widgets/register', [$this, 'register_widgets']);
// 3) Assets : on les enregistre au bon moment côté front.
add_action('elementor/frontend/after_register_styles', [$this, 'register_frontend_styles']);
add_action('elementor/frontend/after_register_scripts', [$this, 'register_frontend_scripts']);
// 4) Option : Dynamic Tag (si l'API est disponible).
add_action('elementor/dynamic_tags/register', [$this, 'register_dynamic_tags']);
}
public function register_category($elements_manager): void {
// $elements_manager est typiquement une instance de ElementorElements_Manager.
$elements_manager->add_category(
'bpcab',
[
'title' => esc_html__('BPCAB', 'bpcab'),
'icon' => 'fa fa-plug',
]
);
}
public function register_widgets($widgets_manager): void {
// Chargement des classes de widgets.
require_once __DIR__ . '/includes/widgets/class-bpcab-widget-badge.php';
// Enregistrement.
$widgets_manager->register(new BPCAB_Widget_Badge());
}
public function register_frontend_styles(): void {
wp_register_style(
'bpcab-badge',
plugins_url('assets/css/badge.css', __FILE__),
[],
self::VERSION
);
}
public function register_frontend_scripts(): void {
wp_register_script(
'bpcab-badge',
plugins_url('assets/js/badge.js', __FILE__),
[],
self::VERSION,
true
);
}
public function register_dynamic_tags($dynamic_tags_manager): void {
// Certains sites n'utilisent pas cette feature : on protège le require.
require_once __DIR__ . '/includes/dynamic-tags/class-bpcab-dynamic-tag-user-position.php';
// Enregistrement du tag.
$dynamic_tags_manager->register(new BPCAB_Dynamic_Tag_User_Position());
}
}
BPCAB_Elementor_Hooks_Plugin::instance();
Súbor 2 — includes/widgets/class-bpcab-widget-badge.php
<?php
declare(strict_types=1);
if (!defined('ABSPATH')) {
exit;
}
use ElementorWidget_Base;
use ElementorControls_Manager;
use ElementorIcons_Manager;
final class BPCAB_Widget_Badge extends Widget_Base {
public function get_name(): string {
return 'bpcab_badge';
}
public function get_title(): string {
return esc_html__('Badge (BPCAB)', 'bpcab');
}
public function get_icon(): string {
return 'eicon-badge';
}
public function get_categories(): array {
return ['bpcab'];
}
public function get_keywords(): array {
return ['badge', 'label', 'cta', 'bpcab'];
}
public function get_style_depends(): array {
// Elementor enqueuera ce style seulement si le widget est présent.
return ['bpcab-badge'];
}
public function get_script_depends(): array {
// Idem pour le script.
return ['bpcab-badge'];
}
protected function register_controls(): void {
$this->start_controls_section(
'section_content',
[
'label' => esc_html__('Contenu', 'bpcab'),
'tab' => Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'title',
[
'label' => esc_html__('Titre', 'bpcab'),
'type' => Controls_Manager::TEXT,
'default' => esc_html__('Nouveau', 'bpcab'),
'placeholder' => esc_html__('Ex: Nouveau', 'bpcab'),
'label_block' => true,
]
);
$this->add_control(
'text',
[
'label' => esc_html__('Texte', 'bpcab'),
'type' => Controls_Manager::TEXTAREA,
'default' => esc_html__('Offre limitée', 'bpcab'),
'placeholder' => esc_html__('Ex: Offre limitée', 'bpcab'),
'rows' => 3,
]
);
$this->add_control(
'icon',
[
'label' => esc_html__('Icône', 'bpcab'),
'type' => Controls_Manager::ICONS,
'default' => [
'value' => 'fas fa-star',
'library' => 'fa-solid',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_style',
[
'label' => esc_html__('Style', 'bpcab'),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'bg_color',
[
'label' => esc_html__('Couleur de fond', 'bpcab'),
'type' => Controls_Manager::COLOR,
'default' => '#111827',
'selectors' => [
'{{WRAPPER}} .bpcab-badge' => 'background-color: {{VALUE}};',
],
]
);
$this->add_control(
'text_color',
[
'label' => esc_html__('Couleur du texte', 'bpcab'),
'type' => Controls_Manager::COLOR,
'default' => '#ffffff',
'selectors' => [
'{{WRAPPER}} .bpcab-badge' => 'color: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'padding',
[
'label' => esc_html__('Padding', 'bpcab'),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => ['px', 'em', 'rem'],
'default' => [
'top' => 12,
'right' => 14,
'bottom' => 12,
'left' => 14,
'unit' => 'px',
],
'selectors' => [
'{{WRAPPER}} .bpcab-badge' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
}
protected function render(): void {
$settings = $this->get_settings_for_display();
// Sanitization/escaping : Elementor stocke des valeurs, mais vous devez sortir du HTML propre.
$title = isset($settings['title']) ? sanitize_text_field((string) $settings['title']) : '';
$text = isset($settings['text']) ? wp_kses_post((string) $settings['text']) : '';
// Icône : Elementor fournit Icons_Manager pour rendre proprement.
$icon = $settings['icon'] ?? null;
echo '<div class="bpcab-badge" role="note">';
echo '<div class="bpcab-badge__head">';
if (!empty($icon) && is_array($icon)) {
echo '<span class="bpcab-badge__icon" aria-hidden="true">';
Icons_Manager::render_icon($icon, ['aria-hidden' => 'true']);
echo '</span>';
}
if ($title !== '') {
echo '<strong class="bpcab-badge__title">' . esc_html($title) . '</strong>';
}
echo '</div>';
if ($text !== '') {
// wp_kses_post permet un sous-ensemble HTML (liens, strong, em, etc.).
echo '<div class="bpcab-badge__text">' . $text . '</div>';
}
echo '</div>';
}
}
Súbor 3 — includes/dynamic-tags/class-bpcab-dynamic-tag-user-position.php
<?php
declare(strict_types=1);
if (!defined('ABSPATH')) {
exit;
}
use ElementorCoreDynamicTagsTag;
final class BPCAB_Dynamic_Tag_User_Position extends Tag {
public function get_name(): string {
return 'bpcab-user-position';
}
public function get_title(): string {
return esc_html__('Utilisateur : Poste (BPCAB)', 'bpcab');
}
public function get_group(): string {
// Groupe "Site" ou "User" selon votre organisation.
return 'site';
}
public function get_categories(): array {
// Catégorie TEXT pour insertion dans des champs texte.
return [ElementorModulesDynamicTagsModule::TEXT_CATEGORY];
}
protected function register_controls(): void {
// Exemple : choisir une meta key (simple). En prod, vous pourriez proposer une liste.
$this->add_control(
'meta_key',
[
'label' => esc_html__('Meta key utilisateur', 'bpcab'),
'type' => ElementorControls_Manager::TEXT,
'default' => 'position',
'placeholder' => 'position',
]
);
}
public function render(): void {
$user_id = get_current_user_id();
if (!$user_id) {
return;
}
$settings = $this->get_settings();
$meta_key = isset($settings['meta_key']) ? sanitize_key((string) $settings['meta_key']) : 'position';
$value = get_user_meta($user_id, $meta_key, true);
if (!is_scalar($value) || $value === '') {
return;
}
echo esc_html((string) $value);
}
}
Súbor 4 — assets/css/badge.css
.bpcab-badge{
display:block;
border-radius:12px;
line-height:1.35;
}
.bpcab-badge__head{
display:flex;
gap:10px;
align-items:center;
}
.bpcab-badge__icon{
display:inline-flex;
}
.bpcab-badge__title{
font-weight:700;
}
.bpcab-badge__text{
margin-top:8px;
opacity:.95;
}
Súbor 5 — assets/js/badge.js
(function () {
// Script minimal : exemple de point d'accroche.
// Ici, on ne fait rien de critique. Gardez vos widgets robustes sans JS si possible.
})();
Vysvetlenie kódu
1) Prečo plugin (a nie functions.php)?
Plugin vám poskytuje jasný životný cyklus, aktiváciu/deaktiváciu, verzovanie a stabilné umiestnenie pre vaše triedy. Často som videl aktualizované stránky Avada/Divi a malý úryvok v téme zmizol alebo sa stal nekompatibilným.
2) Kľúčový bod: načasovanie háčikov
plugins_loadedWordPress nahral pluginy. Môžeme skontrolovať, či je tam Elementor.elementor/initElementor inicializoval svoj hlavný kontajner. Tu pridáte svoje hooky Elementoru.elementor/widgets/register: dostanete správcu widgetov a uložíte si svoje triedy.elementor/elements/categories_registered: deklarujete kategóriu viditeľnú v používateľskom rozhraní nástroja na tvorbu.
Toto rozdelenie sa vyhýba klasickej chybe: „Trieda 'ElementorPlugin' sa nenašla“ alebo „Volanie členskej funkcie register() pri hodnote null“.
3) Podmienené načítanie aktív
Duo get_style_depends() / get_script_depends() je nedostatočne využívaný. Napriek tomu je to jeden z najčistejších spôsobov, ako načítať vaše dáta iba vtedy, keď Elementor vykreslí váš widget.
V zákulisí: Elementor zhromažďuje závislosti widgetov na stránke a dotazuje sa na zodpovedajúce úchyty. Jednoducho... wp_register_style() / wp_register_script() v správnom čase.
4) Bezpečné vykresľovanie: sanitizácia + escaping
- vstup Elementor ukladá hodnoty do databázy. V závislosti od kontextu ich však treba vyčistiť.
- výjazd :
esc_html()pre text,wp_kses_post()ak povolíte obmedzený HTML.
Pasca, ktorú vidím najčastejšie: ísť rovno von $settings['text'] sans wp_kses_post() „Pretože je to administrátor.“ Na stránke s viacerými autormi sa to stáva rizikom XSS.
5) Dynamický tag: prečo je užitočný
Dynamický tag eliminuje potrebu krátkych kódov v poliach Elementoru. Vy sprístupníte údaje (metadáta používateľa, možnosť, pole ACF) a používateľ vyberie tag v používateľskom rozhraní. Toto je jednoduchšie vložiť ako krátky kód do 30 widgetov.
Varianty a prípady použitia
Variant 1 – Vynútenie „uzamknutých“ hodnôt (menej možností pre zákazníka)
Ak chcete zákazníkovi zabrániť v zmene určitých možností, môžete:
- neodhaľujte ovládanie (nie
add_control), - alebo zobraziť uzavretý zoznam (SELECT),
- alebo zaviesť hodnotu v
render().
Príklad: zavedenie CSS triedy na základe „typu“:
// Dans register_controls()
$this->add_control(
'type',
[
'label' => esc_html__('Type', 'bpcab'),
'type' => Controls_Manager::SELECT,
'default' => 'info',
'options' => [
'info' => esc_html__('Info', 'bpcab'),
'warning' => esc_html__('Alerte', 'bpcab'),
],
]
);
// Dans render()
$type = isset($settings['type']) ? sanitize_key((string) $settings['type']) : 'info';
$type_class = in_array($type, ['info', 'warning'], true) ? 'is-' . $type : 'is-info';
echo '<div class="bpcab-badge ' . esc_attr($type_class) . '">...</div>';
Variant 2 – Pridajte ovládací prvok URL a vytvorte čistý odkaz
Klikateľný odznak s výzvou na akciu sa zobrazuje neustále. Elementor poskytuje ovládací prvok URL s možnosťami „otvoriť na novej karte“ a „nofollow“.
// Contrôle URL
$this->add_control(
'link',
[
'label' => esc_html__('Lien', 'bpcab'),
'type' => Controls_Manager::URL,
'options' => ['url', 'is_external', 'nofollow'],
'default' => [
'url' => '',
],
]
);
// Dans render()
$link = $settings['link'] ?? [];
$url = isset($link['url']) ? esc_url((string) $link['url']) : '';
if ($url) {
$target = !empty($link['is_external']) ? ' target="_blank"' : '';
$rel = !empty($link['nofollow']) ? ' rel="nofollow noopener"' : ' rel="noopener"';
echo '<a class="bpcab-badge" href="' . $url . '"' . $target . $rel . '>...</a>';
return;
}
Poznámka: Ak otvoríte odkaz na novej karte, ponechajte noopener (bezpečnosť).
Variant 3 – Načítanie podkladu iba na určitých stránkach (ešte prísnejšie)
Ak máte zložitý skript, môžete skombinovať závislosť widgetu s podmienkou WordPressu. Napríklad: iba na stránkach (nie na tovar):
public function register_frontend_scripts(): void {
wp_register_script(
'bpcab-badge',
plugins_url('assets/js/badge.js', __FILE__),
[],
self::VERSION,
true
);
// ⚠️ Ne faites pas wp_enqueue_script ici : Elementor gère l'enqueue via get_script_depends().
// Si vous voulez vraiment empêcher le chargement sur certains contextes, vous pouvez deregister :
if (!is_page()) {
wp_deregister_script('bpcab-badge');
}
}
Používam ho zriedka: môže byť prekvapujúce, ak sa widget použije v šablóne, ktorá sa zobrazuje inde. Dôkladne ho otestujte.
Kompatibilita s Divi 5 / Elementor / Avada
Elementor
- Vyššie uvedený plugin sa integruje „do“ Elementoru bez závislosti od témy.
- Ak používate šablóny Elementor (Theme Builder), widget zostáva dostupný všade.
- Prostriedky sú podmienené: dobrý postreh na veľmi rušných stránkach.
Divi 5
Divi 5 nepoužíva rozhranie Elementor API. Váš widget sa v Divi nezobrazí a to je normálne.
Ak je vaším cieľom opätovne použiť rovnaký komponent na stránkach Divi, odporúčam stratégiu „bez ohľadu na tvorcu“:
- vytvorte shortcode pre WordPress (alebo lepšie: blok Gutenberg),
- potom ho vložte do Divi pomocou modulu Code/Shortcode,
- a ponechajte Elementor ako „prekrytie používateľského rozhrania“, keď je prítomný.
Podľa mojich skúseností je to jediný prístup, ktorý funguje, ak máte park s viacerými staviteľmi.
Avada (výrobca fúzií)
Platí rovnaká logika: Avada nebude používať widgety Elementoru. Váš plugin však zostáva užitočný, ak web používa Elementor na niektorých stránkach.
Pre Avada je najčistejší vzor tiež: krátky kód alebo blok, potom prvok „Blok kódu“ / „Krátky kód“ vo Fusion Builderi.
Kontroly po inštalácii
- Aktivujte plugin v Rozšírenie.
- Otvorte stránku pomocou Elementoru.
- V paneli widgetov vyhľadajte kategóriu BPCAB potom widget Odznak (BPCAB).
- Umiestnite to na stránku, upravte názov/text/farby a publikujte.
- Na prednej strane skontrolujte stránku: mali by ste vidieť
bpcab-badge.cssnačítané (a nie na stránkach, ktoré nepoužívajú widget).
Rýchla diagnostická tabuľka
| symptóm | Príčina pravdepodobná | overenie | Riešenie |
|---|---|---|---|
| Kategória BPCAB sa nezobrazuje | Hook sa nikdy nevykonal (Elementor sa nenačítal) | Skontrolujte, či ELEMENTOR_VERSION je definovaný a Elementor je aktívny |
Aktivujte Elementor, skontrolujte konflikty/mu-pluginy |
| Závažná chyba „Trieda ElementorWidget_Base sa nenašla“ | Súbor widgetu bol načítaný príliš skoro / Elementor je neaktívny | Zobraziť protokol PHP + stopu zásobníka | Vyžadovať iba widget v elementor/widgets/register po elementor/init |
| CSS/JS nie je načítaný | Neregistrované úchyty alebo chybný registračný hook | preskúmať wp_head / wp_footer + konzola |
skontrolovať after_register_styles/scripts et get_style_depends() |
| Widget sa zobrazuje, ale štýly sú poškodené. | Ukladanie do vyrovnávacej pamäte (plugin/CDN) alebo agresívna minifikácia | Vypnúť vyrovnávaciu pamäť, vymazať CDN, otestovať v režime súkromného prehliadania | Vylúčiť súbory z vyrovnávacej pamäte/minifikácie, zväčšiť verziu |
| Dynamická značka sa nenašla | Funkcia nie je k dispozícii (v závislosti od konfigurácie/Pro) alebo sa neaktivoval hák | Skontrolujte, či sa v textovom poli nachádza panel „Dynamický“ | V prípade potreby nainštalujte/aktivujte Elementor Pro alebo odstráňte sekciu so značkami |
Ak to nefunguje
- Potvrďte verzie WordPress 6.9.4+, PHP 8.1+, Elementor aktualizovaný. Zastaraná verzia PHP spôsobuje chyby na
declare(strict_types=1)alebo typy?self. - Povoliť protokolovanie v
wp-config.php(v štádiu prípravy):
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false); - otvorené
wp-content/debug.loga vyhľadajte „BPCAB“ alebo „Elementor“. - Dočasne deaktivovať Pluginy s úryvkami kódu. Už som videl úryvok kódu „zo starého tutoriálu Elementoru“, ktorý deklaroval triedu s rovnakým názvom a spôsobil fatálny konflikt.
- Vymazať vyrovnávaciu pamäť : vyrovnávacia pamäť pluginov, vyrovnávacia pamäť servera, CDN, vyrovnávacia pamäť prehliadača. V Elementore môže agresívne ukladanie do vyrovnávacej pamäte tiež zachovať chýbajúce prvky.
- Obnovte CSS kód Elementoru (ak vaša stránka používa možnosť generovania CSS). V Elementore máte zvyčajne akciu regenerácie v nastaveniach nástrojov/výkonu.
- Skúste to s neutrálnou témou (dočasné): Twenty Twenty-* alebo odľahčená téma. Téma dokáže zrušiť registráciu skriptov/štýlov.
Časté úskalia a chyby
| Chyba | Spôsobiť | Riešenie |
|---|---|---|
| Kód vložený do nesprávneho súboru | Pridané v functions.php namiesto pluginu |
Vytvorte plugin, nastavte jeho verziu a správne ho aktivujte/deaktivujte |
| „Chyba pri analýze: syntaktická chyba“ | Chýbajúca bodkočiarka, zložená zátvorka navyše, neúplné kopírovanie a vkladanie | Skontrolujte riadok uvedený v protokole, použite IDE s formátovaním PHP |
| Nevhodné pre háčiky Elementor | Použitie init / wp_loaded uložiť widget |
použitie elementor/init potom elementor/widgets/register |
| „Trieda ElementorPlugin sa nenašla“ | Elementor bol zakázaný alebo načítaný po zadaní kódu | skontrolovať defined('ELEMENTOR_VERSION') a nikdy predtým nevolajte Elementoru elementor/init |
| CSS/JS sa nenačítal | Zlý handle, zlý hook alebo vyrovnávacia pamäť/minifikacia | Uložiť cez after_register_styles/scripts, deklarovať závislosti prostredníctvom get_*_depends()vymazať vyrovnávaciu pamäť |
| Konflikt názvov tried | Dva pluginy deklarujú BPCAB_Widget_Badge (alebo nesprávne nakonfigurovaný automatický načítač) |
Ak industrializujete, vždy používajte predpony a menné priestory. |
| Zmätok medzi akciou a filtrom | Snažíte sa „vrátiť“ k akcii | Akcie: vedľajšie účinky. Filtre: vracajú hodnotu. Skontrolujte použitý hook. |
| Priame testovanie vo výrobe | Žiadne stagingové riešenia, žiadne zálohovanie | Plán prípravy + zálohovania + vrátenia zmien (deaktivácia pluginu cez FTP, ak je to potrebné) |
| Nekonzistentné trvalé odkazy/šablóny | Testujete na inej šablóne, ako je tá, ktorá je vykreslená (Tvorca tém). | Skontrolujte, ktorá šablóna Elementoru je skutočne použitá, a vymažte vyrovnávaciu pamäť. |
Tipy na bezpečnosť, výkon a údržbu
Zabezpečenie
- Systematický útek všetko, čo sa vypíše v HTML, musí byť escapované podľa kontextu (
esc_html,esc_attr,esc_url,wp_kses_post). Referencia: WordPress: Overovanie údajov. - Žiadne možnosti „bezplatného HTML“ pre neadministrátorské role. Na stránkach s viacerými autormi je to vektor XSS.
- Žiadne spustenie PHP cez widget (Zdá sa to samozrejmé, ale už som videl nejaké poskladané „kódové widgety“).
výkon
- Podmienené aktíva via
get_style_depends()/get_script_depends()je to najlepší pomer úsilia a zisku. - Vyhnite sa cyklickým požiadavkám v
render()Ak potrebujete načítať dáta (príspevky, meta), uložte ich do vyrovnávacej pamäte (vyrovnávacia pamäť prechodných údajov/vyrovnávacia pamäť objektov) alebo ich pripravte pomocou optimalizovaného dotazu. - Minimálne CSS : widget = malý súbor. Ak ich máte 20, inteligentne ich zoskupte (ale zachovajte podmienenosť).
údržba
- Verzia Použite plugin (Git) a označte svoje vydania. Keď Elementor zmení API, budete vedieť, čo máte nasadiť.
- Vyhnite sa „starým“ návodom ktoré používajú zastarané hooky. Ak znovu používate úryvok z rokov 2021 – 2023, uistite sa, že je kompatibilný so súčasným Elementorom a WordPressom 6.9.4.
- Pripravte si záložnú stratégiu Ak je Elementor vypnutý, váš doplnok by nemal „robiť nič“ bez toho, aby bol fatálny.
zdroje
- Príručka pre vývojárov pluginov pre WordPress
- WordPress jednorazové výrazy
- WordPress Escaping (zabezpečenie)
- wp_register_style()
- wp_register_script()
- Elementor na WordPress.org
- WordPress Core (GitHub)
- WordPress Core Trac
- Manuál PHP
Často kladené otázky
Funguje tento kód s WordPressom 6.9.4?
Áno: plugin sa riadi štandardnými postupmi WordPressu (hooky, zaraďovanie do frontu) a je určený pre PHP 8.1+. Hlavným problémom s kompatibilitou zostáva verzia Elementoru (udržiavajte ju aktualizovanú).
Prečo nepoužiť plugin na úryvky?
Pre rýchly test je to v poriadku. Pre opakovane použiteľný widget Elementoru je skutočný plugin spoľahlivejší: kontrolované načítavanie, organizované súbory, verzovanie a čistá deaktivácia, ak sa pokazí.
Môj widget sa zobrazuje, ale nie je v správnej kategórii.
Skontrolujte, či get_categories() otoč sa ['bpcab']a že kategória je registrovaná prostredníctvom elementor/elements/categories_registered.
Ako pridám viacero widgetov?
Pridať ďalšie súbory do includes/widgets/ a uložte ich do register_widgets()Jeden súbor = jedna trieda.
Ako sa môžem vyhnúť načítaniu JS, ak ho nepotrebujem?
Odstrániť get_script_depends() alebo vrátiť prázdne pole. Udržujte widget funkčný bez JS čo najviac.
Dá sa použiť automatický načítač (Composer)?
Áno, najmä ak máte viac ako 10 widgetov. V kontexte WordPressu dávajte pozor, aby ste nevynútili používanie Composera na finálnej stránke. Bežným prístupom je zahrnutie automatického načítavania PSR-4 do pluginu.
Prečo používať wp_kses_post() Kvôli textu?
Pretože textové pole môže obsahovať HTML, ak to Elementor umožňuje (alebo ak používateľ vloží obsah). wp_kses_post() umožňuje bezpečnú podmnožinu, na rozdiel od surovej ozveny.
Dynamický tag sa nezobrazuje: je to normálne?
Záleží to od konfigurácie vášho Elementoru. Skontrolujte, či je pre vaše polia k dispozícii „dynamické“ používateľské rozhranie. Ak vaša stránka nepodporuje dynamické značky, odstráňte túto časť elementor/dynamic_tags/register a pridružený súbor.
Ako môžem správne testovať bez toho, aby som porušil editor?
Otestujte v režime staging, povoľte logovanie a začnite s minimálnym widgetom (vykreslený + jeden ovládací prvok). Ovládacie prvky pridávajte jeden po druhom. Chyby Elementoru sú často na strane používateľského rozhrania tiché, ale viditeľné v konzole a PHP logu.
Je kompatibilný s podradenou témou Divi/Avada?
Áno, pretože ide o plugin. Widget sa však zobrazí iba v Elementore. V Divi/Avada použite shortcode alebo blok, ak chcete komponent, ktorý je možné zdieľať medzi tvorcami.