背景:
使用
dynamic_sidebar_params
不适用于
HTML
是因为WordPress条带
HTML
来自小部件标题
wp_widget_control()
功能如下:
$widget_title = esc_html( strip_tags( $sidebar_args[\'widget_name\'] ) );
WordPress还剥离
HTML
在默认JavaScript中
wp-admin/js/widgets.js
因此,如果没有定制的解决方案,PHP或JavaScript都没有默认的过滤器或选项来实现您想要的。
自定义PHP解决方案:
自定义PHP解决方案可能只在
wp-admin -> Appearance -> Widgets
, 但不在
Customizer -> Widgets
.
WordPress添加wp_widget_control()
function (生成控件UI)的dynamic_sidebar_params
钩子,因此可以使用此过滤器钩子覆盖它。然而,在customizer中,WordPress调用wp_widget_control()
function 直接,因此此解决方案不适用于自定义程序。
解决方案如下所示(在自定义插件中添加此代码):
add_filter( \'dynamic_sidebar_params\', \'wpse261042_list_widget_controls_dynamic_sidebar\', 20 );
function wpse261042_list_widget_controls_dynamic_sidebar( $params ) {
global $wp_registered_widgets;
// we only want this in wp-admin (may need different check to enable page builder)
if( is_admin() ) {
if ( is_array( $params ) && is_array( $params[0] ) && $params[0][\'id\'] !== \'wp_inactive_widgets\' ) {
$widget_id = $params[0][\'widget_id\'];
if ( $wp_registered_widgets[$widget_id][\'callback\'] === \'wp_widget_control\' ) {
// here we are replacing wp_widget_control() function
// with our custom wpse261042_widget_control() function
$wp_registered_widgets[$widget_id][\'callback\'] = \'wpse261042_widget_control\';
}
}
}
return $params;
}
function wpse261042_widget_control( $sidebar_args ) {
// here copy everything from the core wp_widget_control() function
// and change only the part related to heading as you need
}
正如我之前所说的,此解决方案不适用于定制程序,并且更可能需要将来的更新,因为我们正在覆盖核心功能。
自定义JavaScript解决方案(推荐):
幸运的是,可以使用JavaScript自定义此行为。WordPress仍然使用JavaScript更新小部件控件标题。为此,WordPress保留了一个占位符
in-widget-title
CSS类并使用小部件更新它
title
JavaScript代码中的字段值。我们可以利用这一点来实现我们的目标。
相关的核心JS文件:
首先,您需要知道WordPress加载
wp-admin/js/customize-widgets.js
文件(带有
customize-widgets
手柄)in
wp-admin -> Customize -> Widgets
(自定义程序)和
wp-admin/js/widgets.js
文件(带有
admin-widgets
手柄)in
wp-admin -> Appearance -> Widgets
操作控件UI。这两个文件对小部件UI标记和小部件标题UI操作执行类似的操作,但也有许多不同的操作。因此,对于基于JavaScript的解决方案,我们需要考虑这一点。
定制器的注意事项:
定制器不会在页面加载后立即加载小部件UI标记,而是在相应的
Widgets -> Sidebar
面板打开。因此,我们需要在WordPress加载小部件UI后对其进行操作。例如,由于customizer代码是基于事件的,因此我使用以下代码行在正确的时刻设置事件处理程序:
section.expanded.bind( onExpanded );
此外,customizer使用AJAX立即加载更改,这就是为什么我使用下面的行来访问数据更改:
control.setting.bind( updateTitle );
还有,我需要
widget-added
具有以下代码行的事件:
$( document ).on( \'widget-added\', add_widget );
自定义程序通用(&h3);
wp-admin -> Appearance -> Widgets
:上述两个JavaScript文件都会触发
widget-updated
更新小部件时发生的事件。虽然customizer可以使用AJAX立即完成,但传统的
Widget
管理员在您单击保存按钮后执行此操作。为此,我使用了以下代码行:
$( document ).on( \'widget-updated\', modify_widget );
注意事项
wp-admin -> Appearance -> Widgets
:与定制者相反,传统
Widgets
admin使用PHP加载小部件控件UI,因此我遍历了UI HTML以进行如下初始更改:
$( \'#widgets-right div.widgets-sortables div.widget\' ).each( function() { // code } );
自定义插件代码:以下是一个完整的插件,包含基于JavaScript的解决方案,可在
wp-admin -> Appearance -> Widgets
和
Customizer -> Widgets
:
wpse-widget-control.php
插件PHP文件:
<?php
/**
* Plugin Name: Widget Control
* Plugin URI: https://wordpress.stackexchange.com/questions/261042/how-to-influence-the-information-displayed-on-widget-inside-wp-admin
* Description: Display additional info on Widget Heading in wp-admin & customizer using JS
* Author: Fayaz
* Version: 1.0
* Author URI: http://fmy.me/
*/
if( is_admin() ) {
add_action( \'current_screen\', \'wpse261042_widget_screen\' );
}
function wpse261042_widget_screen() {
$currentScreen = get_current_screen();
if( $currentScreen->id === \'customize\' ) {
add_action( \'customize_controls_enqueue_scripts\', \'wpse261042_customizer_widgets\', 99 );
}
else if( $currentScreen->id === \'widgets\' ) {
add_action( \'admin_enqueue_scripts\', \'wpse261042_admin_widgets\', 99 );
}
}
function wpse261042_customizer_widgets() {
wp_enqueue_script( \'custom-widget-heading\', plugin_dir_url( __FILE__ ) . \'custom-widget-heading.js\', array( \'jquery\', \'customize-widgets\' ) );
}
function wpse261042_admin_widgets() {
wp_enqueue_script( \'custom-widget-heading\', plugin_dir_url( __FILE__ ) . \'custom-widget-heading.js\', array( \'jquery\', \'admin-widgets\' ) );
}
custom-widget-heading.js
JavaScript文件:
(function( wp, $ ) {
var compare = {
// field to compare
field: \'title\',
// value to be compared with
value: \'yes\',
// heading if compare.value matches with compare.field value
heading: \' <i>(mobile/desktop)</i> \',
// alternate heading
alt_heading: \' <i>(desktop only)</i> \',
// WP adds <span class="in-widget-title"></span> in each widget heading by default
heading_selector: \'.in-widget-title\'
};
var widgetIdSelector = \'> .widget-inside > form > .widget-id\';
// heading is added as prefix of already existing heading, modify this as needed
function modify_heading( $elm, isMain ) {
var html = $elm.html();
if ( html.indexOf( compare.heading ) == -1 && html.indexOf( compare.alt_heading ) == -1 ) {
if( isMain ) {
$elm.html( compare.heading + html );
}
else {
$elm.html( compare.alt_heading + html );
}
}
};
function parseFieldSelector( widgetId ) {
return \'input[name="\' + widgetIdToFieldPrefix( widgetId ) + \'[\' + compare.field + \']"]\';
};
// @note: change this function if you don\'t want custom Heading change to appear for all the widgets.
// If field variable is empty, then that means that field doesn\'t exist for that widget.
// So use this logic if you don\'t want the custom heading manipulation if the field doesn\'t exist for a widget
function modify_widget( evt, $widget, content ) {
var field = null;
var field_value = \'\';
if( content ) {
field = $( content ).find( parseFieldSelector( $widget.find( widgetIdSelector ).val() ) );
}
else {
field = $widget.find( parseFieldSelector( $widget.find( widgetIdSelector ).val() ) );
}
if( field ) {
field_value = ( ( field.attr( \'type\' ) != \'radio\' && field.attr( \'type\' ) != \'checkbox\' )
|| field.is( \':checked\' ) ) ? field.val() : \'\';
}
modify_heading( $widget.find( compare.heading_selector ), field_value == compare.value );
}
function parseWidgetId( widgetId ) {
var matches, parsed = {
number: null,
id_base: null
};
matches = widgetId.match( /^(.+)-(\\d+)$/ );
if ( matches ) {
parsed.id_base = matches[1];
parsed.number = parseInt( matches[2], 10 );
} else {
parsed.id_base = widgetId;
}
return parsed;
}
function widgetIdToSettingId( widgetId ) {
var parsed = parseWidgetId( widgetId ), settingId;
settingId = \'widget_\' + parsed.id_base;
if ( parsed.number ) {
settingId += \'[\' + parsed.number + \']\';
}
return settingId;
}
function widgetIdToFieldPrefix( widgetId ) {
var parsed = parseWidgetId( widgetId ), settingId;
settingId = \'widget-\' + parsed.id_base;
if ( parsed.number ) {
settingId += \'[\' + parsed.number + \']\';
}
return settingId;
}
var api = wp.customize;
if( api ) {
// We ate in the customizer
widgetIdSelector = \'> .widget-inside > .form > .widget-id\';
api.bind( \'ready\', function() {
function add_widget( evt, $widget ) {
var control;
control = api.control( widgetIdToSettingId( $widget.find( widgetIdSelector ).val() ) );
function updateTitle( evt ) {
modify_widget( null, $widget );
};
if ( control ) {
control.setting.bind( updateTitle );
}
updateTitle();
};
api.control.each( function ( control ) {
if( control.id && 0 === control.id.indexOf( \'widget_\' ) ) {
api.section( control.section.get(), function( section ) {
function onExpanded( isExpanded ) {
if ( isExpanded ) {
section.expanded.unbind( onExpanded );
modify_widget( null, control.container.find( \'.widget\' ), control.params.widget_content );
}
};
if ( section.expanded() ) {
onExpanded( true );
} else {
section.expanded.bind( onExpanded );
}
} );
}
} );
$( document ).on( \'widget-added\', add_widget );
} );
}
else {
// We are in wp-admin -> Appearance -> Widgets
// Use proper condition and CODE if you want to target any page builder
// that doesn\'t use WP Core Widget Markup or Core JavaScript
$( window ).on( \'load\', function() {
$( \'#widgets-right div.widgets-sortables div.widget\' ).each( function() {
modify_widget( \'non-customizer\', $( this ) );
} );
$( document ).on( \'widget-added\', modify_widget );
} );
}
$( document ).on( \'widget-updated\', modify_widget );
})( window.wp, jQuery );
插件用法:
Note: 如果您将
title
小部件的
yes
, 然后,它将在小部件控件UI标题中显示(移动/桌面),所有其他小部件的标题中将显示(仅桌面)。在customizer中,更改将立即进行
wp-admin -> widgets
更改将在您之后显示
save
这些变化。当然,您可以通过修改代码(在JavaScript中)来改变这种行为,从而为不同的
field_name
或者只向一些小部件显示特定的标题,而不是向所有小部件显示。
例如,假设您有一个名为use_mobile
, 当标题设置为时,您要将其设置为(移动/桌面)yes
. 然后设置compare
变量如下:
var compare = {
field: \'use_mobile\',
value: \'yes\',
heading: \' <i>(mobile/desktop)</i> \',
alt_heading: \' <i>(desktop only)</i> \',
heading_selector: \'.in-widget-title\'
};
此外,如果要更改整个标题(而不是
.in-widget-title
), 然后您可以更改
heading_selector
设置以及的正确标记
heading
&;
alt_heading
这样做。这种可能性是无穷无尽的,但如果您想对生成的标记有太多创造性,请确保WordPress核心代码不会产生任何错误。
页面生成器集成:
这些解决方案是否适用于页面生成器将取决于该页面生成器实现。如果它使用WordPress提供的方法加载小部件控件UI,那么它应该在没有任何修改的情况下工作,否则页面生成器也可能会有类似(但经过修改)的含义。