headerbanner

Lekce XSLT transformace a XML Schema validace, aneb jak v PHP vytvořit menu z XML (5)

Když vytváříme stránku, potřebujeme k ostylování nějaký obsah. Abychom si nepřidávali práci, měl by se dát pracovní HTML dokument s tímto obsahem použít jako šablona. Když bude šablona zobrazována prohlížečem úplně stejně, jako původní pracovní dokument (stránka webu), bude to jen dobře. A když zůstane validním HTML dokumentem, o to lépe.

V šabloně potřebujeme označit místa, kam se má vložit obsah sekce HEAD, generovaný specificky pro každou stranu z podkladového XML. Dále menu a případně další části.

Menu jsme zatím generovali v podobě společné pro všechny strany. Pokud bychom u toho zůstali, nemělo by smysl psát menu do podkladového XML do elementů MENUGROUP, NEMUITEM atd. Přímý zápis kódu rovnou s tagy UL, LI atd. by byl dokonce rychlejší. Jenže - zpravidla u každé strany potřebujeme v menu graficky vyznačit, kde se zrovna nacházíme. Musíme tedy přiřadit položce menu, na kterou jsme kliknuli, než jsme se dostali na danou stránku, nějaký "příznak", tedy třídu nebo id. Když pomocí XSLT přidáme aktuální položce id="current", bude mít vytváření podkladového XML smysl.

Nyní zpěk k šabloně. Zobrazení HTML se nemění vložením komentářů. Když s jejich pomocí dokážeme vyznačit a pak najít místa, kam vkládat specifický kód, bude to jedno z možných řešení. Pak by začátek kódu strany se sekcí HEAD mohl vypadat například takto:

 
<!DOCTYPE html>
<html>
  <head>
  <!--<h>--><!--</h>-->
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
  <meta name="author" content="www.newsroom.cz">
  </head>    
 

Použiji "pseudoelement" H s počáteční i koncovou značkou uzavřenou do komentářů. Takový kód může zůstat i ve výsledném HTML, přičemž uvnitř mezi oběma komentáři bude kód generovaný z podkladového XML.

Značky "tady začíná a tady končí kód generovaný pro HEAD" musíme zachovat i ve výsledném HTML souboru, abychom při změně podkladového XML (změna TITLE kvůli SEO a podobně) mohli v hotové stránce vyměnit jen definovaný kousek kódu. Jinak bychom při každé změně podkladu museli generovat celý web z template a obsah každé strany znovu zapisovat. Template poslouží pouze pro prvotní generování webu, pak budeme viditelný obsah každé strany (mimo menu a dalších generovaných částí) vytvářet zvlášť. Co vytvoříme a nevložíme dovnitř "pseudoelementů", musíme při "regeneraci" po změně podkladového XML zachovat.

V uvedeném vzorku kódu vidíte i další princip zvoleného řešení. Negenerujeme celou sekci HEAD, část můžeme ponechat přímo v šabloně (zde autor a favicon a vložení stylu). Jsou to části, o kterých jsme přesvědčeni, že je nebude potřeba nikdy měnit. Bylo by zbytečné vše "cpát" do podkladového XML.

Výsledná šablona by pak vypadala například takto:

 
<!DOCTYPE html>
<html>
  <head>
    <!--<h>--><!--</h>-->
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
    <meta name="author" content="www.newsroom.cz">
    <link rel="stylesheet" type="text/css" href="style.css" />
  </head>
  <body>
  <!--<ph>--><!--</ph>-->
    <div id="modernbricksmenu">
      <nav ><!--<m>--><ul>
  <li class="first" id="current">
    <a href="">První strana</a>
  </li>
  <li>
    <a href="">Druhá strana</a>
  </li>
  <li class="last" >
    <a href="">Třetí</a>
  </li>
</ul><!--</m>--></nav> 
    </div>
    <div id="modernbricksmenuline"> </div>
    <div class="content">
      <article>
 
        <p class="perex">Lorem ipsum dolor sit amet consectetuer velit lacus accumsan semper eu. Quis malesuada ut orci Suspendisse Nam pretium dignissim ac justo felis. 
        </p>
        <h1>Vitae et pellentesque vitae</h1>  
        <p>Vitae et pellentesque vitae consectetuer tincidunt Sed justo odio pede ante. Purus Pellentesque Nam nibh ornare metus vitae vel id non venenatis. Ipsum justo nibh nisl Sed adipiscing quis nibh arcu dignissim malesuada. Velit mauris Vestibulum.
        </p>
        <h2>Ipsum justo nibh nisl</h2>  
        <p>Vitae et pellentesque vitae consectetuer tincidunt Sed justo odio pede ante. Purus Pellentesque Nam nibh ornare metus vitae vel id non venenatis. Ipsum justo nibh nisl Sed adipiscing quis nibh arcu dignissim malesuada. Velit mauris Vestibulum.</p>
      </article>
      <footer class="footer"><!--<f>-->To je pata.<!--</f>--></footer>
    </div>
  </body>
</html>
 

Podívejte se na výsledek. Šablona rovnou ukazuje, jak bude vypadat hotová strana, jedná se jen o komentáři doplněný HTML kód, který tak jako tak musíte při tvorbě strany napsat. A to nejen u statické strany, ale i v jakémkoli redakčním systému, pokud máte přesnou představu o vzhledu a nespoléháte se na hotovou šablonu. V této fázi jste tedy stále s pracností na úrovni dynamického webu, neděláte prakticky nic navíc.

V menu je nesprávná čeština. Trochu jsem předběhl a do šablony již nevkládal informaci o kódování stránky. S tím se musí trochu opatrně. Znakovou sadu v "META charset" musíme zapsat na začátek sekce HEAD, protože musí být v prvních 1024 bytech dokumentu. Podle některých SEO doporučení by ovšem měl být co nejblíž začátku kódu strany i tag TITLE. Abychom mohli obojí správně zařadit, tedy TITLE hned za META charset, a zároveň abychom mohli znakovou sadu nastavovat pro každý web co nejpohodlněji, definoval jsem ji v podkladovém XML.

V template vidíte, že jsou definovány i další kusy vkládaného kódu kromě mísa v HEAD třeba patička. V ní může být třeba kontakt. Pokud budete chtít ve výsledném statickém webu za půl roku změnit třeba telefon, bude to velmi jednoduché a nebudete muset přepisovat všechny tři strany - a to je vlastně cíl celého snažení.

Když máme template, můžeme napsat podkladový XML. Bude oproti původnímu trochu upravený a bude zahrnovat právě elementy s obsahem společným pro všechny strany:

 
<?xml version="1.0" encoding="UTF-8"?>
<allweb><!--nový kořenový element zdůrazňuje, že v podkladovém XML není jen menu-->
  <menu>
    <menugroup>
      <menuitem>
        <inanchor>Úsporná dmychadla Secoh JDK</inanchor>
        <url>index</url>
        <title>Úsporná dmychadla SECOH JDK na covdily.cz</title> 
        <desc>Úsporná dmychadla SECOH JDK zlevní provoz vaší domovní čistírny odpadních vod. Na dobu případné záruční opravy zapůjčíme náhradní dmychadlo zdarma.</desc>
        <key>Secoh, JDK, dmychadlo, air pump, airpump</key><pagetype>html</pagetype>
        <lang>cs</lang>
      </menuitem>
      <menuitem>
        <inanchor>Technické údaje Secoh JDK</inanchor>
        <url>secoh-jdk-udaje</url>
        <title>Technické údaje Secoh JDK</title>
        <desc>Úsporná dmychadla SECOH JDK - technické údaje.</desc>
        <key>secoh, jdk, záruka</key>
        <pagetype>html</pagetype>
        <lang>cs</lang>
      </menuitem>
      <menuitem>
        <inanchor>Schovejte své dmychadlo</inanchor>
        <url>secoh-jdk-box-sachta</url>
        <title>Secoh JDK informace</title>
        <desc>Úsporná dmychadla SECOH JDK - schovejte své dmychadlo u ČOV na úroveň terénu do speciálního boxu nebo šachty.</desc>
        <key>secoh, jdk, informace</key>
        <pagetype>html</pagetype>
        <lang>cs</lang>
      </menuitem>
    </menugroup>
  </menu>
  <inhead><!--pro všechny strany společné elementy v sekci HEAD-->
    <![CDATA[
      <link rel="stylesheet" type="text/css" href="style.css" /> 
      <script>
         var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-xxxxxx-15']);
        _gaq.push(['_trackPageview']);
      (function() {
          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
        })();
      </script>
    ]]>
  </inhead>
<!--
     Znakovou sadu v "META charset" musíme zapsat na začátek sekce HEAD, protože musí být v prvních 
    1024 bytech dokumentu. (http://www.w3.org/International/questions/qa-html-encoding-declarations).
    Podle některých SEO doporučení by ovšem měl být co nejblíž začátku kódu strany i tag TITLE.
    Abychom mohli obojí správně zařadit, tedy TITLE hned za META charset, definuji znakovou sadu
    zde. Ve výsledné XSLT šabloně pak můžeme řazení lépe dodržet. Jinak by se samozřejmě dala 
    znaková sada zapsat do souhrnného elementu "inhead".
--> 
   <charset>
    utf-8
   </charset>
   <pageheader><!--pro všechny strany společný úvod stránky, například obrázek -->
   </pageheader>
   <footer><!--pro všechny strany společná patička, například s kontakty-->
    <![CDATA[
      Weby s dobrou návštěvností dodává <a href="http://www.newsroom.cz">www.newsroom.cz</a>
    ]]>
   </footer>
</allweb> 
 

Všimněte si, že obsah elementu INHEAD (vkládaný do hlavičky každé stránky) a FOOTER je uzavřen do CDATA. Nemusíme si tedy dělat starosti s v XML nepovolenými znaky, nic v CDATA není kontrolováno na validitu XML dokumentu.

Pro náš "redakční systém" máme tedy definovány dva vstupní dokumenty, template a XML (vše najdete v další části ke stažení). Pro jednoduché weby se stejnou strukturou tedy do budoucna můžete pracovat jen s těmito dokumenty, vše ostatní (samozřejmě kromě zápisu vlastního obsahu každé strany) udělá "systém". V něm - v příštím dílu - využijeme modifikované verze předchozích xsd, xsl a php souborů.