Icons Control | Elementor - wordpress

what does {{{ iconHTML.value }}} stands for in the _content_template?
the render is working fine but there's a reference error: iconHTML is not defined.
This is from the elementor controls documentation but i cant seem understand what should I substitute in {{{ iconHTML.value }}}
add_action( 'elementor/widgets/widgets_registered', function( $widget_manager ) {
class Icons_Control_Test_Widget extends \Elementor\Widget_Base {
public function get_name() {
return 'icons_test_widget';
}
public function get_title() {
return __( 'Icons Test Widget', 'text-domain' );
}
protected function _register_controls() {
$this->start_controls_section(
'section_icon',
[
'label' => __( 'Icon', 'text-domain' ),
]
);
$this->add_control(
'icon',
[
'label' => __( 'Icon', 'text-domain' ),
'type' => \Elementor\Controls_Manager::ICONS,
'default' => [
'value' => 'fas fa-star',
'library' => 'solid',
],
]
);
$this->end_controls_section();
}
protected function render() {
$settings = $this->get_settings_for_display();
?>
<div class="my-icon-wrapper">
<?php \Elementor\Icons_Manager::render_icon( $settings['icon'], [ 'aria-hidden' => 'true' ] ); ?>
</div>
<?php
}
protected function _content_template() {
?>
<div class="my-icon-wrapper">
{{{ iconHTML.value }}}
</div>
<?php
}
}
// register widget
$widget_manager->register_widget_type( new Icons_Control_Test_Widget() );
} );

The elementor itself does not say what that means. For me, iconHTML does not work at all and I have to create the appropriate element myself. My solution doesn't cause logs either.
<div>
<i aria-hidden="true" class="{{{ settings.icon_control_name.value }}}"></i>
</div>
EDIT
Just use renderIcon from elementor.helpers.renderIcon. Eg.
<div class="icon_wrapper">
<# var iconHTML = elementor.helpers.renderIcon( view, settings.icons_controller, { 'aria-hidden': true }, 'i' , 'object' ); #>
<!--- And now it's working --->
{{{ iconHTML.value }}}
</div>
Thanks for #rotemee from issue https://github.com/elementor/elementor/issues/15707

Related

Gutenberg server side rendered (dynamic) block - attributes don't update in editor

I'm making Wordpress server side rendered block and it works well on frontend, but in editor attributes don't save (I have always default value in editor, although on frontend there is my saved value).
This is my code (not whole but minimal reproducible).
Register block on client side and set block options in editor:
const { __ } = wp.i18n;
const { ServerSideRender } = wp.editor;
const { InspectorControls } = wp.blockEditor;
const { PanelBody, __experimentalNumberControl: NumberControl } = wp.components;
registerBlockType(
'mysite/trainings',
{
title: __( 'Trainings list', 'mysite' ),
attributes: {
postsCount: {
type: 'number',
default: 9,
}
},
edit: ( { attributes, setAttributes } ) => {
const { postsCount } = attributes;
return (
<>
<InspectorControls>
<PanelBody
title={ __( 'Set number of displayed trainings', 'mysite' ) }
>
<NumberControl
value={ postsCount }
onChange={ ( value ) => setAttributes( { postsCount: value } ) }
min={ 1 }
max={ 9 }
/>
</PanelBody>
</InspectorControls>
<ServerSideRender
block="mysite/trainings"
attributes={ {
postsCount: 9,
} }
/>
</>
);
},
save() {
return null;
},
}
);
Register and render block on server side:
add_action( 'init', 'register_trainings_block' );
function register_trainings_block() {
register_block_type(
'mysite/trainings',
array(
'api_version' => 2,
'editor_script' => 'sm_editor_script',
'render_callback' => 'render_trainings_block',
'attributes' => array(
'postsCount' => array(
'type' => 'number',
'default' => 9,
),
),
)
);
}
function render_trainings_block( $attributes ) {
$query_args = array(
'post__in' => array(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 // IDs of posts
),
'post_type' => 'sm_training',
'orderby' => 'post__in',
'paged' => '1'
);
$posts = new WP_Query( $query_args );
$output = '<section class="wp-block-mysite-trainings">';
$i = 0;
foreach ( $posts->posts as $post ) {
if ( $i < $attributes['postsCount'] ) {
ob_start();
$output .= get_template_part( 'template-parts/content/training' );
$output .= ob_get_clean();
}
$i++;
}
$output .= '</section>';
return $output;
}
Enqueue editor script:
add_action( 'enqueue_block_editor_assets', 'load_editor_scripts' );
public function load_editor_scripts() {
wp_enqueue_script( 'sm_editor_script', get_template_directory_uri() . '/assets/dist/js/editor.js', array(
'wp-blocks',
'wp-i18n',
'wp-editor',
'wp-components',
'wp-block-editor'
), '1.0.0', true );
wp_localize_script( 'sm_editor_script', 'gutenbergBlocks', array( 'themeUrl' => get_template_directory_uri() ) );
}
What am I missing?
I know :)
Two things:
It should be:
<ServerSideRender
block="mysite/trainings"
attributes={ { postsCount } }
/>
(without default value here)
If attribute is number, you have to ensure that it will be saved as number.
In js change in onChange function:
<NumberControl
value={ postsCount }
onChange={ ( value ) => setAttributes( { postsCount: Number.parseInt( value ) } ) }
min={ 1 }
max={ 9 }
/>
and in php render_trainings_block function:
$attributes['postsCount'] = (int) $attributes['postsCount'];

Wordpress Elementor Widget Development JavaScript not loaded in Editor mode correctly

i want to create an Elementor-Widget with al slick Slider as JavaScript / Jquery. I can add the elements correctly in ELementor Editor Mode, but the Slider didn`t work there. The Slides will shown among themselves. When i add a alert in the javascript file after the check that the element slider is still there, its not work, before the check its works fine. I think the Element will not load correctly in the editor mode...? Have someone an idea what i can do that the slider works also in the editor-mode?
Here the JavaScript-Code:
$( document ).ready(function() {
if ($(".slider").length) {
alert("Test");
$(".slider").css({"opacity" :"1"});
$(".slider").slick({
slidesToShow: 1,
slidesToScroll: 1,
infinite: true,
arrows: true,
speed: 1000,
fade: false,
dots: false,
prevArrow: '<button type="button" class="slick-prev"><i class="arrow fa fa-minus"></i></button>',
nextArrow: '<button type="button" class="slick-next"><i class="arrow fa fa-plus"></i></button>',
responsive: [
{
breakpoint: 992,
settings: {
arrows: false,
dots: true
}
}
]
});
};
Here the Code of the PHP Widget File:
<?php
/**
* Astestimonials class.
*
....
*/
namespace ElementorAstestimonials\Widgets;
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
// Security Note: Blocks direct access to the plugin PHP files.
defined( 'ABSPATH' ) || die();
/**
* Astestimonials widget class.
*
* #since 1.0.0
*/
class Astestimonials extends Widget_Base {
/**
* Class constructor.
*
* #param array $data Widget data.
* #param array $args Widget arguments.
*/
public function __construct( $data = array(), $args = null ) {
parent::__construct( $data, $args );
$plugin = get_plugin_data( __FILE__, false, false );
wp_register_style( 'astestimonialscss', plugins_url( '/assets/css/astestimonials.css', ELEMENTOR_ASTESTIMONIALS ), array(), '1.0.0' );
wp_register_script( 'astestimonialsjs', plugins_url( '/assets/js/astestimonials.js', ELEMENTOR_ASTESTIMONIALS ), array( 'jquery' ), '1.0.0' );
}
/**
* Retrieve the widget name.
*
* #since 1.0.0
*
* #access public
*
* #return string Widget name.
*/
public function get_name() {
return 'astestimonials';
}
/**
* Retrieve the widget title.
*
* #since 1.0.0
*
* #access public
*
* #return string Widget title.
*/
public function get_title() {
return __( 'astestimonials', 'elementor-astestimonials' );
}
/**
* Retrieve the widget icon.
*
* #since 1.0.0
*
* #access public
*
* #return string Widget icon.
*/
public function get_icon() {
return 'eicon-facebook-comments';
}
/**
* 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.0.0
*
* #access public
*
* #return array Widget categories.
*/
public function get_categories() {
return array( 'artisolution-addons' );
}
/**
* Enqueue styles.
*/
public function get_style_depends() {
return array( 'astestimonialscss' );
}
public function get_script_depends() {
return array( 'astestimonialsjs');
}
/**
* Register the widget controls.
*
* Adds different input fields to allow the user to change and customize the widget settings.
*
* #since 1.0.0
*
* #access protected
*/
protected function _register_controls() {
$this->start_controls_section(
'section_content',
array(
'label' => __( 'Content', 'elementor-astestimonials' ),
)
);
$this->add_control(
'slides',
[
'label' => esc_html__( 'Slides', 'elementor-astestimonials' ),
'type' => \Elementor\Controls_Manager::REPEATER,
'fields' => [
[
'name' => 'content',
'label' => __( 'Content', 'elementor-astestimonials' ),
'type' => Controls_Manager::WYSIWYG,
'default' => __( 'Content', 'elementor-astestimonials' ),
],
[
'name' => 'name',
'label' => __( 'Name', 'elementor-astestimonials' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'Beispielname', 'elementor-astestimonials' ),
'default' => __( 'Name', 'elementor-astestimonials' ),
],
[
'name' => 'job',
'label' => __( 'Job / Company', 'elementor-astestimonials' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'Beispieljob', 'elementor-astestimonials' ),
'default' => __( 'Job', 'elementor-astestimonials' ),
],
[
'name' => 'image',
'label' => esc_html__( 'Choose Image', 'elementor-astestimonials' ),
'type' => \Elementor\Controls_Manager::MEDIA,
'default' => [
'url' => \Elementor\Utils::get_placeholder_image_src(),
],
],
],
'default' => [
[
'content' => esc_html__( 'List Item #1', 'elementor-astestimonials' ),
'name' => esc_html__( 'Beispielname #1', 'elementor-astestimonials' ),
'job' => esc_html__( 'Beispiejob #1', 'elementor-astestimonials' ),
],
[
'content' => esc_html__( 'List Item #2', 'elementor-astestimonials' ),
'name' => esc_html__( 'Beispielname #2', 'elementor-astestimonials' ),
'job' => esc_html__( 'Beispiejob #2', 'elementor-astestimonials' ),
],
],
'title_field' => '{{{ name }}}',
]
);
$this->end_controls_section();
}
/**
* Render the widget output on the frontend.
*
* Written in PHP and used to generate the final HTML.
*
* #since 1.0.0
*
* #access protected
*/
protected function render() {
$settings = $this->get_settings_for_display();
?>
<div class="slider">
<?php foreach ( $settings['slides'] as $index => $item ) : ?>
<div class="slide">
<div class="review-wrap">
<div class="review-text 11">
<?php if ( '' != $item['content'] ) {
echo $item['content'];
} ?>
</div>
<div class="reviewer">
<?php if ( '' != $item['image']['url'] ): ?>
<div class="avatar"
style="background-image: url('<?php echo $item['image']['url']; ?>');"></div>
<?php endif; ?>
<div class="reviewer-info">
<h4 class="name"><?php echo $item['name']; ?></h4>
<p><?php echo $item['job']; ?></p>
</div>
</div><!-- //author -->
</div>
</div>
<?php endforeach; ?>
</div><!-- //review-slider -->
<?php
}
/**
* Render the widget output in the editor.
*
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* #since 1.0.0
*
* #access protected
*/
protected function _content_template() {
?>
<div class="slider">
<#
if ( settings.slides ) {
_.each( settings.slides, function( item, index ) {
#>
<div class="slide">
<div class="review-wrap">
<div class="review-text 11">
<# if ( item.content != '' ) { #>
{{{ item.content }}}
<# } #>
</div>
<div class="reviewer">
<# if ( item.image.url != '' ) { #>
<div class="avatar"
style="background-image: url('{{ item.image.url }}');"></div>
<# } #>
<div class="reviewer-info">
<h4 class="name">{{{ item.name }}}</h4>
<p>{{{ item.job }}}</p>
</div>
</div><!-- //author -->
</div>
</div>
<#
} );
}
#>
</div><!-- //review-slider -->
<?php
}
}
Here the Image of the Editor-Mode:
Image Editor-Mode
Here the Code of the JavaScript file for the Editor:
(function ($, elementor) {
"use strict";
var myDataCollection = {
init: function () {
var widgets = {
"astestimonials": myDataCollection.AsTestimonials,
};
$.each(widgets, function (widget, callback) {
elementor.hooks.addAction("frontend/element_ready/" + widget, callback);
});
},
AsTestimonials: function ($scope) {
$scope.find('.slider').hide();
alert("Test");
},
};
$(window).on("elementor/frontend/init", myDataCollection.init);
})(jQuery, window.elementorFrontend);
Basically, your enqueue Javascript doesn't load inside the elementor editor. For loading javascript, you have to follow some easy steps.
Enqueue your javascript with dependency elementor-frontend.
wp_enqueue_script( 'script-handle', 'path/to/file.js', [ 'elementor-frontend' ], '1.0.0', true );
Now you will get a javascript hook elementor/frontend/init that loads your javascript inside the elementor.
For snippet code, you can use this.
(function ($, elementor) {
"use strict";
var myDataCollection = {
init: function () {
var widgets = {
"back-to-top.default": myDataCollection.Back_To_Top,
};
$.each(widgets, function (widget, callback) {
elementor.hooks.addAction("frontend/element_ready/" + widget, callback);
});
},
Back_To_Top: function ($scope) {
$scope.find('.BackTo').on('click', function (e) {
e.preventDefault();
$('body, html').animate({
scrollTop: 0
}, 1500)
});
$(window).on("scroll", function () {
var scrolltop = $(window).scrollTop(),
docHeight = $(document).height() / 2;
if (scrolltop > docHeight) {
$scope.fadeIn("slow");
} else {
$scope.fadeOut("slow");
}
});
},
};
$(window).on("elementor/frontend/init", myDataCollection.init);
})(jQuery, window.elementorFrontend);
Explanation of the above code :
I wrote the above code for Back to the top widget. my widget name is back-to-top. First I am taking an Immediately-invoked Function and I take 2 parameters as I enqueue my script with 2 dependency elementor-frontend and jquery so I will get back 2 parameters. For my code reusability, I make an object myDataCollection.otherwise we can do it like that. follow the below code.
elementor.hooks.addAction("frontend/element_ready/" + "back-to-top.default", "funtion_name");
It works fine but for multiple widgets, I make the first approach.
inside the object, I take a function init. inside init I take another object widget. widget is responsible for taking widget name and function name. after that I loop through it. so that we don't need to hook our widget again and again. Now I am explaining my callback function. Inside Callback, you will get a parameter like $scope.$scope is your actual widget. When your widget drags and drops inside the editor you will get the $scope.You will find your widget markup inside $scope.Now write your custom code for your widget and enjoy.
Enqueue your JS file like this.
add_action( 'elementor/frontend/before_enqueue_scripts', 'enqueue_scripts' );
function enqueue_scripts()
{
wp_enqueue_script( 'elementor-script', get_template_directory_uri( __FILE__ ) . '/assets/js/elementor.js', array( 'jquery', 'elementor-frontend' ), '1.0.0', true );
}
Now follow the first answer. I hope your problem will be solved.

How can I add panels to the sidebar on the Document tab in Gutenberg? [duplicate]

I am trying to add a new component panel under document tab, like categories, featured image etc.
They've added the PluginDocumentSettingPanel SlotFill now.
const { registerPlugin } = wp.plugins
const { PluginDocumentSettingPanel } = wp.editPost
const PluginDocumentSettingPanelDemo = () => (
<PluginDocumentSettingPanel
name="custom-panel"
title="Custom Panel"
className="custom-panel"
>
Custom Panel Contents
</PluginDocumentSettingPanel>
)
registerPlugin('plugin-document-setting-panel-demo', {
render: PluginDocumentSettingPanelDemo
})
add_meta_box will do the trick, but only if you add the context-argument with a value of 'side':
add_meta_box(
'box-id-here',
'Box Title Here',
'createBoxHtml',
'post',
'side' ); // <-- this is important
Arrrh, two days for nothing!
Old answer
According to this tutorial, we can add our custom sidebar and fill it with customized form inputs.
Here is a working example in a React JSX version. This adds a meta field country:
const { registerPlugin } = wp.plugins;
const { PluginSidebar } = wp.editPost;
const { TextControl } = wp.components;
const { withSelect, withDispatch } = wp.data;
// Customized TextControl
const CustomMetaField = withDispatch( ( dispatch, props ) => {
return {
updateMetaValue: ( v ) => {
dispatch( 'core/editor' ).editPost( {
meta: {
[ props.metaFieldName ]: v
}
});
}
};
})( withSelect( ( select, props ) => {
return {
[ props.metaFieldName ]: select( 'core/editor' ).getEditedPostAttribute( 'meta' )[ props.metaFieldName ]
};
} )( ( props ) => (
<TextControl
value={props[ props.metaFieldName ] }
label="Country"
onChange={( v ) => {
props.updateMetaValue( v );
}}
/> )
) );
// Our custom sidebar
registerPlugin( 'custom-sidebar', {
render() {
return (
<PluginSidebar
name="project-meta-sidebar"
title="Project Meta">
<div className="plugin-sidebar-content">
<CustomMetaField metaFieldName="country" />
</div>
</PluginSidebar>
);
},
} );
And in PHP, register the meta field in the init-hook:
register_meta( 'post', 'country', [
'show_in_rest' => TRUE,
'single' => TRUE,
'type' => 'string'
] );
I know:
This is still not the required solution, but nearly.
You can now use the newer useSelect and useDispatch custom hooks. They are similar to withSelect and withDispatch, but utilize custom hooks from React 16.8 for a slightly more concise dev experience:
(Also, using #wordpress/scripts, so the imports are from the npm packages instead of the wp object directly, but either would work.)
import { __ } from '#wordpress/i18n';
import { useSelect, useDispatch } from '#wordpress/data';
import { PluginDocumentSettingPanel } from '#wordpress/edit-post';
import { TextControl } from '#wordpress/components';
const TextController = (props) => {
const meta = useSelect(
(select) =>
select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']
);
const { editPost } = useDispatch('core/editor');
return (
<TextControl
label={__("Text Meta", "textdomain")}
value={meta}
onChange={(value) => editPost({ meta: { _myprefix_text_metafield: value } })}
/>
);
};
const PluginDocumentSettingPanelDemo = () => {
return (
<PluginDocumentSettingPanel
name="custom-panel"
title="Custom Panel"
className="custom-panel"
>
<TextController />
</PluginDocumentSettingPanel>
);
};
export default PluginDocumentSettingPanelDemo;
Along with registering your meta field as usual:
function myprefix_register_meta()
{
register_post_meta('post', '_myprefix_text_metafield', array(
'show_in_rest' => true,
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => function () {
return current_user_can('edit_posts');
}
));
}
add_action('init', 'myprefix_register_meta');
And make sure if using for a custom post type, that you include custom-fields in the array of supports:
'supports' => array('title', 'editor', 'thumbnail', 'revisions', 'custom-fields'),
Hopefully that helps.
You can add this code to your function.php. This code create new tab and add text field to this tab. Text field save to database like custom field in post_meta table and you can output this like default WP post meta.
1. Create tab Настройки UTM.
2. Create custom text field utm_post_class
3. To output in website use $utm = get_post_meta( $post->ID, 'utm_post_class', true );
//Article UTM Link
add_action( 'load-post.php', 'utm_post_meta_boxes_setup' );
add_action( 'load-post-new.php', 'utm_post_meta_boxes_setup' );
function utm_post_meta_boxes_setup() {
add_action( 'add_meta_boxes', 'utm_add_post_meta_boxes' );
add_action( 'save_post', 'utm_save_post_class_meta', 10, 2 );
}
function utm_add_post_meta_boxes() {
add_meta_box(
'utm-post-class',
'Настройки UTM',
'utm_post_class_meta_box',
'post',
'side',
'default'
);
}
function utm_post_class_meta_box( $post ) {
wp_nonce_field( basename( __FILE__ ), 'utm_post_class_nonce' );?>
<div class="components-base-control editor-post-excerpt__textarea">
<div class="components-base-control__field">
<label class="components-base-control__label" for="utm-post-class">UTM ссылка (необязательно)</label>
<input type="text" name="utm-post-class" id="utm-post-class" class="edit-post-post-schedule" value="<?php echo esc_attr( get_post_meta( $post->ID, 'utm_post_class', true ) ); ?>">
</div>
</div>
<?php }
function utm_save_post_class_meta( $post_id, $post ) {
if ( !isset( $_POST['utm_post_class_nonce'] ) || !wp_verify_nonce( $_POST['utm_post_class_nonce'], basename( __FILE__ ) ) )
return $post_id;
$post_type = get_post_type_object( $post->post_type );
if ( !current_user_can( $post_type->cap->edit_post, $post_id ) )
return $post_id;
$new_meta_value = ( isset( $_POST['utm-post-class'] ) ? $_POST['utm-post-class'] : '' );
$meta_key = 'utm_post_class';
$meta_value = get_post_meta( $post_id, $meta_key, true );
if ( $new_meta_value && '' == $meta_value )
add_post_meta( $post_id, $meta_key, $new_meta_value, true );
elseif ( $new_meta_value && $new_meta_value != $meta_value )
update_post_meta( $post_id, $meta_key, $new_meta_value );
elseif ( '' == $new_meta_value && $meta_value )
delete_post_meta( $post_id, $meta_key, $meta_value );
}
add_meta_box adds a new panel there for the gutenberg editor

How to add new panel under "document" in Gutenberg

I am trying to add a new component panel under document tab, like categories, featured image etc.
They've added the PluginDocumentSettingPanel SlotFill now.
const { registerPlugin } = wp.plugins
const { PluginDocumentSettingPanel } = wp.editPost
const PluginDocumentSettingPanelDemo = () => (
<PluginDocumentSettingPanel
name="custom-panel"
title="Custom Panel"
className="custom-panel"
>
Custom Panel Contents
</PluginDocumentSettingPanel>
)
registerPlugin('plugin-document-setting-panel-demo', {
render: PluginDocumentSettingPanelDemo
})
add_meta_box will do the trick, but only if you add the context-argument with a value of 'side':
add_meta_box(
'box-id-here',
'Box Title Here',
'createBoxHtml',
'post',
'side' ); // <-- this is important
Arrrh, two days for nothing!
Old answer
According to this tutorial, we can add our custom sidebar and fill it with customized form inputs.
Here is a working example in a React JSX version. This adds a meta field country:
const { registerPlugin } = wp.plugins;
const { PluginSidebar } = wp.editPost;
const { TextControl } = wp.components;
const { withSelect, withDispatch } = wp.data;
// Customized TextControl
const CustomMetaField = withDispatch( ( dispatch, props ) => {
return {
updateMetaValue: ( v ) => {
dispatch( 'core/editor' ).editPost( {
meta: {
[ props.metaFieldName ]: v
}
});
}
};
})( withSelect( ( select, props ) => {
return {
[ props.metaFieldName ]: select( 'core/editor' ).getEditedPostAttribute( 'meta' )[ props.metaFieldName ]
};
} )( ( props ) => (
<TextControl
value={props[ props.metaFieldName ] }
label="Country"
onChange={( v ) => {
props.updateMetaValue( v );
}}
/> )
) );
// Our custom sidebar
registerPlugin( 'custom-sidebar', {
render() {
return (
<PluginSidebar
name="project-meta-sidebar"
title="Project Meta">
<div className="plugin-sidebar-content">
<CustomMetaField metaFieldName="country" />
</div>
</PluginSidebar>
);
},
} );
And in PHP, register the meta field in the init-hook:
register_meta( 'post', 'country', [
'show_in_rest' => TRUE,
'single' => TRUE,
'type' => 'string'
] );
I know:
This is still not the required solution, but nearly.
You can now use the newer useSelect and useDispatch custom hooks. They are similar to withSelect and withDispatch, but utilize custom hooks from React 16.8 for a slightly more concise dev experience:
(Also, using #wordpress/scripts, so the imports are from the npm packages instead of the wp object directly, but either would work.)
import { __ } from '#wordpress/i18n';
import { useSelect, useDispatch } from '#wordpress/data';
import { PluginDocumentSettingPanel } from '#wordpress/edit-post';
import { TextControl } from '#wordpress/components';
const TextController = (props) => {
const meta = useSelect(
(select) =>
select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']
);
const { editPost } = useDispatch('core/editor');
return (
<TextControl
label={__("Text Meta", "textdomain")}
value={meta}
onChange={(value) => editPost({ meta: { _myprefix_text_metafield: value } })}
/>
);
};
const PluginDocumentSettingPanelDemo = () => {
return (
<PluginDocumentSettingPanel
name="custom-panel"
title="Custom Panel"
className="custom-panel"
>
<TextController />
</PluginDocumentSettingPanel>
);
};
export default PluginDocumentSettingPanelDemo;
Along with registering your meta field as usual:
function myprefix_register_meta()
{
register_post_meta('post', '_myprefix_text_metafield', array(
'show_in_rest' => true,
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => function () {
return current_user_can('edit_posts');
}
));
}
add_action('init', 'myprefix_register_meta');
And make sure if using for a custom post type, that you include custom-fields in the array of supports:
'supports' => array('title', 'editor', 'thumbnail', 'revisions', 'custom-fields'),
Hopefully that helps.
You can add this code to your function.php. This code create new tab and add text field to this tab. Text field save to database like custom field in post_meta table and you can output this like default WP post meta.
1. Create tab Настройки UTM.
2. Create custom text field utm_post_class
3. To output in website use $utm = get_post_meta( $post->ID, 'utm_post_class', true );
//Article UTM Link
add_action( 'load-post.php', 'utm_post_meta_boxes_setup' );
add_action( 'load-post-new.php', 'utm_post_meta_boxes_setup' );
function utm_post_meta_boxes_setup() {
add_action( 'add_meta_boxes', 'utm_add_post_meta_boxes' );
add_action( 'save_post', 'utm_save_post_class_meta', 10, 2 );
}
function utm_add_post_meta_boxes() {
add_meta_box(
'utm-post-class',
'Настройки UTM',
'utm_post_class_meta_box',
'post',
'side',
'default'
);
}
function utm_post_class_meta_box( $post ) {
wp_nonce_field( basename( __FILE__ ), 'utm_post_class_nonce' );?>
<div class="components-base-control editor-post-excerpt__textarea">
<div class="components-base-control__field">
<label class="components-base-control__label" for="utm-post-class">UTM ссылка (необязательно)</label>
<input type="text" name="utm-post-class" id="utm-post-class" class="edit-post-post-schedule" value="<?php echo esc_attr( get_post_meta( $post->ID, 'utm_post_class', true ) ); ?>">
</div>
</div>
<?php }
function utm_save_post_class_meta( $post_id, $post ) {
if ( !isset( $_POST['utm_post_class_nonce'] ) || !wp_verify_nonce( $_POST['utm_post_class_nonce'], basename( __FILE__ ) ) )
return $post_id;
$post_type = get_post_type_object( $post->post_type );
if ( !current_user_can( $post_type->cap->edit_post, $post_id ) )
return $post_id;
$new_meta_value = ( isset( $_POST['utm-post-class'] ) ? $_POST['utm-post-class'] : '' );
$meta_key = 'utm_post_class';
$meta_value = get_post_meta( $post_id, $meta_key, true );
if ( $new_meta_value && '' == $meta_value )
add_post_meta( $post_id, $meta_key, $new_meta_value, true );
elseif ( $new_meta_value && $new_meta_value != $meta_value )
update_post_meta( $post_id, $meta_key, $new_meta_value );
elseif ( '' == $new_meta_value && $meta_value )
delete_post_meta( $post_id, $meta_key, $meta_value );
}
add_meta_box adds a new panel there for the gutenberg editor

To pass a php value in an array in wordpress

I have a function like bellow
if(!function_exists('generate_share_urls')) {
function generate_share_urls() {
$title = the_title();
$content = the_content();
$share_urls = array (
'facebook' => 'http://www.facebook.com/sharer/sharer.php?u=',
'twitter' => 'http://twitter.com/share?url=',
'google_plus' => 'https://plus.google.com/share?url=',
'linkedin' => 'http://www.linkedin.com/shareArticle?mini=true&url=',
'pinterest' => 'http://pinterest.com/pin/create/button/?url=',
'email' => 'mailto:?subject={'.$title.'}&body='.$content.',
'permalink' => ''
);
return $share_urls;
}
}
Now when run the function i cant find the $title and the $content of the page. Is there any fault with my code.
the_title() and the_content() will print the title/content, not return it. What you need instead are the get_ functions:
if(!function_exists('generate_share_urls')) {
function generate_share_urls() {
$title = get_the_title();
$content = get_the_content();
$share_urls = array (
'facebook' => 'http://www.facebook.com/sharer/sharer.php?u=',
'twitter' => 'http://twitter.com/share?url=',
'google_plus' => 'https://plus.google.com/share?url=',
'linkedin' => 'http://www.linkedin.com/shareArticle?mini=true&url=',
'pinterest' => 'http://pinterest.com/pin/create/button/?url=',
'email' => 'mailto:?subject={'.$title.'}&body='.$content.',
'permalink' => ''
);
return $share_urls;
}
}

Resources