Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
236 views
in Technique[技术] by (71.8m points)

php - Elementor development - generate widget from another widget

What I'm trying to accomplish

I'm trying to create some custom widgets for Elementor within there WordPress theme. Ive made a custom thumbnail and currently working on creating a thumbnail group:

enter image description here

The thumbnail works (don't mind the [object Object], it should display an font awesome icon): enter image description here

My problem is as follows. My thumbnail group widget has a button to add a new thumbnail to itself:

enter image description here

The problem

I cant seem to get this button to work properly and since i have limited PHP experience i don't know if its even possible. See the thumbnail class is a PHP class (back-end language) and I'm trying to create a new instance in the front end. I have no clue on how to tackle this issue.

The other reason id like to solve this issue is because it will make life a LOT easier in the future if i want to create dynamic widgets.

Looking for suggestions

Id like some suggestions on how to solve this, I'm thinking about:

  • re implementing the "add new thumbnail" button in JavaScript (would like some help on where to start from there if that's the way to go)
  • make a static thumbnail group that only has 4 thumbnails (this is a last resort)
  • just paste 4 thumbnails next to each other manually (I'm not gonna settle for this)

The code I use to make the widgets work can be found bellow (feel free to use it if you like it). Thanks in advance!

To reproduce

Bellow is the folder structure that is required to reproduce my situation 1 on 1:

enter image description here

Register custom widgets

This is the "custom-elementor.php" file which loops trough the custom widgets folder and registers every widget within that folder:

<?php
namespace NameSpaceExample;

// Global directory variables
$elementorDir = dirname( __FILE__ ) . 'elementor\';
$widgetsDir = $elementorDir . 'custom-widgets\';
str_replace("\", "/", $elementorDir);
str_replace("\", "/", $widgetsDir);

// use ElementorPlugin; ?????
class Widget_Loader {
  // Make class static
  private static $_instance = null;
  public static function instance()
  {
    if (is_null(self::$_instance)) {
      self::$_instance = new self();
    }
    return self::$_instance;
  }

  public function include_and_register_widgets(){
    $dir = $GLOBALS['widgetsDir'];
    foreach (glob($dir . '*.php') as $file)
    {
      require_once($file);
      $class = 'NameSpaceExampleWidgets\' . basename($file, '.php');
      if (class_exists($class))
      {
        $obj = new $class;
        $obj->register_self();
      }
    }
  }

  public function __construct(){
    add_action('elementor/widgets/widgets_registered', [$this, 'include_and_register_widgets'], 99);
  }
}

// Instantiate Plugin Class
Widget_Loader::instance();

Custom thumbnail

This PHP code represents the custom thumbnail widget:

<?php

namespace NameSpaceExampleWidgets;

use ElementorWidget_Base;
use ElementorControls_Manager;

if (!defined('ABSPATH')) exit; // Exit if accessed directly


class Thumbnail extends Widget_Base{

  public function get_name(){
    return 'thumbnail';
  }

  public function get_title(){
    return 'Thumbnail';
  }

  public function get_icon(){
    return 'fa fa-icons';
  }

  public function get_categories(){
    return ['general'];
  }

  public function register_self() {
    ElementorPlugin::instance()->widgets_manager->register_widget_type(new self());
  }

  protected function _register_controls(){

    $this->start_controls_section(
      'section_content',
      [
        'label' => 'Settings',
      ]
    );

    $this->add_control(
      'thumbnail_icon',
      [
        'label' => 'Thumbnail Icon',
        'type' => ElementorControls_Manager::ICONS,
        'default' => [
                    'value' => 'fa fa-pencil-ruler',
                    'library' => 'solid',
                ],
      ]
    );

    $this->add_control(
      'thumbnail_heading',
      [
        'label' => 'Thumbnail Heading',
        'type' => ElementorControls_Manager::TEXT,
        'default' => 'Example Heading'
      ]
    );

    $this->add_control(
      'thumbnail_content',
      [
        'label' => 'Thumbnail Content',
        'type' => ElementorControls_Manager::WYSIWYG,
        'default' => 'Some example content. Start Editing Here.'
      ]
    );

    $this->end_controls_section();
  }

  protected function render(){
    $settings = $this->get_settings_for_display();

    $this->add_inline_editing_attributes('thumbnail_heading', 'basic');
    $this->add_inline_editing_attributes('thumbnail_content', 'basic');

    ?>
    <article class="col-xs-12 col-sm-6 col-md-3 thumbnail-style thumbnail-icon-item text-center">
      <div class="thumbnail">
        <div class="thumbnail-icon">
          <?php ElementorIcons_Manager::render_icon( $settings['thumbnail_icon'], [ 'aria-hidden' => 'true' ] ); ?>
        </div>
        <div class="caption">
          <div class="thumbnail-heading" <?php echo $this->get_render_attribute_string('thumbnail_heading'); ?>>
            <h4>
              <?php echo $settings['thumbnail_heading']?>
            </h4>
          </div>
          <div class="thumbnail-content" <?php echo $this->get_render_attribute_string('thumbnail_content'); ?>>
            <?php echo $settings['thumbnail_content'] ?>
          </div>
        </div>
      </div>
        </article>
    <?php
  }

  protected function _content_template(){
    ?>
    <#
      view.addInlineEditingAttributes( 'thumbnail_heading', 'basic' );
      view.addInlineEditingAttributes( 'thumbnail_content', 'basic' );
    #>
    <article class="col-xs-12 col-sm-6 col-md-3 thumbnail-style thumbnail-icon-item text-center">
      <div class="thumbnail">
        <div class="thumbnail-icon">
          <div>
            {{{ settings.thumbnail_icon }}}
          </div>
        </div>
        <div class="caption">
          <div class="thumbnail-heading">
            <h4 {{{ view.getRenderAttributeString( 'thumbnail_heading' ) }}}>
              {{{ settings.thumbnail_heading }}}
            </h4>
          </div>
          <div class="thumbnail-content">
            <p {{{ view.getRenderAttributeString( 'thumbnail_content' ) }}}>
              {{{ settings.thumbnail_content }}}
            </p>
          </div>
        </div>
      </div>
    </article>
    <?php
  }
}

Custom thumbnail group

This is the ThumbnailGroup widget code:

<?php

namespace NameSpaceExampleWidgets;

use ElementorWidget_Base;
use ElementorControls_Manager;

if (!defined('ABSPATH')) exit; // Exit if accessed directly


class ThumbnailGroup extends Widget_Base{

  public function get_name(){
    return 'thumbnail_group';
  }

  public function get_title(){
    return 'Thumbnail Group';
  }

  public function get_icon(){
    return 'fa fa-layer-group';
  }

  public function get_categories(){
    return ['general'];
  }

  public function register_self() {
    ElementorPlugin::instance()->widgets_manager->register_widget_type(new self());
  }

  protected function _register_controls(){

    $this->start_controls_section(
      'section_content',
      [
        'label' => 'Settings',
      ]
    );

    $this->add_control(
      'new_thumbnail_group_button',
      [
        'label' => 'New Thumbnail',
        'type' => ElementorControls_Manager::BUTTON,
        'text' => 'Add Thumbnail',
        'event' => 'addNewThumbnail',
      ]
    );

    $this->end_controls_section();
  }

  protected function render(){
    $settings = $this->get_settings_for_display();

    ?>

    <div class="thumbnail-group">
      <div class="padding-top-50 padding-bottom-50">
        <div class="container">
          <div class="row">
            <?php $this->addNewThumbnail() ?>
          </div>
        </div>
      </div>
    </div>
    <?php
  }

  protected function _content_template(){
    ?>
    <#

    #>

    <div class="thumbnail-group">
      <div class="padding-top-50 padding-bottom-50">
        <div class="container">
          <div class="row">
            <?php $this->addNewThumbnail() ?>
          </div>
        </div>
      </div>
    </div>
    <?php
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...