Tworzymy własne menu w panelu administracyjnym – czyli korzystanie z Settings API

Co nam będzie potrzebne:

  • szablon wordpressa,
  • podstawowa znajomość php,
  • pomysł na elementy menu
  • i trochę cierpliwości

Wprowadzenie

Na początek tworzymy sobie plik, w którym będzie kod odpowiedzialny za tworzone menu oraz obsługę formularzy nazywamy go dowolnie. Ja nazwałem go theme-options.php i tą nazwą będę się posługiwał w dalszej części artykułu. Skoro mamy już utworzony plik należy go dołączyć do naszego pliku functions.php jeżeli go nie posiadamy należy go koniecznie stworzyć. Oczywiście nie ma przymusu tworzenia oddzielnego pliku i cały kod można pisać w pliku functions.php; ale w ten sposób zostanie zachowany porządek w plikach i będzie dużo łatwiej później edytować dane fragmenty.

if(is_admin()){	
    require_once('theme-options.php');
}

Powyższy kod dołącza plik z tworzonym menu tylko jeżeli jest zalogowany administrator. Proste zabezpieczenie żeby nikt po za nim nie miał dostępu do zaawansowanych opcji. Powyższy fragment należy umieścić w pliku functions.php.

Krok 1: Tworzenie i inicjalizacja wartości domyślnych

W celu utworzenia wartości domyślnych należy utworzyć tablicę z nazwami opcji oraz ich domyślnymi wartościami. Ja tablicę umieściłem w funkcji, która ją będzie zwracać.

function my_theme_default_options () {
     $options = array(
          'logo' => '',
          'search' => false,
          'footer_credit' => false);
     return $options;
}

W ten sposób zostały utworzone trzy opcje, które są odpowiedzialne za zmianę logo oraz pozwalają zadecydować czy będzie wyświetlane pole szukaj oraz informacje o autorze w stopce szablonu.

Teraz należy dodać je do bazy w tym celu tworzymy prostą funkcję.

function my_theme_options_init() {
     global $my_theme_options;
     $my_theme_options = get_option('my_theme_options');
     if ( false === $my_theme_options ) {
          $my_theme_options = my_theme_default_options ();
     }
     update_option('my_theme_options',$my_theme_options);
}

Funkcja najpierw pobiera ustawienia i sprawdza czy istnieją jeżeli ich nie ma to zostają wczytane z uprzednio utworzonej funkcji a następnie zaktualizowane za pomocą update_option. Teraz musimy posłużyć się „hakami” wordpressa i dodać inicjalizację opcji.

add_action('after_setup_theme','my_theme_options_init',9);

Po więcej infromacji na temat „haków” odsyłam do Codexa

Krok 2: Ustawianie parametrów strony z menu

Opcje zostały już zaincjalizowane i będziemy mogli się nimi posługiwać w dalszej części. Teraz należy ustawić parametry dodwanej strony oraz podpiąć ją do istniejącego w panelu menu. Cały kod musimy umieścić w funkcji gdyż będzie trzeba ją dołączyć za pomocą „haka” do admin_init. Cały kod znajduje się poniżej

function my_theme_options_menu() {
     add_theme_page('Theme menu','Theme menu','edit_theme_options'
     ,'my-theme-settings','my_theme_options_page');
}
add_action('admin_menu', 'my_theme_options_menu');

Parametry add_theme_page:

  1. tytuł strony z ustawieniami,
  2. nazwa wyświetlana strony z ustawieniami,
  3. nazwa funkcji umożliwiająca dostęp do strony z ustawieniami,
  4. parametr dodatkowy w adresie np. /wp-admin/themes.php?page=my-theme-settings,
  5. nazwa funkcji, w której zostanie umieszczona zawartość strony z ustawieniami.

Teraz dodamy zalążek strony z ustawieniami. W tym celu należy utworzyć funkcję o nazwie zapisanej przedchwilą w add_theme_page.

function my_theme_options_page() { ?>
     <div class="wrap">
     <div class="icon32" id="icon-options-general"></div>
     <h2>My theme Options</h2>
     <form action="options.php" method="post" enctype="multipart/form-data">
     <?php submit_button(); ?>
     </form>
<?php } ?>

W powyższym kodzie nie ma co tłumaczyć jest to zwykły formularz. Nazwy klasy oraz ID nie powinno się zmieniać wtedy zostaną dodane wordpressowe ikonki. Na tym etapie powinniśmy mieć już dostęp do nasze strony a po przejściu na nią ujrzeć widok jak poniżej

Krok 3: Dodawanie sekcji

Dodanie pól do formularza nie jest takie poste jak mogło by się wydawać. Gdyż nie robimy tego wstawiając po prostu odpowiednie pola. Pierwszym krokiem jest zarejestrowanie naszych ustawień oraz dodanie ich do admin_init. Rejestracja ustawień odbywa się w funkcji.

function my_theme_register_settings() {
	register_setting('my_theme_options','my_theme_options'
        ,'my_theme_validate'); 
}
add_action('admin_init','my_theme_register_settings');

Parametry funkcji my_theme_register_settings:

  1. nazwa ustawień należy ja zapamiętać gdyż będzie później potrzebna,
  2. nazwa tablicy z ustawieniami (pierwszy parametr funkcji updae_option użyty w funkcji my_theme_options_init)
  3. nazwa funkcji w której odbywać będzie się odbiór danych z formularza oraz ich walidacja.

Teraz należy dodać coś w stylu czarnej skrzynki formularza. Robi się to za pomocą kodu zamieszczonego poniżej. Teraz kod będziemy umieszczać wewnątrz utworzonego formularza, chyba że zostanie napisane inaczej.

settings_fields('my_theme_options')

 Nazwa użyta w settings_fields musi być taka sam jak ta użyta w register_setting jako pierwszy parametr.

Po dodaniu tego kodu do formularza zostaną dodane pola widoczne na zrzucie ekranu poniżej.

Teraz należy zdefiniować sekcję dla naszych ustawień, do których będą dodawane pola formularza.
Ja zdecydowałem się podzielić ustawienia na dwie sekcje w pierwszej będzie logo a w drugiej dwa checkboxy odpowiedzialne za wyświetlanie pola szukaj oraz informacji o autorze w stopce. W celu dodania sekcji należy wewnątrz formularza umieścić następujący kod:

add_settings_section('blog_logo','Logo Blog', 'blog_logo_section_fn'
                     ,'my-theme-settings'); 
do_settings_sections('my-theme-settings');

Parametry funckji add_settings_section:

  1. ID sekcji używane wyłącznie do identyfikacji,
  2. nazwa sekcji zostanie wyświetlona jako nagłówek sekcji,
  3. nazwa funkcji, która będzie wyświetlała np. obecne ustawienia,
  4. nazwa strony, do której dodawana jest sekcja.

Parametry funckji do_settings_sections:

  1. nazwa strony, do której dodawana jest sekcja

 nazwa strony użyta w add_settings_section musi być taka sam jak ta użyta w my_theme_options_menu jako przedostatni parametr.

 nazwa strony użyta w do_settings_sections musi być taka sam jak ta użyta w my_theme_options_menu jako przedostatni parametr oraz w add_settings_section jako ostatni parametr.

Aktualna zawartość formularza powinna wyglądać jak poniżej

<form action="options.php" method="post" enctype="multipart/form-data">
<?php 
      settings_fields('my_theme_options'); 		   
      add_settings_section('blog_logo','Logo Blog', 'blog_logo_section_fn'
      ,'my-theme-settings');
      add_settings_section('show_settings','Show settings'
      ,'show_settings_section_fn','my-theme-settings');	   
      do_settings_sections('my-theme-settings');
      submit_button(); ?>   
</form>

Jak widać zostały dodane dwie sekcje. Skoro sekcje zostały już zdefiniowane kolej na utworzenie funkcji pokazującej obecne ustawienia lub wyświetlające informacje o możliwościach edycji danych w sekcji.
W tym celu należy utworzyć dwie funkcje o nazwach zdefiniowanych w add_settings_section. To już należy zrobić po za formularzem. Najlepiej na końcu pliku żeby nie robić bałaganu.

<?php } 
function blog_logo_section_fn() { 
  $theme_options = get_option('my_theme_options'); ?>
  <img style="float:left;" src="<?php echo $theme_options['logo'] ?> " 
  alt="logo" title="logo" />
  <p style="float: left;margin-left: 30px;width: 50%;">
	Obecne logo. Można je zmienić używając formularza poniżej.
  </p>
  <div style="clear:both;"></div>
<? }

Powyższy kod wyświetla obecne logo bloga oraz informuje użytkownika o możliwości jego zmiany za pomocą formularza. Teraz należy zdefiniować funkcję dla drugiej sekcji. Należy pamiętać, że dla każdej sekcji musi istnieć taka funkcja.

<?php
function show_settings_section_fn() { ?>
W tej sekcji można ustawić widoczność pola szukaj oraz informacji w stopce.
<? } ?>

Po tym kroku tworzona strona powinna wyglądać tak jak pokazuje to screen poniżej.

Krok 4: Dodawanie pól formularza

Skoro obie sekcje zostały już zdefiniowane i wyświetlają się poprawnie należy dodać do nich pole formularza. Jest to również realizowane za pomocą funkcji wordpressowej. Kod dodawanie pól należy pisać w formularzy zawsze po deklaracji sekcji, do której dane pole jest przypisywane.

add_settings_field('blog_logo_field','Chose your logo file','blog_logo_fn'
,'my-theme-settings'
 ,'blog_logo');

Parametry funckji add_settings_field:

  1. ID dodawanego pola,
  2. label dla pola formularza,
  3. nazwa funkcji, w której będą znajdowały się pola formularza,
  4. nazwa strony, do której dodawane jest pole,
  5. nazwa sekcji, do której dodawane jest pole

 nazwa strony użyta w add_settings_field musi być taka sam jak ta użyta w my_theme_options_menu jako przedostatni parametr.

 nazwa sekcji użyta w add_settings_field musi być taka sam jak ta użyta w add_settings_section jako pierwszy parametr.

Teraz pora na dodanie dwóch pól do drugiej sekcji.

  add_settings_field('search_show','Pokazywać pole szukaj?','search_show_fn'
  ,'my-theme-settings','show_settings')
  add_settings_field('footer_info_show','Pokazywać informacje w stopce?'
  ,'footer_info_fn','my-theme-settings','show_settings');

Teraz należy dodać funkcje, o których była mowa przed chwilą odpowiedzialne za wyświetlanie pól formularza. Tutaj nie ma nic nadzwyczajnego zwykły kod HTML, którego nie trzeba tłumaczyć :) Kod funkcji już nie musi być pisany wewnątrz formularza; a nawet lepiej dla czytelności jeżeli zostanie dodany na końcu pliku. Poniżej znajduje się kody funkcji dla dodanych pól.

<?php
function blog_logo_fn() { ?> 
   <input type="file" name="blog_logo" id="document_file" />
   <span class="description">Your blog logo</span> 
<? }
function search_show_fn() {
    $theme_options = get_option('my_theme_options'); ?>
    <input type="checkbox" name="my_theme_options[search]" value="1" 
    <?php if($theme_options['search']) echo 'checked'; ?>  />
<? }
function footer_info_fn() { 
     $theme_options = get_option('my_theme_options');  ?>
     <input type="checkbox" name="my_theme_options[footer_credit]" value="1" 
     <?php if($theme_options['footer_credit']) echo 'checked'; ?>  />
<? }  ?>

Jeżeli wszystko zrobiliśmy poprawnie po przejściu na naszą stronę z ustawieniami powinniśmy zobaczyć efekt podobny do tego poniżej.

screan4

Krok 5: Odbiór danych z formularz oraz ich walidacja

Po wszystkich trudach ustawień strony, sekcji oraz pól przyszedł czas na obsługę naszego formularza. W tym celu należy utworzyć funkcję o nazwie podanej jako ostatni argument w funkcji register_setting czyli w naszym przypadku należy napisać taki oto kod:

function my_theme_validate($input) 
{
   $my_settings = get_option('my_theme_options');
   return $my_settings;
}

Funkcja przyjmuje jeden parametr, którym jest pole z naszego formularza oraz zwraca zaktualizowane opcje. Na początku zostały dodatkowo wczytane obecnie ustawione opcje.

Teraz za pomocą instrukcji warunkowych wystarczy odpowiednio obsłużyć dane z formularza i gotowe. Nie będę tego opisywał dokładnie bo są już podstawy obsługi formularzy, a z tym raczej nikt nie powinien mieć problemów. Cała opisywana funkcja:

function my_theme_validate($input) 
{
    $my_settings = get_option('my_theme_options');
    $theme_image_dir = ABSPATH.'/wp-content/uploads/theme_image_upload/';
    if(!empty($_FILES['blog_logo']))
    {
	$logo = $_FILES['blog_logo'];
	$logo_type = explode('/',$logo['type']);
	if($logo_type[1] != 'jpeg' && $logo_type[1] != 'png'
           && $logo_type[1] != 'gif')
	{
            add_settings_error('blog_logo','input_error','Można dodać tylko
            pliki graficzne','error');
	}
	else
	{
	    if(!file_exists($theme_image_dir)) mkdir($theme_image_dir);
	    $logo_original_image_dir = $theme_image_dir.$logo['name'];
	    move_uploaded_file($logo['tmp_name'],$logo_original_image_dir);
	    $my_settings['logo'] = get_option('siteurl').'/wp-content/uploads
            /theme_image_upload/'.$logo['name'];
	}
     }
     if($input['search'] == 0) $my_settings['search'] = false;
     else $my_settings['search'] = true;
     if($input['footer_credit'] == 0) $my_settings['footer_credit'] = false;
     else $my_settings['footer_credit'] = true;
     return $my_settings;
}

I to tyle jeżeli chodzi o obsługę formularza. Jednak teraz po przesłaniu formularza nie wyświetlają się żadne komunikaty. Zostanie to omówione w następnym kroku.

Krok 6: Wyświetlanie komunikatów

W poprzednim kroku przy sprawdzaniu typu przesłanego pliku pojawiła się pewna linijka a mianowicie:

add_settings_error('blog_logo','input_error'
,'Można dodać tylko pliki graficzne','error');

Jest to funkcja, która przesyła instrukcję, że wystąpił błąd. Sama nie wyświetla błędu!

Parametry add_settings_error:

  1. ID pola, którego dotyczy błąd,
  2. Nazwa klasy dodanej do pola zawierającego błąd,
  3. Wyświetlany komunikat
  4. Typ są dwie możwliwośći error lub update.

Do wyświetlenia komunikatów należy stworzyć dodatkową funkcje. Wspomniana funkcja wygląda następująco.

function my_theme_admin_msgs($message, $msgclass = 'info') {  
    $settings_pg = strpos($_GET['page'], 'my-theme-settings');  
    $set_errors = get_settings_errors();     
    if(current_user_can ('manage_options') && $settings_pg !== FALSE 
        && !empty($set_errors)){  
        if($set_errors[0]['code'] == 'settings_updated' 
        && isset($_GET['settings-updated'])){  
	    echo "<div id='message' class='updated'><p>"
            .$set_errors[0]['message']."</p></div>";
        }else{   
            foreach($set_errors as $set_error){ 
		echo "<div id='message' class='error'>
                <p class='setting-error-message' title='"
		.$set_error['setting']."'>".$set_error['message']
                ."</p></div>"; 
            }  
        }  
    }    
}

Nie będę opisywał powyższego kodu gdyż jest tam głównie php i dwie funkcje wordpressowe odpowiedzialne za odebranie błędów oraz sprawdzenie uprawnień zalogowanego użytkownika.Jedyną ważną linijką jest ta poniższa gdzie w zależnosci od potrzeb należy zmienić drugi parametr.

$settings_pg = strpos($_GET['page'], 'my-theme-settings');

Czyli zamiast my-theme-settings należy wpisać przedostatni parametr funkcji my_theme_options_menu. Teraz należy funkcję odpowiedzialną za wyświetlanie wiadomości dodać do admin_notices za pomocą kodu:

add_action('admin_notices', 'my_theme_admin_msgs');

Po wielu trudach i znojach w końcu udało się nam dobrnąć do końca. Efekt nasze pracy powinien być podobny do tego ze screena poniżej w przypadku wystąpienia błędu.

Gdy wszystko pójdzie jak należy zobaczymy komunikat o pozytywnym zaktualizowaniu opcji.

Podsumowanie

Można jeszcze dołączyć pliki JavaScript lub CSS; ale o tym postaram się napisać w kolejnym artykule. Gdyż było by za dużo informacji na raz. Po za dołączaniem plików następnym razem opiszę jak tworzyć menu z zakładkami oraz dodać pomoc dla użytkowników. Mam nadzieję, że artykuł przyda się i będzie pomocny. W razie pytań bądź sugesti proszę pisać w komentarza na pewno w miarę możliwości pomogę.


Opublikowano

w

, ,

przez

Komentarze

3 odpowiedzi na „Tworzymy własne menu w panelu administracyjnym – czyli korzystanie z Settings API”

  1. Awatar Kamil

    Wpis godzien zakładki ;)

    PS. Szkoda trochę, że linkujesz do swojego bloga na którym jest to samo.

    1. Awatar Grzegorz Kielar

      Linkuję bo czasami tam umieszczam artykuły ogólnie o kodowaniu stron i może ktoś przy okazji z czegoś skorzysta :)
      Tak czy inaczej wpis jest głównie dla wpzlecenia zrobiony ;)

  2. Awatar Projektowanie logo - nlogo

    świetny wpis i myślę, że bardzo wiele osób może z niego skorzystać jeśli robi coś w temacie ;-)