W odróżnieniu od innych tutoriali tutaj nie będziemy pokazywać wszystkiego krok po kroku od samego początku. Zakładam, że znamy podstawy języka PHP oraz umiemy zainstalować sobie WordPressa lokalnie lub znaleźć jakiś darmowy hosting i tam się nim pobawić.

Będziemy omawiać kawałki kodu napisanego w tym frameworku, tłumacząc co i jak działa.

’The loop’ – pierwszy rzut oka

Tak wygląda słynna pętla WordPressa, tzw. the loop:

<?php
if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        // Display post content
    endwhile;
endif;
?>

Mamy tutaj sprawdzenie warunku, czy jakiekolwiek posty istnieją/zostały przekazane do pętli, następnie pętlę while przechodzącą po każdym poście (the_post() sprawia, że pętla działa odpowiednio przechodząc po każdym elemencie).

Takie pętle znajdują się w różnych plikach klasycznych szablonów WordPressa, np. index.php, często też przed wyświetleniem postów mamy do czynienia z wyświetleniem czegoś na samej górze, jakiegoś elementu loga i nawigacji stałych dla wszystkich stron:

<?php
get_header();
if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        // Display post content
    endwhile;
endif;
?>

Tutaj funkcja get_header() ładuje zawartość pliku header.php (zawierającego tag <head> oraz początek tagu <body> (</body zazwyczaj w pliku footer.php) oraz różne elementy stałe dla szablonu, które mają wyświetlać się na samej górze strony, np. logo, pasek nawigacyjny.

Warunek „if” nie jest konieczny – jeżeli pętla while nie znajdzie żadnych postów po prostu niczego nie wyświetli. Można natomiast z tego warunku korzystać, jeżeli chcemy, aby w przypadku braku jakichkolwiek postów wyświetliła się jakaś informacja:

<?php
get_header();

if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        the_content();
    endwhile;
else :
    _e( 'Sorry, no posts matched your criteria.', 'textdomain' );
endif;

get_sidebar();
get_footer();
?>

Tutaj mamy blok else, który wyświetla informację, gdy żadnych postów w pętli nie mamy. Funkcja _e() to takie nieco bardziej zaawansowane „echo”, ułatwiające tłumaczenie stron w przyszłości (stąd argument 'textdomain’).

Możemy to _e zamienić na echo:

<?php
get_header();

if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        the_content();
    endwhile;
else :
    echo '<p>Sorry, no posts matched your criteria.</p>';
endif;

get_sidebar();
get_footer();
?>

Możemy także wewnątrz bloku else wyjść z PHP do HTML, zaprezentować kod HTML i wejść na powrót do PHP:

<?php
get_header();

if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        the_content();
    endwhile;
else :
    ?>
    <p>Sorry, no posts matched your criteria.</p>
    <?php 
endif;

get_sidebar();
get_footer();
?>

Wyświetlanie elementów postu – praca wewnątrz pętli

W poprzednim przykładzie poznaliśmy już funkcję the_content(). Użyta w pętli wyświetla zawartość posta. Wszystkie funkcje zaczynające się od „the” coś wyświetlają (za wyjątkiem the_post, funkcji pomocniczej w naszej pętli).

Funkcje te mają swoje odpowiedniki zaczynające się od „get”. Np. „get_the_content” pozwoliłoby zapisać treść do zmiennej PHP.

Trzymajmy się jednak funkcji wyświetlających coś:

<?php
if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        the_title( '<h1>', '</h1>' );
        the_content();
    endwhile;
else:
    _e( 'Sorry, no pages matched your criteria.', 'textdomain' );
endif;
?>

Mamy tutaj funkcję the_title, która wyświetli tytuł posta, w tagach <h1>, bo tak sobie zażyczyliśmy. Funkcja the_content wyświetla zawartość.

Kolejny przykład:

<?php
if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        the_title( '<h2>', '</h2>' );
        the_post_thumbnail();
        the_excerpt();
    endwhile;
else:
    _e( 'Sorry, no posts matched your criteria.', 'textdomain' );
endif;
?>

Funkcja the_post_thumbnail wyświetla obrazek danego posta, zaś the_excerpt – zajawkę, czyli krótki opis.

Restart pętli – rewind_posts

Pętlę możemy chcieć wywołać dwa razy. Na przykład po to, aby w jednym miejscu na stronie wyświetlić tytuły postów, w drugim – posty.

Do zrestartowania pętli służy funkcja rewind_posts()

<?php
// Start the main loop
if ( have_posts() ) :
    while ( have_posts() ) : the_post();
        the_title();
    endwhile;
endif;

// Use rewind_posts() to use the query a second time.
rewind_posts();

// Start a new loop
while ( have_posts() ) : the_post();
    the_content();
endwhile;
?>

Funkcje sprawdzające – renderowanie warunkowe

Nie wszystkie posty muszą mieć np. zajawkę. Chcemy ją wyświetlić tylko wtedy, gdy post takową posiada. Mamy od sprawdzenia tego funkcję has_excerpt():

if ( ! has_excerpt() ) {
	echo '';
} else { 
	the_excerpt();
}

Jeżeli nie ma zajawki – wyświetlamy pusty napis. Jeżeli jest – zajawkę.

Oto kolejny przykład:

if ( has_excerpt() ) {
	the_excerpt();
} else { 
	echo substr( get_the_content(), 0, 200 ) . ' ' . __( 'read more..' );
}

Jeżeli zajawki nie ma – wypisujemy pierwsze 200 znaków + „czytaj więcej”. Oczywiście logika jest dowolna – możemy na przykład ograniczyć liczbę wyrazów, jakie chcemy zaprezentować.

Wreszcze – możemy używać innych tagów warunkowych oraz prezentować HTML zamiast PHP:

<?php if ( ! has_excerpt() ) : ?>
	<!-- your text or code -->
<?php endif; ?>

Podobne funkcje dotyczą także innych elementów, takich jak na przykład obrazek (thumbnail) posta:

<?php
// Must be inside a loop.

if ( has_post_thumbnail() ) {
	the_post_thumbnail();
}
else {
	echo '<img src="' . get_bloginfo( 'stylesheet_directory' ) 
		. '/images/thumbnail-default.jpg" />';
}
?>

Tutaj sprawdzamy, czy post ma obrazek, jeżeli tak – wyświetlamy go. Jeżeli nie – wyświetlamy jakiś defaultowy obrazek.

Istnieją też funkcje sprawdzające, czy np. znajdujemy się w jakiejś kategorii:

<?php
// Start the Loop.
if ( have_posts() ) :
    while ( have_posts() ) : the_post();

        if ( in_category( 3 ) ) : ?>
        <div class="post-category-three">
        <?php else : ?>
        <div class="post">
        <?php endif; 
            the_title( '<h2>', ';</h2>' ); 
         //(...)

Tutaj mamy, jeżeli znajdujemy się w kategorii o ID 3, otwarcie tagu <div> z klasą „post-category-three”, albo, w innym przypadku, z klasą „post”. Dalej otwieramy tytuł i kontynuujemy naszą logikę.

Takich funkcji jest wiele, możemy na przykład sprawdzić, czy jesteśmy na stronie głównej (is_home()) albo na stronie wyszukiwania (is_search()) w bardzo podobny sposób.

Wyszukiwanie tych funkcji w manualu czy innej dokumentacji nie jest trudne, w dodatku jeżeli zrozumiemy pewien mechanizm, pewną konwencję, to jedyne, czego będziemy szukać to będzie nazwa funkcji, z której zazwyczaj będziemy w stanie sami wydedukować jak jej użyć.

Zadanie – przeanalizuj kod pliku index.php

Mamy plik index.php, z szablonu klasycznego WordPressa, znaleziony na GitHubie.

Wkleimy poniższy kod do jakiegoś ładnego edytora tekstowego, np. VSCode (aby nie dostać oczopląsu tylko ładnie, stosownymi kolorami podświetlać różne elementy składni) i przeanalizujemy go sobie:

<?php

get_header(); ?>

<div class="page-banner">
  <div class="page-banner__bg-image" style="background-image: url(<?php echo get_theme_file_uri('/images/ocean.jpg') ?>);"></div>
  <div class="page-banner__content container container--narrow">
    <h1 class="page-banner__title">Welcome to our blog!</h1>
    <div class="page-banner__intro">
      <p>Keep up with our latest news.</p>
    </div>
  </div>  
</div>

<div class="container container--narrow page-section">
<?php
  while(have_posts()) {
    the_post(); ?>
    <div class="post-item">
      <h2 class="headline headline--medium headline--post-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
      
      <div class="metabox">
        <p>Posted by <?php the_author_posts_link(); ?> on <?php the_time('n.j.y'); ?> in <?php echo get_the_category_list(', '); ?></p>
      </div>

      <div class="generic-content">
        <?php the_excerpt(); ?>
        <p><a class="btn btn--blue" href="<?php the_permalink(); ?>">Continue reading »</a></p>
      </div>

    </div>
  <?php }
  echo paginate_links();
?>
</div>

<?php get_footer();

?>

Dużo tutaj divów, z różnymi, długimi klasami, to jest HTML, który powinniśmy znać.

Rzecz pierwsza – wklejenie zawartości pliku header.php, zawierającego tagi <head> </head> wraz z zawartością oraz <body> i zapewne jakiś element nawigacji na początku strony:

<?php

get_header(); ?>

Dalej mamy <div>, któremu nadajemy inline-style CSS na obrazek tła:

<div class="page-banner">
  <div class="page-banner__bg-image" style="background-image: url(<?php echo get_theme_file_uri('/images/ocean.jpg') ?>);"></div>

Tutaj wchodzi nam funkcja PHP o nazwie get_theme_file_uri(), która zwraca nam ścieżkę do folderu, w którym znajduje się plik index.php oraz dokleja to, co między nawiasami (w naszym przypadku '/images/ocean.jpg’).

Funkcja z „get” zwraca nam tylko wartość, nie ją wyświetla, zatem jeszcze musieliśmy użyć „echo”.

Dalej mamy pętlę i kilka funkcji, które powinniśmy znać:

  • the_permalink() – wyświetla link do danego posta. Umieszczone w atrybucie href tagu <a>
  • the_title() – zwraca nam tytuł posta. Umieszczone w zawartości tagu <a></a>
  • the_author_posts_link() – zwraca nam link do strony zawierającej wszystkie posty napisane przez autora danego posta
  • the_time() – zwraca nam czas/datę publikacji posta, według podanego formatu
  • get_the_category_list(’, ’) – zwraca listę kategorii, do których post należy, oddzielonych znakiem przecinka i spacji. Funkcja „get” – musimy użyć echo, aby wynik wyświetlić.
  • the_excerpt() – zwraca zajawkę posta
  • paginate_links() – zwraca linki paginacji (numerowane strony), nie zaczyna się ani od „get” ani „the”, ale echo użyć musimy (taka dziwna funkcja, jedna z funkcji dot. paginacji)

Inne funkcje warte uwagi

Funkcja the_ID() wyświetla ID naszego posta:

<p>Post Number: <?php the_ID(); ?></p>

Możemy to wykorzystać np. do dynamicznego tworzenia klas CSS:

<h3 id="post-<?php the_ID(); ?>"><?php the_title(); ?></h3>

Funkcja the_tags() wyświetla tagi, do których nasz post należy:

<p><?php the_tags(); ?></p>

Możemy jej podać trzy opcjonalne argumenty – co przed, co pomiędzy, co po wypisaniu tagów:

<?php the_tags( 'Tags: ', ', ', '<br />' ); ?> 

Przed mamy napis „Tags: „, pomiędzy znak przecinka oraz spacji, po – znak nowej linii „<br />”.

Zróbmy sobie tagi oddzielone znakiem strzałki „>”, bez niczego po ostatnim z nich:

<?php the_tags( 'Social tagging: ',' > ' ); ?>

Przed napis 'Social tagging: ’, po każdym tagu ’ > ’, na końcu – nic.

Wykorzystajmy funkcję the_tags do granic możliwości, ładując wszystkie tagi jako element <li> (list item) w tagu <ul> (unordered list):

<?php the_tags( '<ul><li>', '</li><li>', '</li></ul>' ); ?>

Na początku – otwieramy <ul> i pierwszy <li>. Pomiędzy tagami – zamykamy </li>, otwieramy nowe <li>. Po tagach – zamykamy ostatni </li> oraz </ul>

Kolejna funkcja, czyli the_autor(), wyświetlająca autora posta:

<p>This post was written by <?php the_author(); ?></p>

Funkcja is_home(), sprawdzająca, czy jesteśmy na stronie głównej:

if ( is_home() ) {
    // This is the blog posts index
    get_sidebar( 'blog' );
} else {
    // This is not the blog posts index
    get_sidebar();
}

Myślę, że to są te najważniejsze funkcje i omówiliśmy je sobie wszystkie.