headerbanner

Lekce XSLT ... (7) - konečně "redakční systém"

Máme rozbalený zip archiv z minulého článku, který obsahuje výkonný skript skeletoncreator.php:

 
<!DOCTYPE html>
<html lang="cs">
  <head>
  <meta charset="UTF-8"> 
  <meta name="author" content="www.newsroom.cz">
  </head>
  <body>
 
<?php
 
libxml_use_internal_errors(true);//abychom mohli vypsat chyby
libxml_clear_errors();
 
//regulární výrazy pro textu v ozančených místech šablony
$patterns = array();
//pro jazyk strany, tedy pro atribut lang v tagu <html lang="cs">
$patterns["l"] = "~(.*)(<\s*html[^>]*>)(.*)~is";
//pro sekci head
$patterns["h"] = "~(.*)(<\!--<h>-->)(.*)(<\!--</h>-->)(.*)~is";
//pro hlavičku obsahu stránky (nemusí existovat)
$patterns["ph"] = "~(.*)(<\!--<ph>-->)(.*)(<\!--</ph>-->)(.*)~is";
//pro menu
$patterns["m"] = "~(.*)(<\!--<m>-->)(.*)(<\!--</m>-->)(.*)~is";
//pro patičku obsahu stránky (nemusí existovat)
$patterns["f"] = "~(.*)(<\!--<f>-->)(.*)(<\!--</f>-->)(.*)~is";
 
 
 
//zásada "vše psát jen jednou" - proto načtení do DOMDocument a výpis chyb ve funkci 
function getDOMDoc($filename){
  $filename=realpath($filename);
  $xml= new DOMDocument();
  $xml->load($filename, LIBXML_NOENT|LIBXML_DTDLOAD|LIBXML_DTDATTR);
  $errors =  libxml_get_errors();
  if (count($errors)){
    foreach ($errors as $error) {
      echo $error->file.'|'.$error->line.'|'.$error->message."\n";
    }
    die ("Nenačten $filename");
  }
  return $xml;
}
//--------------------------------------------------------------------
//validace souboru s údaji o webu podle XML Schema
//má oproti původnímu přidané elementy s obsahem společným
//pro všechny strany webu
$xmlweb= getDOMDoc('userxml/exampleweb.xml');
if (!@$xmlweb->schemaValidate('systemxml/allweb.xsd')){
    $errors=  libxml_get_errors();
    foreach ($errors as $error) {
        echo $error->file.'|'.$error->line.'|'.$error->message."\n";
    }
    die ('Nevalidní XML');
}
//--------------------------------------------------------------------
 
 
 
//--------------------------------------------------------------------
//získáme obsahy všech elementů url z podkladového XML
//zároveň i typ souboru a jazyk stránky  
$xslurls= getDOMDoc('systemxml/allurls.xsl');
$procurls = new xsltprocessor();
$procurls->importStylesheet($xslurls);
$urlscontent= explode('~', $procurls->transformToXML($xmlweb));
//položka za posledním znakem '~' bude prázdná (resp. nový řádek), odstraníme ji
array_pop($urlscontent);
unset($xslurls);
unset($procurls);
//--------------------------------------------------------------------
 
//--------------------------------------------------------------------
//připravíme si nový procesor s transformační XSLT šablonou pro 
//obsah hlavičky
$xslhead = getDOMDoc('systemxml/allforpages.xsl');
$prochead = new xsltprocessor();
$prochead->importStylesheet($xslhead);
//--------------------------------------------------------------------
 
//načteme šablonu pro získání kódu  menu 
//a připravíme transformační XSLT procesor
$xslmenu = getDOMDoc('systemxml/allmenu.xsl');
$procmenu = new xsltprocessor();
$procmenu->importStylesheet($xslmenu);
//projde stránky 
foreach ($urlscontent as $value) {
  $urlslangs=explode("~",$value);//získá pole řetezců ve tvaru url|jazyk 
  if ($urlslangs[0]!==''){
    $tmp=explode("|",$value);//získá pole, v prvku [0] je url, v [1] jazyk
    $lang=$tmp[1];
    $url=$tmp[0];
    $tmp=explode(".",$tmp[0]);
    $urlname= $tmp[0];//základ jména souboru pro pozdější vytvoření zálohy
 
 
    //pokud stránka existuje, jen "vyměníme" obsahy uvnitř pseudoelementů
    //a původní stránku uložíme jako zálohu s koncovkou .bak
    //jinak stránku vytvoříme z template/template.html 
    if (file_exists($url)){
      $html=file_get_contents($url);
      file_put_contents($urlname.'.bak',$html); //ulož původní do zálohy
      echo "Přepíši existující stranu $url".'<br>';
    }else{
      $html= file_get_contents(realpath("template/template.html"));
      echo "Ze šablony vytvořím stranu $url".'<br>';
    }
 
    //vynulování a nastavení parametru pro XSLT
    //je to dynamické nastavení parametru
    //místo statického vložení přímo do šablony4
    // pomocí <xsl:variable name="pageurl" select="....">
    $procmenu->removeParameter('', 'pageurl');
    $procmenu->setParameter('', 'pageurl', $urlname);
     $prochead->removeParameter('', 'pageurl');
    $prochead->setParameter('', 'pageurl', $urlname);   
    //prochází a přepisuje obsah přepsatelných částí jedné strany
    foreach ($patterns as $key=>$value){
      if(preg_match($patterns[$key],$html ,$match)){
        $tmp=0;
        if (isset($match[3])){
          switch ($key) {
            case "l":
              $match[2]="<html lang=\"$lang\">";
            break;  
            case "h":
              //individuální i společné tagy v HEAD pro každou stranu
              $match[3]=$prochead->transformToXML($xmlweb);
            break;
            case "ph":
              $part =$xmlweb->documentElement->getElementsByTagName("pageheader");
              if (isset($part->item(0)->textContent)){
                $match[3]= $part->item(0)->textContent;
              }
            break;
            case "m":
              //echo $procmenu->transformToXML($xmlweb);
              $match[3]=$procmenu->transformToXML($xmlweb);
             break;
            case "f":
              $part =$xmlweb->documentElement->getElementsByTagName("footer");
              if (isset($part->item(0)->textContent)){
                $match[3]= $part->item(0)->textContent;
              }
            break;                         
          }
          $tmp=count($match);
        }
        if($tmp){
          $html='';
          for($i=1;$i<$tmp;$i++){
            $html.=$match[$i];
          }
          //echo $html;
          file_put_contents($url, $html);
        }  
      }
    }
 
  }
}
?>    
</body>
</html>
 

Není to nijak elegantní programování, žádné třídy (kromě vestavěných), prakticky žádná kontrola chyb. Jenže u tak jednoduchého skriptu (nebýt komentářů, je to jen kousek kódu) není nic takového potřeba. Spuštěním skeletoncreator.php se ze šablony v adresáři template a z podkladového xml v adresáři userxml vytvoří kostra webu. Kostra je vytvářena ve stejném adresáři jako PHP skript, je tam také ikona favicon a stylopis CSS.

Pro generování "microsite" je to plně použitelný nástroj, i když ho samozřejmě nemůžete svěřit do rukou zákazníka. Ovšem - můžete to udělat třeba s Joomlou? V devíti z deseti případů. kdy zákazník sáhne do administrace, vám sekretářka zavolá "mně se tam něco rozbilo" a budete to napravovat. Když v mikrowebu potřebuje zákazník třeba přidat stránku, je to díky našemu novému "pseudoredakčnímu systému" hračka a je to možná rychlejší, než se pídit po tom, co "se rozbilo". Výsledné mikrosite pro dmychadla Secoh je příkladem použití.

Je fakt, že zveřejněným skriptům ještě pár užitečností chybí, ale ty si můžete dodělat sami. Například automatické generování sitemap je hračka. Pro SEO je to skoro nutné a tato funkce pak zvýrazňuje efektivitu "systému".