Glifis_LP: Eigene Templates

Hey Leute!

Also erstmal wollte ich nur sagen, dass ich hier ganz neu im Forum, und erst 13 Jahre alt bin!
Aber mein Alter hat mich trotzdem nicht daran gehindert, mit programmieren anzufangen!

Meine Frage lautet: Wie kann ich ein einfaches Templatesystem entwickeln?
Ich will euch genaueres anhand einen Beispiels erklären. Das Beispiel ist eine Downloadseite. Es gibt eine Downloads.php (in der wird eine Liste aller verfügbaren Downloads aufgelistet), eine  eine download.php (hier wird ein Download gezeit, auf den man geklickt hat, und eine download.tpl.htm (hier drin soll das Template stehen).

Die download.php vergibt jedem einzelnem Download eine downloadID, und über die soll der Browser dann erkennen, welcher Download das jetzt ist. In einer Datenbank sollen die Zeilen: "downloadID", "headline", "teaser", "Text", "Foto" sein. Ich will in der download.php eingetragen haben, dass der das, was in der Datenbank steht, auslesen will. Aber halt die richtige downloadID.

Der HTML Code für download.tpl.php:

  
<!doctype html>  
<html>  
    <head>  
       <title>Templatesystem</title>  
       <meta charset="UTF-8">  
    </head>  
    <body>  
          <!--Die Überschrift soll angezeigt werden: -->  
            [:HEADLINE:]  
  
          <!--Der Teaser soll ausgegeben werden:-->  
            [:TEASER:]  
  
          <!--Der Text soll ausgegeben werden:-->  
            [:TEXT:]  
  
          <!--Ein Foto soll angezeigt werden:-->  
            [:FOTO:]  
  
  
    </body>  
</html>  
  

Ich wollte nur mal vorweg sagen, dass ich PHP beherrsche, aber ich trotz langem rumprobierens nichts geschafft habe.

Ich hoffe, es kann mir jemand helfen.

Mir freundlichen Grüssen,
Lukas plaewe

  1. Mahlzeit,

    Meine Frage lautet: Wie kann ich ein einfaches Templatesystem entwickeln?

    Bei "einfach" solltest du auf Platzhalter verzichten und direkt die PHP-Variablen anzeigen. ALso anstatt

    [:HEADLINE:]

    schreibst du

    <?php echo $headline;?>

    Dabei solltest du aber $headline in einer anderen Datei definieren, da die Logik und die Anzeige getrennt bleiben sollte. Deshalb nutzt man ja ein Template-System ;)
    Die Datei sollte dann natürlich download.tpl.php heissen und per include in die download.php eingebunden werden.

    Ich wollte nur mal vorweg sagen, dass ich PHP beherrsche, aber ich trotz langem rumprobierens nichts geschafft habe.

    Jetzt wäre gut zu wissen, was du genau probiert hast.
    Du benötigst einen Parser, der dein Template durchgeht und dann die Platzhalter ersetzt.
    Das geht z.B. per str_replace(), preg_replace() oder vergleichbaren Funktionen.

    Schau dir das hier mal an, das könnte dir evtl. weiterhelfen, wie ein Template-System arbneitet. Ich nutze Smarty3, das ist aber schon ein Klopper für grossere Projekte und für Grundlagenforschung wohl zu gross ;)

    --
    42
  2. Hello Lukas,

    Also erstmal wollte ich nur sagen, dass ich hier ganz neu im Forum, und erst 13 Jahre alt bin!
    Aber mein Alter hat mich trotzdem nicht daran gehindert, mit programmieren anzufangen!

    Meine Frage lautet: Wie kann ich ein einfaches Templatesystem entwickeln?
    Ich will euch genaueres anhand einen Beispiels erklären. Das Beispiel ist eine Downloadseite. Es gibt eine Downloads.php (in der wird eine Liste aller verfügbaren Downloads aufgelistet), eine  eine download.php (hier wird ein Download gezeit, auf den man geklickt hat, und eine download.tpl.htm (hier drin soll das Template stehen).

    Die download.php vergibt jedem einzelnem Download eine downloadID, und über die soll der Browser dann erkennen, welcher Download das jetzt ist. In einer Datenbank sollen die Zeilen: "downloadID", "headline", "teaser", "Text", "Foto" sein. Ich will in der download.php eingetragen haben, dass der das, was in der Datenbank steht, auslesen will. Aber halt die richtige downloadID.

    Der HTML Code für download.tpl.php:

    <!doctype html>
    <html>
        <head>
           <title>Templatesystem</title>
           <meta charset="UTF-8">
        </head>
        <body>
              <!--Die Überschrift soll angezeigt werden: -->
                [:HEADLINE:]

    <!--Der Teaser soll ausgegeben werden:-->
                [:TEASER:]

    <!--Der Text soll ausgegeben werden:-->
                [:TEXT:]

    <!--Ein Foto soll angezeigt werden:-->
                [:FOTO:]

    </body>
    </html>

      
    Ich finde Deinen Ansatz gut.  
    Vollständige Trennung von Markup, Style und Content wäre ein erstrebenswertes Ziel.  
      
    Das ertüchtigt das System dann ganz leicht zur Syndication. Die Partner können also ein eigenes Markup und eigene Sytels bereitstellen und nuten nur den Content der zentralen Verwaltung.  
      
    Wie man das dann abwickeln kann, da gibt es unterschiedliche Ansätze.  
    Ich würde mich freuen, dich bei deinen eigenen Gedanken zu dem Thema zu unterstützen.  
      
      
    Du könntest selbstverständlich auch schauen, wie es andere "Templatesysteme" machen. Aber ich würde das erst nach der Formulierung der eigenen Gedanken tun, denn man wird sehr schnell blind für Innovation und Kreativität, wenn "man es so macht, wie es üblich ist", also "das Rad nicht neu erfindet". Aber ich bin sicher, dass das ultimative Rad noch gar nicht erfunden wurde.  
      
    Mein Vorschlag wäre also: erstmal eigene Ideen diskutieren, sich nicht kirre machen lassen von "Best-Practice"-Vorschlägen, die hier ganz bestimmt gleich kommen werden \*g\*  
      
    Die Methode, die dir M. vorgeschlagen hat, ist eine übliche, hält aber die Trennung nicht ein. Man gibt dem Template-Trustie damit auch Macht über die Programmierung. Dies gilt es aber i.d.R. zu unterbinden.  
      
      
      
    Die Schwierigkeit bei Deiner Methode (die ich persönlich am saubersten finde) sind immer die optionalen oder wiederholten Inhalte (Tabellen, Listen, Abfragen aus der Datenbank, usw.) Das kann man aber auch lösen.  
      
    Und ein Template-System ist nur so gut, wie die zusätzlichen Werkzeuge für den Developer. Man muss also sowohl feststellen können, welche Platzhalter im Template zur Verfügung stehen, als auch wissen, welche Replace-Funktionen dafür zur Verfügung stehen.  
      
    Und man sollte sich von vorne herein immer klar machen, dass das Template nur passiv bleibt und nur zur Darstellung dient, nicht aber zur Steuerung!  
      
      
    Wenn Du Interesse hast, daraus eine längere Sache zu machen, dann kannst Du mir gerne auch eine eMail schreiben an tom.vom.berg@online.de  
      
    Und als Grundidee schau Dir mal die Mächtigkeit der PHP-Funktion str\_replace() an  
    <http://de2.php.net/manual/en/function.str-replace.php>  
      
      
      
      
      
      
      
      
    Liebe Grüße aus dem schönen Oberharz  
      
      
    Tom vom Berg  
    ![](http://selfhtml.bitworks.de/Virencheck.gif)  
      
    
    -- 
     ☻\_  
    /▌  
    / \ Nur selber lernen macht schlau  
    [Die ultimative Seite für Selbermacher](http://getscript.de/)
    
  3. hi,

    Meine Frage lautet: Wie kann ich ein einfaches Templatesystem entwickeln?

    Vorab überlegen, was gebraucht wird und wie die Patzhalter aussehen könnten. Für Dein Vorhaben sollte das Templatesystem (nennen wir es Template Engine, TE) Loops können. Hinzu kommt das einfache Ersetzen von Platzhaltern, die einfache Literale (Strings) sind. Oft gebraucht in einem Template sind Kontroll-Elemente if/else. Das wären die Mindestanforderungen.

    Die Platzhalter könnten so aussehen, Loops mit %loop_*% beginnen, wobei * dann ein frei wählbarer Name ist. Die TE muss wissen, wann Schluss ist, das könnten wir einheitlich mit %endloop% kennzeichnen.

    Ähnlich if/else und das mal zusammen mit einer Schleife in einem Template

    %if_downloads%

    %loop_downloads%
     <h2> %title% </h2>
     <p> %descr% </p>
    %endloop%

    %else%

    <p>Leider gibts heute nix zum Download, aber <a href=%link_story%" title="%title_story%">eine schöne Gute-Nacht-Geschichte</a>.   </p>

    %endif%

    So oder so ähnlich sehen viele Templates aus, gesprochen wird die Sprache der TE wobei die Geschäftslogik und die Beschaffung der Inhalte an einer anderen Stelle erfolgt.

    Umsetzen könntest Du das entweder mit Regulären Ausdrücken oder mit einem Parser, Ersteres ist einfacher, Beispiel fürs Loop: Alles was zwischen %loop_*% und %endloop% liegt, wird ermittelt, das ist sozusagen ein Template im Template, hier wären dann nur noch Literale zu ersetzen. Die TE geht durch das Array der Platzhalter und nimmt die Ersetzungen vor.

    Ähnlich %if_*% %else% %endif% hier hätten wir wiederum kleine Template-Fragmente innerhalb des gesamten Templates.

    Zum Schluss werden die übriggebliebenen %literale% ersetzt und das Template gilt als gerendert.

    Willst Du Dir das antun? Ja, oder Ja? Ja, ich habs auch gemacht und ich habe es nicht bereut, an meiner TE habe ich immer wieder meine Freude beim Erstellen von Seiten mit dynamischen Inhalten oder interaktiven Anwendungen, weil sowohl Code als auch Templates schön übersichtlich sind.

    MfG

    1. Hi,

      Die Platzhalter könnten so aussehen, Loops mit %loop_*% beginnen, wobei * dann ein frei wählbarer Name ist. Die TE muss wissen, wann Schluss ist, das könnten wir einheitlich mit %endloop% kennzeichnen.

      […]

      Umsetzen könntest Du das entweder mit Regulären Ausdrücken oder mit einem Parser, Ersteres ist einfacher, Beispiel fürs Loop: Alles was zwischen %loop_*% und %endloop% liegt, wird ermittelt

      Das bringt dich in der RegEx-Variante aber leicht in Schwierigkeiten, wenn Schleifen verschachtelt werden.

      Wenn du den Ende-Marker analog zum Start-Marker „benennst“ – %loop_FOO% und korrespondierendes %endloop_FOO% – lässt sich zumindest das umgehen (wobei man im regulären Ausdruck dann bspw. eine Back Reference nutzen könnte).

      Und mit if/else/endif analog.

      MfG ChrisB

      --
      Autocomplete has spoiled me to a point where it happens every so often that I encounter a CAPTCHA, and I just type in the first character … and then wait for the rest of the code to be automatically suggested :/
      1. Hi!

        So wie ich den Hotti einschaetze hat der das auch ohne Namen im Ende-Marker. Frei nach der Devise: "zumachen kann man nur das zuletzt aufgemachte". Wandert da rekursiv durch, oder so. Funktioniert sicher auch, vorrausgesetzt das Template is sauber umgesetzt.

        --
        Signaturen sind bloed.
      2. hi,

        Umsetzen könntest Du das entweder mit Regulären Ausdrücken oder mit einem Parser, Ersteres ist einfacher, Beispiel fürs Loop: Alles was zwischen %loop_*% und %endloop% liegt, wird ermittelt

        Das bringt dich in der RegEx-Variante aber leicht in Schwierigkeiten, wenn Schleifen verschachtelt werden.

        Ja, da hast Du vollkommen recht.

        Wenn du den Ende-Marker analog zum Start-Marker „benennst“ – %loop_FOO% und korrespondierendes %endloop_FOO% – lässt sich zumindest das umgehen (wobei man im regulären Ausdruck dann bspw. eine Back Reference nutzen könnte).

        Das wäre die Lösung. Und machbar ist das alles auch für if/else.

        Praktisch meine ich jedoch, dass ein Template so einfach wie möglich aufgebaut sein soll, insbesondere dann, wenn es in die Hände von Kunden gegeben wird. Also ich meine, wenn ein Template dahin tendiert, der Programmlogik immer ähnlicher zu werden, dass es in solchen Fällen besser via Programmlogik ausgetauscht werden sollte.

        Geschachtelte Schleifen sind oft erforderlich, z.B. zum Aufbau einer Tabelle für einen Kalendermonat. Wenn die TE nur einfache Schleifen kann, geht das entweder mit mehreren Templates zu lösen oder die Schachtelung wird über dem Code abgebildet mit nur einem Template.

        Auf jeden Fall sollte eine TE Kontrollstrukturen innerhalb einer Schleife können. Bei meinem Framework kann ich auch die TE komplett austauschen, das Datenversteck (Platzhalter-Hash) ist bei mir kompatibel zu HTML::Template, wenn's erforderlich ist, binde ich das zur Laufzeit über die Factory ein.

        Es gibt immer Gründe für eigene Entwicklungen. Ich hatte mal einen Nachbarn, der hat sich sogar eine Kreissäge selbst zusammengeschweißt, weil seine Brennholzlieferung zeitlich nicht zum Leihplan der Dorfkreissäge passte ;)

        Viele Grüße,
        Horst Heizer

        1. Moin!

          Es gibt immer Gründe für eigene Entwicklungen. Ich hatte mal einen Nachbarn, der hat sich sogar eine Kreissäge selbst zusammengeschweißt, weil seine Brennholzlieferung zeitlich nicht zum Leihplan der Dorfkreissäge passte ;)

          Wo kommst Du eigentlich her? Aus MacGyverland?
          "Natuerlich ist das ausserhalb jeder vernuenftigen Spezifikation, aber es funktioniert."

          Gruesse aus dem Wiewawunderland,
          Steel

        2. Meine Herren!

          Praktisch meine ich jedoch, dass ein Template so einfach wie möglich aufgebaut sein soll

          Ja, im Idealfall logic-less und rein deklarativ. Handlebars und Mustache machen es vor.

          Auf jeden Fall sollte eine TE Kontrollstrukturen innerhalb einer Schleife können.

          Pfui, am besten gar keine Kontrollstukturen ;)

          --
          “All right, then, I'll go to hell.” – Huck Finn
          1. hi,

            Pfui, am besten gar keine Kontrollstukturen ;)

            Und: Keine Formulare!!!

            Oh Mann, hätte nie gedacht, dass JavaScript so geil sein kann und eine Skalierung über canvas was bringt, das Upload einer vergleichbaren Bild-Elite konnte ich so von 5 Minuten auf 47 Sekunden senken, Zeit ist Geld ;)

            (Is aber auch nüschd Neues)

            MfG

            PS: Heut abend Feuerwerk in Nierstein near Oppenheim, bis dann :)

          2. Mahlzeit,

            Ja, im Idealfall logic-less und rein deklarativ. Handlebars und Mustache machen es vor.

            Die kochen auch nur mit Wasser. Ob die Suppe nach dem Essen drinbleibt, entscheidet der Gast :)

            MfG

            1. Meine Herren!

              Ja, im Idealfall logic-less und rein deklarativ. Handlebars und Mustache machen es vor.

              Die kochen auch nur mit Wasser. Ob die Suppe nach dem Essen drinbleibt, entscheidet der Gast :)

              Was soll ich darauf jetzt entgegnen? Deklarativ oder imperativ ist ein Paradigmen-Wechsel, ein viel größeres Unterscheidungsmerkmal für Template-Engine gibt es vermutlich nicht.

              Btw, dein Vorschlag mit %loop_downloads% ist ja auch deklarativer Natur. Imperativ wäre vergleichsweise: <? for ( $i = 0; $i < length( $downloads ); $i++ ) ?>

              --
              “All right, then, I'll go to hell.” – Huck Finn
      3. Hello,

        Die Platzhalter könnten so aussehen, Loops mit %loop_*% beginnen, wobei * dann ein frei wählbarer Name ist. Die TE muss wissen, wann Schluss ist, das könnten wir einheitlich mit %endloop% kennzeichnen.

        […]

        Umsetzen könntest Du das entweder mit Regulären Ausdrücken oder mit einem Parser, Ersteres ist einfacher, Beispiel fürs Loop: Alles was zwischen %loop_*% und %endloop% liegt, wird ermittelt

        Das bringt dich in der RegEx-Variante aber leicht in Schwierigkeiten, wenn Schleifen verschachtelt werden.

        Wenn du den Ende-Marker analog zum Start-Marker „benennst“ – %loop_FOO% und korrespondierendes %endloop_FOO% – lässt sich zumindest das umgehen (wobei man im regulären Ausdruck dann bspw. eine Back Reference nutzen könnte).

        Die Platzhalter im Markup sollten sich in der Art überhaupt nicht unterscheiden.

        Sie können entweder weitere Platzhalter nebst Markup enthalten, oder nicht. Ob sie eien Schleife darstellen oder nicht, entscheidet sich in der Steuerdatei des Controllers. Diese zieht dafür die Datenlage und die Geschäftsregeln zu Rate.

        Ich sage hier extra nicht "HTML", denn welches Markup benutzt wird, muss den Platzhaltern vollkommen egal sein. Sie dürfen es nur einschließen, wenn nötig.

        Um es nochmal auf den Punkt zu bringen: In der Markup-Datei darf man gar nicht erkennen können, ob es eine Schleife gibt, oder der ganze Summs nur einmal kommt, genauso, wie er da steht.

        Schön wäre es, wenn man eine solche Markup-Datei vailidieren könnte. Das müsste auch möglich sein, wenn man vorher alle Platzhalter-Symbole extrahiert. Leider kann dann der Controller trotzdem die resultierende Datei noch ungültig machen, wenn er an Stellen, an die soetwas nicht gehört, trotzdem Wiederholungen einpflanzt.

        Er muss daher leider wissen, bei welchem Markup welches Element repeatable oder mandativ ist, und welches nicht.

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        Die ultimative Seite für Selbermacher
        1. hi,

          Ich sage hier extra nicht "HTML", denn welches Markup benutzt wird, muss den Platzhaltern vollkommen egal sein. Sie dürfen es nur einschließen, wenn nötig.

          Das war einer meiner Gründe zum Entwickeln einer eigenen TE mit der ich auch Text/Plain-, CSV-, XML- o.a. Ausgaben recht einfach erzeugen kann; da wird nur das Template ausgetauscht, am Code ändert sich nichts.

          MfG