Wykorzystanie kontekstu w ekranie personalizacji motywu

Obsługa kontekstu dla kontrolek to moim zdaniem najważniejsze udogodnienie dodane w ekranie personalizacji motywu w WordPressie 4.0. Dzięki niej można znacząco ograniczyć ilość kontrolek widocznych na danej podstronie oraz tworzyć dodatkowe zależności pomiędzy poszczególnymi opcjami.

Ważne cechy kontekstu

Z kontekstem wiążą się dwie ważne cechy:

  1. Jest określany tylko dla kontrolek
  2. Widoczność kontrolek oddolnie wpływa na widoczność sekcji oraz paneli

Zatem nie możemy określić kontekstu dla konkretnej sekcji, ale możemy sprawić, że dana sekcja zniknie poprzez ukrycie wszystkich jej opcji.

Jak dodać kontekst dla kontrolki?

Kontekst dla kontrolki dodajemy poprzez określenie parametru active_callback w trakcie jej tworzenia:

$wp_customizer->add_control(
  'setting_name',
  array(
    'type' => 'text',
    'section' => 'section_name',
    'label' => 'Option with context',
    'active_callback' => 'is_front_page'
  )
);

W powyższym przykładzie nasza kontrolka pojawi się tylko wtedy, gdy w podglądzie będzie wyświetlana strona główna naszej witryny. Wszystko to dzięki wykorzystaniu natywnej funkcji is_front_page.

Dodatkowo, jeżeli jest to jedyna kontrolka w danej sekcji to sekcja ta będzie niewidoczna gdy w podglądzie będzie wyświetlana strona inna niż strona główna.

Własne funkcje określające kontekst

Oczywiście nie jesteśmy skazani wyłącznie na natywne funkcje WordPressa i możemy tworzyć własne funkcje kontekstu – na przykład funkcję, która wykryje czy wyświetlana jest podstrona z szablonem galerii:

function mytheme_is_gallery_page() {
   return is_page_template('template.gallery.php');
}

Przy tworzeniu kontrolki możemy dodać ją tak samo jak funkcję is_front_page:

$wp_customizer->add_control(
  'setting_name',
  array(
    'type' => 'text',
    'section' => 'section_name',
    'label' => 'Option with context',
    'active_callback' => 'mytheme_is_gallery_page'
  )
);

Tworzenie opcji zależnych

Kontekst dla kontrolek jest aktualizowany przy zmianach na stronie i zmianach jej opcji – dzięki temu możemy wyświetlać kontrolki bazując na aktualnych ustawieniach innych kontrolek.

Tworzenie takich zależności wymaga pewnej wiedzy o strukturze ekranu personalizacji i zależnościach zachodzącymi pomiędzy jego klasami.

Poniżej prezentuję funkcję, która na bazie wartości opcji określającej krój pisma na stronie, wyświetli dodatkowe pole na URL fonta z usługi Google Fonts w momencie, gdy użytkownik ustawi jako krój pisma wartość “google”:

function mytheme_show_font_field($control) {
    $option = $control->manager->get_setting('mytheme_font');

    return $option->value() == 'google';
}

Całość działa dzięki temu, że do każdej funkcji obsługującej kontekst przekazywany jest uchwyt do kontrolki, której kontekst ma dotyczyć. Mając obiekt kontrolki możemy odwołać się do menedżera ekranu personalizacji (właściwość manager), który z kolei daje nam możliwość odczytania aktualnych ustawień metodą get_setting.

Potem wystarczy już tylko dla obiektu ustawienia wywołać metodę value aby uzyskać dostęp do obecnej wartości interesującej nas opcji.

Dzięki temu mechanizmowi możemy tworzyć bardzo złożone relacje pomiędzy opcjami, a przede wszystkim możemy ukryć niektóre, często niepotrzebne pola konfiguracyjne.

Jak wykorzystać kontekst?

Głównym zadaniem kontekstu jest oczywiście dostosowanie zawartości panelu opcji do aktualnej podstrony w podglądzie.

Garść ciekawych pomysłów na wykorzystanie kontekstu poniżej:

  • Nie musimy tworzyć złożonych kontrolek łączących cechy kilku standardowych kontrolek – wystarczy stworzyć pomiędzy nimi powiązania poprzez kontekst.
  • Możemy stworzyć jedną sekcję z opcjami dla szablonów podstron naszego motywu i pokazywać w niej opcje dostosowane do danej podstrony – oczywiście na innych stronach taka sekcja będzie zupełnie niewidoczna.
  • Możliwe jest rozszerzenie poprzedniego pomysły o podstrony wpisów, kategorii, tagów etc.
  • Możemy stworzyć wtyczki, które dodają do ekranu personalizacji motywu opcje tylko na określonych podstronach.
  • Z użyciem kontekstu możemy sprawdzić poprzez odczyt wartości określonych ustawień czy aktywne są inne wtyczki/ustawienia potrzebne do działania naszej opcji.

Kontekst we własnych kontrolkach

Na koniec w ramach ciekawostki – warto wiedzieć, że tworząc własną kontrolkę możemy też od razu zdefiniować jej domyślną funkcję kontekstu. Bazowa funkcja kontekstu wygląda następująco:

public function active_callback() {
   return true;
}

Wystarczy ją nadpisać w klasie naszej kontrolki. Może się to przydać np. w sytuacji gdy dana kontrolka potrzebuje do poprawnego działania np. dodatkowej wtyczki.

Podsumowanie

Kontekst to niesamowite udogodnienie oraz kolejny element, który sprawia, że tworzenie własnych paneli z opcjami motywu staje się coraz mniej potrzebne.

Share on Facebook3Tweet about this on TwitterShare on Google+0Email this to someonePrint this page
  • Kasia Świderska

    Dziudek, coś mi ten kontekst nie działa. Dałam is_single i sekcja mi zniknęła, ale też się na samym wpisie nie pojawiła. Więc to nie bangla. Co mogę robić źle?

    • Kasiu, sorry za opóźnienie w odpowiedzi ale jak mówi pradawne przysłowie programistyczne „Nie kodź w święta – bug się rodzi” – stąd odpoczywałem 🙂

      Odnośnie Twojego problemu – jedyne co mi przychodzi do głowy to brak kontrolek w sekcji, ale z drugiej strony piszesz „dałam is_single i sekcja mi zniknęła” co sugeruje, że jakieś kontrolki w sekcji wcześniej miałaś.

      W motywie 2015 zmodyfikowałem kod akcji customize_register na szybko:

      function twentyfifteen_customize_register( $wp_customize ) {
      $color_scheme = twentyfifteen_get_color_scheme();

      $wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
      $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';

      // Add color scheme setting and control.
      $wp_customize->add_setting( 'color_scheme', array(
      'default' => 'default',
      'sanitize_callback' => 'twentyfifteen_sanitize_color_scheme',
      'transport' => 'postMessage',
      ) );

      $wp_customize->add_control( 'color_scheme', array(
      'label' => __( 'Base Color Scheme', 'twentyfifteen' ),
      'section' => 'colors',
      'type' => 'select',
      'choices' => twentyfifteen_get_color_scheme_choices(),
      'priority' => 1,
      ) );

      // Add custom header and sidebar text color setting and control.
      $wp_customize->add_setting( 'sidebar_textcolor', array(
      'default' => $color_scheme[4],
      'sanitize_callback' => 'sanitize_hex_color',
      'transport' => 'postMessage',
      ) );

      $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'sidebar_textcolor', array(
      'label' => __( 'Header and Sidebar Text Color', 'twentyfifteen' ),
      'description' => __( 'Applied to the header on small screens and the sidebar on wide screens.', 'twentyfifteen' ),
      'section' => 'colors',
      ) ) );

      // Remove the core header textcolor control, as it shares the sidebar text color.
      $wp_customize->remove_control( 'header_textcolor' );

      // Add custom header and sidebar background color setting and control.
      $wp_customize->add_setting( 'header_background_color', array(
      'default' => $color_scheme[1],
      'sanitize_callback' => 'sanitize_hex_color',
      'transport' => 'postMessage',
      ) );

      $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'header_background_color', array(
      'label' => __( 'Header and Sidebar Background Color', 'twentyfifteen' ),
      'description' => __( 'Applied to the header on small screens and the sidebar on wide screens.', 'twentyfifteen' ),
      'section' => 'test',
      ) ) );

      // Add an additional description to the header image section.
      $wp_customize->get_section( 'header_image' )->description = __( 'Applied to the header on small screens and the sidebar on wide screens.', 'twentyfifteen' );
      $wp_customize->add_section('test', array(
      'title' => 'Test',
      'description' => 'Test description',
      'active_callback' => 'is_single'
      ));
      }
      add_action( 'customize_register', 'twentyfifteen_customize_register', 11 );

      i mi osobiście to działa poprawnie – sekcja „Test” pojawia się dopiero na podglądzie wpisu.

      • Kasia Świderska

        OK. W przykładzie w komentarzu dałeś active_callback w $wp_customize->add_section, a we wpisie umieściłeś w
        $wp_customizer->add_control – tak też się tym sugerowałam i to mi nie zadziałało. No a dodanie do sekcji sprawia, że działa tak jak trzeba.

        • No to Kasiu coś chyba masz namieszane w kodzie, bo poniżej masz przykład, gdzie wrzuciłem active_callback do kontrolki:

          function twentyfifteen_customize_register( $wp_customize ) {
          $color_scheme = twentyfifteen_get_color_scheme();

          $wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
          $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';

          // Add color scheme setting and control.
          $wp_customize->add_setting( 'color_scheme', array(
          'default' => 'default',
          'sanitize_callback' => 'twentyfifteen_sanitize_color_scheme',
          'transport' => 'postMessage',
          ) );

          $wp_customize->add_control( 'color_scheme', array(
          'label' => __( 'Base Color Scheme', 'twentyfifteen' ),
          'section' => 'colors',
          'type' => 'select',
          'choices' => twentyfifteen_get_color_scheme_choices(),
          'priority' => 1,
          ) );

          // Add custom header and sidebar text color setting and control.
          $wp_customize->add_setting( 'sidebar_textcolor', array(
          'default' => $color_scheme[4],
          'sanitize_callback' => 'sanitize_hex_color',
          'transport' => 'postMessage',
          ) );

          $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'sidebar_textcolor', array(
          'label' => __( 'Header and Sidebar Text Color', 'twentyfifteen' ),
          'description' => __( 'Applied to the header on small screens and the sidebar on wide screens.', 'twentyfifteen' ),
          'section' => 'colors',
          ) ) );

          // Remove the core header textcolor control, as it shares the sidebar text color.
          $wp_customize->remove_control( 'header_textcolor' );

          // Add custom header and sidebar background color setting and control.
          $wp_customize->add_setting( 'header_background_color', array(
          'default' => $color_scheme[1],
          'sanitize_callback' => 'sanitize_hex_color',
          'transport' => 'postMessage',
          ) );

          $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'header_background_color', array(
          'label' => __( 'Header and Sidebar Background Color', 'twentyfifteen' ),
          'description' => __( 'Applied to the header on small screens and the sidebar on wide screens.', 'twentyfifteen' ),
          'section' => 'test',
          'active_callback' => 'is_single'
          ) ) );

          // Add an additional description to the header image section.
          $wp_customize->get_section( 'header_image' )->description = __( 'Applied to the header on small screens and the sidebar on wide screens.', 'twentyfifteen' );
          $wp_customize->add_section('test', array(
          'title' => 'Test',
          'description' => 'Test description'
          ));
          }

          • Kasia Świderska

            Wygląda na to, że tak. Wrzuciłam swój kod do zupełnie innego motywu i przetestowałam z dodaniem do kontrolki i sekcji, dla obu zadziałało tak jak trzeba. Czyli coś co jest poza customizerem może mi to psuć. Dzięki za pomoc.