W tym odcinku poznamy WordPress Shortcode API – popularne narzędzie umożliwiające nam pisanie własnych shortcodes, czyli kodów, które możemy umieścić na stronie w różnych miejscach, np. we wpisach. Shortcodes są często używane w pluginach i potrafią być ogromną pomocą dla każdego developera WordPressa. Zróbmy kilka ćwiczeń i poznajmy je lepiej.
Obrazek – pierwszy shortcode
Zaczynamy od znalezienia pliku functions.php w wybranym przez nas szablonie w naszej instalacji WordPressa. Później do tego typu zabaw będziemy używać własnych pluginów, teraz jednak poszukajmy sobie naszego pliku functions.php i dodajmy poniższy kod
function myimg1_shortcode($atts, $content = null) {
return "<p>". esc_html($content) . "</p>";
}
add_shortcode('my-img1', 'myimg1_shortcode');
Funkcja add_shortcode dodaje shortcode o tagu 'my-img1′, który obsługuje podana przez nas z nazwy funkcja, którą zapisaliśmy powyżej. Funkcja ta wyświetla content (zawartość między tagiem otwierającym i zamykającym) oplecioną tagiem <p>. Użycie esc_html jest tylko dla bezpieczeństwa.
Teraz trzeba wejść do jakiegoś wpisu, kliknąć plusik, znaleźć shortcode i wpisać następującą treść:
[my-img1]blablabla[/my-img1]
Stworzony zostanie paragraf, który będzie zawierał treść między tagami. Teraz możemy zająć się tworzeniem naszego obrazka. Nasz kod będzie wyglądał tak:
function myimg1_shortcode($atts, $content = null) {
return '<img src="'. esc_url($content) . '" alt=""/>';
}
add_shortcode('my-img1', 'myimg1_shortcode');
Funkcja esc_url jest tam dla bezpieczeństwa. Oczywiście skądś ten url musimy pobrać. Możemy wejść w panelu admina do media, wybrać obrazek, kliknąć skopiuj do schowka. Następnie umieścić nasz url w tagu, w ten sposób:
[my-img1]TUTAJ URL[/my-img1]
Powinno działać. Zauważmy, że nasz url przekazujemy jako content, czyli zawartość pomiędzy tagami. Możemy też używać atrybutów. Dodajmy sobie taki atrybut do obsługi htmlowego atrybutu alt dla obrazka:
function myimg1_shortcode($atts, $content = null) {
$atts = shortcode_atts(array(
'alt' => 'picture',
), $atts);
return '<img src="'. esc_url($content) . '" alt="' . esc_attr($atts['alt']) . '"/>';
}
add_shortcode('my-img1', 'myimg1_shortcode');
Tutaj wykonujemy pewną czynność z naszymi atts, aby umożliwić nam przekazywanie atrybutów alt, z domyślną wartością 'picture’. Następnie korzystamy z tego atrybutu, zaś dla bezpieczeństwa używamy jeszcze funkcji esc_attr. Teraz każdy nasz obrazek będzie miał domyślnie alt ustawione na 'picture’. Możemy to oczywiście zmienić:
[my-img1 alt="blabla blabla"]TUTAJ URL[/my-img1]
Tak przekazany obrazek będzie miał alt ustawiony na „blabla blabla”. Koniecznie cudzysłów, chyba że używamy tylko jednego wyrazu. W ten sposób napisaliśmy pierwszy shortcode używający contentu i atrybutu.
Zabawy z tekstem – shortcode wzorem bbcodes
Napiszemy sobie coś podobnego do bbcodes. Shortcode dla pogrubienia tekstu, pochylenia go (zapis kursywą) oraz do zapisania go wielką literą. Warto tutaj dodać, że shortcode możemy dodawać także wewnątrz paragrafu WordPressa, nie musimy tego robić przez blok shortcode.
Najpierw kod:
function bold_text_shortcode($atts, $content = null) {
return '<strong>' . $content . '</strong>';
}
add_shortcode('bold', 'bold_text_shortcode');
Teraz, wewnątrz jakiegoś paragrafu, dodajemy:
[bold]asdasdsad[/bold]
Z kursywą będzie podobnie:
function em_text_shortcode($atts, $content = null) {
return '<em>' . $content . '</em>';
}
add_shortcode('em', 'em_text_shortcode');
Nasz shortcode:
[em]basdsadsad[/em]
Do zapisania tekstu wielką literą użyjemy wbudowanej funkcji PHP o nazwie strtoupper:
function upper_text_shortcode($atts, $content = null) {
return strtoupper($content);
}
add_shortcode('up', 'upper_text_shortcode');
Nasz shortcode:
[up]asdsadsad[/up]
Dla bezpieczeństwa moglibyśmy jeszcze dodać esc_html do naszych content:
function bold_text_shortcode($atts, $content = null) {
return '<strong>' . esc_html($content) . '</strong>';
}
add_shortcode('bold', 'bold_text_shortcode');
function em_text_shortcode($atts, $content = null) {
return '<em>' . esc_html($content) . '</em>';
}
add_shortcode('em', 'em_text_shortcode');
function upper_text_shortcode($atts, $content = null) {
return strtoupper(esc_html($content));
}
add_shortcode('up', 'upper_text_shortcode');
Poza umieszczaniem bloku shortcode albo wrzucaniem shortcode bezpośrednio do akapitu WordPressa, istnieje jeszcze inny sposób, który możemy wykorzystać m. in. w klasycznych szablonach WordPressa, gdzieś na stronie wewnątrz pliku HTML. Jest to funkcja do_shortcode:
do_shortcode('[bold]asdasdsad[/bold]');
Wydawać by się mogło, że jest to średnio użyteczne, zwłaszcza jeżeli klasyczne szablony nas w ogóle nie interesują. Ma to jednak jeszcze inne zastosowanie – tę funkcję możemy używać do umożliwiania naszym shortcodes na zagnieżdżanie jednych wewnątrz drugich.
Oto jak wyglądają nasze shortcodes, które pozwalają na zagnieżdżanie:
function bold_text_shortcode($atts, $content = null) {
return '<strong>' . do_shortcode($content) . '</strong>';
}
add_shortcode('bold', 'bold_text_shortcode');
function em_text_shortcode($atts, $content = null) {
return '<em>' . do_shortcode($content) . '</em>';
}
add_shortcode('em', 'em_text_shortcode');
function upper_text_shortcode($atts, $content = null) {
return strtoupper(do_shortcode($content));
}
add_shortcode('up', 'upper_text_shortcode');
Teraz możemy tylko otworzyć w jakimś wpisie nowy akapit i wpisać:
blabla [em]basdsadsad [bold]asdasdsad[/bold] [up]asdsadsad[/up] [/em]
I nasze shortcodes będą pozwalały na takie zagnieżdżanie.
Ostatnie wpisy – bardziej zaawansowane shortcodes
Najwyższa pora zrobić coś naprawdę ciekawego. Napiszmy sobie shortcode, który wyświetla element <ul> zawierający tytuły 5 ostatnich postów, jednocześnie będące linkami do tych postów. Pomyślmy, jak się chcemy do tego zabrać. Proponuję funkcję get_posts, z odpowiednio przekazanymi argumentami (posts_per_page 5, orderby date, order DESC) oraz pętlę foreach dodającą każdy post jako element <li> z linkiem, do utworzenia którego użyjemy get_permalink oraz tytułem jako treścią linka.
Do tego użyjmy sobie bloku if-else, który w przypadku braku jakichkolwiek postów, również nas o tym poinformuje. Tytuł posta wrzućmy w funkcję esc_html, dla bezpieczeństwa.
function recent_posts_list_shortcode() {
$args = array(
'posts_per_page' => 5,
'orderby' => 'date',
'order' => 'DESC',
);
$recent_posts = get_posts($args);
if ($recent_posts) {
$output = '<ul>';
foreach ($recent_posts as $post) {
$output .= '<li><a href="' . get_permalink($post->ID) . '">' . esc_html($post->post_title) . '</a></li>';
}
$output .= '</ul>';
return $output;
} else {
return 'Brak ostatnich postów.';
}
}
add_shortcode('recent_posts', 'recent_posts_list_shortcode');
Jeżeli znamy podstawy WordPressa to ten kod nie powinien mieć dla nas tajemnic. Jeżeli nie, możemy szybko odnaleźć wszystko w dokumentacji, aż tak skomplikowane to nie jest. Oczywiście, aby zobaczyć efekt naszych działań musimy dodać do wpisu poniższy shortcode:
[recent-posts]
Teraz możemy zechcieć, aby domyślnie nasz shortcode zaciągał 5 ostatnich postów, ale też aby użytkownik mógł przekazać argument posts i podać własną liczbę, odpowiadającą jego zapotrzebowaniu. Umiemy już robić atrybuty dla shortcodes, więc specjalnie trudne to nie jest:
function recent_posts_list_shortcode($atts) {
$atts = shortcode_atts(array(
'posts' => 5, // Domyślna liczba postów
), $atts);
$args = array(
'posts_per_page' => intval($atts['posts']),
'orderby' => 'date',
'order' => 'DESC',
);
$recent_posts = get_posts($args);
if ($recent_posts) {
$output = '<ul>';
foreach ($recent_posts as $post) {
$output .= '<li><a href="' . get_permalink($post->ID) . '">' . esc_html($post->post_title) . '</a></li>';
}
$output .= '</ul>';
return $output;
} else {
return 'Brak ostatnich postów.';
}
}
add_shortcode('recent_posts', 'recent_posts_list_shortcode');
Teraz domyślna wartość to 5, ale możemy przekazać inną liczbę, na przykład:
[recent_posts posts="4"]
I już. Działa jak należy.
Shortcodes jako plugin – piszemy bezpieczny plugin
Skoro wiemy już jak pisać nasze shortcodes wewnątrz functions.php, najwyższy czas nauczyć się pisać własne pluginy. Przechodzimy do folderu plugins w folderze wp-content w naszej instalacji WordPressa. Tworzymy tam folder o nazwie „my-shortcodes”.
Wewnątrz tego folderu tworzymy plik index.php o następującej treści:
<?php
# Silence is golden.
Nie zamykamy tagu PHP – robimy to ze względów bezpieczeństwa. Ten plik będziemy w takiej oto treści zawsze umieszczać w naszych pluginach. Nie zagłębiając się w szczegóły – jest to standardowa praktyka zabezpieczająca przed wejściem do tego folderu przez potencjalnego hakera.
Teraz wewnątrz folderu my-shortcodes (czyli tego samego co index.php) tworzymi plik naszego pluginu o takiej samej nazwie, czyli my-shortcodes.php:
<?php
/*
Plugin Name: My Custom Plugin
Description: Opis Twojego pluginu
Version: 1.0
Author: Twój autor
*/
Dopasowujemy nazwę, opis i autora do naszych upodobań. Teraz możemy już zobaczyć ten nasz plugin w panelu admina w zakładce wtyczki i go włączyć. Do pełni szczęścia potrzebne nam jeszcze tylko jedno zabezpieczenie:
<?php
/*
Plugin Name: My Custom Plugin
Description: Opis Twojego pluginu
Version: 1.0
Author: Twój autor
*/
if( ! defined( 'ABSPATH') ){
exit;
}
Podobnie jak w poprzednim przypadku – jest to rutynowa akcja zwiększająca bezpieczeństwo naszego pluginu. Nie ma co się nad tym rozwodzić. Teraz możemy poniżej dodawać nasze shortcodes. Ja dodam ten ostatni:
<?php
/*
Plugin Name: My Custom Plugin
Description: Opis Twojego pluginu
Version: 1.0
Author: Twój autor
*/
if( ! defined( 'ABSPATH') ){
exit;
}
function recent_posts_list_shortcode($atts) {
$atts = shortcode_atts(array(
'posts' => 5, // Domyślna liczba postów
), $atts);
$args = array(
'posts_per_page' => intval($atts['posts']),
'orderby' => 'date',
'order' => 'DESC',
);
$recent_posts = get_posts($args);
if ($recent_posts) {
$output = '<ul>';
foreach ($recent_posts as $post) {
$output .= '<li><a href="' . get_permalink($post->ID) . '">' . esc_html($post->post_title) . '</a></li>';
}
$output .= '</ul>';
return $output;
} else {
return 'Brak ostatnich postów.';
}
}
add_shortcode('recent_posts', 'recent_posts_list_shortcode');
Żebyśmy mieli pewność, że działa wykomentujmy jeszcze te samą funkcję z pliku functions.php:
// function recent_posts_list_shortcode($atts) {
// $atts = shortcode_atts(array(
// 'posts' => 5, // Domyślna liczba postów
// ), $atts);
// $args = array(
// 'posts_per_page' => intval($atts['posts']),
// 'orderby' => 'date',
// 'order' => 'DESC',
// );
// $recent_posts = get_posts($args);
// if ($recent_posts) {
// $output = '<ul>';
// foreach ($recent_posts as $post) {
// $output .= '<li><a href="' . get_permalink($post->ID) . '">' . esc_html($post->post_title) . '</a></li>';
// }
// $output .= '</ul>';
// return $output;
// } else {
// return 'Brak ostatnich postów.';
// }
// }
// add_shortcode('recent_posts', 'recent_posts_list_shortcode');
Możemy też usunąć ten kod z functions.php – to już nasz wybór. Możliwe, że będziemy musieli wyłączyć plugin, wykomentować functions.php, dodać do pluginu i włączyć raz jeszcze – tak się zdarza. Tym niemniej, mamy teraz własny plugin dodający shortcode.
Możemy jeszcze, nabywając od samego początku dobre praktyki pisania bezpiecznego kodu, zabezpieczyć się – dodać shortcode tylko wtedy, gdy taki nie istnieje. Służy do tego funkcja shortcode_exists:
<?php
/*
Plugin Name: My Custom Plugin
Description: Opis Twojego pluginu
Version: 1.0
Author: Twój autor
*/
if( ! defined( 'ABSPATH') ){
exit;
}
if ( ! shortcode_exists( 'recent_posts' ) ) {
function recent_posts_list_shortcode($atts) {
$atts = shortcode_atts(array(
'posts' => 5, // Domyślna liczba postów
), $atts);
$args = array(
'posts_per_page' => intval($atts['posts']),
'orderby' => 'date',
'order' => 'DESC',
);
$recent_posts = get_posts($args);
if ($recent_posts) {
$output = '<ul>';
foreach ($recent_posts as $post) {
$output .= '<li><a href="' . get_permalink($post->ID) . '">' . esc_html($post->post_title) . '</a></li>';
}
$output .= '</ul>';
return $output;
} else {
return 'Brak ostatnich postów.';
}
}
add_shortcode('recent_posts', 'recent_posts_list_shortcode');
}
Tutaj dodajemy nasz shortcode tylko wtedy, gdy taki (o takiej nazwie) nie istnieje już gdzieś – np. w functions.php albo dodana przez inny plugin. Innym elementem pisania bezpiecznego kodu jest takie nazywanie dodawanych w pluginie rzeczy, aby te nazwy były unikalne, aby nikt nie wpadł na podobny pomysł. Warto zatem przed nazwą wszystkiego dodać jakiś prefix dla naszego pluginu.