A feladat a következő: a sablonban megtalálható egyéni bejegyzés-szerkesztő kibővítése új mezőkkel, és az ehhez tartozó funkcionalitás kialakítása a sablonban. Mindezt lehetőleg úgy, hogy ne a vásárolt sablon fájljait szerkesszük, hanem plusz kódot adjunk hozzá valamiféleképpen, hogy a sablon továbbra is frissíthető maradjon.
Kontextus
Adott egy egyéni bejegyzés-típus (“portfolio
“), ami a sablonban van regisztrálva, és az egyes elemek (bejegyzések) jellemzőit Advanced Custom Fields mezők kitöltésével adhatja hozzá az adminisztrátor.

portfolio
” bejegyzéseknélEzen típusba tartozó bejegyzések különböző stílusú galériákban megjeleníthetők, pl. egészoldalas, carousel, stb. A galériákat blokként vagy shortcode-dal lehet hozzáadni az egyes oldalakhoz. A galériák már be vannak illesztve előre létrehozott oldalakra – a végfelhasználónak leginkább csak a portfolio
bejegyzéseket kell majd kezelnie, ehhez kellenek új mezők.
A feladatok
- A galériákban megjelenik egy “Tovább” gomb, ami elvezet az adott
portfolio
bejegyzésre (“single post” nézetre). Azt szeretnénk, hogy ez a link egy egyénileg megadott URL-re mutasson, nem pedig a bejegyzés linkjére. Ez lenne az első extra mező ACF-ben. - Minden galériában megjelenik az összes
portfolio
bejegyzés. Azt szeretnénk, hogy közvetlenül a szerkesztőben megadhassuk, mely oldalakon jelenjen meg egy adott bejegyzés, és melyeken ne. Ehhez kéne még egy ACF mező.
Új mezők hozzáadása a szerkesztőfelülethez
A fenti screenshot-on látható mezők alá akarunk két új mezőt hozzáadni. Ehhez meg kell keresnünk a sablon fájljaiban a kódot, ahol ezeket a mezőket regisztrálja. Mivel tudjuk, hogy Advanced Custom Fields mezőkről van szó, ezért első körben ehhez kapcsolódó fájlneveket keresünk. Ha nem találunk ilyen fájlt, akkor érdemes letölteni az összes sablonfájlt a saját gépünkre, majd valamilyen fájlszerkesztő vagy fájlkezelő programmal az összes fájl tartalmában egyszerre keresni, például az egyik mező nevére: “Meta 1 Title
“, vagy arra, hogy “acf
“.
A kérdéses sablonban meg is találtuk a fájlt, amiben szerepel a kód:
acf_add_local_field_group(array(
'key' => 'group_5f05a7575b216',
'title' => 'Portfolio Meta',
'fields' => array(
array(
'key' => 'field_5f05ac0726f03',
'label' => '',
'name' => 'meta_1_title',
'type' => 'text',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '50',
'class' => '',
'id' => '',
),
'default_value' => '',
'placeholder' => '',
'prepend' => 'Meta 1 Title',
'append' => '',
'maxlength' => '',
),
[...]
Az ACF dokumentációjából megtudható, hogyan kell hozzáadni egy új mezőt egy létező mezőcsoporthoz: az acf_add_local_field()
függvényt kell használni, és meg kell adni a mezőcsoport nevét a parent
paraméterben. A mezőcsoport neve az acf_add_local_field_group()
függvény key
paraméterében található – a fenti kódban ez “group_5f05a7575b216
“.
A kódunkat ajánlott az acf_init
action hook-ban lefuttatni, de mindenképp az alap mezőket regisztráló sablon kód után kell. Az acf_init
használatának az előnye, hogy csak akkor fog lefutni a kód, ha telepítve van az Advanced Custom Fields, így nem fog hibára futni, amikor valamiért deaktiváljuk az ACF plugint.
Az egyéni mezőket hozzáadó kódunk így fog kinézni:
/**
* ACF mezők hozzáadása.
*
* @return void
*/
function oldalneveponthu_acf() {
acf_add_local_field( array(
'key' => 'link_url',
'label' => 'Tovább Gomb Link',
'instructions' => 'Ha üresen hagyjuk, akkor az alap portfolio-link lesz használva.',
'name' => 'moreinfo_url',
'type' => 'url',
'parent' => 'group_5f05a7575b216',
'wrapper' => array(
'width' => '50',
),
) );
acf_add_local_field( array(
'key' => 'show_on_pages',
'label' => 'Elem Megjelenítése Itt',
'instructions' => 'Ez az elem csak a kijelölt oldalakon fog megjelenni.',
'name' => 'show_on_pages',
'type' => 'select',
'default_value' => '',
'ui' => 1,
'multiple' => true,
'parent' => 'group_5f05a7575b216',
'choices' => oldalneveponthu_get_pages(),
'allow_null' => true,
'placeholder' => 'Válasszuk ki az oldalakat',
'wrapper' => array(
'width' => '50',
),
) );
}
add_action( 'acf/init', 'oldalneveponthu_acf', 20 );
A kódban a következő dolgok történnek:
- A
link_url
mező hozzáadása, ami egy szöveges (URL) mező. Ebben semmi különös nincs, a szokásos paramétereket adjuk meg hozzá. - A
show_on_pages
mező hozzáadása, ami egy “select” (legördülő menü) típusú mező, amiben több érték is kiválasztható ('multiple' => true
), és mivel a'ui' => 1
paraméter is meg van adva, ezért nem legördülő menüként, hanem kiválasztható “címkékként” fog megjelenni a mező (lásd lejjebb). A választható értékek (choices
paraméter) azoldalneveponthu_get_pages()
egyéni függvényből jön.
A oldalneveponthu_get_pages()
függvény így néz ki:
/**
* Oldalak listázása, az admin checkboxokhoz.
*
* @return void
*/
function oldalneveponthu_get_pages() {
$out = array();
$pages = get_pages( array( 'hierarchical' => false ) );
foreach ( $pages as $post ) {
$out[ $post->ID ] = $post->post_title;
}
return $out;
}
Ez a függvény az összes létrehozott oldalt listázza egy tömbként, mégpedig “ID => Oldalcím
” formátumban. Így a felhasználó az oldalcímeket látja a mezőben, az adatbázisba elmentett értékek pedig az ID-k lesznek.
Egyéni plugin létrehozása
Mivel azt akarjuk, hogy a sablont továbbra is frissíteni lehessen, ezért nem szerkeszthetjük közvetlenül. A vásárolt sablonoknál és bővítményeknél nagyon fontos, hogy mindig a legfrissebb verziót használjuk (itt leírtuk miért: A WP Frissítésekről). Ha egy egyéni sablonról lenne szó, és nem várható soha frissítés hozzá, akkor nyugodtan szerkeszthetnénk magát a sablont is.
Így a következő lehetőségeink vannak a kód hozzáadására:
- Származtatott sablon (child theme)
- Egyéni bővítmény
- Kötelezően használandó bővítmény (mu-plugin)
Az egyes módszerek különbségeiről az egyéni kóddal kapcsolatos cikkünkben írtunk.
Jelen esetben az egyéni bővítményt választottuk. Létrehoztunk egy új mappát a /wp-content/plugins
mappában, és benne egy új PHP fájlt, a következő tartalommal:
<?php
/**
* Plugin Name: OldalNevePontHu Webhely-plugin
* Plugin URI: https://oldalneve.hu
* Description: Az OldalNevePontHu webhellyel kapcsolatos egyéni kódok.
* Version: 1.0
*/
Ez alá pedig beillesztettük a fenti ACF mezőket regisztráló kódot. Az új plugin aktiválása után az admin felületen meg is jelennek az új mezők:

Az új mezők ott vannak, és el lehet menteni az egyéni post meta értékeket, de nincsen semmilyen funkciójuk még.
1. Új funkció: “Tovább” gomb link módosítása
A sablonfájlokban kikerestük azt a részt, ami megjeleníti a linket. Így néz ki:
<a href="<?php echo get_the_permalink(); ?>">
A get_the_permalink()
egy alap WP függvény, és az értéke módosítható a post_type_link
filterrel. Ezt használva ki tudjuk alakítani a kívánt funkciót:
/**
* Link kicserélése, ha szükséges.
*
* @param string $url Permalink.
* @param int $post_id Post ID.
* @return string
*/
function oldalneveponthu_portfolio_permalink( $url, $post_id ) {
if ( ! function_exists( 'get_field' ) ) {
return $url;
}
if ( ! is_page() || get_post_type( $post_id ) != 'portfolios' ) {
return $url;
}
$link_url = get_field( 'link_url' );
if ( ! $link_url ) {
return $url;
}
return $link_url;
}
add_filter( 'post_type_link', 'oldalneveponthu_portfolio_permalink', 20, 2 );
Ebben a kódban a következők történnek:
- Az
if ( ! function_exists( 'get_field' ) ) {
sorral ellenőrizzük, hogy az ACF plugin aktiválva van, hogy ne legyen PHP hiba, amikor nincs. Ha az ACF nem aktív, és aget_field()
funkciója nincs definiálva, akkor simán visszaadjuk a filternek az eredeti$url
értéket areturn $url;
sorral. Így az alatta lévő kódok nem futnak le. - Az
if ( ! is_page() || get_post_type( $post_id ) != 'portfolios' ) {
sorral ellenőrizzük, hogy jelenleg egy oldalt (page
típusú bejegyzést) nézünk-e, illetve, hogy a kért permalinkportfolio
típusú bejegyzéshez tartozik-e. Ha ezek közül bármelyik nem teljesül, akkor csakúgy mint az előző feltételnél, itt is visszaadjuk módosítatlanul az$url
-t. - A
$link_url = get_field( 'link_url' );
sorban lekérjük az ACF mezőben elmentettlink_url
értékét. Ha nincs megadva egyéni URL ebben a mezőben, akkor azif ( ! $link_url ) {
feltétellel megint csak visszaadjuk az eredeti$url
-t. - Ha minden oké, és az előző feltételeken túljutott a kód, akkor visszaadjuk az egyéni URL-t, a
return $link_url;
sorban.
A kódot az egyéni plugin fájlba beillesztve működik is a funkció, ahogy kell: ha meg van adva egy egyéni “Tovább Gomb Link”, akkor a galériában megjelenő “Tovább” gomb arra a linkre mutat, nem pedig a portfolio
oldalra.
2. Új funkció: “portfolio” bejegyzések szűrése oldal szerint
A portfolio
bejegyzéseket a sablon a WP_Query
osztály segítségével tölti be, egy ehhez hasonló kóddal:
$args = array(
'post_type' => 'portfolios',
'post_status' => 'publish',
'posts_per_page' => 10,
);
$loop = new \WP_Query( $args ); ?>
<div class="portfolio-gallery">
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<div class="gallery-item">
<h3><?php the_title(); ?></h3>
[...]
</div>
<?php endwhile; ?>
</div>
Szerencsére itt is elérhető egy filter hook (a pre_get_posts
filter), amivel módosíthatjuk a WP_Query
lekérés paramétereit mielőtt az lefut, így leszűrhetjük a bejegyzéseket, hogy csak azokat mutassa, amiket bejelölt a felhasználó.
A kódunk így fog kinézni:
/**
* Elemek elrejtése a gyűjtő oldalakon, ha szükséges.
*
* @param WP_Query $query WP Query object.
* @return void
*/
function oldalneveponthu_exclude_portfolios( $query ) {
if ( is_admin() || ! is_page() || $query->is_main_query() || $query->get( 'post_type' ) != 'portfolios' ) {
return;
}
$page_id = get_the_ID();
$meta_query = array(
'relation' => 'or',
array(
'key' => 'show_on_pages',
'compare' => '=',
'value' => $page_id,
),
array(
'key' => 'show_on_pages',
'compare' => 'LIKE',
'value' => '"' . $page_id . '"',
),
);
$query->set( 'meta_query', $meta_query );
}
add_action( 'pre_get_posts', 'oldalneveponthu_exclude_portfolios' );
A kódban ezek a lépések futnak le:
- Először is ellenőrizzük, hogy le kell-e futnia a kódunknak vagy sem:
if ( is_admin() || ! is_page() || $query->is_main_query() || $query->get( 'post_type' ) != 'portfolios' ) {
Mivel apre_get_posts
szinte minden oldalon többször is lefut (amikor bármilyen bejegyzést lekér a rendszer), de nekünk csak azokat a kéréseket kell szűrnünk, amikre a következők mind igazak:- Nem az admin oldalon vagyunk épp:
is_admin()
- Egy adott oldalt nézünk, “single page” nézetben:
is_page()
(mivel ezekre vannak beillesztve a galériák) - Nem az oldal “fő kéréséről” van szó:
$query->is_main_query()
A fő kérés az, amiben a rendszer magát az oldalt kéri le a megjelenítéshez (címét, tartalmát, stb.) - A kérés
portfolio
típusú bejegyzéseket kér le:$query->get( 'post_type' ) != 'portfolios'
- Nem az admin oldalon vagyunk épp:
- Ha a fenti feltételek közül bármelyik nem teljesül, akkor a
return;
sorral egyből le is zárjuk a függvényt, nem futtatjuk tovább, és nem módosítunk semmit. - Ezután a
WP_Query
-nek ameta_query
paraméterével beállítjuk, hogy csak azonportfolio
elemeket mutassa, amelyeknél ashow_on_pages
meta érték egyenlő a jelenlegi oldal ID-vel ('compare' => '='
), vagy pedig tartalmazza azt ('compare' => 'LIKE'
), amennyiben ashow_on_pages
több értéket is tárol.
Ezzel a kóddal már úgy működik a dolog, ahogy kell: minden oldalon (“page” típusú bejegyzésnél, “single post” nézetben) lefutó portfolio
-t lekérő WP_Query
szűrve lesz a függvényünk által, és csak a jelen oldalhoz kiválasztott portfolio
elemeket fogja visszaadni.
+1 Funkció: mezők magyarítása
Mivel az oldal sosem lesz többnyelvűsítve, ezért az egyéni kódban nem használtuk a gettext
fordítási funkciókat. Ha fordíthatóvá és többnyelvűsíthetővé akarjuk tenni a kódot, akkor minden, a felhasználó számára látható szövegnél használni kell a megfelelő fordítási funkciót, pl. ehelyett: 'Tovább Gomb Link'
ezt kell írnunk: __( 'Tovább Gomb Link', 'oldalneveponthu-plugin' )
.
Viszont a vásárolt sablon eredeti készítője sem használta a fordítási funkciókat mindenhol, ahol kellett volna, így a sablon szövegei nem lefordíthatóak a hagyományos módokon (.po fájlokkal, a Poedit app vagy a Loco Translate bővítmény segítségével). Például ez a sor nem fordítható:
'title' => 'Portfolio Meta',
Így kéne kinéznie a sornak, hogy könnyen lefordítható legyen az adminisztrátor számára:
'title' => __( 'Portfolio Meta', 'sablonneve' ),
Szerencsére az ACF egyik filter hook-ját használva át lehet írni ezeket a sorokat:
/**
* Mező nevek és leírások fordítása.
*
* @param array $field
* @return array
*/
function oldalneveponthu_translate_fields( $field ) {
switch ( $field['label'] ) {
case 'Summary':
$field['label'] = 'Leírás';
$field['instructions'] = 'Elem teljes leírása.';
break;
case 'Excerpt':
$field['label'] = 'Rövid leírás';
$field['instructions'] = 'Elem rövid bemutatója.';
break;
}
return $field;
}
add_action( 'acf/prepare_field', 'oldalneveponthu_translate_fields' );
Ez a kód minden ACF mező paramétereit tudja módosítani. A label
paraméter (a mező címkéje) alapján célozva változtathatjuk meg a paramétereket. Például, ha a label
“Summary”, akkor a label
paraméter változzon arra, hogy “Leírás”, és az instructions
paraméter (a mező kitöltési útmutatója) pedig legyen “Elem teljes leírása”. A label
paraméter helyett célozhatunk akármelyik másik paraméter alapján is, például a key
-vel, és ebben az esetben így változik a kód:
[...]
switch ( $field['key'] ) {
case 'field_5f05ac0726f03':
[...]
Ez a kód annak a feltételnek felel meg, hogy “ha a mező key
paramétere field_5f05ac0726f03
, akkor […]”.
Végszó
Az általunk lérehozott egyéni pluginnal hozzáadtuk a kívánt funkciókat, sőt, még a sablon hiányosságán is javítani tudtunk, anélkül, hogy a sablon fájljait szerkesztettük volna. Megkönnyítette a dolgunkat, hogy a sablon az Advanced Custom Fields-et használta a mezők hozzáadásához, mivel az ACF egy fejlesztőbarát, könnyen bővíthető plugin.