問題描述
首先,我想澄清一下 – 這不是一個 CSS 問題。
在 wp-admin,邊欄或頁面構建器中處於關閉/打開模式時,我想更改顯示該小工具的數據。這是一個更好的解釋的形象。
我想要能夠動態地添加東西/從 widget 的標題中刪除,並使用 widget $ instance 這樣做
所需的結果:添加一個説明移動/桌面/兩者的小信息標籤 – 這是特定小工具內的選項
想法嗎?
更新由於我在這個問題的解決方案中看到一些 intrest:@cjbj 解決方案精美地工作,只能在側邊欄中,只有部分:
add_filter ('dynamic_sidebar_params','wpse261042_change_widget_title');
function wpse261042_change_widget_title ($params) {
$widget_id = $params[0]['widget_id'];
$widget_instance = strrchr ($widget_id, '-');
$wlen = strlen ($widget_id);
$ilen = strlen ($widget_instance);
$widget_name = substr ($widget_id,0,$wlen-$ilen);
$widget_instance = substr ($widget_instance,1);
// get the data
$widget_instances = get_option('widget_' . $widget_name);
$data = $widget_instances[$widget_instance];
$use_mobile = $data['use_mobile']; // option inside my widget
if($use_mobile == 'yes') {$string = 'desktop / mobile';} else {$string = 'desktop only';}
$params[0]['widget_name'] .= $string;
return $params;
}
但是.. 你不能在該字符串中插入任何 html(或至少我 cannt)
如果我找到一個工作的解決方案將更新。
最佳解決方案
背景:
dynamic_sidebar_params 不能使用 HTML 進行過濾的原因是因為 WordPress 從 wp_widget_control()中的 Widget 標題中剝離 HTML,功能如下:
$widget_title = esc_html( strip_tags( $sidebar_args['widget_name'] ) );
WordPress 還在 wp-admin/js/widgets.js 中默認使用 HTML
所以沒有一個定製的解決方案,沒有默認的過濾器或選項與 PHP 或 JavaScript 來實現你想要的。
自定義 PHP 解決方案:
一個自定義 PHP 解決方案是可行的,只能在 wp-admin -> Appearance -> Widgets 中使用,但不能在 Customizer -> Widgets 中使用。
WordPress 使用 dynamic_sidebar_params 鈎子添加 wp_widget_control()函數 (生成小工具控件 UI),因此可以使用此過濾器鈎子覆蓋它。但是,在定製程序中,WordPress 直接調用 wp_widget_control()功能,因此此解決方案將無法為定製程序生效。
該解決方案的工作原理如下 (在自定義插件中添加此代碼):
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 更新 Widget 控制標題 JavaScript 。要做到這一點 WordPress 保留一個佔位符 in-widget-title CSS 類,並使用小工具 title 字段值從 JavaScript 代碼更新。我們可以操縱這個來實現我們的目標。
相關的核心 JS 文件:
首先,您需要知道 WordPress 在 wp-admin 中加載 wp-admin /js /customize-widgets.js 文件 (使用 customize-widgets 句柄) – > 自定義 – > wp-admin 中的 Widgets(定製程序) 和 wp-admin /js /widgets.js 文件 (帶有 admin-widgets 句柄) – > 外觀 – > 控制窗口小工具控件 UI 。這兩個文件對 Widget UI 標記和 Widget 標題 UI 操作進行類似的操作,但也有很多不同的事情。所以我們需要考慮到我們基於 JavaScript 的解決方案。
定製器的注意事項:
定製器在頁面加載後立即不加載 Widget UI 標記,而是在相應的 Widgets -> Sidebar 面板打開時加載 JavaScript 。所以我們需要在 WordPress 加載後操作 Widget UI 。例如,由於定製程序 CODE 是基於事件的,所以我使用以下代碼行將事件處理程序設置在正確的時刻:
section.expanded.bind( onExpanded );
此外,定製程序使用 AJAX 立即加載更改,這就是為什麼我已經使用以下行來瀏覽數據更改:
control.setting.bind( updateTitle );
此外,我需要使用以下代碼行進入 widget-added 事件:
$( document ).on( 'widget-added', add_widget );
普通用户 wp-admin -> Appearance -> Widgets:
當更新小工具時,上述 JavaScript 文件都會觸發 widget-updated 事件。儘管自定義程序立即使用 AJAX,但傳統的 Widget 管理員在您點擊 Save 按鈕後即可執行此操作。我使用以下代碼行代碼:
$( document ).on( 'widget-updated', modify_widget );
wp-admin -> Appearance -> Widgets 的注意事項:
與定製器相反,傳統的 Widgets 管理員用 PHP 加載 Widget 控制界面,所以我已經遍歷了 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: With the above sample Plugin CODE as it is, if you set the
titleof a Widget toyes, then it’ll show (mobile/desktop) within the Widget Control UI heading, all the other Widget’s will have (desktop only) in the Heading. In the customizer the change will be immediate, inwp-admin -> widgetsthe change will show after yousavethe changes. Of course you can change this behaviour by modifying the CODE (in JavaScript) to do the heading change for a differentfield_nameor to only show that specific heading to some widgets and not to all of them.
例如,假設您有一個名為 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 提供的方法來加載 Widget Control UI,那麼它應該沒有任何修改,否則類似 (但修改) 的含義也可能是頁面構建器。
次佳解決方案
首先看看是否可以更改管理員中小工具標題中顯示的信息。該列表由 wp_list_widget_controls 生成,wp_list_widget_controls 調用 dynamic_sidebar,其中包含一個過濾器 dynamic_sidebar_params 來更改控件中的參數,包括標題。我們來試試:
add_filter ('dynamic_sidebar_params','wpse261042_change_widget_title');
function wpse261042_change_widget_title ($params) {
$string = ' Added info';
$params[0]['widget_name'] .= $string;
return $params;
}
$string 不完全在你所指的地方,但我會説這是足夠好的。
現在,我們需要用 $string 替換當前小工具內部的一些信息。幸運的是,我們知道我們在哪個小工具,因為 $params 還包含 widget_id 。我將 refer to this answer 解釋如何使用 widget_id 來檢索窗口小工具數據。開始了:
// we need to separate the widget name and instance from the id
$widget_id = $params[0]['widget_id'];
$widget_instance = strrchr ($widget_id, '-');
$wlen = strlen ($widget_id);
$ilen = strlen ($widget_instance);
$widget_name = substr ($widget_id,0,$wlen-$ilen);
$widget_instance = substr ($widget_instance,1);
// get the data
$widget_instances = get_option('widget_' . $widget_name);
$data = $widget_instances[$widget_instance];
現在,數組 $data 包含窗口小工具的實例,您可以選擇要傳遞給 $string 的函數。
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。
