
Если вы еще не проверили плагин Elementor – вам следует. В свое время я использовал много конструкторов plug-n-play, и этот, безусловно, выбивает остальных из воды. Но вы здесь, чтобы узнать, как создавать собственные виджеты Elementor и угадайте, что? Это подпруга!
В этой статье мы создадим простой пользовательский виджет Elementor, который позволит пользователю редактировать текст, изображения и стили как в настройках виджета, так и во встроенном режиме! Мы назовем этот виджет Elementor Awesomesauce.
Я не могу сказать вам, сколько раз я видел пользовательские реализации, сделанные в теме (что возможно), но не очень хорошо для компонентного подхода. Встраивание в плагин позволяет вам разделять код, чтобы ваши существующие PHP, CSS и JS не попали в код вашей темы. Более того, вы можете условно загрузить свои ресурсы веб-интерфейса только в тех местах, где появится пользовательский виджет, что повысит производительность. Итак, начнем там, создадим плагин Elementor Awesomesauce :
<?php
/**
* Plugin Name: Elementor Awesomesauce
* Description: A simple Elementor Awesomesauce plugin that holds some most excellent custom widgets.
* Plugin URI: https://benmarshall.me/build-custom-elementor-widgets/
* Version: 1.0.0
* Author: Ben Marshall
* Author URI: https://benmarshall.me
* Text Domain: elementor-awesomesauce
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Main Elementor Awesomesauce Class
*
* The init class that runs the Elementor Awesomesauce plugin.
* Intended To make sure that the plugin's minimum requirements are met.
*
* You should only modify the constants to match your plugin's needs.
*
* Any custom code should go inside Plugin Class in the plugin.php file.
* @since 1.0.0
*/
final class Elementor_Awesomesauce {
/**
* Plugin Version
*
* @since 1.0.0
* @var string The plugin version.
*/
const VERSION = '1.0.0';
/**
* Minimum Elementor Version
*
* @since 1.0.0
* @var string Minimum Elementor version required to run the plugin.
*/
const MINIMUM_ELEMENTOR_VERSION = '2.0.0';
/**
* Minimum PHP Version
*
* @since 1.0.0
* @var string Minimum PHP version required to run the plugin.
*/
const MINIMUM_PHP_VERSION = '7.0';
/**
* Constructor
*
* @since 1.0.0
* @access public
*/
public function __construct() {
// Load translation
add_action( 'init', array( $this, 'i18n' ) );
// Init Plugin
add_action( 'plugins_loaded', array( $this, 'init' ) );
}
/**
* Load Textdomain
*
* Load plugin localization files.
* Fired by `init` action hook.
*
* @since 1.2.0
* @access public
*/
public function i18n() {
load_plugin_textdomain( 'elementor-awesomesauce' );
}
/**
* Initialize the plugin
*
* Validates that Elementor is already loaded.
* Checks for basic plugin requirements, if one check fail don't continue,
* if all check have passed include the plugin class.
*
* Fired by `plugins_loaded` action hook.
*
* @since 1.2.0
* @access public
*/
public function init() {
// Check if Elementor installed and activated
if ( ! did_action( 'elementor/loaded' ) ) {
add_action( 'admin_notices', array( $this, 'admin_notice_missing_main_plugin' ) );
return;
}
// Check for required Elementor version
if ( ! version_compare( ELEMENTOR_VERSION, self::MINIMUM_ELEMENTOR_VERSION, '>=' ) ) {
add_action( 'admin_notices', array( $this, 'admin_notice_minimum_elementor_version' ) );
return;
}
// Check for required PHP version
if ( version_compare( PHP_VERSION, self::MINIMUM_PHP_VERSION, '<' ) ) {
add_action( 'admin_notices', array( $this, 'admin_notice_minimum_php_version' ) );
return;
}
// Once we get here, We have passed all validation checks so we can safely include our plugin
require_once( 'plugin.php' );
}
/**
* Admin notice
*
* Warning when the site doesn't have Elementor installed or activated.
*
* @since 1.0.0
* @access public
*/
public function admin_notice_missing_main_plugin() {
if ( isset( $_GET['activate'] ) ) {
unset( $_GET['activate'] );
}
$message = sprintf(
/* translators: 1: Plugin name 2: Elementor */
esc_html__( '"%1$s" requires "%2$s" to be installed and activated.', 'elementor-awesomesauce' ),
'<strong>'. esc_html__( 'Elementor Awesomesauce', 'elementor-awesomesauce' ). '</strong>',
'<strong>'. esc_html__( 'Elementor', 'elementor-awesomesauce' ). '</strong>'
);
printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );
}
/**
* Admin notice
*
* Warning when the site doesn't have a minimum required Elementor version.
*
* @since 1.0.0
* @access public
*/
public function admin_notice_minimum_elementor_version() {
if ( isset( $_GET['activate'] ) ) {
unset( $_GET['activate'] );
}
$message = sprintf(
/* translators: 1: Plugin name 2: Elementor 3: Required Elementor version */
esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'elementor-awesomesauce' ),
'<strong>'. esc_html__( 'Elementor Awesomesauce', 'elementor-awesomesauce' ). '</strong>',
'<strong>'. esc_html__( 'Elementor', 'elementor-awesomesauce' ). '</strong>',
self::MINIMUM_ELEMENTOR_VERSION
);
printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );
}
/**
* Admin notice
*
* Warning when the site doesn't have a minimum required PHP version.
*
* @since 1.0.0
* @access public
*/
public function admin_notice_minimum_php_version() {
if ( isset( $_GET['activate'] ) ) {
unset( $_GET['activate'] );
}
$message = sprintf(
/* translators: 1: Plugin name 2: PHP 3: Required PHP version */
esc_html__( '"%1$s" requires "%2$s" version %3$s or greater.', 'elementor-awesomesauce' ),
'<strong>'. esc_html__( 'Elementor Awesomesauce', 'elementor-awesomesauce' ). '</strong>',
'<strong>'. esc_html__( 'PHP', 'elementor-awesomesauce' ). '</strong>',
self::MINIMUM_PHP_VERSION
);
printf( '<div class="notice notice-warning is-dismissible"><p>%1$s</p></div>', $message );
}
}
// Instantiate Elementor_Awesomesauce.
new Elementor_Awesomesauce();
plugin.php
<?php
namespace ElementorAwesomesauce;
/**
* Class Plugin
*
* Main Plugin class
* @since 1.0.0
*/
class Plugin {
/**
* Instance
*
* @since 1.0.0
* @access private
* @static
*
* @var Plugin The single instance of the class.
*/
private static $_instance = null;
/**
* Instance
*
* Ensures only one instance of the class is loaded or can be loaded.
*
* @since 1.2.0
* @access public
*
* @return Plugin An instance of the class.
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* widget_scripts
*
* Load required plugin core files.
*
* @since 1.2.0
* @access public
*/
public function widget_scripts() {
wp_register_script( 'elementor-awesomesauce', plugins_url( '/assets/js/awesomesauce.js', __FILE__ ), [ 'jquery' ], false, true );
}
/**
* Include Widgets files
*
* Load widgets files
*
* @since 1.2.0
* @access private
*/
private function include_widgets_files() {
require_once( __DIR__. '/widgets/awesomesauce.php' );
}
/**
* Register Widgets
*
* Register new Elementor widgets.
*
* @since 1.2.0
* @access public
*/
public function register_widgets() {
// Its is now safe to include Widgets files
$this->include_widgets_files();
// Register Widgets
ElementorPlugin::instance()->widgets_manager->register_widget_type( new WidgetsAwesomesauce() );
}
/**
* Plugin class constructor
*
* Register plugin action hooks and filters
*
* @since 1.2.0
* @access public
*/
public function __construct() {
// Register widget scripts
add_action( 'elementor/frontend/after_register_scripts', [ $this, 'widget_scripts' ] );
// Register widgets
add_action( 'elementor/widgets/widgets_registered', [ $this, 'register_widgets' ] );
}
}
// Instantiate Plugin Class
Plugin::instance();
widgets/awesomesauce.php
<?php
namespace ElementorAwesomesauceWidgets;
use ElementorWidget_Base;
use ElementorControls_Manager;
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* @since 1.1.0
*/
class Awesomesauce extends Widget_Base {
/**
* Retrieve the widget name.
*
* @since 1.1.0
*
* @access public
*
* @return string Widget name.
*/
public function get_name() {
return 'awesomesauce';
}
/**
* Retrieve the widget title.
*
* @since 1.1.0
*
* @access public
*
* @return string Widget title.
*/
public function get_title() {
return __( 'Awesomesauce', 'elementor-awesomesauce' );
}
/**
* Retrieve the widget icon.
*
* @since 1.1.0
*
* @access public
*
* @return string Widget icon.
*/
public function get_icon() {
return 'fa fa-pencil';
}
/**
* Retrieve the list of categories the widget belongs to.
*
* Used to determine where to display the widget in the editor.
*
* Note that currently Elementor supports only one category.
* When multiple categories passed, Elementor uses the first one.
*
* @since 1.1.0
*
* @access public
*
* @return array Widget categories.
*/
public function get_categories() {
return [ 'general' ];
}
/**
* Register the widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* @since 1.1.0
*
* @access protected
*/
protected function _register_controls() {
$this->start_controls_section(
'section_content',
[
'label' => __( 'Content', 'elementor-awesomesauce' ),
]
);
$this->add_control(
'title',
[
'label' => __( 'Title', 'elementor-awesomesauce' ),
'type' => Controls_Manager::TEXT,
'default' => __( 'Title', 'elementor-awesomesauce' ),
]
);
$this->add_control(
'description',
[
'label' => __( 'Description', 'elementor-awesomesauce' ),
'type' => Controls_Manager::TEXTAREA,
'default' => __( 'Description', 'elementor-awesomesauce' ),
]
);
$this->add_control(
'content',
[
'label' => __( 'Content', 'elementor-awesomesauce' ),
'type' => Controls_Manager::WYSIWYG,
'default' => __( 'Content', 'elementor-awesomesauce' ),
]
);
$this->end_controls_section();
}
/**
* Render the widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* @since 1.1.0
*
* @access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
$this->add_inline_editing_attributes( 'title', 'none' );
$this->add_inline_editing_attributes( 'description', 'basic' );
$this->add_inline_editing_attributes( 'content', 'advanced' );
?>
<h2 <?php echo $this->get_render_attribute_string( 'title' ); ?>><?php echo $settings['title']; ?></h2>
<div <?php echo $this->get_render_attribute_string( 'description' ); ?>><?php echo $settings['description']; ?></div>
<div <?php echo $this->get_render_attribute_string( 'content' ); ?>><?php echo $settings['content']; ?></div>
<?php
}
/**
* Render the widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 1.1.0
*
* @access protected
*/
protected function _content_template() {
?>
<#
view.addInlineEditingAttributes( 'title', 'none' );
view.addInlineEditingAttributes( 'description', 'basic' );
view.addInlineEditingAttributes( 'content', 'advanced' );
#>
<h2 {{{ view.getRenderAttributeString( 'title' ) }}}>{{{ settings.title }}}</h2>
<div {{{ view.getRenderAttributeString( 'description' ) }}}>{{{ settings.description }}}</div>
<div {{{ view.getRenderAttributeString( 'content' ) }}}>{{{ settings.content }}}</div>
<?php
}
}
assets/js/awesomesauce.js
( function( $ ) {
/**
* @param $scope The Widget wrapper element as a jQuery element
* @param $ The jQuery alias
*/
var WidgetAwesomesauceHandler = function( $scope, $ ) {
console.log( $scope );
};
// Make sure you run this code under Elementor.
$( window ).on( 'elementor/frontend/init', function() {
elementorFrontend.hooks.addAction( 'frontend/element_ready/awesomesauce.default', WidgetAwesomesauceHandler );
} );
} )( jQuery );
Шаг 2. Добавьте свои настраиваемые поля.
Elementor – очень мощный инструмент, позволяющий легко добавлять пользовательские вкладки, поля, настройки стиля и даже отзывчивость. В приведенном выше коде _register_controls
мы уже добавили несколько полей для заголовка, описания и содержимого, но что, если вам нужно больше? Посмотрите примеры ниже, чтобы добавить еще больше удивительности в ваш плагин Awesomesauce.
Добавить / изменить вкладку «Элементор»
Вы можете добавить / изменить вкладку содержимого и параметры, отображаемые в них, на боковой панели редактора Elementor, указав следующее:
widgets / awesomesauce.php – В _register_controls
методе.
$this->start_controls_section(
'section_content',
[
'label' => __( 'Content', 'elementor-awesomesauce' ),
]
);
/* Add the options you'd like to show in this tab here */
$this->end_controls_section();
Добавить / изменить вкладку стиля элемента
Вы можете добавить / изменить вкладку стиля и параметры, отображаемые в них, на боковой панели редактора Elementor с помощью следующего:
widgets / awesomesauce.php – В _register_controls
методе.
$this->start_controls_section(
'style_section',
[
'label' => __( 'Style Section', 'elementor-awesomesauce' ),
'tab' => ElementorControls_Manager::TAB_STYLE,
]
);
/* Add the options you'd like to show in this tab here */
$this->end_controls_section();
Elementor Widget Image Field
Возможность добавлять / изменять изображения имеет решающее значение для любой хорошей темы WordPress, вот как добавить пользовательское поле изображения в виджет Elementor с помощью Controls_Manager::MEDIA
:
widgets / awesomesauce.php – В _register_controls
методе.
$this->add_control(
'mask_image',
[
'label' => __( 'Mask Image', 'elementor-awesomesauce' ),
'type' => Controls_Manager::MEDIA,
'default' => [
'url' => Utils::get_placeholder_image_src(),
]
]
);
Elementor Widget Select Выпадающий
Что, если мы хотим позволить пользователю выбрать HTML-элемент для заголовка, это также удобно Controls_Manager::SELECT
:
widgets / awesomesauce.php – В верхней части файла, где use
находятся операторы.
se ElementorUtils;
widgets / awesomesauce.php – В _register_controls
методе.
$this->add_control(
'mask_image',
[
'label' => __( 'Mask Image', 'elementor-awesomesauce' ),
'type' => Controls_Manager::MEDIA,
'default' => [
'url' => Utils::get_placeholder_image_src(),
]
]
);
Elementor Widget Button Group
Как насчет добавления параметров выравнивания, используя группу кнопок, легко с Controls_Manager::CHOOSE
:
widgets / awesomesauce.php – В _register_controls
методе.
$this->add_control(
'text_align',
[
'label' => __( 'Alignment', 'elementor-awesomesauce' ),
'type' => ElementorControls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => __( 'Left', 'elementor-awesomesauce' ),
'icon' => 'fa fa-align-left',
],
'center' => [
'title' => __( 'Center', 'elementor-awesomesauce' ),
'icon' => 'fa fa-align-center',
],
'right' => [
'title' => __( 'Right', 'elementor-awesomesauce' ),
'icon' => 'fa fa-align-right',
],
],
'default' => 'center',
'toggle' => true,
]
);
Типографские параметры виджета Elementor
Elementor поставляется с мощным редактором типографики, который включает отзывчивые опции, вот как вы можете добавить его с помощью Group_Control_Typography
& Scheme_Typography::TYPOGRAPHY_1
.
widgets / awesomesauce.php – В верхней части файла, где use
находятся операторы.
use ElementorGroup_Control_Typography;
use ElementorScheme_Typography;
widgets / awesomesauce.php – В _register_controls
методе.
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'content_typography',
'label' => __( 'Typography', 'elementor-awesomesauce' ),
'scheme' => Scheme_Typography::TYPOGRAPHY_1,
'selector' => '{{WRAPPER}} .elementor-awesomesauce',
'fields_options' => [
'letter_spacing' => [
'range' => [
'min' => 0,
'max' => 100
]
]
]
]
);
Источник записи: https://benmarshall.me