elementor-development について
Elementor アドオン開発者向けのリファレンススキルです。プラグイン構成、ウィジェット開発、登録フックに加え、アセット管理やレンダリング、互換性上の注意点を扱います。
主な機能
- 01プラグイン構成とメインクラス
- 02カスタムウィジェットとコントロールの開発
- 03コンポーネントの登録・解除フック
- 04フロントエンド・エディター・プレビューのアセット管理
- 05レンダリング方式とよくある問題
活用シーン
- 01Elementor アドオンの新規作成
- 02ウィジェット、コントロール、動的タグの追加
- 03ウィジェット単位のスクリプトとスタイル読み込み
- 04非推奨フックやレンダリング実装の確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ peixotorms/ odinlayer-skills --skill elementor-developmentインストール後、Claude Code で/elementor-developmentを入力して読み込まれたか確認します。
同梱ファイルresources/data-deprecations-cli.mdresources/widget-rendering.md
詳細
Elementor Addon & Widget Development
アドオンのアーキテクチャ、ウィジェットの作成、マネージャーへの登録、スクリプト/スタイル、データ構造、非推奨化、CLI コマンドをまとめたリファレンスです。
関連項目:
- ウィジェットのレンダリングの詳細 -- コントロールの登録、render()、content_template()、レンダリング属性の詳細
- データ構造、非推奨化、CLI -- JSON 形式、要素の構造、非推奨化のタイムライン、CLI コマンド
1. アドオンの構造
プラグインヘッダー
Elementor のすべてのアドオンには、標準の WordPress ヘッダーに加えて、オプションの Elementor ヘッダーが必要です。
<?php
/**
* Plugin Name: Elementor Test Addon
* Description: Custom Elementor addon.
* Plugin URI: https://elementor.com/
* Version: 1.0.0
* Author: Elementor Developer
* Author URI: https://developers.elementor.com/
* Text Domain: elementor-test-addon
* Requires Plugins: elementor
*
* Elementor tested up to: 3.25.0
* Elementor Pro tested up to: 3.25.0
*/
defined( 'ABSPATH' ) || exit;
function elementor_test_addon() {
require_once __DIR__ . '/includes/plugin.php';
\Elementor_Test_Addon\Plugin::instance();
}
add_action( 'plugins_loaded', 'elementor_test_addon' );
メインクラス(シングルトン+互換性チェック)
namespace Elementor_Test_Addon;
final class Plugin {
const VERSION = '1.0.0';
const MINIMUM_ELEMENTOR_VERSION = '3.20.0';
const MINIMUM_PHP_VERSION = '7.4';
private static $_instance = null;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __construct() {
if ( $this->is_compatible() ) {
add_action( 'elementor/init', [ $this, 'init' ] );
}
}
public function is_compatible(): bool {
if ( ! did_action( 'elementor/loaded' ) ) {
add_action( 'admin_notices', [ $this, 'admin_notice_missing_main_plugin' ] );
return false;
}
if ( ! version_compare( ELEMENTOR_VERSION, self::MINIMUM_ELEMENTOR_VERSION, '>=' ) ) {
add_action( 'admin_notices', [ $this, 'admin_notice_minimum_elementor_version' ] );
return false;
}
if ( version_compare( PHP_VERSION, self::MINIMUM_PHP_VERSION, '<' ) ) {
add_action( 'admin_notices', [ $this, 'admin_notice_minimum_php_version' ] );
return false;
}
return true;
}
public function init(): void {
add_action( 'elementor/widgets/register', [ $this, 'register_widgets' ] );
add_action( 'elementor/controls/register', [ $this, 'register_controls' ] );
}
public function register_widgets( $widgets_manager ): void {
require_once __DIR__ . '/widgets/widget-1.php';
$widgets_manager->register( new \Elementor_Widget_1() );
}
public function register_controls( $controls_manager ): void {
require_once __DIR__ . '/controls/control-1.php';
$controls_manager->register( new \Elementor_Control_1() );
}
}
フォルダー構造
elementor-test-addon/
elementor-test-addon.php # Main file with headers
includes/
plugin.php # Main class (singleton)
widgets/ # Widget classes
controls/ # Custom controls
dynamic-tags/ # Dynamic tag classes
finder/ # Finder category classes
assets/
js/ # Frontend/editor JS
css/ # Frontend/editor CSS
images/
2. ウィジェットの開発
ウィジェットクラスのスケルトン
class Elementor_Test_Widget extends \Elementor\Widget_Base {
// --- Required ---
public function get_name(): string {
return 'test_widget';
}
public function get_title(): string {
return esc_html__( 'Test Widget', 'textdomain' );
}
public function get_icon(): string {
return 'eicon-code';
}
public function get_categories(): array {
return [ 'general' ];
}
// --- Optional ---
public function get_keywords(): array {
return [ 'test', 'example' ];
}
public function get_custom_help_url(): string {
return 'https://example.com/widget-help';
}
public function get_script_depends(): array {
return [ 'widget-custom-script' ];
}
public function get_style_depends(): array {
return [ 'widget-custom-style' ];
}
public function has_widget_inner_wrapper(): bool {
return false; // DOM optimization: single wrapper
}
protected function is_dynamic_content(): bool {
return false; // Enable output caching for static content
}
protected function get_upsale_data(): array {
return [
'condition' => ! \Elementor\Utils::has_pro(),
'image' => esc_url( ELEMENTOR_ASSETS_URL . 'images/go-pro.svg' ),
'image_alt' => esc_attr__( 'Upgrade', 'textdomain' ),
'title' => esc_html__( 'Promotion heading', 'textdomain' ),
'description' => esc_html__( 'Get the premium version.', 'textdomain' ),
'upgrade_url' => esc_url( 'https://example.com/upgrade-to-pro/' ),
'upgrade_text' => esc_html__( 'Upgrade Now', 'textdomain' ),
];
}
protected function register_controls(): void { /* see resources/widget-rendering.md */ }
protected function render(): void { /* see resources/widget-rendering.md */ }
protected function content_template(): void { /* see resources/widget-rendering.md */ }
}
カスタムウィジェットカテゴリーの登録
function add_elementor_widget_categories( $elements_manager ) {
$elements_manager->add_category( 'my-category', [
'title' => esc_html__( 'My Category', 'textdomain' ),
'icon' => 'fa fa-plug',
] );
}
add_action( 'elementor/elements/categories_registered', 'add_elementor_widget_categories' );
セレクタートークン
| トークン | 説明 |
|---|---|
{{WRAPPER}} | ウィジェットのラッパー要素 |
{{VALUE}} | コントロールの値 |
{{UNIT}} | 単位コントロールの値 |
{{URL}} | メディアコントロールの URL |
{{SELECTOR}} | グループコントロールの CSS セレクター |
インライン編集ツールバー
| モード | ツールバー | 用途 |
|---|---|---|
'none' | ツールバーなし | プレーンテキストの見出し |
'basic' | 太字、斜体、下線 | 短い説明 |
'advanced' | フル(リンク、見出し、リスト) | リッチテキストコンテンツ |
3. マネージャーへの登録
登録フックのリファレンス
| コンポーネント | フック | マネージャーの種類 | メソッド |
|---|---|---|---|
| ウィジェット | elementor/widgets/register | \Elementor\Widgets_Manager | register() / unregister() |
| コントロール | elementor/controls/register | \Elementor\Controls_Manager | register() / unregister() |
| ダイナミックタグ | elementor/dynamic_tags/register | \Elementor\Core\DynamicTags\Manager | register() / unregister() |
| Finder | elementor/finder/register | Categories_Manager | register() / unregister() |
| カテゴリー | elementor/elements/categories_registered | Elements_Manager | add_category() |
ウィジェットの登録
function register_new_widgets( $widgets_manager ) {
require_once __DIR__ . '/widgets/widget-1.php';
$widgets_manager->register( new \Elementor_Widget_1() );
}
add_action( 'elementor/widgets/register', 'register_new_widgets' );
ウィジェットの登録解除
function unregister_widgets( $widgets_manager ) {
$widgets_manager->unregister( 'heading' );
$widgets_manager->unregister( 'image' );
}
add_action( 'elementor/widgets/register', 'unregister_widgets' );
コントロールの登録/登録解除
function register_new_controls( $controls_manager ) {
require_once __DIR__ . '/controls/control-1.php';
$controls_manager->register( new \Elementor_Control_1() );
}
add_action( 'elementor/controls/register', 'register_new_controls' );
function unregister_controls( $controls_manager ) {
$controls_manager->unregister( 'control-1' );
}
add_action( 'elementor/controls/register', 'unregister_controls' );
ダイナミックタグの登録/登録解除
function register_dynamic_tags( $dynamic_tags_manager ) {
require_once __DIR__ . '/dynamic-tags/tag-1.php';
$dynamic_tags_manager->register( new \Elementor_Dynamic_Tag_1() );
}
add_action( 'elementor/dynamic_tags/register', 'register_dynamic_tags' );
function unregister_dynamic_tags( $dynamic_tags_manager ) {
$dynamic_tags_manager->unregister( 'dynamic-tag-1' );
}
add_action( 'elementor/dynamic_tags/register', 'unregister_dynamic_tags' );
Finder カテゴリーの登録/登録解除
function register_finder_categories( $finder_manager ) {
require_once __DIR__ . '/finder/finder-1.php';
$finder_manager->register( new \Elementor_Finder_Category_1() );
}
add_action( 'elementor/finder/register', 'register_finder_categories' );
function unregister_finder_categories( $finder_manager ) {
$finder_manager->unregister( 'finder-category-1' );
}
add_action( 'elementor/finder/register', 'unregister_finder_categories' );
4. スクリプトとスタイル
フロントエンドのフック
| フック | 目的 |
|---|---|
elementor/frontend/before_register_scripts | Elementor の前にスクリプトを登録 |
elementor/frontend/after_register_scripts | Elementor の後にスクリプトを登録 |
elementor/frontend/before_enqueue_scripts | Elementor の前にスクリプトをエンキュー |
elementor/frontend/after_enqueue_scripts | Elementor の後にスクリプトをエンキュー |
elementor/frontend/before_register_styles | Elementor の前にスタイルを登録 |
elementor/frontend/after_register_styles | Elementor の後にスタイルを登録 |
elementor/frontend/before_enqueue_styles | Elementor の前にスタイルをエンキュー |
elementor/frontend/after_enqueue_styles | Elementor の後にスタイルをエンキュー |
エディターのフック
| フック | 目的 |
|---|---|
elementor/editor/before_enqueue_scripts | エディタースクリプトをエンキュー(前) |
elementor/editor/after_enqueue_scripts | エディタースクリプトをエンキュー(後) |
elementor/editor/before_enqueue_styles | エディタースタイルをエンキュー(前) |
elementor/editor/after_enqueue_styles | エディタースタイルをエンキュー(後) |
プレビューのフック
| フック | 目的 |
|---|---|
elementor/preview/enqueue_scripts | プレビュースクリプトをエンキュー |
elementor/preview/enqueue_styles | プレビュースタイルをエンキュー |
フロントエンドの登録パターン
function my_plugin_frontend_scripts() {
wp_register_script( 'my-widget-script', plugins_url( 'assets/js/widget.js', __FILE__ ) );
wp_register_style( 'my-widget-style', plugins_url( 'assets/css/widget.css', __FILE__ ) );
}
add_action( 'wp_enqueue_scripts', 'my_plugin_frontend_scripts' );
ウィジェットレベルの依存関係
ウィジェットクラス内で宣言します。Elementor はそのウィジェットが使用された場合にのみ読み込みます。
public function get_script_depends(): array {
return [ 'my-widget-script', 'external-library' ];
}
public function get_style_depends(): array {
return [ 'my-widget-style', 'external-framework' ];
}
コントロールレベルのエンキュー
class My_Control extends \Elementor\Base_Control {
protected function enqueue(): void {
wp_enqueue_script( 'control-script' );
wp_enqueue_style( 'control-style' );
}
}
8. よくある間違い
| 間違い | 修正方法 |
|---|---|
elementor/widgets/widgets_registered フックを使用する | elementor/widgets/register を使用します(古いフックは非推奨です) |
register_widget_type() を呼び出す | ウィジェットマネージャーの register() を使用します |
色やタイポグラフィに scheme を使用する | Global_Colors/Global_Typography 定数とともに global を使用します |
アンダースコア接頭辞付きの _register_controls() を使用する | register_controls() を使用します(アンダースコアなし) |
did_action('elementor/loaded') の確認を省略する | クラスを使用する前に、Elementor が読み込まれていることを必ず確認します |
Requires Plugins: elementor ヘッダーがない | WordPress が Elementor の依存関係を適用できるよう、追加します |
JS テンプレートの HTML 出力に {{ }} を使用する | エスケープせずに HTML を出力するには {{{ }}}(三重)を使用します。{{ }} は出力をエスケープします |
| ウィジェットのスクリプト/スタイルの依存関係を宣言しない | get_script_depends()/get_style_depends() を実装します |
| スクリプトをウィジェットごとではなくグローバルにエンキューする | wp_register_script で登録し、get_script_depends() で宣言します |
エディターの JS で innerHTML = を使用する | Elementor のテンプレート構文または DOM メソッドを使用します |
翻訳可能な文字列に esc_html__() を使用しない | ユーザーに表示される文字列は、必ずローカライズ関数で囲みます |
| `defined('ABSPATH') | |
必要がないのに has_widget_inner_wrapper が true を返す | DOM ノードを減らすため、false を返します(最適化) |
content_template() を実装しない | 実装しないと、変更のたびにエディターのプレビューでサーバーとの往復通信が必要になります |
content_template() 内で add_render_attribute を使用する | JS テンプレートでは view.addRenderAttribute() を使用します |
コメント
Markdown 対応