it-swarm.com.de

Beeinflussen der Informationen, die in wp-admin auf dem Widget angezeigt werden

Zunächst möchte ich - klarstellen, dies ist keine CSS-Frage.

Ich möchte die angezeigten Daten des Widgets im geschlossenen/geöffneten Modus innerhalb von wp-admin in einer Seitenleiste oder einem Seitenersteller ändern. Hier ist ein Bild zur besseren Erklärung.

 enter image description here 

Ich möchte in der Lage sein, dem Titel des Widgets dynamisch etwas hinzuzufügen/daraus zu entfernen, und verwende dazu die $ instance des Widgets

Das gewünschte Ergebnis:
Fügen Sie ein kleines Info-Label hinzu, in dem Mobile/Desktop/Both steht - eine Option, die in diesem speziellen Widget ausgewählt wurde

Ideen jemand?

UPDATE
Da ich eine interessante Antwort auf diese Frage sehe:
@ cjbj Lösung funktioniert wunderbar, aber nur in der Seitenleiste und nur teilweise:

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;
}

Sie können jedoch keine HTML in diese Zeichenfolge einfügen (oder zumindest konnte ich nicht)

Würde aktualisieren, wenn ich eine funktionierende Lösung finde.

6
Sagive SEO

Hintergrund:

Der Grund, warum das Filtern mit dynamic_sidebar_params nicht mit HTML funktioniert, ist, dass WordPress HTML aus dem Widget entfernt. Überschrift in wp_widget_control() Funktion wie folgt:

$widget_title = esc_html( strip_tags( $sidebar_args['widget_name'] ) );

WordPress entfernt auch HTML in Standard-JavaScript in wp-admin/js/widgets.js

Ohne eine angepasste Lösung gibt es also weder mit PHP noch mit JavaScript einen Standardfilter oder eine Standardoption, um die gewünschten Ergebnisse zu erzielen.

Benutzerdefinierte PHP Lösung:

Eine benutzerdefinierte PHP Lösung ist möglich, die nur in wp-admin -> Appearance -> Widgets, nicht jedoch in Customizer -> Widgets funktioniert.

WordPress fügt wp_widget_control() function (das Widget Control UI generiert) mit dynamic_sidebar_params hook hinzu, so dass es möglich ist, es mit diesem Filter-Hook zu überschreiben. Im Customizer ruft WordPress jedoch wp_widget_control() function direkt auf, sodass diese Lösung für den Customizer nicht funktioniert.

Die Lösung funktioniert wie folgt (fügen Sie diesen Code in ein benutzerdefiniertes Plugin ein):

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 
} 

Wie ich bereits sagte, funktioniert diese Lösung nicht für den Customizer und erfordert mit größerer Wahrscheinlichkeit zukünftige Updates, da wir eine Kernfunktion überschreiben.

Benutzerdefinierte JavaScript-Lösung (empfohlen):

Glücklicherweise ist es möglich, dieses Verhalten mit JavaScript anzupassen. WordPress aktualisiert Widget Control Heading trotzdem mit JavaScript. Dazu behält WordPress einen Platzhalter der CSS-Klasse in-widget-title bei und aktualisiert ihn mit dem Widget-Feldwert title aus JavaScript CODE. Wir können dies manipulieren, um unser Ziel zu erreichen.

Verwandte Core JS-Dateien:

Zuerst müssen Sie wissen, dass WordPress wp-admin/js/customize-widgets.js Datei (mit customize-widgets Handle) in wp-admin -> Customize -> Widgets (Customizer) und wp-admin/js/widgets.js Datei (mit admin-widgets Handle) in wp-admin -> Appearance -> Widgets lädt, um die Widget Control-Benutzeroberfläche zu manipulieren. Diese beiden Dateien führen ähnliche Vorgänge für Widget-UI-Markups und die Widget-Überschriften-UI-Manipulation aus, aber auch viele andere Vorgänge. Das müssen wir für unsere JavaScript-basierte Lösung berücksichtigen.

Überlegungen zum Customizer:

Der Customizer lädt das Widget-UI-Markup nicht unmittelbar nach dem Laden der Seite, sondern mit JavaScript, wenn das entsprechende Widgets -> Sidebar-Bedienfeld geöffnet ist. Daher müssen wir die Widget-Benutzeroberfläche nach dem Laden durch WordPress bearbeiten. Da der Customizer-CODE beispielsweise ereignisbasiert ist, habe ich die folgende CODE-Zeile verwendet, um den Ereignishandler zum richtigen Zeitpunkt festzulegen:

section.expanded.bind( onExpanded );

Außerdem hat der Customizer AJAX verwendet, um Änderungen sofort zu laden. Deshalb habe ich die folgende Zeile verwendet, um die Datenänderung anzuzapfen:

control.setting.bind( updateTitle );

Außerdem musste ich mit der folgenden CODE-Zeile auf widget-added event tippen:

$( document ).on( 'widget-added', add_widget );

Common for Customizer & wp-admin -> Appearance -> Widgets:

Beide oben genannten JavaScript-Dateien lösen das Ereignis widget-updated aus, wenn ein Widget aktualisiert wird. Der Customizer erledigt dies zwar sofort mit AJAX, während der traditionelle Administrator Widget dies nach dem Klicken auf tut Save Taste. Ich habe die folgende CODE-Zeile verwendet:

$( document ).on( 'widget-updated', modify_widget );

Überlegungen zu wp-admin -> Appearance -> Widgets:

Im Gegensatz zum Customizer lädt der traditionelle Administrator von Widgets die Widget Control-Benutzeroberfläche mit PHP. Daher habe ich den HTML-Code der Benutzeroberfläche durchlaufen, um die ersten Änderungen wie folgt vorzunehmen:

$( '#widgets-right div.widgets-sortables div.widget' ).each( function() { // code } ); 

Benutzerdefinierter Plugin-Code:

Es folgt ein vollständiges Plugin mit einer JavaScript-basierten Lösung, die sowohl in wp-admin -> Appearance -> Widgets als auch in Customizer -> Widgets funktioniert:

wpse-widget-control.php Plugin PHP Datei:

<?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-Datei:

(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 );

Plugin-Verwendung:

Hinweis: Mit dem obigen Beispiel-Plugin-CODE, wie es ist, wenn Sie title eines Widgets festlegen Wenn Sie yes wählen, wird (Mobil/Desktop) in der Überschrift der Widget-Steueroberfläche angezeigt. Alle anderen Widgets haben (nur Desktop) in der Überschrift. Im Customizer wird die Änderung sofort wirksam. In wp-admin -> widgets wird die Änderung angezeigt, nachdem Sie save die Änderungen vorgenommen haben. Natürlich können Sie dieses Verhalten ändern, indem Sie den CODE (in JavaScript) so ändern, dass die Überschriften für einen anderen field_name geändert werden oder nur diese bestimmte Überschrift für einige Widgets und nicht für alle von ihnen angezeigt wird.

Angenommen, Sie haben ein Feld mit dem Namen use_mobile und möchten die Überschrift auf (Mobil/Desktop) setzen, wenn sie auf yes gesetzt ist. Dann setzen Sie die Variable compare auf etwas wie:

var compare = {
    field: 'use_mobile',
    value: 'yes',
    heading: ' <i>(mobile/desktop)</i> ',
    alt_heading: ' <i>(desktop only)</i> ',
    heading_selector: '.in-widget-title'
};

Wenn Sie außerdem die gesamte Überschrift ändern möchten (anstelle von nur .in-widget-title), können Sie die Einstellung heading_selector zusammen mit dem korrekten Markup für heading & alt_heading ändern, um dies zu tun. Die Möglichkeiten sind endlos, aber stellen Sie sicher, dass WordPress-Kern-CODE keine Fehler erzeugt, wenn Sie mit dem resultierenden Markup zu kreativ sein möchten.

Page Builder-Integration:

Ob eine dieser Lösungen für einen Page Builder funktioniert oder nicht, hängt von der Implementierung des Page Builders ab. Wenn es die von WordPress bereitgestellten Methoden zum Laden der Widget Control-Benutzeroberfläche verwendet, sollte es ohne Änderungen funktionieren.

4
Fayaz

Lassen Sie uns zunächst prüfen, ob es möglich ist, die in den Widget-Titeln in admin angezeigten Informationen zu ändern. Diese Liste wird von wp_list_widget_controls generiert, das dynamic_sidebar aufruft, das einen Filter enthält dynamic_sidebar_params , um die Parameter in den Steuerelementen einschließlich des Titels zu ändern. Lass es uns versuchen:

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;
  }

Der $string befindet sich nicht genau an der Stelle, auf die Sie zeigen, aber ich würde sagen, er ist gut genug.

Jetzt müssen wir $string durch einige Informationen aus dem aktuellen Widget ersetzen. Zum Glück wissen wir, in welchem ​​Widget wir uns befinden, da $params auch den widget_id enthält. Ich beziehe mich auf diese Antwort für eine Erklärung, wie Sie den widget_id verwenden, um Widget-Daten abzurufen. Auf geht's:

 // 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];

Jetzt enthält das Array $data die Instanzen des Widgets und Sie können auswählen, welche Sie in der Funktion an $string übergeben möchten.

3
cjbj

In WordPress ist bereits eine ähnliche Funktion in die Widgets-Benutzeroberfläche integriert. Sehen Sie sich zum Beispiel an, wie der vom Benutzer eingegebene "Titel" -Wert an den Titel dieses Such-Widgets angehängt wird:

 Search widget with title appended 

Der Code, der dies tut, befindet sich in wp-admin/js/widgets.js :

appendTitle : function(widget) {
    var title = $('input[id*="-title"]', widget).val() || '';

    if ( title ) {
        title = ': ' + title.replace(/<[^<>]+>/g, '').replace(/</g, '&lt;').replace(/>/g, '&gt;');
    }

    $(widget).children('.widget-top').children('.widget-title').children()
            .children('.in-widget-title').html(title);

},

Es findet das Element input in einem Widget, dessen Attribut id mit -title endet, und fügt den in dieser Eingabe eingegebenen Wert an den Text in der Widget-Titelleiste an.

Wenn die Einstellung, an die Sie denken, auf einem input-Feld basiert (egal ob die type eine text oder eine radio usw. ist), müssen Sie ihr nur eine id geben, die mit -title endet, und WordPress übernimmt das sich ausruhen.

Auf diese Weise wird die Zeichenfolge in der Titelleiste automatisch aktualisiert, wenn der Benutzer die Einstellung ändert.

1
J.D.