Selective Refresh im Customizer nutzen

Seit WordPress 4.5 gibt es die Möglichkeit, bei einer Änderung im Customizer nur Teile der Vorschau neu zu laden. Damit wird dem Nutzer mindestens das Gefühl gegeben, schneller eine Änderung zu sehen – und in den meisten Fällen wird das nicht nur gefühlt der Fall sein (und außerdem könnte mit dieser Funktion die Customizer-Seite unnötig werden und durch Inline-Bearbeitungsfunktionen ersetzt werden, wie Weston Ruter in seinem Beitrag »Selective Refresh in the Customizer« schreibt). Hier zeige ich euch kurz, wie diese Funktion umgesetzt werden kann.

Einrichtung von Selective Refresh für eine Customizer-Einstellung

Die Einrichtung des Selective-Refresh-Features an sich ist relativ schnell erledigt, wenn ihr bereits eine Customizer-Einstellung angelegt habt. Hier mal ein komplettes Beispiel für eine Customizer-Einstellung aus meinem Photographus-Theme:

/**
 * Create setting for page.
 */
$wp_customize->add_setting( "photographus_panel_{$i}_page", [
	'default'           => false,
	'sanitize_callback' => 'absint',
	'transport'         => 'postMessage',
] );

/**
 * Create control for page.
 */
$wp_customize->add_control( "photographus_panel_{$i}_page", [
	'label'           => __( 'Select page', 'photographus' ),
	'section'         => 'photographus_options',
	'type'            => 'dropdown-pages',
	'allow_addition'  => true,
	'active_callback' => 'photographus_is_page_panel',
	'input_attrs'     => [
		'data-panel-number' => $i,
	],
] );

$wp_customize->selective_refresh->add_partial( "photographus_panel_{$i}_page_partial", [
	'selector'            => "#frontpage-section-$i",
	'settings'            => [
		"photographus_panel_{$i}_page",
	],
	'render_callback'     => 'photographus_the_page_panel',
	'container_inclusive' => true,
] );

Der add_setting()- und add_control()-Teil sollten nichts Neues sein, wenn ihr bereits mit dem Customizer gearbeitet habt. Seit 4.5 ist $wp_customize->selective_refresh->add_partial möglich, dem neben einem eindeutigen Bezeichner als ersten Parameter folgende Werte im Array übergeben werden:

  • Ein HTML-Selektor, der das neuzuladende Element angibt.
  • Ein oder mehrere settings, bei denen der Refresh ausgeführt werden soll.
  • Eine Callback-Funktion, die das neue Markup ausgibt.
  • Die Angabe, dass in unserem Fall auch der Container mit neugeladen werden soll (also #frontpage-section-$i).

Und damit hätten wir die Umsetzung von Selective Refresh bereits geschafft ? Es gibt allerdings eine Besonderheit:

Von JavaScript verändertes Markup in render_callback

Wenn ihr ein Element mit dieser Methode neu ladet, und es etwas enthält, was durch JavaScript verändert wird (zum Beispiel ein Masonry-Grid), dann müsst ihr die entsprechende Funktion bei dem Selective Refresh neu ausführen. Bei meinem Photographus-Theme sieht das Handling so aus:

/**
 * Custom JavaScript functions for the customizer preview.
 *
 * @version 1.0.0
 *
 * @package Photographus
 */
;(function () {
    document.addEventListener('DOMContentLoaded', function () {
        /**
         * Selectice refresh check from https://github.com/xwp/wp-jetpack/blob/feature/selective-refresh-widget-support/modules/widgets/contact-info/contact-info-map.js#L35
         * @type {*}
         */
        hasSelectiveRefresh = (
            'undefined' !== typeof wp &&
            wp.customize &&
            wp.customize.selectiveRefresh &&
            wp.customize.widgetsPreview &&
            wp.customize.widgetsPreview.WidgetPartial
        );
        if (hasSelectiveRefresh) {
            wp.customize.selectiveRefresh.bind('partial-content-rendered', function (placement) {
                buildMasonryGrid(hasSelectiveRefresh);

                addClassToImageLinks();

                fullWidthImages();

                /**
                 * Get the front page panels.
                 * @type {NodeList}
                 */
                var panels = document.querySelectorAll('.frontpage-section');
                /**
                 * Check if we have panels.
                 */
                if (0 !== panels.length) {
                    var panelsWithContent = 0;
                    /**
                     * Loop through them.
                     */
                    for (var i = 0; i < panels.length; i++) {
                        /**
                         * Check if it is a panel placeholder.
                         */
                        if (!panels[i].classList.contains('frontpage-section-placeholder')) {
                            panelsWithContent++;
                        }
                    }
                    /**
                     * Refresh the preview if we have only panel placeholders, so the default homepage is displayed
                     * correctly.
                     *
                     * @link https://make.xwp.co/2015/12/08/implementing-selective-refresh-in-the-customizer/
                     */
                    if (panelsWithContent === 0) {
                        wp.customize.preview.send('refresh');
                    }
                }
            });
        }
    });
})();

Wichtig ist der erste Abschnitt bis einschließlich Zeile 22 – danach könnt ihr dann die Funktionen aufrufen, um das gewünschte Verhalten für das neu geladene Markup zu erreichen.

Das könnte auch interessant sein

2 Kommentare zu »Selective Refresh im Customizer nutzen«

  1. Tim

    Hey Florian, ich hätte eine Frage bezüglich eines Problems, dass ich habe.
    ich habe gerade deine Website entdeckt und war direkt davon überzeugt, dass du der Richtige bist, um dir die folgende Frage zustellen... 🙂

    Ich möchte die Page ID der Page, die gerade im Customizer gepreviewed wird in die $active_page_id Variable schreiben, so dass sich in diesem Fall die Headline und deren Control sowie Setting ändert. Das hätte den Effekt, dass die Headline auf jeder Seite anderes ist.
    Beispiel:

    //Add Headline
          $wp_customize->add_setting('TCarticle-'.$active_page_id.'-headline', array(
            'transport' => 'postMessage',
            'default' => 'Custom Headline',
          ));
          $wp_customize->add_control( new WP_Customize_Control($wp_customize, 'TCarticle-'.$active_page_id.'-headline-control', array(
            'label' => 'Headline',
            'description' => '',
            'section' => 'TCarticle-section',
            'settings' => 'TCarticle-'.$active_page_id.'-headline',
            'input_attrs' => array(
                'maxlength' => 25,
            ),
          )));

    Ich habe einiges probiert, jedoch hat bis jetzt nichts so funktioniert wie ich es mir vorstelle. Ich würde mich freuen wenn du für mein Problem eine Lösung berreit hättest.
    MfG Tim

    Antworten
    1. Florian Brinkmann

      Hi Tim,

      erst mal sorry für die späte Antwort, dein Kommentar ist versehentlich im Spam gelandet …
      Zu deiner Frage: ich verstehe noch nicht ganz, was du erreichen willst. Du möchtest für die aktive Seite immer eine bestimmte Control anzeigen (also du hast für jede Seite Control und Setting und möchtest dann die passende für die entsprechende Seite anzeigen)?

      LG
      Florian

      Antworten

Schreib einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.