U ovom članku baviću se WordPress child temama. Objasniću šta su child teme, zbog čega su praktične, kako ih napraviti, uz nekoliko konkretnih primera za neke popularne teme.
Sadržaj:
- Šta je to WordPress child tema?
- Kako napraviti child temu za WordPress
- Primeri WordPress child tema
3.1. Storefront child tema
3.2. Astra child tema
3.3. GeneratePress child tema - Izmene izgleda pomoću style.css child teme
- Izmene izgleda i funkcionalnosti pomoću functions.php child teme
5.1. Prikaz breadcrumbs navigacije - Čemu sve to?
- Zaključak
1. Šta je to WordPress child tema?
Prvo ću ukratko objasniti šta je WordPress tema:
Tema je skup CSS i PHP koda (i fajlova) koji određuju kako će vaš sajt izgledati. Gde će se nalazidi vidžeti, koji fontovi će biti prikazani i kako, koja će biti boja pozadine itd. Većina tema dozvoljava prilagođavanje izgleda – neke u manjoj, neke u većoj meri.
Ipak, nekada je potrebno dobiti neki izgled, ili čak funkcionalnost, koju autor teme nije predvideo. Tu na scenu stupaju child teme – koje omogućavaju da se, bez dodatnih plagina, ili pravljenja skroz nove teme, dobiju željene izmene – tako da ostanu bez obzira na budući update verzije teme.
Na primer: “Powered by bacon & electricity” kopirajt u dnu ove stranice ubačen je pomoću child teme i par linija PHP/HTML koda.
Child tema “radi” tako što menja određene elemente originalne teme. Konkretan primer, pomoću kojeg će se lakše razumeti:
// begin copyright izmene
add_filter( 'generate_copyright','tu_custom_copyright' );
function tu_custom_copyright() {
?>
<span class="copyright">© 2018 - <?php echo date("Y"); ?> I/O Gremlin</span> • Powered by bacon & electricity </div>
<?php
}
// end copyright izmene
Tako je originalni copyright tekst napisan od strane autora teme izmenjen. U ovom slučaju to je urađeno pomoću nove funkcije “tu_custom_copyright”. Izmenama ćemo se kasnije baviti nešto detaljnije, prvo par reči o kreiranju child teme.
2. Kako napraviti child temu za WordPress
Postupak pravljenja “deteta” postojeće teme relativno je jednostavan. Potrebno je uraditi svega nekoliko stvari. Za početak, napraviti direktorijum za child temu unutar direktorijuma gde se nalaze WordPress teme, što je:
wp-content/themes
Za početak, direktorijum se može napraviti na lokalnom računaru, pa kasnije, sa svim fajlovima, uploadovati unutar wp-content/themes direktorijuma. Obično se uzme “ime_teme-child“, kao ime direktorijuma. Bez naših “ćčšžš” slova, bez praznih mesta i bez ćirilice u imenu direktorijuma (minus “-” i donja crta “_” su dozvoljeni)!
Zatim treba napraviti tekstualni fajl (u tekst editoru) nazvan “style.css” – i nikako drugačije. Taj fajl treba da sadrži određena polja, formatirana u vidu komentara, ali na početku style.css fajla, WordPress neće ignorisati ovaj komentar kao upućen samo “čitaocu fajla”, već će uzeti njegove vrednosti u obzir:
/*
Theme Name: GeneratePress child
Theme URI: https://io.bikegremlin.com/11334/child-theme/#3.3
Description: GeneratePress child theme
Author: BikeGremlin
Author URI: https://www.bikegremlin.com/about/
Template: generatepress
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready, woo commerce ready
Text Domain: generatepress-child
*/
“Template:” je ime direktorijuma u kojem se nalazi “glavna” tema, na osnovu koje se pravi child tema.
Ostala polja mogu biti ispunjena po želji i neće uticati na funkcionalnost child teme.
Polja nakon (ispod) “Template” se mogu u potpunosti izostaviti (ali ne zaboravite “zatvoriti” komentar sa “*/”.
Ostaje još da se napravi functions.php tekstualni fajl. U njemu će se dodavati funkcije koje omogućavaju dodatnu funkcionalnost, ili menjaju ponašanje postojećih funkcija teme (kasnije o tome). Generalno može ostati prazan, mada neke teme “insistiraju” da sadrži određene funkcije. Ovo je najčešće dovoljno:
<?php
add_action('wp_enqueue_scripts', 'add_child_theme_style');
function add_child_theme_style() {
wp_enqueue_style('parent-style', get_template_directory_uri() . '/style.css');
}
// vaš kod ide direkt ispod ovoga
?>
Nakon ovoga, kada otvorite meni za teme, videćete svoju novu child temu ponuđenu. Aktivirajte je. 🙂

Slika 1
3. Primeri WordPress child tema
Pre objašnjavanja načina na koje se izgled i funkcionalnosti menjaju korištenjem child tema, navešću konkretne primere “blanko” (pripremljenih za izmene) child tema za nekoliko popularnih WordPress tema. Prikazom sadržaja style.css i functions.php fajlova child tema.
Za konkretnu temu nije loše posetiti sajt autora i videti ima li nekih posebnih preporuka, šta da se ubaci u functions.php.
3.1. Storefront child tema
Storefront je tema autora WordPress-a (Automattic), prvenstveno namenjena za WooCommerce web prodavnice. Kako napraviti child temu za nju?
style.css:
/*
Theme Name: Storefront Child
Version: 1.0
Description: Child theme for Storefront.
Author: Woo
Author URI: http://woocommerce.com
Template: storefront
*/
functions.php:
<?php
// Storefront Child tema - dodati svoj kod ispod (nov red), a pre znaka "?>"
?>
3.2. Astra child tema
Astra je vrlo brza i dobro napisana tema, sa dobrom integracijom za Elementor i WooCommerce.
style.css:
/**
Theme Name: Astra-child
Author: BikeGremlin
Author URI: https://io.bikegremlin.com
Description: Astra child theme
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: astra-child
Template: astra
*/
functions.php:
<?php
/**
* Astra-child Theme functions and definitions
*
* @link https://developer.wordpress.org/themes/basics/theme-functions/
*
* @package Astra-child
* @since 1.0.0
*/
/**
* Define Constants
*/
define( 'CHILD_THEME_ASTRA_CHILD_VERSION', '1.0.0' );
/**
* Enqueue styles
*/
function child_enqueue_styles() {
wp_enqueue_style( 'astra-child-theme-css', get_stylesheet_directory_uri() . '/style.css', array('astra-theme-css'), CHILD_THEME_ASTRA_CHILD_VERSION, 'all' );
}
add_action( 'wp_enqueue_scripts', 'child_enqueue_styles', 15 );
// izmene i dodaci idu ispod, a pre znaka
?>
3.3. GeneratePress child tema
GeneratePress je jedna od omiljenih mi tema. Sa fenomenalnom dokumentacijom, podrškom i integracijom sa Elementorom. Brza, odlično napisana.
- Ovde možete skinuti već kreiranu child temu čiji kod je prikazan ispod:
https://files.bikegremlin.com/wordpress/themes/generatepress-child.zip - A ovde je child tema sa BikeGremlin izmenama – samo izmenite, ili uklonite “YOUR-TRACKING-CODE” i “YOUR-PUB-CODE” za Google Analytics i AdSense:
https://files.bikegremlin.com/wordpress/themes/generatepress-bikegremlin.zip
style.css:
/*
Theme Name: GeneratePress child
Theme URI: https://io.bikegremlin.com/11334/child-theme/#3.3
Description: GeneratePress child theme
Author: BikeGremlin
Author URI: https://www.bikegremlin.com/about/
Template: generatepress
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready, woo commerce ready
Text Domain: generatepress-child
*/
/*
Enter your custom code below
*/
functions.php:
<?php
/**
* GeneratePress child theme functions and definitions.
*
* Add your custom PHP in this file.
* Only edit this file if you have direct access to it on your server (to fix errors if they happen).
*/
/*
* BEGIN removing mostly needless code like RTL language check
* Arab language sites should include this code
function generatepress_child_enqueue_scripts() {
if ( is_rtl() ) {
wp_enqueue_style( 'generatepress-rtl', trailingslashit( get_template_directory_uri() ) . 'rtl.css' );
}
}
add_action( 'wp_enqueue_scripts', 'generatepress_child_enqueue_scripts', 100 );
* END removing mostly needless code like RTL language check
*/
// add your functions and code below this, above the "?>"
?>
4. Izmene izgleda pomoću style.css child teme
Možete videti kod svog WordPress sajta, pritiskanjem F12 u većini browsera dok gledate sajt i biranjem “Elements” opcije.
Konkretan primer izmene: u situaciji kada se gledaju slike galerija, nije mi se sviđalo da dugmići za “šerovanje” stoje u kadru, hteo sam da budu nevidljivi. Prvo je trebalo utvrditi gde je definisan stil za te dugmiće, što je urađeno postupkom prikazanim na slici 2:

Slika 2
Slika je dosta sitna, ali moraćete mi verovati na reč da pod brojem 4 na slici 2 stoji vrednost “.heateor_sss_vertical_sharing”. Tako da sam izmenio “vertikalnu” poziciju ovih dugmića, kako se ne bi prikazivali dok se gleda Lightbox galerija slika, izmenom style.css fajla child teme:
/* pomeranje shared ikona u pozadinu galerije */
.heateor_sss_vertical_sharing {
z-index:100000 !important;
}
/* kraj izmene pomeranje shared ikona u pozadinu galerije */
Sada, kada je stil “.heateor_sss_vertical_sharing” definisan (i) u child temi, on će uzeti primat nad onim definisanim u glavnoj temi. Na ovaj način pomoću child teme menja se izgled sajta – sve definisano u child temi ima primat.
Rezultat ovakvih izmena može se videti recimo na sajtu studija za šminkanje u Novom Sadu.
Drugi primer je promena pozadine. Definicija izgleda je “ulovljena” metodom prikazanom u slici 2, a urađeno je više izmena:
/* izmena pozadinske slike i stilisanje iste - ne zaboravite "zatvoriti" komentar */
body {
background-image: url( 'https://io.bikegremlin.com/wp-content/uploads/2019/03/io_bikegremlin_background2.jpg' );
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
}
/* kraj izmena pozadinske slike i stilisanje iste */
5. Izmene izgleda i funkcionalnosti pomoću functions.php child teme
Kod izmena pomoću functions.php fajla, moguće je napisati potpuno novu, dodatnu funkciju. Na primer, funkcija za prikazivanje “child” stranica “glavnije” strane (po hijerarhiji), pomoću pre-definisanog short-code:
// BEGIN list child pages
function relja_list_child_pages() {
global $post;
if ( is_page() )
$childpages = wp_list_pages( 'sort_column=menu_order&title_li=&child_of=' . $post->ID . '&echo=0' );
if ( isset($childpages )) {
$string = '<ul>' . $childpages . '</ul>';
}
else{
$string = '';
}
return $string;
}
add_shortcode('relja_child_pages', 'relja_list_child_pages');
// END list child pages
Dodata je funkcija “relja_list_child_pages”. Sada će shortcode “relja_child_pages” dodati spisak stranica. Primer sa ovog sajta je klik na link “Usluge” u glavnom meniju.
Editovana verzija koda, koja izlistava i “decu,” ali i “rođake” stranice, tj. stranice na istom hijerarhijskom nivou sa stranicom na kojoj je shortcode ubačen:
// BEGIN list child and same-level pages
function relja_list_child_pages() {
global $post;
if ( is_page() && $post->post_parent )
$childpages = wp_list_pages( 'sort_column=menu_order&title_li=&child_of=' . $post->post_parent . '&echo=0' );
else
$childpages = wp_list_pages( 'sort_column=menu_order&title_li=&child_of=' . $post->ID . '&echo=0' );
if ( $childpages ) {
$string = '<ul>' . $childpages . '</ul>';
}
return $string;
}
add_shortcode('relja_child_pages', 'relja_list_child_pages');
// END list child and same-level pages
Takođe, postojeće funkcije teme se mogu re-definisati. Jedan od načina za to je korištenje “hooks”. Slika to lepše objašnjava: evo prikaza hoook-ova za GeneratePress temu.
A ovo je kod kojim se postojeća funkcija menja, kako bi se kontakt telefon i mejl prikazali u plavoj liniji na vrhu strane jednog sajta:
// tanka plava linija na vrhu
add_action( 'generate_before_header', 'blue_top_menu' );
function blue_top_menu(){
?>
<div class="blue-top-menu"><a title="[email protected]" alt="[email protected]" href="mailto:[email protected]" class="link-blue-top-menu">[email protected] <a title="+38163666999" alt="+38163666999" href="tel:+38163666999" class="link-blue-top-menu">+38163666999</a></div>
<?php
}
// kraj tanka plava linija na vrhu
Definisana je nova funkcija “blue_top_menu” i iskorišten je hook “generate_before_header” kao mesto za njeno prikazivanje.
Kako to izgleda u praksi, može se videti na ovom sajtu za jedrenje u Grčkoj.
5.1. Prikaz breadcrumbs navigacije
Bez puno priče, evo koda koji radi: 🙂
// BEGIN BREADCRUMBS
function the_breadcrumb()
{
$lg_home_name ="Home";
$lg_archive_by_category = "";
$lg_search_results_for = "Search:";
$lg_posts_tagged = "Keyword:";
$lg_articles_posted_by = "Author:";
$showOnHome = 0; // 1 - show breadcrumbs on the homepage, 0 - don't show
$delimiter = '»'; // delimiter between crumbs
//$home = 'Home'; // text for the 'Home' link
$home = $lg_home_name; // text for the 'Home' link
$showCurrent = 1; // 1 - show current post/page title in breadcrumbs, 0 - don't show
$before = '<span class="current">'; // tag before the current crumb
$after = '</span>'; // tag after the current crumb
global $post;
$homeLink = get_bloginfo('url');
if (is_home() || is_front_page()) {
if ($showOnHome == 1) {
echo '<div id="crumbs"><a href="' . $homeLink . '">' . $home . '</a></div>';
}
}
else {
echo '<div id="crumbs"><a href="' . $homeLink . '">' . $home . '</a> ' . $delimiter . ' ';
if (is_category()) {
$thisCat = get_category(get_query_var('cat'), false);
if ($thisCat->parent != 0) {
echo get_category_parents($thisCat->parent, true, ' ' . $delimiter . ' ');
}
//echo $before . 'Archive by category "' . single_cat_title('', false) . '"' . $after;
echo $before .$lg_archive_by_category. ' ' . single_cat_title('', false) . '' . $after;
}
elseif (is_search()) {
//echo $before . 'Search results for "' . get_search_query() . '"' . $after;
echo $before .$lg_search_results_for.' "' . get_search_query() . '"' . $after;
}
elseif (is_day()) {
echo '<a href="' . get_year_link(get_the_time('Y')) . '">' . get_the_time('Y') . '</a> ' . $delimiter . ' ';
echo '<a href="' . get_month_link(get_the_time('Y'), get_the_time('m')) . '">' . get_the_time('F') . '</a> ' . $delimiter . ' ';
echo $before . get_the_time('d') . $after;
}
elseif (is_month()) {
echo '<a href="' . get_year_link(get_the_time('Y')) . '">' . get_the_time('Y') . '</a> ' . $delimiter . ' ';
echo $before . get_the_time('F') . $after;
}
elseif (is_year()) {
echo $before . get_the_time('Y') . $after;
}
elseif (is_single() && !is_attachment()) {
if (get_post_type() != 'post') {
$post_type = get_post_type_object(get_post_type());
$slug = $post_type->rewrite;
echo '<a href="' . $homeLink . '/' . $slug['slug'] . '/">' . $post_type->labels->singular_name . '</a>';
if ($showCurrent == 1) {
echo ' ' . $delimiter . ' ' . $before . get_the_title() . $after;
}
}
else {
$cat = get_the_category();
$cat = $cat[0];
$cats = get_category_parents($cat, true, ' ' . $delimiter . ' ');
if ($showCurrent == 0) {
$cats = preg_replace("#^(.+)\s$delimiter\s$#", "$1", $cats);
}
echo $cats;
if ($showCurrent == 1) {
echo $before . get_the_title() . $after;
}
}
}
elseif (!is_single() && !is_page() && get_post_type() != 'post' && !is_404()) {
$post_type = get_post_type_object(get_post_type());
echo $before . $post_type->labels->singular_name . $after;
}
elseif (is_attachment()) {
$parent = get_post($post->post_parent);
$cat = get_the_category($parent->ID);
$cat = $cat[0];
echo get_category_parents($cat, true, ' ' . $delimiter . ' ');
echo '<a href="' . get_permalink($parent) . '">' . $parent->post_title . '</a>';
if ($showCurrent == 1) {
echo ' ' . $delimiter . ' ' . $before . get_the_title() . $after;
}
}
elseif (is_page() && !$post->post_parent) {
if ($showCurrent == 1) {
echo $before . get_the_title() . $after;
}
}
elseif (is_page() && $post->post_parent) {
$parent_id = $post->post_parent;
$breadcrumbs = array();
while ($parent_id) {
$page = get_page($parent_id);
$breadcrumbs[] = '<a href="' . get_permalink($page->ID) . '">' . get_the_title($page->ID) . '</a>';
$parent_id = $page->post_parent;
}
$breadcrumbs = array_reverse($breadcrumbs);
for ($i = 0; $i < count($breadcrumbs); $i++) {
echo $breadcrumbs[$i];
if ($i != count($breadcrumbs)-1) {
echo ' ' . $delimiter . ' ';
}
}
if ($showCurrent == 1) {
echo ' ' . $delimiter . ' ' . $before . get_the_title() . $after;
}
}
elseif (is_tag()) {
//echo $before . 'Posts tagged "' . single_tag_title('', false) . '"' . $after;
echo $before . $lg_posts_tagged .' "' . single_tag_title('', false) . '"' . $after;
}
elseif (is_author()) {
global $author;
$userdata = get_userdata($author);
//echo $before . 'Articles posted by ' . $userdata->display_name . $after;
echo $before . $lg_articles_posted_by.' ' . $userdata->display_name . $after;
}
elseif (is_404()) {
echo $before . 'Error 404' . $after;
}
if (get_query_var('paged')) {
if (is_category() || is_day() || is_month() || is_year() || is_search() || is_tag() || is_author()) {
echo ' (';
}
echo __('Page') . ' ' . get_query_var('paged');
if (is_category() || is_day() || is_month() || is_year() || is_search() || is_tag() || is_author()) {
echo ')';
}
}
echo '</div>';
}
}
add_action( 'generate_before_main_content', 'tabela_zaglavlje' );
function tabela_zaglavlje(){
if (function_exists('the_breadcrumb')){
the_breadcrumb();
echo "<hr style='margin:10px 0 20px 0;'>";
}
}
//END BREADCRUMBS
6. Čemu sve to?
Savršeno logično pitanje, iako sam ga ostavio za kraj.
Osnovni izgled i funkcionalnost WordPress sajta može se dobiti izborom odgovarajuće teme. Ipak, nije uvek moguće pronaći gotovu, kvalitetnu temu koja odgovara vašim potrebama u potpunosti.
Naravno, postoji i puno dobrih plaginova, kojima se dosta toga može dodati i prilagoditi. Ipak, mislim da je bolje rešiti stvari bez plaginova, pogotovo one “sitnije” koje se mogu relativno lako i brzo rešiti. Zašto?
- Svaki plagin dodatno opterećuje sajt, dodajući često i više nego što je neophodno (kako u funkcionalnosti, tako i u kodu koji se mora izvršiti pri svakoj poseti stranice).
- Svaki plagin je potencijalni bezbednosni rizik.
- Zbog prethodne dve stavke: što manje plagina, to bolje. Koristiti samo one koji su zaista neophodni. Pravite sve druge, “manje” izmene pomoću child teme.
Pri tome, ove izmene se mogu raditi direktno na samoj temi. Ali: u slučaju apdejta teme, na primer, izmene će biti izgubljene. Child tema je način da se željene izmene na lak način učine “trajnim”.
7. Zaključak
Kada birate temu za svoj WordPress sajt, radite to pažljivo i promišljeno. Naravno, tema mora pružiti izgled i funkcionalnost (u najvećoj meri) koji su vam potrebni. Ali takođe proverite i koliko se redovno ažurira, kakva je podrška i dokumentacija (bitno zbog izmena pomoću child teme), kao i koliko je dobro napisana i “brza”. Napisao sam niz članaka o optimizaciji sajta, koji taj deo detaljnije objašnjavaju.
Napravite odmah child temu.