Premièrement, je veux clarifier - ce n’est pas une question CSS.
Je souhaite modifier les données affichées du widget en mode fermé/ouvert dans l'admin wp-admin, dans une barre latérale ou un générateur de page. Voici une image à mieux expliquer.
Je veux pouvoir ajouter quelque chose/supprimer du titre du widget de manière dynamique et utiliser le widget $ instance pour le faire
Le résultat souhaité:
Ajouter une petite étiquette d’information indiquant mobile/desktop/les deux - option choisie dans le widget spécifique.
Des idées n'importe qui?
METTRE À JOUR
Depuis que je vois quelque intrest dans une solution à cette question:
@ cjbj solution fonctionne à merveille mais uniquement dans l'encadré et seulement partiellement:
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;
}
Cependant .. vous ne pouvez pas insérer de code HTML dans cette chaîne (ou au moins je ne pourrais pas)
Mettrait à jour si je trouve une solution de travail.
La raison pour laquelle le filtrage avec dynamic_sidebar_params
ne fonctionne pas avec HTML
est que WordPress supprime HTML
de l'en-tête du widget dans wp_widget_control()
fonctionne comme suit:
$widget_title = esc_html( strip_tags( $sidebar_args['widget_name'] ) );
WordPress supprime également HTML
dans JavaScript par défaut dans wp-admin/js/widgets.js
Donc, sans solution personnalisée, il n'y a pas de filtre ou d'option par défaut, ni avec PHP ni avec JavaScript pour obtenir ce que vous voulez.
Une solution personnalisée PHP est possible et ne fonctionnera que dans wp-admin -> Appearance -> Widgets
, mais pas dans Customizer -> Widgets
.
WordPress ajoute fonction wp_widget_control()
(qui génère une interface utilisateur de contrôle de widget) avec un hook dynamic_sidebar_params
; il est donc possible de le remplacer à l'aide de ce hook de filtre. Toutefois, dans le programme de personnalisation, WordPress appelle directement fonction wp_widget_control()
, cette solution ne fonctionnera donc pas pour le programme de personnalisation.
La solution fonctionne comme suit (ajoutez ce code dans un plugin personnalisé):
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
}
Comme je l'ai déjà dit, cette solution ne fonctionne pas pour le personnalisateur et a plus de chances de nécessiter de futures mises à jour car nous remplaçons une fonction principale.
Heureusement, il est possible de personnaliser ce comportement avec JavaScript. WordPress met quand même à jour le cap du contrôle de widget avec JavaScript. Pour ce faire, WordPress conserve une classe CSS in-widget-title
et remplace celle-ci avec la valeur du champ widget title
à partir de JavaScript CODE. Nous pouvons manipuler cela pour atteindre notre objectif.
Vous devez d’abord savoir que WordPress charge wp-admin/js/customize-widgets.js
fichier (avec customize-widgets
handle) dans wp-admin -> Customize -> Widgets
(personnalisateur) et wp-admin/js/widgets.js
fichier (avec admin-widgets
handle) dans wp-admin -> Appearance -> Widgets
pour manipuler l’UI de contrôle de widget. Ces deux fichiers effectuent des opérations similaires pour les annotations d'interface utilisateur de widget et la manipulation d'interface utilisateur d'en-tête de widget, mais également dans de nombreux domaines différents. Nous devons donc en tenir compte pour notre solution basée sur JavaScript.
Le personnaliseur ne charge pas le balisage de l'interface utilisateur du widget immédiatement après le chargement de la page. Il se charge plutôt avec JavaScript lorsque le panneau Widgets -> Sidebar
correspondant est ouvert. Nous devons donc manipuler l'interface utilisateur du widget après le chargement de WordPress. Par exemple, comme le personnalisateur CODE est basé sur les événements, j'ai utilisé la ligne suivante de CODE pour définir le gestionnaire d'événements au bon moment:
section.expanded.bind( onExpanded );
En outre, le personnalisateur a utilisé AJAX pour charger les modifications immédiatement. C'est pourquoi j'ai utilisé la ligne suivante pour puiser dans la modification des données:
control.setting.bind( updateTitle );
De plus, je devais faire appel à l'événement widget-added
avec la ligne suivante de CODE:
$( document ).on( 'widget-added', add_widget );
wp-admin -> Appearance -> Widgets
:Les deux fichiers JavaScript mentionnés ci-dessus déclenchent l'événement widget-updated
lors de la mise à jour d'un widget. Bien que le personnalisateur le fasse immédiatement avec AJAX, alors que l’administrateur Widget
traditionnel le fait après avoir cliqué sur Save bouton. J'ai utilisé la ligne suivante de CODE pour cela:
$( document ).on( 'widget-updated', modify_widget );
wp-admin -> Appearance -> Widgets
:Contrairement à l'outil de personnalisation, l'administrateur Widgets
traditionnel charge l'interface utilisateur du contrôle des widgets avec PHP. J'ai donc parcouru le code HTML de l'interface utilisateur pour apporter les modifications initiales suivantes:
$( '#widgets-right div.widgets-sortables div.widget' ).each( function() { // code } );
Voici un plugin complet avec une solution basée sur JavaScript qui fonctionnera à la fois dans wp-admin -> Appearance -> Widgets
et Customizer -> Widgets
:
wpse-widget-control.php
Plugin PHP fichier:
<?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
fichier 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 );
Remarque: Avec l'exemple de code de plugin ci-dessus tel quel, si vous définissez le
title
d'un widgetyes
name__, alors il affichera (mobile/desktop) dans l'en-tête de l'interface utilisateur du contrôle de widget, tous les autres widgets auront (desktop uniquement) dans la rubrique. Dans le personnalisateur, les modifications seront immédiates. Danswp-admin -> widgets
, les modifications apparaîtront après que vous aurez modifiésave
name__. Bien sûr, vous pouvez modifier ce comportement en modifiant le CODE (en JavaScript) afin de modifier le titre pour unfield_name
différent ou d'afficher uniquement ce titre spécifique pour certains widgets et non pour tous.
Par exemple, supposons que vous ayez un champ nommé use_mobile
et que vous souhaitez définir l'en-tête sur (mobile/desktop) lorsqu'il est défini sur yes
name__. Puis définissez la variable compare
à quelque chose comme:
var compare = {
field: 'use_mobile',
value: 'yes',
heading: ' <i>(mobile/desktop)</i> ',
alt_heading: ' <i>(desktop only)</i> ',
heading_selector: '.in-widget-title'
};
De même, si vous souhaitez modifier l'en-tête entier (au lieu de .in-widget-title
), vous pouvez modifier le paramètre heading_selector
ainsi que le balisage approprié pour heading
& alt_heading
. Les possibilités sont infinies, mais assurez-vous que WordPress Core CODE ne génère aucune erreur si vous voulez être trop créatif avec le balisage résultant.
Le fait que l'une ou l'autre de ces solutions fonctionne ou non pour un générateur de page dépend de son implémentation. S'il utilise les méthodes fournies par WordPress pour charger l'interface utilisateur de Widget Control, il devrait fonctionner sans aucune modification. Dans le cas contraire, une implication similaire (mais modifiée) pourrait également être possible pour les constructeurs de page.
Voyons d'abord s'il est possible de changer les informations affichées dans les titres de widgets dans admin. Cette liste est générée par wp_list_widget_controls
, qui appelle dynamic_sidebar
, qui contient un filtre dynamic_sidebar_params
pour modifier les paramètres des contrôles, y compris le titre. Essayons ça:
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;
}
Le $string
ne se trouve pas exactement à l'endroit où vous vous dirigez, mais je dirais que c'est suffisant.
Maintenant, nous devons remplacer $string
par des informations provenant du widget en cours. Heureusement, nous connaissons le widget dans lequel nous nous trouvons, car $params
contient également le widget_id
. Je vais référez-vous à cette réponse pour une explication de la façon dont vous utilisez le widget_id
pour récupérer les données du widget. Et c'est parti:
// 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];
Maintenant, le tableau $data
contient les instances du widget et vous pouvez choisir celle que vous voulez transmettre à $string
dans la fonction.
WordPress a déjà une fonctionnalité similaire intégrée dans l'interface utilisateur des widgets. Voyez par exemple comment la valeur "Titre" saisie par l'utilisateur est ajoutée au titre de ce widget de recherche:
Le code qui fait cela se trouve dans 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);
},
Il trouve l'élément input
dans un widget doté d'un attribut id
se terminant par -title
et ajoute la valeur entrée dans cette entrée au texte de la barre de titre du widget.
Donc, si le paramètre que vous avez à l’esprit est basé sur un champ input
(peu importe si type
est text
ou radio
, etc.), il vous suffit de lui attribuer une id
se terminant par -title
, et WordPress se chargera du du repos.
Et de cette façon, la chaîne dans la barre de titre sera automatiquement mise à jour lorsque l'utilisateur modifiera le paramètre.