Ugrás a tartalomra

Sminkkészítés PHP Template-tel

Címkék:

Eljött az újabb idők szele, és vele együtt végre a Drupal 4.7, ami jelenleg a 4.7.2-nél tart. Ezzel együtt bekerült a smink motorok közé a PHP Template is, de külön elérhető korábbi verziókra is a http://drupal.org/project/phptemplate oldalon. Telepítéséhez a be kell másolni a kibontott fájlokat a themes/engines/phptemplate mappába. Segítségével teljes egészében le lehet váltani a PHP alapú sminkeket is, erre mutatok most pár megoldást.

A PHP Template tpl.php kiterjesztésű fájlokon (továbbiakban smink fájl) keresztül végzi el a sminkelést. A fájl neve a módosítandó theme függvénnyel kell hogy egyezzen, ami például node esetén node.tpl.php. A motor alapértelmezetten csak pár sminkelhető részhez kínál felületet, azaz csak pár smink fájlt fog alapértelmezetten keresni és feldolgozni.

A sminkelhető részek a következők:

  • page.tpl.php: a teljes oldal sminkelése
  • block.tpl.php: blokk sminkelése
  • box.tpl.php: általános befoglaló doboz sminkelése
  • comment.tpl.php: hozzászólás sminkelése
  • node.tpl.php: tartalom (node) sminkelése

Alapértelmezett részek sminkelése

Hogy lássuk hogyan is kell kinéznie egy ilyen smink fájlnak, tekintsük át ezek alapértelmezettjeit. Ezeket a fájlokat a drupal themes/engines/phptemplate könyvtárában találjuk tpl.php kitejesztéssel. Új smink készítése esetén kezdjük azzal, hogy ezeket a fájlokat bemásoljuk saját sminkünk (themes/[sajátsmink]) könyvtárába. A Drupal, ahogy más sminkek esetén, itt is a smink mappánkban levő style.css fájlt fogja használni a HTML elemek stílusának meghatározására, ezért ennek megfelelően járjunk el a CSS fájl létrehozásakor. Ha ezzel megvagyunk, tekintsük át hogy is működik a dolog.

A smink fájlok működése eléggé egyszerű. Amikor a motor megtalálja a fájlunkat átad neki pár megfelelő változót. Ezeket megtaláljuk a smink fájlunkban, vagy ha valamit mégis hiányolnánk, akkor hagyatkozzunk a PHP Template dokumentációjára, hogy melyek is az elérhető változók. Például a teljes oldal (page) sminkelése esetében elérhető változók listáját megtaláljuk a http://drupal.org/node/11812 oldalon.

Ezek a fájlok alapjában véve HTML fájlok, amikben csak pár PHP kódrészletet találunk csupán a változók kiírására. Nézzük meg erre a legegyszerűbb példát, ami a befogaló doboz sminkelését módosítja (ez pedig a box.tpl.php).
A teljes kód (a box.tpl.php tartalma) a következőképpen néz ki:

<div class="box">
  <?php if ($title): ?>
  <h2 class="title"><?php print $title ?></h2>
  <?php endif; ?>
  <div class="content"><?php print $content ?></div>
</div>

Mint látjuk ez akár egy HTML kódoló, vagy desinger számára is viszonylag könnyen értelmezhető, és akár Dreamweaver-ben, vagy hasonló vizuális szerkesztőben is könnyen szerkeszthető, ezzel levéve a terhet a programozó válláról. Azt is észrevehetjük hogy igazi programozás nincs is a fájlokban, csak egy egyszerű print $változó php kód van beszúrva oda ahol a megfelelő dinamikus tartalmat ki kell íratni, ami ebben az esetben a $title és a $content, ami megfelel a doboz címének illetve tartalmának. A sminkek olyan egyszerű dolgokon kívül mint egy if feltétel semmilyen PHP kódot nem tartalmaznak. A doboz sminkelése esetén ez azt jelenti, hogy ha volt a doboznak címe, akkor kiírjuk, ha nem, akkor nem írjuk ki a címet.
Amennyiben a PHP beállítások támogatják, és esetleg áttekinthetőbb, rövidebb kódot szeretnénk, a <?php print $változó ?> kódrészletet <?=$változó?>-ra cserélhetjük, amit talán a fájl szerkesztője könnyebben értelmezhetőnek, vagy könnyebben beilleszthetőnek tekinti.

A PHP Template motor lehetőséget biztosít minden egyes tartalom típus esetén egyedi megjelenítésre. Ennek eléréséhez nem kell mást tennünk, mint létrehozni a tartalom típusokhoz egy smink fájlt node-[tartalomtípus].tpl.php néven (például node-story.tpl.php, vagy node-page.tpl.php). Ezek a smink fájlok ugyanazokat a paramétereket kapják meg, mint maga a node.tpl.php, de attól teljesen különböző módon jeleníthetjük meg.

A fenti példánál bonyolultabb dologra igazából nem is lesz szükségünk, amennyiben csak az alapértelmezett részeket szeretnénk sminkelni. Ha azonban bonyolultabb dolgokat szeretnénk elérni, vagy ennél több eleme megjelenését kívánjuk megváltoztatni, akkor nagyobb előkészületre van szükségünk.

Más elemek sminkelése

Ahhoz hogy az alapértelmezett elemeken kívül más elemeket megjelenését is szeretnénk módosítani létre kell hoznunk egy template.php fájlt a smink könyvtárában. Minden egyes formázandó elemhez létre kell hozni egy phptemplate_[formázandó] függvényt ebben a fájlban, ahol a [formázandó] helyett a megfelelő Drupal-os smink függvény nevét kell behelyettesíteni. A sminkfüggvényeket a 4.6-os Drupal esetén a http://api.drupal.org/api/4.6/group/themeable, illetve 4.7 esetén a http://api.drupal.org/api/4.7/group/themeable oldalon találjuk.

Ha mondjuk a kép megjelenését akarjuk megváltoztatni, akkor vesszük az ehhez tartozó theme_image függvény alapján létrehozzunk egy phptemplate_image függvényt. A függvény paramétereinek meg kell egyeznie az eredeti smink függvény paramétereivel, valamint hogy a smink fájl milyen néven éri majd el ezeket a változókat. Ezen kívül meg kell határoznunk hogy melyik tpl.php fájl lesz a felelős a formázásért. Szerencsés ha ezt ugyan annak határozzuk meg ami a smink függvény neve, ebben az esetben image.tpl.php.

A teljes kód ebben az esetben tehát a következő:

<?php
function phptemplate_image($path, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE) {
  return
_phptemplate_callback('image',
    array(
'path' => $path, 'alt' => $alt, 'title' => $title, 'attributes' => $attributes, 'getsize' => $getsize));
}
?>

Az érthetőség kedvéért tisztázom a dolgokat. Amikor smink motor betölti a sminkünket, először megvizsgálja, mely elemek vannak meghatározva az alapértelmezettek közül, valamint betölti a template.php állományt. Amikor egy elemet kell megjeleníteni, ami alapértelmezett, és van hozzá smink fájl, akkor annak átadja a paramétereket, és a kódot eltárolja egy saját memória pufferbe.
Ha nem alapértelmezett, akkor megnézi van-e a megjelenítendő elemnek megfelelő phptemplate_[formázandó] függvény. Ha talál ilyen függvény a template.php fájlban, akkor azt meghívja azt az eredeti smink függvény paramétereit átadva ennek a függvénynek.

Ezután a _phptemplate_callback lép működésbe (az alapértelmezettek esetén is, csakhogy ott transzparensen, a programozó beavatkozása nélkül is), ami az egyes változóknak egyedi nevet ad, amelyeket majd a smink fájl behelyettesít a megfelelő helyekre. A _phptemplate_callback első paramétere a meghívandó smink fájl neve, a második pedig egy asszociatív tömb, melynek kulcsa az átadandó változó neve lesz, értéke pedig maga az érték ami átadódik.

A fenti esetben a smink fájlban elérhető változók a következők lesznek: $path, $alt, $title, $attributes, $getsize, azaz ezekkel tud majd a smink fájlunk manipulálni.

Egyéb trükkök

Amennyiben szeretnénk módosítani a változók tartalmát, azt a phptemplate_[formázandó] függvényben id elvégezhetjük, még a _phptemplate_callback meghívása előtt. Persze kevesebb, vagy több változót is átadhatunk a smink fájlunknak, valamint más neveket is adahatunk a változóknak az eredeti helyett, ám érdemes beszédes neveket használni, hogy a smink fájl szerkesztője is tudja, melyik változó mire való, mit is takar.

Minthogy a smink fájlok többször meghívásra kerülhetnek, nem szabad ezekben függvényeket elhelyezni, ugyanis a PHP-ban egy már létező függvény nem definiálható felül. Azonban ha mégis függvényekre van szükségünk a következőképpen járhatunk el.

A függvényeket a template.php rakjuk, és elnevezés tekintetében használjuk a _[sminkneve]_[függvény] sémát (például function _sminkem_menu_path() {}), a függvénynév összeakadások elkerülése végett. Ezeket a függvényeket akár a smink fájlokból is elérhetjük, és igen nagy szabadságot kívál fejlesztés tekintetében, de azt javaslom inkább a phptemplate_[formázandó] függvényben használjuk őket az átadandó változók formázására, előkészítésére a sminkfájl kódjának tisztán tartása, valamint a megjelenítés és a kód elválasztása okán is.

Ha akarjuk, akkor a megjelenítést további részekre bonthatjuk, azaz a phptemplate_[formázandó] függvényben többször is meghívhatunk _phptemplate_callback segítségével azonos, vagy különböző sminkfájlokat, a nekik megfelelő paramétereket átadva, és ezen függvények által visszaadott szöveget összefűve adhatjuk vissza a megfelelő kimenetet. A technika használatával olyan elemeket is formázhatunk, amelyek theme függvénye rengeteg PHP, vagy csak PHP kódot tartalmaz, ilyen például a theme_blocks vagy a theme_table.

Példa

Nagyon egyedi smink, illetve sminkrészlet is kialakítható PHP Template segítségével. Erre példaként a Quality Property Management oldalát hoznám fel, ahol egy alapvető változást eszközöltem, méghozzá a menüben.

A dolog lényege a blocks smink függvény felüldefiniálása volt. A függvényem megvizsgálja hogy az illető blokk menü blokk-e illetve a user modul 1-es deltájú blokkja. Utóbbi a felhasználó saját menüje, bejelentkezés nélkül pedig a ?Navigáció½ nevezetű blokk. Ha ilyen blokkal találkozik, akkor lekérdezi rekurzívan a megjelenítendő menüt teljes mélységig, nem csak az aktuálisan megjelenítendő mélységig, és abból épít egy XML fájlt, ami az összes menü elemet tartalmazza. A menü helyén megjelenő Flash mozi, pedig ezt az XML-t tölti be, és ez alapján jeleníti meg a menüt.

Persze mivel ez a rész teljesen PHP-ban van megírva, ezért használhattam többféle gyorsítótárat a menü változásának figyelésére. Egyik ilyen, hogy nem minden esetben kérdezem le a teljes menüfát, hanem csak megvizsgálom, hogy a lementett XML és a cache-ben tárolt változat mérete külömbözik-e. A cache a menü modul cache-ével együtt ürül ki, ugyhogy csak arra kell figyelnem, hogy létezik-e cache-elt változat. Mivel a Flash nem minden esetben tölti be az XML-t, hanem vagy kikényszerítik (változott a menü), vagy ha lejárt a saját cache-elése (bizonyos intervallumon után mindenképpen frissít), ezért újabb pár miliszekundumot és pár bájtnyi sávszélességet lehet nyerni. Ezek okán a Flash megjelenítését, és a neki átadandó paraméterket már a smink fájlban tudtam elhelyezni, megfelelő változókat adva át neki.

http://www.qpm.hu

Nagyom rendi lennél ha részleteznéd www.qpm.hu -n lévő megoldásod.

Más: ha itt a "hosszú cikk" végén a hozzászólás linkre kattintok,
ide printeli a hozzászólás ablakot... csak hogy a lap tetejéről kel legörgetnem hogy beleirjak. Nem lehet valahogy a müvelet után ide horgonyozni? mert pl. ha anyám nézné biztos azt hinné hogy nem működik a posztoló (nem görgetne le és váltaná meg a világot hozzászólásával...)

egyébként ez a hiba az én sminkemnél is meg van :(

A megoldásról meg legyen kedves cikket írni!

Ádi

Mire gondolsz?

Melyik részére gondolsz, nem minden része publikus a dolognak, legfeljebb ötleteket adhatok, ha konkrét kérdés van.
--
Poetro

xml flash menu részére

Zseniális,

XML generálás

Az XML-t a menüből nem olyan egyszerű legenerálni, mivel Drupal alatt a menü megjelenítése/generálása nem egy egyszerű megfejtés. Az XML legenerálása valahogy a következőképpen néz ki:

function qpmx_theme_menu_tree($pid = 1) {
  if ($tree = qpmx_menu_tree($pid)) {
    return $tree;
  }
}
function qpmx_menu_tree($pid = 1) {
  $menu = menu_get_menu();
  $output = '';

  if (isset($menu['visible'][$pid]) && $menu['visible'][$pid]['children']) {
    foreach ($menu['visible'][$pid]['children'] as $mid) {
      $output .= qpmx_theme_menu_item($mid, menu_in_active_trail($mid) || 
        ($menu['visible'][$mid]['type']) 
          ? qpmx_theme_menu_tree($mid) : '',         
        count($menu['visible'][$mid]['children']) == 0);
    }
  }

  return $output;
} 

function qpmx_theme_menu_item($mid, $children = '', $leaf = TRUE) {
  return '' . $children ."\n";
}

function qpmx_menu_item_link($mid) {
  $menu = menu_get_menu();

  $link_mid = $mid;
  while ($menu['items'][$link_mid]['type'] & MENU_LINKS_TO_PARENT) {
    $link_mid = $menu['items'][$link_mid]['pid'];
  }

  return 'title="'. $menu['items'][$mid]['title'] .'" link="'. url($menu['items'][$link_mid]['path']).'"';
}

$xml = qpmx_menu_tree($block->delta);

Ekkor a megfelelő blokkhoz tartozó menü XML-jét generálja le az Adatbevitel XML segítségéve Flash MX mozikba-ban látott formában, persze a tagok nélkül.
A kód eléggé bonyolultnak látszik, és igazából az is, majdnem pont olyan mint a theme_menu_tree által generált, és működés tekintetében is nagyon hasonló ahhoz.
--
Poetro

a flash-be melyik php file-t töltöd be?

megvan az xml-t generáló fv-nyed, de azt hogyan hivod meg flash-ből?

Mentés / URL hívás

Két megoldás létezhet:

  • Lemented a kimenetet, azaz a menüdet egy XML fileba és azt töltöd be.
  • Egy drupal URL-en elérhetővé teszed ezt a kimenetet, és ekkor a generáló oldal URL-jét kell megadni a flashben.

--
Poetro

nem találok változót

kezdem érteni, de egy ilyen egyszerű példát hogy lehet meoldani javascript nélkül tpl-ben?

footerben: legyen egy link a lap tetejére:
pl:(itt code kéne hogy megjelenjen, lehet hogy kifiltereli a drupal)

<p id="to_top"><a href="#header">vissza</a></p>

A gond az hogy a kedőlap tetejre visz, nem az épp aktuális lap elejére. Tehát közé kéne printelini az aktualis oldal címét, amire
nem találok default változót PHP Template súgóban.
pl:

<a href="<?php print $meghivando_aktualis_oldal_elerese ?>#header">vissza a lap tetejére</a>

Van ennek megoldása szkript nélkül?

Ádi

Path

A $_GET['q']-ban mindig megtalálható az aktuális elérési út.
--
Poetro

Köszönöm!

Köszönöm!

Nem nyugszik

A $_GET['q']
sokat segített,
De ha azt szeretném hogy mondjuk a f?oldal vagy valamely
kategória
valamelyik cikkének közepére horgonyozzak ami a <!--break-->
után van..?

..tehát ha pldául megnyitom http://www.poetro.hu/blog oldalad
és mondjuk a "Hogyan
használjunk natív UTF-8 kódolást Drupal alatt"
cikket választom, az teljesen relativ a http://www.poetro.hu/blog
oldalhoz képest. Még is egy generalt link úgy irányítana az oldal
közepére
hogy a cikk valódi oldalára ugrik (a horgonyhoz).
Erre ez apélda nem meg felel?:

<p
id="to_top"><a href="/poetro.hu/<?php print $_GET['q']?>#header">vissza</a></p>

mert ugye most nem a current oldal elérésére , hanem a generált node
egyik tartalmának az elérésére van szükség.
tehát a
#kozepe megoldás nem jó.
Ötlet?
Köszönöm a segítséged!

Üdv,
Ádi

Nem értem

Nem teljesen értem, mit is szeretnél.

Egy másik oldal bizonyos horgonyára ugrató linket?
Mert ha mondjuk az előző oldal horgonyára mutatót, akkor

<?php
l
("vissza", $_SERVER['HTTP_REFERER'], array(), NULL, "#header");
?>

lesz számodra a megoldás. Ha persze nem az előzőre, hanem egy konkrét oldalra akarsz ugrani, akkor ennek megfelelően cseréld le a $_SERVER['HTTP_REFERER'] részt.
--
Poetro

header változó

az alapértelmezett bluemarine theme is php template -et használ, van a page.tpl.php -ban egy rész ahol a $header -t irat ki egy div -es részen.

na itt még soha nem láttam tartalmat.

ez mire van tulajdonképpen?

header változó

az alapértelmezett bluemarine theme is php template -et használ, van a page.tpl.php -ban egy rész ahol a $header -t irat ki egy div -es részen.

na itt még soha nem láttam tartalmat.

ez mire van tulajdonképpen?