Muammo / Ehtiyoj

Agar siz allaqachon Elementor saytini taqdim etgan bo'lsangiz va mijoz sizdan "Menga vidjet kerak" deb so'rasa moslashtirilgan, lekin 12 ta qo'shimchani o'rnatmasdan”, siz allaqachon to'g'ri refleksga egasiz: kodni ko'rib chiqing.

Elementor (Free/Pro) quruvchini to'g'ri sozlash uchun yetarlicha barqaror ilgaklar va hodisalar API-sini taqdim etadi: vidjetlar toifasini qo'shish, maxsus vidjetni saqlash, boshqaruv elementlarini kiritish, standart qiymatlarni majburlash, skriptlarni faqat kerak bo'lganda yuklash va hatto teg orqali dinamik maydon qo'shish.

Biznesning odatiy ehtiyoji: Elementorning UX ni saqlab qolgan holda qayta ishlatiladigan komponentlarni (CTAlar, mualliflar uchun qutilar, mahsulot varaqlari, jadvallar, GDPR bannerlari va boshqalar) sanoatlashtirish. Oxir-oqibat, siz toza va mos mini-plaginni qanday tuzishni bilib olasiz. WordPress 6.9.4+ va PHP 8.1+ versiyalarida, va siz loyihalaringiz uchun qayta ishlatiladigan bazaga ega bo'lasiz.

Tez xulosa

  • Mini-plagin yarating WordPress (bir martalik ishlatiladigan parcha emas), bu Elementor bilan integratsiyalashgan holda buziladiadmin.
  • To'g'ri Elementor ilgaklaridan foydalaning: elementor/init, elementor/widgets/register, elementor/elements/categories_registered, elementor/frontend/after_register_scripts.
  • Boshqaruv elementlari, xavfsiz renderlash va uslublar bilan maxsus "Bage" vidjetini (sarlavha + matn + rang + belgi) qo'shing.
  • Foydalanuvchi meta-ma'lumotlaridan qiymat kiritish uchun dinamik teg (kengaytirilgan variant) qo'shing (masalan, pozitsiya/rol).
  • CSS/JS ni faqat plaginingizdagi vidjet mavjud bo'lganda yuklang ("hamma narsani hamma joyga yuklashdan" saqlaydi).

Ushbu yechimdan qachon foydalanish kerak

  • Siz bir nechta saytlarda (agentlik, frilanser, jamoa) qayta ishlatilishi mumkin bo'lgan barqaror, versiyalangan komponentni xohlaysiz.
  • Mijoz uchun 50 ta "xavfli" variant qoldirmasdan, uslub qo'llanmasiga (ranglar, tipografiya, interval) rioya qilishingiz kerak.
  • Sizga ogohlantirishsiz o'zgarishi mumkin bo'lgan uchinchi tomon qo'shimchasiga tayanmasdan aniq front-end renderlash kerak.
  • Siz unumdorlikni oshirishni xohlaysiz: aktivlar faqat kerak bo'lganda yuklanadi, vidjetlarning "katta to'plami" yo'q.
  • Siz WordPress ma'lumotlarini (meta, variantlar, ACF/Podlar va boshqalar) dinamik teglar orqali integratsiya qilmoqchisiz.

Ushbu yechimdan qachon foydalanmaslik kerak

  • Ehtiyoj faqat vizual va vaqti-vaqti bilan bo'ladi: a oddiy Elementor shabloni, konteyner va ozgina CSS yetarli bo'lishi mumkin.
  • Siz texnik xizmat ko'rsatish ustidan nazoratga ega emassiz: maxsus vidjet Elementorga (va ba'zan uning eskirishlariga) amal qilishni anglatadi.
  • Agar siz Elementorni keng ko'lamda "tuzatmoqchi" bo'lsangiz (masalan, muharrirning ichki xatti-harakatlarini o'zgartirmoqchi bo'lsangiz), u kamdan-kam hollarda barqaror bo'ladi. Rasmiy kengaytmalarni tanlang yoki ma'lum darajada texnik qarzni qabul qiling.
  • Mijozingiz asosan Gutenberg/bloklardan foydalanadi: bu holda, maxsus blok (Block API) ko'pincha mosroq bo'ladi. Rasmiy hujjatlarga qarang: Blok muharriri qo'llanmasi.

Talablar / Boshlashdan oldin

  • WordPress 6.9.4+ va PHP 8.1+ (agar sizning xosting provayderingiz yetib bora olsa, 2026-yilda ideal holda 8.2/8.3).
  • Elementor o'rnatildi va faollashtirildi (bepul versiyasi ushbu vidjet misoli uchun yetarli). Kengaytirilgan dinamik teglar uchun Elementor Pro ko'pincha ishlatiladi, lekin biz iloji boricha ommaviy API-larga amal qilamiz.
  • Har qanday o'zgartirishlar kiritilishidan oldin bosqichma-bosqich muhit va zaxira nusxasi juda muhimdir. Men ko'pincha ishlab chiqarishga joylashtirilgan, halokatli xatoga olib keladigan va administrator interfeysini qulflaydigan parchalarni ko'rganman.
  • Jurnallar plagini (yoki hech bo'lmaganda) WP_DEBUG_LOG) PHP xatolarini o'qish uchun.

Foydali WordPress havolalari:

Sodda yondashuv (va nima uchun undan qochish kerak)

Klassik yondashuv: kodning katta qismini joylashtiring functions.php mavzuni (ko'pincha bolalar mavzusisiz) o'zgartirish, skriptlarni hamma joyda saqlash va yuklanganda Elementor sinflarini yaratish.

Odatdagi misol (anti-naqsh)

<?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');
});

Nima uchun u buziladi (ko'pincha)

  • Xronologiya Elementor o'sha paytda menejerlarini ishga tushirishni hali tugatmagan edi init (versiyalar/kontekstlarga qarab).
  • Fatal error : agar Elementor o'chirilgan bo'lsa, ElementorPlugin mavjud emas.
  • bajarish CSS/JS hamma joyda, shu jumladan Elementordan foydalanmaydigan sahifalarda ham yuklanadi.
  • saqlash : kod mavzuda yo'qolgan, versiyasini to'g'ri o'zgartirish imkonsiz, mavzularni o'zgartirganda mo'rt.

To'g'ri yondashuv — bosqichma-bosqich qo'llanma

Biz quyidagilar bilan mini-plagin yaratmoqchimiz:

  • Elementor faol yoki yo'qligini tekshiradigan yuklash chizig'i,
  • vidjetlarning maxsus toifasi,
  • maxsus vidjet,
  • shartli aktivlarni yuklash,
  • Kengaytirilgan filtr/registrni ko'rsatish uchun ixtiyoriy "Dinamik yorliq" varianti.

1-qadam — Plaginni yarating

Ushbu papkani yarating: wp-content/plugins/bpcab-elementor-hooks/

Keyin bu fayl: wp-content/plugins/bpcab-elementor-hooks/bpcab-elementor-hooks.php

2-qadam — Bootstrap + Elementor tekshiruvi

Biz kodimizni biriktiramiz plugins_loaded keyin kutamiz elementor/initAsosiy nuqta: plagin tayyor bo'lmaguncha hech qachon Elementor sinflarini chaqirmang.

3-qadam — Kategoriya + vidjetni saqlang

Elementor maxsus harakatlarni namoyish etadi. Amalda, ular bir nechta versiyalar uchun barqaror bo'lgan:

  • elementor/elements/categories_registered kategoriya qo'shish uchun,
  • elementor/widgets/register vidjetni saqlash uchun.

Men qat'iy turibman: ilgaklarni "tasodifiy" ishlatishdan saqlaning (masalan, init ou wp_loaded) Elementorga teginish uchun. Muammo kamdan-kam hollarda vidjet kodidan kelib chiqadi, lekin u ishga tushirilgan paytdan boshlab.

4-qadam — CSS/JS ni kerakli vaqtda yuklang

Aktivlar orqali qayd etiladi elementor/frontend/after_register_styles / elementor/frontend/after_register_scriptskeyin biz enqueue faqat vidjet aslida render qilingan bo'lsa.

5-qadam — (Ixtiyoriy) Dinamik teg qo'shish

Agar siz Elementor Pro dan foydalanayotgan bo'lsangiz (yoki sizning stekingiz dinamik teglarni qo'llab-quvvatlasa), maxsus teg ko'pincha qisqa kodga qaraganda tozaroq bo'ladi. Siz ma'lumotlarni ochasiz va Elementor in'ektsiyani o'zining "Dinamik" boshqaruv elementlariga qayta ishlaydi.

To'liq kod

Quyidagi hamma narsani nusxalang va joylashtiring. Plagin mustaqil ravishda ishlaydi va siz keyinroq vidjetlar qo'shishingiz mumkin.

1-fayl — 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();

2-fayl — 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>';
	}
}

3-fayl — 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);
	}
}

4-fayl — aktivlar/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;
}

5-fayl — aktivlar/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.
})();

Kodning izohi

1) Nima uchun plagin (va functions.php emas)?

Plagin sizga aniq hayot aylanishi, faollashtirish/o'chirish, versiyalash va sinflaringiz uchun barqaror joylashuvni taqdim etadi. Men Avada/Divi saytlarining yangilanganini va mavzudagi kichik bir parcha yo'qolganini yoki mos kelmasligini tez-tez ko'rganman.

2) Asosiy nuqta: ilgaklarning vaqti

  • plugins_loaded WordPress plaginlarni yukladi. Elementor bor-yo'qligini tekshirishimiz mumkin.
  • elementor/init Elementor o'zining asosiy konteynerini ishga tushirdi. Bu yerda siz Elementor ilgaklaringizni qo'shasiz.
  • elementor/widgets/register : siz vidjet menejerini olasiz va sinflaringizni saqlaysiz.
  • elementor/elements/categories_registered : siz quruvchining foydalanuvchi interfeysida ko'rinadigan kategoriyani e'lon qilasiz.

Ushbu tahlil klassik xatodan qochadi: “'ElementorPlugin' klassi topilmadi” yoki “Nulldagi register() a'zo funktsiyasiga chaqiruv”.

3) Aktivlarni shartli ravishda yuklash

Ikkilik get_style_depends() / get_script_depends() kam foydalaniladi. Shunga qaramay, bu faqat Elementor sizning vidjetingizni ko'rsatganda aktivlaringizni yuklashning eng toza usullaridan biridir.

Sahna ortida: Elementor sahifadagi vidjetlarning bog'liqliklarini to'playdi va tegishli tutqichlarga so'rov yuboradi. Siz shunchaki... wp_register_style() / wp_register_script() to'g'ri vaqtda.

4) Xavfsiz renderlash: dezinfeksiya + qochish

  • kirish Elementor qiymatlarni ma'lumotlar bazasida saqlaydi. Kontekstga qarab, ularni tozalashingiz kerak.
  • Sortie : esc_html() matn uchun, wp_kses_post() Agar siz cheklangan HTMLga ruxsat bersangiz.

Men eng ko'p ko'radigan tuzoq: to'g'ridan-to'g'ri chiqib ketish $settings['text'] Sans wp_kses_post() "Chunki bu administrator." Ko'p muallifli saytda bu XSS xavfiga aylanadi.

5) Dinamik teg: nima uchun u foydali

Dinamik teg Elementor maydonlarida qisqa kodlarga ehtiyojni bartaraf etadi. Siz ma'lumotlarni (foydalanuvchi meta-ma'lumotlari, parametr, ACF maydoni) ochasiz va foydalanuvchi interfeysda tegni tanlaydi. Bu 30 ta vidjetga joylashtirilgan qisqa kodga qaraganda ancha osonroq saqlanadi.

Variantlar va foydalanish holatlari

1-variant — "Qulflangan" qiymatlarni majburan qo'llash (mijozlarning kamroq imkoniyatlari)

Agar mijozning ma'lum variantlarni o'zgartirishiga yo'l qo'ymaslikni istasangiz, quyidagilarni qilishingiz mumkin:

  • nazoratni fosh qilmang (yo'q) add_control),
  • yoki yopiq ro'yxatni (SELECT) ochish,
  • yoki qiymat qo'ying render().

Misol: "turi" asosida CSS klassini joriy qilish:

// 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>';

2-variant — URL boshqaruvini qo'shing va toza havola yarating

Bosish mumkin bo'lgan nishon CTA doimo paydo bo'ladi. Elementor "yangi yorliqda ochish" va "nofollow" opsiyalari bilan URL boshqaruvini taqdim etadi.

// 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;
}

Eslatma: Agar havolani yangi yorliqda ochsangiz, uni saqlab qo'ying noopener (xavfsizlik).

3-variant — Aktivni faqat ma'lum sahifalarga yuklang (hatto undan ham qattiqroq)

Agar sizda murakkab skript bo'lsa, vidjetga bog'liqlikni WordPress sharti bilan birlashtirishingiz mumkin. Masalan: faqat sahifalarda (emas) maqolalar):

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');
	}
}

Men uni kamdan-kam ishlataman: agar vidjet boshqa joyda ko'rsatilgan shablonda ishlatilsa, bu ajablanarli bo'lishi mumkin. Uni yaxshilab sinab ko'ring.

Divi 5 / Elementor / Avada mosligi

Elementor

  • Yuqoridagi plagin mavzuga bog'liq bo'lmasdan Elementorga "integratsiyalashadi".
  • Agar siz Elementor (Theme Builder) shablonlaridan foydalanayotgan bo'lsangiz, vidjet hamma joyda mavjud bo'lib qoladi.
  • Aktivlar shartli: juda gavjum saytlarda yaxshi fikr.

5-bo'lim

Divi 5 Elementor API-dan foydalanmaydi. Sizning vidjetingiz Divi-da ko'rinmaydi va bu normal holat.

Agar maqsadingiz Divi sahifalarida bir xil komponentdan qayta foydalanish bo'lsa, men "quruvchi-agnostik" strategiyani tavsiya qilaman:

  • WordPress qisqa kodini yarating (yoki undan ham yaxshiroq: Gutenberg bloki),
  • keyin uni Kod/Qisqa kod moduli orqali Divi-ga joylashtiring,
  • va Elementor mavjud bo'lganda uni "UI qoplamasi" sifatida saqlang.

Mening tajribamda, agar sizda ko'p qavatli uy bo'lsa, bu yagona yondashuv ishlaydi.

Avada (Fusion Builder)

Xuddi shu mantiq qo'llaniladi: Avada Elementor vidjetlaridan foydalanmaydi. Biroq, agar sayt ba'zi sahifalarda Elementordan foydalansa, plaginingiz foydali bo'lib qoladi.

Avada uchun eng toza naqsh ham: qisqa kod yoki blok, keyin Fusion Builder-dagi “Kod bloki” / “Qisqa kod” elementi.

O'rnatishdan keyingi tekshiruvlar

  1. Plaginni faollashtiring Kengaytmalar.
  2. Elementor bilan sahifa oching.
  3. Vidjetlar panelida kategoriyani qidiring BPCAB keyin vidjet Nishon (BPCAB).
  4. Uni sahifaga joylashtiring, sarlavhani/matnni/ranglarni tahrirlang va nashr eting.
  5. Old tomonda sahifani tekshiring: ko'rishingiz kerak bpcab-badge.css yuklangan (va vidjetdan foydalanmaydigan sahifalarda emas).

Tez diagnostika jadvali

alomat Ehtimoliy sabab tekshiruv qaror
BPCAB kategoriyasi ko'rinmayapti Hook hech qachon bajarilmadi (Elementor yuklanmagan) Tekshirib ko'ring ELEMENTOR_VERSION aniqlangan va Elementor faol Elementorni faollashtiring, ziddiyatlar/mu-plaginlarni tekshiring
“Class ElementorWidget_Base topilmadi” xatosi Vidjet fayli juda erta yuklandi / Elementor faol emas PHP jurnali + stek izini ko'rish Faqat vidjetni talab qiling elementor/widgets/register après elementor/init
CSS/JS yuklanmadi Ro'yxatdan o'tmagan tutqichlar yoki noto'g'ri ro'yxatdan o'tish ilgagi tekshiring wp_head / wp_footer + konsol nazorat after_register_styles/scripts et get_style_depends()
Vidjet ko'rsatiladi, lekin uslublar buzilgan. Keshlash (plagin/CDN) yoki agressiv minififikatsiya Keshni o'chiring, CDNni tozalang, shaxsiy ko'rish rejimida sinab ko'ring Fayllarni kesh/minify, bump versiyasidan chiqarib tashlash
Dinamik teg topilmadi Funksiya mavjud emas (konfiguratsiya/Pro ga qarab) yoki hick ishga tushirilmagan Matn maydonida "Dynamic" paneli mavjudligini tekshiring Agar kerak bo'lsa, Elementor Pro-ni o'rnating/faollashtiring yoki teg qismini olib tashlang

Agar bu ishlamasa

  1. Versiyalarni tasdiqlang WordPress 6.9.4+, PHP 8.1+, Elementor yangilangan. Eskirgan PHP versiyasi xatolarga sabab bo'lmoqda declare(strict_types=1) yoki turlari ?self.
  2. Jurnalni yoqish yilda wp-config.php (sahnalashtirilgan):

    define('WP_DEBUG', true);

    define('WP_DEBUG_LOG', true);

    define('WP_DEBUG_DISPLAY', false);
  3. ochiq wp-content/debug.log va “BPCAB” yoki “Elementor” ni qidiring.
  4. Vaqtinchalik o'chirib qo'yish Parcha plaginlari. Men allaqachon "eski Elementor qo'llanmasidan" bir parchani xuddi shu nomdagi klassni e'lon qilganini va halokatli to'qnashuvga sabab bo'lganini ko'rganman.
  5. Keshlarni tozalang : plagin keshi, server keshi, CDN, brauzer keshi. Elementorda agressiv keshlash yo'qolgan aktivlarni ham saqlab qolishi mumkin.
  6. Elementor CSS-ni qayta yarating (agar saytingiz CSS generatsiya opsiyasidan foydalansa). Elementorda odatda vositalar/ishlash sozlamalarida regeneratsiya amali mavjud.
  7. Neytral mavzu bilan sinab ko'ring (vaqtinchalik): Yigirma Yigirma* yoki yengil mavzu. Mavzu skriptlar/uslublarni ro'yxatdan o'chirishi mumkin.

Umumiy xatolar va kamchiliklar

xato Sababi qaror
Kod noto'g'ri faylga joylashtirildi Qo'shilgan functions.php plagin o'rniga Plagin yarating, uni versiyalashtiring va uni to'g'ri yoqing/o'chiring.
"Tahlil xatosi: sintaksis xatosi" Nuqtali vergul yo'q, qo'shimcha jingalak qavs, nusxa ko'chirish/joylashtirish tugallanmagan Jurnalda ko'rsatilgan qatorni ko'rib chiqing, PHP formatlash bilan IDE dan foydalaning
Hook Elementor mos emas dan foydalanish init / wp_loaded vidjetni saqlash uchun foydalanish elementor/init so'ng elementor/widgets/register
“Class ElementorPlugin topilmadi” Kodingizdan keyin Elementor o'chirilgan yoki yuklangan nazorat defined('ELEMENTOR_VERSION') va ilgari hech qachon Elementorga qo'ng'iroq qilmang elementor/init
CSS/JS yuklanmadi Noto'g'ri tutqich, noto'g'ri ilmoq yoki kesh/minifikatsiya Saqlash orqali after_register_styles/scripts, orqali bog'liqliklarni e'lon qilish get_*_depends()keshni tozalash
Sinf nomidagi ziddiyat Ikki plagin e'lon qiladi BPCAB_Widget_Badge (yoki noto'g'ri sozlangan avtomatik yuklagich) Agar siz sanoatlashtirayotgan bo'lsangiz, har doim prefikslar va nomlardan foydalaning.
Harakat va filtr o'rtasidagi chalkashlik Siz aksiyaga "qaytishga" harakat qilyapsiz Harakatlar: yon ta'sirlar. Filtrlar: qiymatni qaytarish. Foydalanilgan kancani ko'rib chiqish.
Ishlab chiqarishda to'g'ridan-to'g'ri sinov Sahnalashtirish yo'q, zaxira nusxasi yo'q Sahnalashtirish + zaxira nusxasi + orqaga qaytarish rejasi (agar kerak bo'lsa, FTP orqali plaginni o'chirish)
Doimiy havolalar/shablonlar nomuvofiq Siz renderlanganidan boshqa shablonda sinovdan o'tkazmoqdasiz (Mavzu quruvchisi). Qaysi Elementor shabloni aslida qo'llanilganligini tekshiring va keshni tozalang.

Xavfsizlik, ishlash va texnik xizmat ko'rsatish bo'yicha maslahatlar

xavfsizlik

  • Tizimli qochish HTMLda chiqarilgan barcha narsalar kontekstga muvofiq escape qilinishi kerak (esc_html, esc_attr, esc_url, wp_kses_post). Malumotnoma: WordPress: Ma'lumotlarni tekshirish.
  • "Bepul HTML" variantlari yo'q administrator bo'lmagan rollar uchun. Ko'p muallifli saytlarda bu XSS vektoridir.
  • Vidjet orqali PHP bajarilmaydi (Bu aniq ko'rinadi, lekin men allaqachon bir nechta toshbo'ron qilingan "kod vidjetlarini" ko'rganman).

bajarish

  • Shartli aktivlar orqali get_style_depends() / get_script_depends() : bu eng yaxshi harakat/yutuq nisbati.
  • So'rovlarni takrorlashdan saqlaning yilda render()Agar siz ma'lumotlarni (xabarlar, meta) yuklashingiz kerak bo'lsa, uni keshlang (o'tish davri/ob'ekt keshi) yoki optimallashtirilgan so'rov orqali tayyorlang.
  • Minimal CSS : vidjet = kichik fayl. Agar sizda 20 ta bo'lsa, ularni aqlli ravishda guruhlang (lekin shartlilikni saqlang).

saqlash

  • Versiya Plagindan (Git) foydalaning va relizlaringizni teglang. Elementor API ni o'zgartirganda, nimani joylashtirishni bilib olasiz.
  • "Eski" darsliklardan qoching eskirgan ilmoqlardan foydalanadiganlar. Agar siz 2021-2023 yillardagi parchadan qayta foydalanayotgan bo'lsangiz, uning joriy Elementor va WordPress 6.9.4 bilan mos kelishiga ishonch hosil qiling.
  • Zaxira strategiyasini tayyorlang : agar Elementor o'chirilgan bo'lsa, plaginingiz halokatli bo'lmasdan "hech narsa qilmasligi" kerak.

resurslari

FAQ

Ushbu kod WordPress 6.9.4 bilan ishlaydimi?

Ha: plagin standart WordPress amaliyotlariga amal qiladi (hooks, enqueue) va PHP 8.1+ ga qaratilgan. Asosiy moslik muammosi Elementor versiyasi bo'lib qolmoqda (uni yangilab turing).

Nima uchun snippet plaginidan foydalanmaslik kerak?

Tez sinov uchun bu yaxshi. Qayta ishlatiladigan Elementor vidjeti uchun haqiqiy plagin ishonchliroq: boshqariladigan yuklash, tartibli fayllar, versiyalash va agar u ishlamay qolsa, toza o'chirish.

Mening vidjetim paydo bo'ldi, lekin u to'g'ri kategoriyada emas.

Tekshirib ko'ring get_categories() o'girilmoq; ishni bajarmoq ['bpcab']va kategoriya ro'yxatdan o'tgan elementor/elements/categories_registered.

Bir nechta vidjetlarni qanday qo'shishim mumkin?

Ko'proq fayllarni qo'shing includes/widgets/ va ularni saqlang register_widgets()Bitta faylni saqlang = bitta sinf.

Agar menga JS kerak bo'lmasa, uni yuklashdan qanday qochishim mumkin?

O'chirish get_script_depends() yoki bo'sh massivni qaytaring. Vidjetni iloji boricha JSsiz ishlashini ta'minlang.

Avtomatik yuklagich (Composer) dan foydalanish mumkinmi?

Ha, ayniqsa, agar sizda 10 dan ortiq vidjet bo'lsa. WordPress kontekstida, Composerni oxirgi saytga majburlamaslikka ehtiyot bo'ling. Plagin ichiga PSR-4 avtomatik yuklagichini qo'shish odatiy yondashuvdir.

Nima uchun foydalanish kerak wp_kses_post() Matn uchunmi?

Chunki agar Elementor ruxsat bersa (yoki foydalanuvchi kontentni joylashtirsa), matn maydoni HTMLni o'z ichiga olishi mumkin. wp_kses_post() xom echodan farqli o'laroq, xavfsiz kichik to'plamga imkon beradi.

Dinamik yorliq ko'rsatilmaydi: bu normal holatmi?

Bu sizning Elementor konfiguratsiyangizga bog'liq. Maydonlaringiz uchun "Dynamic" UI mavjudligini tekshiring. Agar saytingiz dinamik teglarni qo'llab-quvvatlamasa, qismni olib tashlang. elementor/dynamic_tags/register va unga bog'liq fayl.

Muharrirni buzmasdan qanday qilib to'g'ri sinovdan o'tkazishim mumkin?

Sahna rejimida sinab ko'ring, jurnalni yoqing va minimal vidjetdan boshlang (render + bitta boshqaruv elementi). Boshqaruv elementlarini birma-bir qo'shing. Elementor xatolari ko'pincha UI tomonida jim bo'ladi, lekin konsol va PHP jurnalida ko'rinadi.

Bu Divi/Avada bolalar mavzusi bilan mos keladimi?

Ha, chunki bu plagin. Biroq, vidjet faqat Elementorda ko'rinadi. Divi/Avada uchun, agar siz quruvchilar o'rtasida ulashilishi mumkin bo'lgan komponentni xohlasangiz, qisqa kod yoki blokdan foydalaning.