Skip to content

Supports Widgets Bundle

Alex Prokopenko edited this page Aug 27, 2018 · 3 revisions

SiteOrigin Widgets Bundle is a plugin with highly customizable widgets of any kinds. Usually they are used with a Page Builder plugin. If you didn't read about how we support a Page Builder plugin - we recommend to read Page Builder Support page first.

Of course you can try to use new widgets from this plugin to build your unique pages, however again we deal with a problem, that they have too many options and strict HTML, which you can't modify. Usually custom site designs are not based on some widgets. They are just creative idea of a designer.

What is really cool inside this plugin - it contains a form builder for widgets. So you can use it to create you own widget with a specific options focused on your design. So how we use them:

  • Enable plugin
  • Disable all widgets except Editor inside Plugins -> SiteOrigin Widgets page
  • Write own widgets using form builder

You can create widgets with help of the official SiteOrigin documentation.

However, we bring few more things in this process too.

Widget base class

This plugin has a base class for a page builder widget to help you implement it. It has:

  • Auto-add your widget to "Recommended" widgets list
  • Notify you what methods have to be overwritten to create a widget
  • Add new method to pre-process input data before saving it
  • Load widget preview image/slider

Let's take a look how to create a widget.

Creating a widget

To create a widget you need to create a child class of widget base class and overwrite methods for form fields declaration, instance modification before print and widget print method itself

<?php

namespace Boilerplate\Theme\Widgets;

use JustCoded\WP\Framework\Page_Builder\v25\Page_Builder_Widget;
use JustCoded\WP\Framework\Web\View;

/**
 * Class Hero_Slider_Widget
 * Custom image WordPress widget based on siteorigin widgets bundle
 */
class Hero_Slider_Widget extends Page_Builder_Widget {
	/**
	 * Hero_Slider_Widget constructor.
	 */
	public function __construct() {
		parent::__construct(
			'hero-slider', __( 'Hero Slider' ),
			array(
				'description' => __( 'Hero Slider' ),
				'has_preview' => true,
			),
			array(), false, ''
		);
	}

	/**
	 * Form fields configuration
	 *
	 * @return array
	 */
	public function get_widget_form() {
		return array(
			'images'      => array(
				'type'       => 'repeater',
				'label'      => __( 'Images', 'boilerplate' ),
				'item_name'  => __( 'Image', 'boilerplate' ),
				'item_label' => array(
					'selector'     => "[name*='title']",
					'update_event' => 'change',
					'value_method' => 'val',
				),
				'fields'     => array(
					'image'       => array(
						'type'  => 'media',
						'label' => __( 'Image', 'boilerplate' ),
					),
					'title'       => array(
						'type'  => 'text',
						'label' => __( 'Image title', 'boilerplate' ),
					),
					'description' => array(
						'type'  => 'text',
						'label' => __( 'Description', 'boilerplate' ),
					),
					'button_text' => array(
						'type'  => 'text',
						'label' => __( 'Button text', 'boilerplate' ),
					),
					'button_link' => array(
						'type'  => 'link',
						'label' => __( 'Button link', 'boilerplate' ),
					),
				),
			),
		);
	}

	/**
	 * Modify form submitted values before save.
	 *
	 * @param array $instance submitted form values.
	 *
	 * @return array
	 */
	public function modify_instance( $instance ) {
		return $instance;
	}

	/**
	 * Print widget method.
	 *
	 * @param array $args Widget display arguments.
	 * @param array $instance Widget settings.
	 */
	public function widget( $args, $instance ) {
		$instance = $this->get_template_variables( $instance, $args );
		if ( ! empty( $instance['images'] ) ) {
			View::instance()->include( 'widgets/hero-slider', array(
				'instance'      => $instance,
				'before_widget' => $args['before_widget'],
				'after_widget'  => $args['after_widget'],
			) );
		}
	}
}

As you can see all is pretty easy.

Data pre-processing

To pre-process data before saving it to database (for example format a phone number in a specific format) you need to overwrite before_update method.

class Hero_Slider_Widget extends Page_Builder_Widget {

    // ...
    
    /**
     * Method called before saving instance to database.
     *
     * @param array               $new_instance Array of widget field values.
     * @param array               $form_options Array of form field options.
     * @param Page_Builder_Widget $widget Widget class instance.
     *
     * @return array
     */
    public function before_update( $new_instance, $form_options, $widget ) {
        return $new_instance;
    }    

Widget preview

By default SiteOrigin Widgets Bundle supports loading widget real preview. So actually it can generate a real HTML like it does on a frontend. However adding previews to each widget can take really huge amount, because you need to write CSS inside the admin panel, which can conflict with other CSS. And furthermore, you need to support different device resolutions (because WordPress has a responsive admin interface).

To simplify preview generation we decide to load an image gallery with design assets (or real site screnshots). So user can see how this widget can look like and you don't need much time to provide this preview for him.

By default our Page_Builder_Widget class will look for an image in assets/widgets/{id}.png to show a preview. You can provide a list of custom images for a gallery if you overwrite a get_preview_images() method.

Inside this method you should specify an array of image file names and image captions:

class Hero_Slider_Widget extends Page_Builder_Widget {

    // ...
    
    /**
     * Preview images theme folder
     *
     * @var string
     */
    public $preview_folder = 'assets/widgets';

    /**
     * Return a list of images to be shown as preview.
     * By default it's widget {id_base}.png with $this->name
     *
     * @return array
     */
    public function get_preview_images() {
        return array(
            'hero-slider1.png' => 'Desktop view',
            'hero-slider2.png' => 'Mobile view',
        );
    }

New field types

Also we created few more new field types to allow you to select posts or terms. Default Widgets Bundle page builder has autocomplete field, which allows you to do the same. However, when you select something you see only ID, which is not user friendly at all.

We created new fields, which use Select2 multiple dropdown to provide a good looking interface to select posts or terms.

Posts selector

To create a posts selector field you need to specify select-posts as a type. Also you can specify specific post types you want to appear in your search results:

	/**
	 * Form fields configuration
	 *
	 * @return array
	 */
	public function get_widget_form() {
		return array(
			'featured_services' => array(
				'type'       => 'select-posts',
				'label'      => __( 'Featured Services', 'textdomain' ),
				'post_types' => 'service,case_study',
			),
		);
	}

By default it search across all post types.

Terms selector

To create a terms selector field you need to specify select-terms as a type. Also you can specify specific taxonomies you want to appear in your search results:

	/**
	 * Form fields configuration
	 *
	 * @return array
	 */
	public function get_widget_form() {
		return array(
			'featured_categories' => array(
				'type'       => 'select-terms',
				'label'      => __( 'Featured Categories', 'textdomain' ),
				'post_types' => 'category',
			),
		);
	}

By default it search across all taxonomies.