Gutenberg dynamic SelectControl values object - wordpress

I want to dynamically pass the options object to Gutenberg SelectControl:
el( SelectControl, {
label: __( 'Animation' ),
value: props.attributes.animation,
onChange: ( value ) => { props.setAttributes( { animation: value } ); },
options: [
{ value: 'date', label: __( 'One column' ) },
{ value: 'title', label: __( 'Two columns' ) },
],
}
),
I have a PHP function that returns an object of available animations?
function animation( ) {
$animations = array(
'' => 'none',
'fade' => 'fade',
'fade-up' => 'fade-up',
'fade-down' => 'fade-down',
'zoom-out-up' => 'zoom-out-up',
'zoom-out-down' => 'zoom-out-down',
'zoom-out-left' => 'zoom-out-left',
'zoom-out-right' => 'zoom-out-right'
);
return apply_filters( '_animations', $animations );
}

I have used wp_localize_script to get the array as object in JS:
$variables['animations'] = _functions::_animation();
wp_localize_script( $this->plugin_name, 'meetongo', $variables );
and you can access that object like this:
console.log( meetongo.animations );

Related

Overriding a function in a class from the Wordpress plugin Elementor Pro about Product Upsells

I would like to find a way to override the following file in the plugin Elementor Pro for wordpress to add an "else" in "protected function render()". I want to be able to display a message when there is no upsell available in my carrousel from element pro.
<?php
namespace ElementorPro\Modules\Woocommerce\Widgets;
use Elementor\Controls_Manager;
use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
use Elementor\Group_Control_Typography;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Product_Upsell extends Products_Base {
public function get_name() {
return 'woocommerce-product-upsell';
}
public function get_title() {
return esc_html__( 'Upsells', 'elementor-pro' );
}
public function get_icon() {
return 'eicon-product-upsell';
}
public function get_keywords() {
return [ 'woocommerce', 'shop', 'store', 'upsell', 'product' ];
}
protected function register_controls() {
$this->start_controls_section(
'section_upsell_content',
[
'label' => esc_html__( 'Upsells', 'elementor-pro' ),
]
);
$this->add_columns_responsive_control();
$this->add_control(
'orderby',
[
'label' => esc_html__( 'Order By', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'default' => 'date',
'options' => [
'date' => esc_html__( 'Date', 'elementor-pro' ),
'title' => esc_html__( 'Title', 'elementor-pro' ),
'price' => esc_html__( 'Price', 'elementor-pro' ),
'popularity' => esc_html__( 'Popularity', 'elementor-pro' ),
'rating' => esc_html__( 'Rating', 'elementor-pro' ),
'rand' => esc_html__( 'Random', 'elementor-pro' ),
'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ),
],
]
);
$this->add_control(
'order',
[
'label' => esc_html__( 'Order', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'default' => 'desc',
'options' => [
'asc' => esc_html__( 'ASC', 'elementor-pro' ),
'desc' => esc_html__( 'DESC', 'elementor-pro' ),
],
]
);
$this->end_controls_section();
parent::register_controls();
$this->start_injection( [
'at' => 'before',
'of' => 'section_design_box',
] );
$this->start_controls_section(
'section_heading_style',
[
'label' => esc_html__( 'Heading', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'show_heading',
[
'label' => esc_html__( 'Heading', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => esc_html__( 'Hide', 'elementor-pro' ),
'label_on' => esc_html__( 'Show', 'elementor-pro' ),
'default' => 'yes',
'return_value' => 'yes',
'prefix_class' => 'show-heading-',
]
);
$this->add_control(
'heading_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
'selectors' => [
'{{WRAPPER}}.elementor-wc-products .products > h2' => 'color: {{VALUE}}',
],
'condition' => [
'show_heading!' => '',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'heading_typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
'selector' => '{{WRAPPER}}.elementor-wc-products .products > h2',
'condition' => [
'show_heading!' => '',
],
]
);
$this->add_responsive_control(
'heading_text_align',
[
'label' => esc_html__( 'Text Align', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => esc_html__( 'Left', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => esc_html__( 'Right', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}.elementor-wc-products .products > h2' => 'text-align: {{VALUE}}',
],
'condition' => [
'show_heading!' => '',
],
]
);
$this->add_responsive_control(
'heading_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em' ],
'selectors' => [
'{{WRAPPER}}.elementor-wc-products .products > h2' => 'margin-bottom: {{SIZE}}{{UNIT}}',
],
'condition' => [
'show_heading!' => '',
],
]
);
$this->end_controls_section();
$this->end_injection();
}
protected function render() {
$settings = $this->get_settings_for_display();
// Add a wrapper class to the Add to Cart & View Items elements if the automically_align_buttons switch has been selected.
if ( 'yes' === $settings['automatically_align_buttons'] ) {
add_filter( 'woocommerce_loop_add_to_cart_link', [ $this, 'add_to_cart_wrapper' ], 10, 1 );
}
$limit = '-1';
$columns = 4;
$orderby = 'rand';
$order = 'desc';
if ( ! empty( $settings['columns'] ) ) {
$columns = $settings['columns'];
}
if ( ! empty( $settings['orderby'] ) ) {
$orderby = $settings['orderby'];
}
if ( ! empty( $settings['order'] ) ) {
$order = $settings['order'];
}
ob_start();
woocommerce_upsell_display(
sanitize_text_field( $limit ),
sanitize_text_field( $columns ),
sanitize_text_field( $orderby ),
sanitize_text_field( $order )
);
$upsells_html = ob_get_clean();
if ( $upsells_html ) {
$upsells_html = str_replace( '<ul class="products', '<ul class="products elementor-grid', $upsells_html );
// PHPCS - Doesn't need to be escaped since it's a WooCommerce template, and 3rd party plugins might hook into it.
echo $upsells_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
///////// The code I want to add ///////
else {
echo "no product available";
}
///////// The code I want to add ///////
if ( 'yes' === $settings['automatically_align_buttons'] ) {
remove_filter( 'woocommerce_loop_add_to_cart_link', [ $this, 'add_to_cart_wrapper' ] );
}
}
public function render_plain_content() {}
public function get_group_name() {
return 'woocommerce';
}
}
I tried many things but with no success. For example, put the same file in child theme with same path or calling it with the namespace. I can't use the filters and I have no idea how to do it properly. Right now it is working but if I update the plugin I loose the modification.

Custom elementor forms extension - Not redirecting after submit

This is an extension for elementor pro forms that sends the form data to an API.
This first API will return a success or failure message.
If successful, the response will also contain an ID number.
That ID number should then be used in a second API request where the number is appended to the URL. This second API will return a login URL.
The plugin should then redirect the user to the returned URL.
Currently I am receiving a response from the first API. the response I've received is as follows:
{"code":201,"data":{"id":133714},"message":"Success"}
The second API Response I get is the following:
{"code": 200,"request_method":"GET","autologin":"https://www.exampleurl.com/login" }
But it is not redirecting the user. Can you help me discover why?
`
<?php
/*
Plugin Name: Elementor Custom form
Plugin URI:
Description:
Version:
Author:
Author URI:
License:
License URI:
*/
/*
This plugin adds a custom form action to Elementor Pro forms.
The new action sends an API Request to a custom endpoint.
After receiving a valid response, the form will send another API Request to a different endpoint.
The response from the second API Request is used to redirect the user to a different page.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Bpd_Custom_Form_Action extends \ElementorPro\Modules\Forms\Classes\Action_Base {
public function get_name() {
return 'custom_form_action';
}
public function get_label() {
return __( 'Custom Form Action', 'elementor-pro' );
}
public function register_settings_section( $widget ) {
$widget->start_controls_section(
'section_custom_form_action',
[
'label' => $this->get_label(),
'condition' => [
'submit_actions' => $this->get_name(),
],
]
);
//////////////////////////////////////////////
//
// FIRST API - SETTINGS & AUTHORIZATION
//
//////////////////////////////////////////////
$widget->add_control(
'custom_form_action_api_url',
[
'label' => __( 'URL', 'elementor-pro' ),
'type' => \Elementor\Controls_Manager::TEXT,
'placeholder' => 'https://example.com/api/',
'description' => __( 'Enter the URL of the API endpoint you want to send the form data to.', 'elementor-pro' ),
'label_block' => true,
'separator' => 'before',
]
);
$widget->add_control(
'custom_form_action_application_token',
[
'label' => __( 'Application Token', 'elementor-pro' ),
'type' => \Elementor\Controls_Manager::TEXT,
'placeholder' => 'https://example.com/api/',
'label_block' => true,
'description' => __( 'Enter the application token for your API request.', 'elementor-pro' ),
'separator' => 'before',
]
);
//////////////////////////////////////////////
//
// FIRST API - Body & Response Options
//
//////////////////////////////////////////////
$widget->add_control(
'custom_form_action_api_body',
[
'label' => __( 'Body', 'elementor-pro' ),
'type' => \Elementor\Controls_Manager::TEXTAREA,
'placeholder' => '{ "name": "{{{ name }}}", "email": "{{{ email }}}" "ip": "{{{ USERIP }}}" }',
'description' => __( 'Enter the body of the API request. You can use the form fields as placeholders. For example: { "name": "{{{ name }}}", "email": "{{{ email }}}" }', 'elementor-pro' ),
'label_block' => true,
'separator' => 'before',
]
);
//////////////////////////////////////////////
//
// Second API - SETTINGS & AUTHORIZATION
//
//////////////////////////////////////////////
$widget->add_control(
'custom_form_action_second_api_url',
[
'label' => __( 'Second API URL', 'elementor-pro' ),
'type' => \Elementor\Controls_Manager::TEXT,
'placeholder' => 'https://example.com/thank-you/',
'description' => __( 'Enter the URL of the page you want to redirect the user to after the form is submitted.', 'elementor-pro' ),
'label_block' => true,
'separator' => 'before',
]
);
$widget->add_control(
'custom_form_action_second_application_token',
[
'label' => __( 'Second Application Token', 'elementor-pro' ),
'type' => \Elementor\Controls_Manager::TEXT,
'placeholder' => 'https://example.com/api/',
'label_block' => true,
'description' => __( 'Enter the application token for your API request.', 'elementor-pro' ),
'separator' => 'before',
]
);
$widget->end_controls_section();
}
public function register_form_action( $widget ) {
$widget->add_form_action(
'custom_form_action',
[
'label' => __( 'Custom Form Action', 'elementor-pro' ),
'event' => \ElementorPro\Modules\Forms\Classes\Form_Record::get_form_settings( 'custom_form_action_event' ),
'callback' => [ $this, 'custom_form_action' ],
]
);
}
public function run( $record, $ajax_handler ) {
$debugLog = '';
$settings = $record->get( 'form_settings' );
// create the first api request
$first_api_url = $settings['custom_form_action_api_url'];
$first_api_body = $settings['custom_form_action_api_body'];
// set up the first header request
$first_api_header_authorization = 'Bearer ' . $settings['custom_form_action_application_token'];
// get the form fields
$fields = $record->get( 'fields' );
// replace the placeholders with the form field values
$first_api_body = $this->replace_placeholders( $first_api_body, $fields );
//////////////////////////////////////////
//
// Make the first API request
//
//////////////////////////////////////////
//if the method is post
// send the post request
$first_api_response = wp_remote_post( $first_api_url, [
'method' => 'POST',
'headers' => array(
'Authorization' => 'Bearer ' . $settings['custom_form_action_application_token'],
'content-type' => 'application/json',
),
'body' => $first_api_body,
'timeout' => 20,
'redirection' => 5,
'httpversion' => '1.0',
//SET BLOCKING TO TRUE TO WAIT FOR A RESPONSE - 5 hours wasted for this.
'blocking' => true,
'data_format' => 'body',
] );
if ( ! is_wp_error( $first_api_response ) ) {
$response_data = json_decode( $first_api_response['body'], true );
if ( isset( $response_data['data']['id'] ) ) {
$new_lead_id = $response_data['data']['id'];
}
else{
$new_lead_id = '';
}
}
//////////////////////////////////////////
//
// Make the second API request
//
//////////////////////////////////////////
// create the second api request
$second_api_url = $settings['custom_form_action_second_api_url'];
// set up the second header request
$second_api_header_authorization = 'Bearer ' . $settings['custom_form_action_second_application_token'];
if (!empty($first_api_response_body)){
$new_lead_id = $first_api_response_body->data->id;
}
$new_api_url = $second_api_url . $new_lead_id;
$new_api_body = '{ "lead_id": ' . $new_lead_id . '}';
// send the second api request
$second_api_response = wp_remote_post( $new_api_url, [
'method' => 'POST',
'headers' => array(
'Authorization' => 'Bearer ' . $second_api_header_authorization,
'content-type' => 'application/json',
),
'body' => $new_api_body,
'timeout' => 20,
'redirection' => 5,
'httpversion' => '1.0',
'blocking' => true,
'data_format' => 'body',
] );
//Check for errors in the Second api response.
if ( ! is_wp_error( $second_api_response ) ) {
$response_data = json_decode( $second_api_response['body'], true );
if ( isset( $response_data['autologin'] ) ) {
$autologin = $response_data['autologin'];
}
else{
$autologin = 'https://google.com';
}
}
//redirect the user
if ( ! empty( $autologin ) ) {
wp_redirect( $autologin );
exit;
}
else{
wp_redirect( 'https://www.google.com' );
exit;
}
if ( is_wp_error( $first_api_response ) ) {
wp_remote_retrieve_response_code( $second_api_response );
if ( wp_remote_retrieve_response_code( $second_api_response ) == 201 ) {
//add success message
$ajax_handler->add_success_message( __( 'First API Response: ' . $second_api_response['body'], 'elementor-pro' ) );
}
elseif ( wp_remote_retrieve_response_code( $second_api_response ) == 202 ) {
//add error message
$ajax_handler->add_error_message( __( 'First API Response: ' . $second_api_response['body'], 'elementor-pro' ) );
}
}
if ( is_wp_error( $second_api_response ) ) {
$ajax_handler->add_error_message( __( '<br><br>Data ID From First Response: '. $first_api_response_body->data->id
. '<br>Second API Body: ' . json_encode($second_api_body)
. '<br> First API Response Selector: ' . $first_api_body_response_selector
. '<br>Second API Response: ' . $second_api_response['body']
. '<br>Redirect URL: ' . $redirect_response_url
. '<br><br>',
'elementor-pro'
)
);
return;
}
if ( ! empty( $redirect_response_url ) && filter_var( $redirect_response_url, FILTER_VALIDATE_URL ) ) {
$ajax_handler->add_response_data( 'redirect_url', $redirect_response_url );
}
}//end run function
public function on_export( $element ) {
unset( $element['custom_form_action_message_redirect_url'] );
return $element;
}
public function replace_placeholders( $string, $fields ) {
$ip_of_current_user = $this->bpd_get_user_ip();
foreach ( $fields as $id => $field ) {
$string = str_replace( '{{{ USERIP }}}', $ip_of_current_user, $string );
$string = str_replace( '{{{ ' . $id . ' }}}', $field['value'], $string );
}
return $string;
}
public function bpd_get_user_ip() {
/*
if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
return $ip;
} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
return $ip;
} else {
$ip = $_SERVER['REMOTE_ADDR'];
return $ip;
}
*/
$ip = $_SERVER['REMOTE_ADDR'];
return $ip;
}
}
`

Selectable street depending on the city

I add the following code in in functions.php (wordpress), but it doesn't work correctly:
function change_city_to_dropdown( $fields ) {
$city_args = wp_parse_args( array(
'type' => 'select',
'options' => array(
'city1' => 'City1',
'city2' => 'City2',
'city3' => 'City3',
'city4' => 'City4',
'city5' => 'City5',
'city6' => 'City6',
),
'input_class' => array(
'wc-enhanced-select',
)
), $fields['shipping']['shipping_city'] );
$fields['shipping']['shipping_city'] = $city_args;
$fields['billing']['billing_city'] = $city_args; // Also change for billing field
wc_enqueue_js( "
jQuery( ':input.wc-enhanced-select' ).filter( ':not(.enhanced)' ).each( function() {
var select2_args = { minimumResultsForSearch: 5 };
jQuery( this ).select2( select2_args ).addClass( 'enhanced' );
});" );
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'change_city_to_dropdown' );
function change_address_1_to_dropdown( $fields ) {
$address_1_args = wp_parse_args( array(
'type' => 'select',
'options' => array(
'street1' => 'Street1',
'street2' => 'Street2',
'street3' => 'Street3',
'street4' => 'Street4',
'street5' => 'Street5',
'street6' => 'Street6',
),
'input_class' => array(
'wc-enhanced-select',
)
), $fields['shipping']['shipping_address_1'] );
$fields['shipping']['shipping_address_1'] = $address_1_args;
$fields['billing']['billing_address_1'] = $address_1_args; // Also change for billing field
wc_enqueue_js( "
jQuery( ':input.wc-enhanced-select' ).filter( ':not(.enhanced)' ).each( function() {
var select2_args = { minimumResultsForSearch: 5 };
jQuery( this ).select2( select2_args ).addClass( 'enhanced' );
});" );
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'change_address_1_to_dropdown' );
I would like "street1" and "street2" to be assigned only to "city1", not to all cities. Likewise, "street3" and "street4" should be assigned to the city "city2". And, "street5" and "street6" should be assigned to the citys "city3", "city4", "city5" and "city6". Can you help me with these changes?
Thank you very much!

How to create multiple meta fields in gutenberg block

I need to create a wordpress Gutenberg block that will allow me to insert some data as name and surname, company name, the best sentence from the references.
So far I managed to create a Gutenberg block that is saving one text field.
dc-references-block.php
// register custom meta tag field
function dcr_register_post_meta() {
register_post_meta( 'page', 'dc_references_block_field', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
) );
}
add_action( 'init', 'dcr_register_post_meta' );
function dcr_enqueue() {
wp_enqueue_script(
'dc-references-block-script',
plugins_url( 'dc-references-block.js', __FILE__ ),
array( 'wp-blocks', 'wp-element', 'wp-components' )
);
}
add_action( 'enqueue_block_editor_assets', 'dcr_enqueue' );
dc-references-block.js
( function( wp ) {
var el = wp.element.createElement;
var registerBlockType = wp.blocks.registerBlockType;
var TextControl = wp.components.TextControl;
registerBlockType( 'dc-references-block/dc-references-block', {
title: 'Title',
icon: 'edit',
category: 'common',
attributes: {
blockValue: {
type: 'string',
source: 'meta',
meta: 'dc_references_block_field'
}
},
edit: function( props ) {
var className = props.className;
var setAttributes = props.setAttributes;
function updateBlockValue( blockValue ) {
setAttributes({ blockValue });
}
return el(
'div',
{ className: className },
el( TextControl, {
label: 'write here name of company',
value: props.attributes.blockValue,
onChange: updateBlockValue
}
)
);
},
save: function() {
return null;
}
} );
} )( window.wp );
Whenever I try to add a second text field or textarea to the block I get an error "site does not support this block".
Could anyone explain to me how to, in this situation, add correctly more then one text field and textarea to a block?
It would be better if you included the code that did not work. In any case, I changed your code by adding another text input and a textarea (with relevant entries in attributes and meta).
Here is the modified code. Also, I have changed some of the code to be more readable.
Javascript
( function( wp ) {
const el = wp.element.createElement;
const registerBlockType = wp.blocks.registerBlockType;
const TextControl = wp.components.TextControl;
const TextareaControl = wp.components.TextareaControl;
registerBlockType( 'dc-references-block/dc-references-block', {
title: 'Title',
icon: 'edit',
category: 'common',
attributes: {
blockValue: {
type: 'string',
source: 'meta',
meta: 'dc_references_block_field'
},
// Add two new attributes
name: {
type: 'string',
source: 'meta',
meta: 'dc_references_block_field_name'
},
desc: {
type: 'string',
source: 'meta',
meta: 'dc_references_block_field_desc'
}
},
edit: function( props ) {
const className = props.className;
const setAttributes = props.setAttributes;
// Original element with onChange event as an anonymous function
const text = el( TextControl, {
label: 'write here name of company',
value: props.attributes.blockValue,
key: 'companyName',
onChange: function( value ) {
setAttributes( { name: value } );
}
} );
//Add two new elements
const secondText = el( TextControl, {
label: 'Write your name',
value: props.attributes.name,
key: 'username',
onChange: function( value ) {
setAttributes( { name: value } );
}
} );
const textArea = el( TextareaControl, {
label: 'Write a description',
value: props.attributes.desc,
key: 'desc',
onChange: function( value ) {
setAttributes( { desc: value } );
}
} );
return el(
'div',
{ className: className },
// Children of the main div as an array
[ text, secondText, textArea ]
);
},
save: function() {
return null;
}
} );
}( window.wp ) );
PHP
register_post_meta( 'page', 'dc_references_block_field', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
) );
// register two new meta corresponding to attributes in JS
register_post_meta( 'page', 'dc_references_block_field_name', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
) );
register_post_meta( 'page', 'dc_references_block_field_desc', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
) );

Add Custom Button to TinyMCE in WordPress

I want to add a new button with popup to TinyMCE. But i never see the button. I probably are doing wrong this modification. How to insert the new button on that TinyMCE Code?
I have this TinyMCE Code for showing in Wordpress Front-End:
$qt = '';
if( $this->options[ 'wpcc_edit_in_html' ] ) $qt = array( 'buttons' => 'strong,em,block,del,ul,ol,li,spell,close' );
else {
$qt = FALSE;
add_filter( 'wp_default_editor', create_function( '', 'return "tinymce";' ) ); // force visual editor
}
$editor_settings = array(
'theme_advanced_blockformats' => array( 'h2','h3','p' ),
'wpautop' => true,
'media_buttons' => false,
'tinymce' => array(
'theme_advanced_buttons1' => 'bold,italic,blockquote,strikethrough,bullist,numlist,spellchecker,|,undo,redo,|,mygallery_button',
'theme_advanced_buttons2' => '',
'theme_advanced_buttons3' => '',
'theme_advanced_buttons4' => ''
),
'quicktags' => $qt
);
And this one to insert new button:
function filter_mce_button( $buttons ) {
// add a separation before our button, here our button's id is "mygallery_button"
array_push( $buttons, '|', 'mygallery_button' );
return $buttons;
}
function filter_mce_plugin( $plugins ) {
// this plugin file will work the magic of our button
$plugins['myplugin'] = plugin_dir_url( __FILE__ ) . 'mygallery_plugin.js';
return $plugins;
}
add_filter( 'mce_buttons', array( $this, 'filter_mce_button' ) );
add_filter( 'mce_external_plugins', array( $this, 'filter_mce_plugin' ) );
Read this tutorial. https://www.gavick.com/magazine/adding-your-own-buttons-in-tinymce-4-editor.html#tc-section-4
Very detailed tutorial. But the bare essentials are as follows: in your functions.php add this code to register and create your button:
function add_container_button() {
if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') )
return;
if ( get_user_option('rich_editing') == 'true') {
add_filter('mce_external_plugins', 'add_container_plugin');
add_filter('mce_buttons_3', 'register_container_button');
}
}
add_action('init', 'add_container_button');
function register_container_button($buttons) {
array_push($buttons, "|", "skizzar_container");
return $buttons;
}
function add_container_plugin($plugin_array) {
$plugin_array['skizzar_container'] = plugin_dir_url( __FILE__ ) . 'shortcodes-js/container.js';;
return $plugin_array;
}
Then you'll need to create a js file which handles how the buttons acts in the editor (you can see mine is referenced in the code above as container.js. Here is the code of my js file:
(function() {
tinymce.PluginManager.add('skizzar_container', function( editor, url ) {
editor.addButton( 'skizzar_container', {
title: 'Add a Container',
icon: 'icon dashicons-media-text',
onclick: function() {
editor.windowManager.open( {
title: 'Container',
body: [{
type: 'listbox',
name: 'style',
label: 'Style',
'values': [
{text: 'Clear', value: 'clear'},
{text: 'White', value: 'white'},
{text: 'Colour 1', value: 'colour1'},
{text: 'Colour 2', value: 'colour2'},
{text: 'Colour 3', value: 'colour3'},
]
}],
onsubmit: function( e ) {
editor.insertContent( '[container style="' + e.data.style + '"]<br /><br />[/container]');
}
});
}
});
});
})();
This creates a popup with a dropdown menu where the user can select a style. Hope this helps in some way

Resources