最初に、私は明確にしたい - これはCSSの質問ではない。
ウィジェットがwp-admin内、サイドバーまたはページビルダー内でクローズ/オープンモードのときに表示されるデータを変更したい。これはよりよく説明するための画像です。
私は何かを動的に追加したり、ウィジェットのタイトルから削除したりするためにwidget $ instanceを使用したいと思います。
望ましい結果:
mobile/desktop/bothを示す小さな情報ラベルを追加します。これは、その特定のウィジェット内で選択されたオプションです。
誰か考え?
UPDATE
私はこの質問の解決策にいくらか興味があるので:
@ 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を挿入することはできません(または少なくとも私はできませんでした)。
私は実用的な解決策を見つけた場合は更新されるでしょう。
dynamic_sidebar_params
でのフィルタリングがHTML
で機能しない理由は、WordPressが wp_widget_control()
関数のウィジェットの見出しからHTML
を削除するためです。
$widget_title = esc_html( strip_tags( $sidebar_args['widget_name'] ) );
WordPressは wp-admin/js/widgets.js
のデフォルトJavaScriptでHTML
も削除します
そのため、カスタマイズされたソリューションがなければ、PHPまたはJavaScriptを使用して目的を達成するためのデフォルトのフィルターまたはオプションはありません。
wp-admin -> Appearance -> Widgets
でのみ機能し、Customizer -> Widgets
では機能しないカスタムPHPソリューションが可能です。
WordPressはdynamic_sidebar_params
フックで wp_widget_control()
function (ウィジェット制御UIを生成する)を追加するため、このフィルターフックを使用してオーバーライドできます。ただし、カスタマイザーでは、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を使用してこの動作をカスタマイズできます。 WordPressは、とにかくJavaScriptでウィジェットコントロールの見出しを更新します。そのためにWordPressはプレースホルダーin-widget-title
CSSクラスを保持し、JavaScript CODEのウィジェットtitle
フィールド値で更新します。これを操作して目標を達成できます。
まず、WordPressがwp-admin/js/customize-widgets.js
(カスタマイザー)で customize-widgets
ファイル(wp-admin -> Customize -> Widgets
ハンドル付き)をロードし、wp-admin/js/widgets.js
で admin-widgets
ファイル(wp-admin -> Appearance -> Widgets
ハンドル付き)をロードすることを知っておく必要がありますウィジェットコントロールUI。これらの2つのファイルは、ウィジェットUIマークアップとウィジェット見出しUI操作に対して同様の操作を行いますが、多くの異なることも行います。そのため、JavaScriptベースのソリューションではそれを考慮する必要があります。
カスタマイザーは、ページのロード直後にウィジェットUIマークアップをロードせず、代わりに、対応するWidgets -> Sidebar
パネルが開いているときにJavaScriptでロードします。そのため、WordPressが読み込まれた後にウィジェットUIを操作する必要があります。たとえば、カスタマイザーCODEはイベントベースであるため、次の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
adminは、 Save ボタン。これには次のコード行を使用しました。
$( document ).on( 'widget-updated', modify_widget );
wp-admin -> Appearance -> Widgets
に関する考慮事項:カスタマイザーとは異なり、従来のWidgets
adminはWidget Control UIをPHPでロードするため、UI HTMLを走査して次のような初期変更を行いました。
$( '#widgets-right div.widgets-sortables div.widget' ).each( function() { // code } );
以下は、wp-admin -> Appearance -> Widgets
とCustomizer -> Widgets
の両方で機能するJavaScriptベースのソリューションを備えた完全なプラグインです。
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 );
注:ウィジェットの
title
を設定した場合、上記のサンプルプラグインコードをそのまま使用yes
にすると、ウィジェットコントロールUI見出し内に(mobile/desktop)が表示され、他のすべてのウィジェットには(desktopのみ)見出し。カスタマイザでは、変更はすぐに反映され、wp-admin -> widgets
では、変更をsave
後に表示します。もちろん、(JavaScriptで)CODEを変更して別のfield_name
の見出しを変更するか、特定の見出しをすべてのウィジェットではなく一部のウィジェットにのみ表示することで、この動作を変更できます。
たとえば、use_mobile
という名前のフィールドがあり、yes
に設定されているときに見出しを(mobile/desktop)に設定するとします。次に、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
およびheading_selector
の正しいマークアップとともにalt_heading
設定を変更することもできます。可能性は無限にありますが、結果のマークアップで創造的になりたい場合は、WordPressコアCODEでエラーが発生しないようにしてください。
これらのソリューションのいずれかがページビルダーで機能するかどうかは、そのページビルダーの実装に依存します。 WordPressが提供するメソッドを使用してウィジェットコントロールUIをロードする場合、変更せずに動作します。そうしないと、同様の(ただし変更された)意味がページビルダーでも可能になります。
まずadminのウィジェットタイトルに表示される情報を変更できるかどうかを見てみましょう。このリストは 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
も含まれているので、自分がどのウィジェットにいるのかがわかります。ウィジェットデータを取得するために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
に渡すかを選択できます。
WordPressにはすでにウィジェットのUIに組み込まれた同様の機能があります。たとえば、ユーザーが入力した「タイトル」の値がこの検索ウィジェットのタイトルにどのように追加されるかを参照してください。
これを行うコードは wp-admin/js/widgets.js
にあります。
appendTitle : function(widget) {
var title = $('input[id*="-title"]', widget).val() || '';
if ( title ) {
title = ': ' + title.replace(/<[^<>]+>/g, '').replace(/</g, '<').replace(/>/g, '>');
}
$(widget).children('.widget-top').children('.widget-title').children()
.children('.in-widget-title').html(title);
},
ウィジェット内で-title
で終わるinput
属性を持つid
要素を見つけ、その入力に入力された値をウィジェットのタイトルバーのテキストに追加します。
あなたが念頭に置いている設定がinput
フィールドに基づいている場合(type
がtext
であるかradio
であるかにかかわらず)、あなたはそれに-title
で終わるid
を与える必要があるだけです、そしてWordPressは残り。
これにより、ユーザーが設定を変更したときにタイトルバーの文字列が自動的に更新されます。