Pouze tento týden sleva až 80 % na e-learning týkající se C# .NET. Zároveň využij akci až 30 % zdarma při nákupu e-learningu - Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 13 - Šablonovací systém XSLT v PHP - vícejazyčné šablony

V minulé lekci, Šablonovací systém XSLT v PHP - jednoduché čtení RSS, jsme si ukázali jednoduché čtení RSS pomocí transformace XSLT.

Možná je načase vytáhnout zbraně silnějšího kalibru. Co když chceme vytvořit vícejazyčný web? Možností je několik. Například můžeme všechny texty uložit do databáze, před vlastní prezentací si je vytáhnout a použít v šabloně. Myšlenka je to lákavá a zřejmě i velmi často používána.

Uvedené řešení však má několik nevýhod. Například zbytečnou zátěž databáze při hromadném výběru celého slovníku. Co kdybychom měli každý slovník v jiném souboru? Stejně ho vždy musíme přečíst celý. Jako obvykle však musíme vybrat vhodný formát. Jenže když už výstupní šablonu mám v XSLT, co kdybych udělal v XSLT i slovník?

Ano, tohle řešení funguje. Vhodný postup jsem našel na jednom webu, i když nebyl zcela ideální. Proto jsem ho přizpůsobil svým potřebám. Nejprve tedy výstupní šablona, kterou uložím do souboru template.xsl:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
<xsl:output method="html" cdata-section-elements="a"/>

<xsl:variable name="lang.webname">Český název webu</xsl:variable>

<xsl:template match="/stranka">
<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;
</xsl:text>
<html lang="{$lang}">
<head>
<xsl:apply-templates select="title"/>
<link rel="StyleSheet" href="/style.css" type="text/css" />
</head>
<body>
<h1><xsl:value-of select="$lang.webname"/></h1>
<p><xsl:value-of select="$lang.text"/></p>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

Je vidět, že zde používáme proměnné $lang, $lang.webname a $lang.text. Tyto texty budeme chtít napsat v požadovaném jazyce. Vytvořím tedy další soubory:

  • lang-cs.xsl:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
<xsl:import href="template.xsl"/>
<xsl:output method="html" encoding="utf-8" indent="yes"/>

<xsl:variable name="lang">cs</xsl:variable>
<xsl:variable name="lang.webname">Český název webu</xsl:variable>
<xsl:variable name="lang.text">Český pevný text</xsl:variable>
</xsl:stylesheet>
  • lang-en.xsl:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
<xsl:import href="template.xsl"/>
<xsl:output method="html" encoding="utf-8" indent="yes"/>

<xsl:variable name="lang">en</xsl:variable>
<xsl:variable name="lang.webname">English webname</xsl:variable>
<xsl:variable name="lang.text">English fixed text</xsl:variable>
</xsl:stylesheet>

Pro každý jazyk si napíšeme další slovník s uvedenou strukturou. Výstupní šablona stále zůstává jen jedna. Všimněme si, že jsem v původní šabloně definoval hodnotu proměnné $lang.webname. Pokud bych ji zapomněli definovat ve slovníku, bude použita jako defaultní hodnota.

A jak dál? Už skoro nic. Jen je potřebné zavolat ten správný slovník, viz předchozí lekce:

<?php
$templ = new DOMDocument();
$templ->load('lang-cs.xsl');

$xsl = new XSLTProcessor();
$xsl->importStyleSheet($templ);

$doc = new DOMDocument();
$doc->load('data.xml');
echo $xsl->transformToXML($doc);
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Toto řešení má jednu nevýhodu:

  • Pro každou šablonu je nutná sada jazykových šablon. Ovšem většinou si vystačíme s jedinou šablonou na celý portál a proto je tato nevýhoda nepodstatná.

A rychlost? Zpracování šablony se slovníkem, který měl 1000 slov trvalo na mém Celeronu cca 100 ms. Většinou si však vystačíme s desetinovým i kratším, proto i výstupní časy budou kratší než 10 ms. Databázi by to trvalo déle.

K čemu se to hodí? Hlavně k lokalizaci menu, hlavního nadpisu, patičky, copyrightu a dalších pevných textů, které se generují na většině podstránek. Nehodí se na dynamická menu, tedy menu rozšiřovaná do databáze. Takové menu je lepší řešit přímo v databázi.

Prezentace stromové struktury z databáze

Nedávno jsem se v diskuzním fóru zmínil o tom, že jsem vyřešil prezentace stromové struktury z databáze. Nelze to dělat přímo v databázi, protože relační databáze na takový typ dat nejsou stavěny. Je však možné zkombinovat to nejlepší z databáze i PHP.

Nejprve si založíme databázi a naplníme ji nějakými daty:

> sqlite3 tree.sqlite

BEGIN TRANSACTION;
CREATE TABLE strom(id integer primary key autoincrement, gid int, pid int, nazev text);
INSERT INTO "strom" VALUES(1,1,NULL,'prvni vlakno');
INSERT INTO "strom" VALUES(2,1,NULL,'prvni vlakno 2');
INSERT INTO "strom" VALUES(3,1,1,'prvni vlakno 3');
INSERT INTO "strom" VALUES(4,2,NULL,'druhe vlakno 1');
INSERT INTO "strom" VALUES(5,2,NULL,'druhe vlakno 2');
INSERT INTO "strom" VALUES(6,2,4,'druhe vlakno 13');
INSERT INTO "strom" VALUES(7,2,4,'druhe vlakno 14');
INSERT INTO "strom" VALUES(8,2,1,'druhe vlakno 15');
INSERT INTO "strom" VALUES(9,2,7,'druhe vlakno 141');
INSERT INTO "strom" VALUES(10,2,7,'druhe vlakno 142');
INSERT INTO "strom" VALUES(11,2,9,'Příšerně žluťoučký kůň úpěl ďábelské ódy');
INSERT INTO "strom" VALUES(12,2,5,'Přidaný text');
DELETE FROM sqlite_sequence;
INSERT INTO "sqlite_sequence" VALUES('strom',12);
COMMIT;

Význam sloupců:

  • id - jednoznačná identifikace záznamu
  • gid - identifikace stromu. V jedné tabulce může být víc stromů
  • pid - označení rodiče aktuálního záznamu
  • nazev - jakýkoli text

Jako primární klíč ponechám id, pro větší fórum je vhodné udělat další index podle gid.

Data už máme, zbývá nám pouze jejich výpis:

<?php
$db=new PDO('sqlite:tree.sqlite');
$prep=$db->prepare('SELECT id, pid, nazev FROM strom WHERE gid=? ORDER BY id;');
$prep->execute(array(2));
$xml=new DOMdocument();
$pole=array();
$pole[0]=$xml->appendChild(new DOMElement('forum'));
while($row=$prep->fetch(PDO::FETCH_ASSOC)){
        $id=$row['id'];
        $pid=isset($row['pid'])?$row['pid']:0;
        $pid=isset($pole[$pid])?$pid:0;
        $pole[$id]=$pole[$pid]->appendChild(new DOMElement('item',$row['nazev']));
}
$xsl=new DOMdocument();
$xsl->load('strom.xsl');
$xslt = new XSLTProcessor();
$xslt->importStylesheet($xsl);
echo $xslt->transformToXML($xml);

Jak je vidět, v průběhu načítání dat z něj vytváříme stromovou strukturu v paměti. Tuto strukturu už přímo předáme šablonovacímu systému.

Výstupní šablona strom.xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="UTF-8" />

<xsl:template match="/">
<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;
</xsl:text>
<html>
<xsl:apply-templates />
</html>
</xsl:template>

<xsl:template match="/forum">
    <head>
    <title>Diskuzní fórum</title>
    <link rel="stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
    <xsl:apply-templates />
    </body>
</xsl:template>

<xsl:template match="item">
    <div class="vetvicka">
    <xsl:apply-templates />
    </div>
</xsl:template>

</xsl:stylesheet>

A nakonec ještě odkazovaný kaskádový styl style.css. Ten pro náš účel nemusí být vůbec dlouhý:

.vetvicka {
        margin-left:4%;
}

A to je vše. Aby z toho vzniklo opravdové diskuzní fórum, musel bych přidat vstupní formulář, jeho zpracování a uložení dat do databáze. K tomu by se hodila nějaká antispamová ochrana a administrační rozhraní pro moderátora. Pro náročnější ještě registrace uživatelů, přístupová práva, ... Chybí toho ještě hodně.

Uvedený příklad vůbec neřeší běhové chyby ani formátování příspěvku. Je to jen ukázka jednoduché prezentace stromového diskuzního fóra.

V další lekci, Práce s dokumenty Excel v PHP - Úvod a první skripty, se začneme věnovat knihovně PHPSpreadsheet pro práci s tabulkovými dokumenty a vytvoříme první xlsx soubor.


 

Předchozí článek
Šablonovací systém XSLT v PHP - jednoduché čtení RSS
Všechny články v sekci
Soubory a práce s nimi v PHP
Přeskočit článek
(nedoporučujeme)
Práce s dokumenty Excel v PHP - Úvod a první skripty
Článek pro vás napsal Kit
Avatar
Uživatelské hodnocení:
4 hlasů
Jsem spokojeným uživatelem operačních systémů založených na linuxovém jádře. Zejména openSUSE a Ubuntu. Pro psaní veškerých textů a programů používám vynikající textový editor Vim. Aplikace se snažím psát vždy v tom nejvhodnějším programovacím jazyk...
Aktivity

 

 

Komentáře

Avatar
Daniel Vraspír:9. srpna 16:08

Možnost stáhnout si soubor s daty by byla určitě fajn. :)

Odpovědět
9. srpna 16:08
Život je jedna velká hra.
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Daniel Vraspír:9. srpna 17:12

Detailněji popsané soubory a propojení, možnost stáhnout si soubor a files.

Odpovědět
9. srpna 17:12
Život je jedna velká hra.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.