Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Template "Fehler"

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] Template "Fehler"

    Nabend zusammen,

    ich habe folgendes Problem mit meiner eigenen "Template-Engine":

    Hier erstmal die target Seite {TITLE} (mit dem "Fehler")

    Der Fehler ist offensichtlich. Die Tabelle mit den Logs ist nicht im Content-Bereich.
    Meine Frage: Wie kommt das, dass die über dem Layout ist?

    Normale Strings kann er anzeigen wie {DATUM} z.B.

    Würde mich freuen wenn jemand einen Einfall für die Lösung hat.
    PHP-Code:
    # tpl.php

    <?php
    session_start
    ();
    include(
    'inc/inc.config.php');
    include(
    'lib/class.template.php');
    include(
    'lib/class.log.php');
    $class1log = new Logging();

    $tpl = new Template;
    $tpl->makeFile('tpl/template.html');
    $tpl->makeReplace('TITEL','Header');
    $tpl->makeReplace('LOGINNAME'$tpl->showLoginname());
    $tpl->makeReplace('DATUM'$tpl->showDate());
    $tpl->makeReplace('CONTENT'$class1log->showLogs());

    echo 
    $tpl->compileTemplate();
    ?>
    PHP-Code:
    # class.template.php

    <?php
    class Template {
        var 
    $template;
        var 
    $tpltag = array();
        var 
    $output;

            function 
    makeFile($file){
                if (
    file_exists($file)) {
                    
    $this->template '';
                    
    $fp fopen ($file'r');
                        while(!
    feof($fp)){
                            
    $this->template .= fgets ($fp128);
                        }
                    
    fclose ($fp);
                } else {
                    return 
    false;
                }
            }

            function 
    makeReplace($name$content){
                
    $this->tpltag[$name] = $content;
            }

            function 
    compileTemplate(){
                if(!
    $this->output)
                    
    $this->output $this->template;
                    
    $keys = @array_keys($this->tpltag);
                    
    $status 0;
                    
    $start "{";
                    
    $end "}";
                        foreach (
    $keys as $key){
                            
    $this->output preg_replace('/'.$start.$key.$end.'/'$this->tpltag[$key], $this->output);
                                if (
    preg_match('/'.$start.$key.$end.'/'$this->output)) {
                                
    $status 1;
                            }
                        }
                        if (
    $status) {
                        
    $this->compileTemplate();
                        }

                    return 
    $this->output;
            }

            function 
    showLoginname(){
                
    $sql "SELECT vorname, nachname FROM user WHERE email='".$_SESSION['login_email']."'";
                
    $result mysql_query($sql);
                
    $row mysql_fetch_assoc($result);
                return 
    $row['vorname']." ".$row['nachname'];
            }

            function 
    showDate(){
                return 
    date("H:i")." Uhr am ".date("m.d.Y");
            }
    }
    ?>
    PHP-Code:
    # template.html

    <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.1//EN' 'xhtml11.dtd'>
    <
    html>
    <
    head>
    <
    link rel='stylesheet' type='text/css' href='style.css' media='all' />
    <
    title>{TITLE}</title>
    </
    head>
    <
    body>
    <
    div class='container'>
       <
    div class='headleft'><img src='image/top-links.jpg' alt='' width="6" height="19" /></div>
       <
    div class='headmiddle'>Logged in as <a href='#' class='headmiddlelink'>{LOGINNAME}</a>&nbsp;
          <
    span class="headmiddle1">|</span>&nbsp;Time: <span class="headmiddle2">{DATUM}</span>
          <
    span class="headmiddle1">|</span>
          <
    span class="headmiddle2"><a href='logout.php' class='headmiddlelink'>Logout</a></span>
       </
    div>
       <
    div class='headright'><img src='image/top-rechts.jpg' alt='' width="6" height="19" /></div>
       <
    div class='headbuttom'></div>
       <
    div class='header'></div>
       <
    div class='headred'></div>
       <
    div class='headend'></div>
          <
    div class='content'>
             <
    div class='navi'>
                <
    div class='navimain'><img src='image/main_menu.jpg' width='191' height='43' alt='' /></div>
                <
    div class='navirot'><a href='?menu=close' class='navirotlink'>&nbsp;&nbsp;News</a></div>
                <
    div class='navisub'>&nbsp;&nbsp;Hinzufuegen</div>
                <
    div class='navisub'>&nbsp;&nbsp;Loeschen</div>
                <
    div class='navinorm'><a href='getlogs.php'>&nbsp;&nbsp;Log</a></div>
             </
    div>
             <
    div class='context'>
                <
    div class='con1'></div>
                <
    div class='con2'></div>
                <
    div class='con3'></div>
                <
    div class='con4'>
                   <
    input class='searchinput' type='text' name='search' value='Ihr Suchebegriff...' />
                   <
    input name='searchbutton' type='submit' class='searchbutton' value='Senden' />
                </
    div>
                <
    div class='con5'></div>
                   <
    div class='contextmitte'>{CONTENT}</div>
                </
    div>
             </
    div>
    </
    div>
    </
    body>
    </
    html

  • #2
    Vermutlich weil deine showLogs() Methode der Logging Klasse den Wert nicht per return zurückliefert, sondern mit echo in den Ausgabepuffer schreibt.

    Benutz mal HTML-Validierung, das ist ja grauenhaft und kann dir bei einigen Problemen mit HTML sehr helfen (diesem allerdings nicht).

    Für Firefox:
    https://addons.mozilla.org/de/firefox/addon/249
    https://addons.mozilla.org/de/firefox/addon/60
    (Tools -> Validate HTML)

    Kommentar


    • #3
      Lasse ich es aber als return ausgeben wird nur eine Zeile aus der DB geholt. Verständlich nach einem return bricht er ja auch ab. Eine Idee wie ich das lösen kann?

      Das Template sollte doch Valid sein ansonsten wäre das eine Aufgabe die ich später in Angriff nehmen werde. Trotzdem danke für deine Antwort.

      Kommentar


      • #4
        Hallo methanol,

        SQL-Abfrage-Routingen haben in einer Template-Engine designtechnisch nichts zu suchen. Die Komponente sollte so unabhängig sein, dass sie ohne das funktioniert. SQL-Abfragen und Ausgaben sollten in eigenen Präsentationslogik-Komponenten residieren.

        Just my 2 cents!

        Kommentar


        • #5
          Naja die SQL-Abfrage hat ja auch nur indirekt mit der Template-Engine zu tun. Ich habe keine Ahnung wie ich sonst die Ausgabe der Tpl-Engine übergeben soll.

          Wie gehe ich am besten vor? Die showLogs()-Funktion umschreiben oder etwas an der Tpl-Engine ändern. Wo soll ich ansätzen?

          Ansonsten bedanke ich mich auch bei dir für deine Mühe.

          Kommentar


          • #6
            Definiere eine externe Klasse, die die Datenbankabfragen übernimmt. Deine Templateklasse benutzt dann nur noch diese Datenbankklasse als Schnittstelle und hat nichts mehr selbst damit am Hut.

            Kommentar


            • #7
              Indirekt hat die Tpl-Engine trotzdem etwas damit zu tun. Jetzt macht die Tpl-Engine doch auch keine SQL-Abfrage.

              Ich steh auf dem Schlauch. Kannst du mir evt. ein bsp. geben oder einen Ansatz.

              PHP-Code:
              class meinSQL
              {
                  var 
              $sqlquery$sqlresult$sqlfetch$sqlrows;

                  function 
              meinSQL(){
                      
              $this->sqlquery "SELECT * FROM log ORDER BY id DESC";
                      
              $this->sqlresult mysql_query($this->sqlquery);
                      
              $this->sqlfetch mysql_fetch_assoc($this->sqlresult);
                      
              $this->sqlrows mysql_num_rows($this->sqlresult);
                  }

              }

              class 
              Logging extends meinSQL
              {
              ...

              Etwa so?

              Kommentar


              • #8
                Also ich weiß nicht... Ich kann mit dieser Klasse im Allgemeinen nichts Anfangen. Der Support von PHP 4 wurde mit dem Release der Version 4.4.9 nun offiziell eingestellt. Dieser Schritt wurde bereits letztes Jahr angekündigt und sollte mit dem Start der Olympischen Spiele in Bejing zusammenfallen. Ich kann nur empfehlen, dass schnellst möglich alle ihre alten und noch verwendbaren Klassen oder Scripte auf den Stand von PHP5 bringen (ist auch komfortabler). Zudem habe ich mir nur die Methode makeFile() angesehen und schon den Faden verloren. Wieso heißt diese Methode makeFile()? Soweit ich das sehe erstellt diese methode doch garkeine Datei sondern lädt ein Template. Daher solltest du lieber einen Konstruktor oder wenigstens einen Namen wie load() oder so verwenden. Zudem ist es viel einfacher das Template mit [man]file_get_contents()[/man] einzulesen. Die Variable $template musst du im übrigen nicht nochmal in der Methode deklarieren. Es reicht auch, wenn du das am Anfang der Klasse machst. Wie kann das ganze nun alternativ aussehen?

                Greife doch einfach auf die magischen Funktionen von PHP zurück. Mit __set(), __get() und __call läst sich eine sehr sehr einfache und übersichtliche Klasse basteln, mit der du dieses Problem nicht hast.

                PHP-Code:
                <?php

                /***
                * Class Template 
                *
                * Template class allows filling templates with life.
                * Sure this class supports also the nesting of
                * different templates. So you can manage superior
                * designs and webpages.
                *  
                * @package Template
                * @version 0.4
                * @author Mauricio Hannika
                * @author Andreas Wilhelm <Andreas2209@web.de>
                * @copyright Mauricio Hannika, Andreas Wilhelm
                **/  
                class Template
                {
                    protected 
                $template;
                    protected 
                $vars;

                    
                /**
                    * Constructor - Sets the filename of the template
                    *
                    * @access public
                    * @param Str $template
                    * @return Boolean
                    */
                    
                public function __construct($template)
                    {
                        if( !
                file_exists($template) || !is_readable($template) )
                        {
                            throw new 
                Exception('Could not load template file.');
                        }   
                      
                        
                $this->template $template;
                    }

                    
                /**
                    * __get() - Returns the queried value
                    * 
                    * @access public
                    * @param Str $key
                    * @return String
                    */
                    
                public function __get($key)
                    {
                        return isset(
                $this->vars[$key]) ? $this->vars[$key] : '';
                    }

                    
                /**
                    * __set() - Sets the variables
                    * 
                    * @access public
                    * @param Str $key
                    * @param Str $value
                    * @return String
                    */
                    
                public function __set($key$value)
                    {
                        if(isset(
                $this->vars[$key]))
                        {
                            throw new 
                Exception($key ' has already been set.');
                        }
                       
                        
                $this->vars[$key] = $value;
                    }

                    
                /**
                    * parse() - Parses a file and returns it
                    * 
                    * @access public
                    * @param Str $path
                    * @return String
                    */
                    
                public function parse($path=''
                    {    
                        
                ob_start(); 
                        
                        if( !@include_once(
                $path) )
                        {
                            throw new 
                Exception('Failed to parse file.');            
                        }
                        
                        
                $parsed ob_get_contents(); 
                        
                ob_end_clean(); 
                        
                        return 
                $parsed
                    }

                    
                /**
                    * __toString() - Renders the template
                    * 
                    * @access public
                    * @return String
                    */
                    
                public function __toString() 
                    {  
                        return 
                $this->parse$this->template ); 
                    }
                }
                ?>
                Ein Template dazu könnte so aussehen:
                Code:
                <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
                    
                <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
                
                    <head>            
                        <title>&middot; <?= $this->title; ?> &middot;</title>
                
                        <meta name="Title" content="<?= $this->title; ?>" />
                        <meta name="Author" content="pseudo@mail.de" />
                        <meta name="Publisher" content="pseudo.tld" />
                        <meta name="Copyright" content="pseudo.tld" />
                        <meta name="Revisit" content="After 2 days" />
                        <meta name="Keywords" content="pseudo, test, titel, homepage, website" />
                        <meta name="Description" content="Besuchen Sie meine Seite! Es k&ouml;nnte sich lohnen." />
                        <meta name="Abstract" content="Visit my website. It'll be great." />
                        <meta name="Robots" content="INDEX,FOLLOW" />
                        <meta name="Language" content="Deutsch" />
                        <meta name="Distribution" content="global" />
                        <meta http-equiv="content-Type" content="text/html;charset=iso-8859-1" />
                        
                        <link rel="stylesheet" type="text/css" href="design.css"/>    
                    </head>
                        
                    <body>
                        <div id="page">
                        
                            <h1 id="headline"><?= $this->title; ?></h1>        
                            
                            <ul id="navigation">
                                <?= $this->navigation; ?>
                            </ul>
                            
                            <div id="content">
                                <?= $this->content; ?>
                            </div>                    
                            
                            <p id="footer">
                                powered by <?= $this->title; ?> © <?= $this->date; ?>                
                            </p>
                        </div>
                    </body>
                </html>
                Die index.php dazu sieht dann so aus:
                PHP-Code:
                <?php
                    
                try
                    {
                        
                // load required classes
                        
                require_once('Template.php');
                                        
                        
                $mysqli = new mysqli('DB_HOST''DB_USER''DB_PWD''DB_NAME');
                            
                        
                $tpl = new Template('layout.html');
                            
                        if( empty(
                $_GET['site']) )
                        {
                            
                $content $tpl->parse('home.html');
                        }
                            
                        elseif( !isset(
                $_GET['site']) || !file_exists($_GET['site']) || !is_readable($_GET['site']) )
                        {
                            
                $content '<p>Die Seite konnte leider nicht gefunden werden.</p>';
                        }
                            
                        else
                        {
                            
                $site $_GET['site'];
                            
                $content $tpl->parse($site);
                        }
                        
                        
                        
                $sql "SELECT 
                                *
                            FROM
                                navigation
                            ORDER BY
                                name"
                ;
                        
                        
                // send sql-query
                        
                if ( $result $mysqli->query($sql) ) 
                        {        
                            
                // save result into an array
                            
                $navigation '';
                            while( 
                $row $result->fetch_assoc() ) 
                            {
                                
                $navigation .= '<li><a href="index.php?site='.$row['id'].'">'.$row['name'].'</a></li>';
                            }
                        }
                        
                        else
                        {
                            
                $navigation '<b>Die Navigation konnte leider nicht geladen werden.</b>';
                        }
                        
                        
                $tpl->title $navigation;
                        
                $tpl->navigation $navigation;
                        
                $tpl->content $content;
                        
                $tpl->date date('Y');
                            
                        echo 
                $tpl;
                    }
                        
                    catch(
                Exception $e)
                    {
                        echo 
                '<p>'.$e->getMessage().'</p>';
                    }
                ?>
                Denke das ist doch sehr übersichtlich und absolut einfach. Um das ganze noch abszurunden, kann man noch die hässliche URL via mod-rewrite verstecken. Das Beispiel sollte so funktionieren, habe das ganze aber nicht getestet.

                [man]str_replace()[/man] kann man zwar verwenden, halte ich aber für eine schlechte Idee, da das ein echter Performance Fresser werden kann. Habe ich früher auch gemacht, geht auch für sehr sehr kleine Projekte, ist aber nicht sehr empfehlenswert und, wie man sieht, geht es doch auch sehr sehr viel einfacher.
                MfG, Andy

                Kommentar


                • #9
                  Danke für deine Mühe!

                  Ich mag nicht sagen dass du sie evt. umsonst gemacht hast. Aber ich verstehe echt nur ein Bruchteil.
                  Ich habe mich eben zu Exceptions und diesem throw'n'catch angelesen. Ich kann es nur sehr schwer nachvollziehen.
                  Von __set() __get() habe ich auch das erste Mal gehört.

                  Nun gut, der Funktions-Name war sicherlich doof gewählt und zum Verständnis erst recht und ja ich habe $template fälschlicherweise zwei mal inizialisiert.
                  str_replace() verwende ich doch nicht.

                  Ich möchte ja einfach nur, dass ich durch makeReplace('CONTENT', "text oder".function()) meinen Inhalt anzeigen lassen kann.

                  Kommentar


                  • #10
                    Du verwendest zwar nicht [MAN]str_replace()[/MAN] aber du verwendest [MAN]preg_replae()[/MAN]. Das meinte ich. Ich denke die Klasse ist relativ einfach zu verstehen. Kleine Schwierigkeiten bereiten, wie du bereits erwähntest, zumeist die magischen Methoden, sowie das Handling von Exceptions. Exceptions sind einfach eine gute und sehr saubere Fehlerbehandlung.

                    • __get($memberName) wird aufgerufen, wenn lesend auf das Attribut $memberName eines Objekts zugegriffen wird, das Attribut aber nicht gesetzt ist.

                    • __set($memberName, $value) wird aufgerufen, wenn schreibend auf das Attribut $memberName eines Objekts zugegriffen wird und das Attribut vorher nicht gesetzt war. Der zweite Parameter $value enthält den Wert, mit dem das Attribut belegt werden soll.

                    • __toString() wird aufgerufen, wenn eine Typumwandlung eines Objekts in einen String durchgeführt werden soll.


                    (Quelle: selfphp.de)
                    MfG, Andy

                    Kommentar


                    • #11
                      Ok, soweit alles verstanden (5 Sterne URL )

                      Ich verwende jetzt die Engine in etwa so wie du sie mir gezeigt hast. Funktionieren tut das ganze noch nicht. Ist wahrscheinlich nur ein kleiner Fehler den ich da mache.

                      Mein Quelltext:

                      PHP-Code:
                      #template.html ES GEHT NUR UM $tpl->date !

                      <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.1//EN' 'xhtml11.dtd'>
                      <html>
                      <head>
                      <link rel='stylesheet' type='text/css' href='style.css' media='all' />
                      <title>{TITLE}</title>
                      </head>
                      <body>
                      <div class='container'>
                         <div class='headleft'><img src='image/top-links.jpg' alt='' width="6" height="19" /></div>
                         <div class='headmiddle'>Logged in as <a href='#' class='headmiddlelink'>{LOGINNAME}</a>&nbsp;
                            <span class="headmiddle1">|</span>&nbsp;Time: <span class="headmiddle2">{DATUM}</span>
                            <span class="headmiddle1">|</span>
                            <span class="headmiddle2"><a href='logout.php' class='headmiddlelink'>Logout</a></span>
                         </div>
                         <div class='headright'><img src='image/top-rechts.jpg' alt='' width="6" height="19" /></div>
                         <div class='headbuttom'></div>
                         <div class='header'></div>
                         <div class='headred'></div>
                         <div class='headend'></div>
                            <div class='content'>
                               <div class='navi'>
                                  <div class='navimain'><img src='image/main_menu.jpg' width='191' height='43' alt='' /></div>
                                  <div class='navirot'><a href='?menu=close' class='navirotlink'>&nbsp;&nbsp;News</a></div>
                                  <div class='navisub'>&nbsp;&nbsp;Hinzufuegen</div>
                                  <div class='navisub'>&nbsp;&nbsp;Loeschen</div>
                                  <div class='navinorm'><a href='getlogs.php'>&nbsp;&nbsp;Log</a></div>
                               </div>
                               <div class='context'>
                                  <div class='con1'></div>
                                  <div class='con2'></div>
                                  <div class='con3'></div>
                                  <div class='con4'>
                                     <input class='searchinput' type='text' name='search' value='Ihr Suchebegriff...' />
                                     <input name='searchbutton' type='submit' class='searchbutton' value='Senden' />
                                  </div>
                                  <div class='con5'></div>
                                     <div class='contextmitte'><?php $tpl->date ?></div>
                                  </div>
                               </div>
                      </div>
                      </body>
                      </html>
                      PHP-Code:
                      # class.template.php

                      <?php

                      /***
                      * Class Template
                      *
                      * Template class allows filling templates with life.
                      * Sure this class supports also the nesting of
                      * different templates. So you can manage superior
                      * designs and webpages.
                      *
                      * @package Template
                      * @version 0.4
                      * @author Mauricio Hannika
                      * @author Andreas Wilhelm <Andreas2209@web.de>
                      * @copyright Mauricio Hannika, Andreas Wilhelm
                      **/
                      class Template
                      {
                          protected 
                      $template;
                          protected 
                      $vars;

                          
                      /**
                          * Constructor - Sets the filename of the template
                          *
                          * @access public
                          * @param Str $template
                          * @return Boolean
                          */
                          
                      public function __construct($template)
                          {
                              if( !
                      file_exists($template) || !is_readable($template) )
                              {
                                  throw new 
                      Exception('Could not load template file.');
                              }

                              
                      $this->template $template;
                          }

                          
                      /**
                          * __get() - Returns the queried value
                          *
                          * @access public
                          * @param Str $key
                          * @return String
                          */
                          
                      public function __get($key)
                          {
                              return isset(
                      $this->vars[$key]) ? $this->vars[$key] : '';
                          }

                          
                      /**
                          * __set() - Sets the variables
                          *
                          * @access public
                          * @param Str $key
                          * @param Str $value
                          * @return String
                          */
                          
                      public function __set($key$value)
                          {
                              if(isset(
                      $this->vars[$key]))
                              {
                                  throw new 
                      Exception($key ' has already been set.');
                              }

                              
                      $this->vars[$key] = $value;
                          }

                          
                      /**
                          * parse() - Parses a file and returns it
                          *
                          * @access public
                          * @param Str $path
                          * @return String
                          */
                          
                      public function parse($path='')
                          {
                              
                      ob_start();

                              if( !@include_once(
                      $path) )
                              {
                                  throw new 
                      Exception('Failed to parse file.');
                              }

                              
                      $parsed ob_get_contents();
                              
                      ob_end_clean();

                              return 
                      $parsed;
                          }

                          
                      /**
                          * __toString() - Renders the template
                          *
                          * @access public
                          * @return String
                          */
                          
                      public function __toString()
                          {
                              return 
                      $this->parse$this->template );
                          }
                      }
                      ?>
                      PHP-Code:
                      # tpl.php 

                      <?php
                      try
                          {
                              
                      // load required classes
                              
                      require_once('lib/class.template.php');

                              
                      $tpl = new Template('tpl/template.html');
                              
                      $tpl->date date('Y');
                              echo 
                      $tpl;
                          }

                          catch(
                      Exception $e)
                          {
                              echo 
                      '<p>'.$e->getMessage().'</p>';
                          }
                      ?>
                      target {TITLE}

                      Kommentar


                      • #12
                        Den letzten Code-Schnipsel musst du nicht tpl.php sondern index.php nennen. Den ersten Schnipsel nennst du template.html.

                        Der Quelltext für die index.php sollte dann so aussehen:
                        PHP-Code:
                        <?php
                        try
                            {
                                
                        // load required classes
                                
                        require_once('lib/class.template.php');

                                
                        $tpl = new Template('tpl/template.html');
                                
                        $tpl->date date('Y');
                                 
                        $tpl->title'Title of your website';
                                 
                        $tpl->user'user-name';
                                echo 
                        $tpl;
                            }

                            catch(
                        Exception $e)
                            {
                                echo 
                        '<p>'.$e->getMessage().'</p>';
                            }
                        ?>
                        In das Template (template.html) musst du nun anstatt {DATUM} $this->date, anstatt {LOGINNAME} $this->user und anstatt {TITEL} $this->title schreiben. So einfach ist das.
                        MfG, Andy

                        Kommentar


                        • #13
                          Ob ich die jetzt tpl.php oder index nenne ist doch egal. Ausschlaggebend ist welche ich aufrufe. template.html heisst bei mir auch template.html trotzdem ohne Erfolg.

                          Kommentar


                          • #14
                            template.html heisst bei mir auch template.html trotzdem ohne Erfolg.
                            Dann sei doch bitte so gut uns verwende etwas fertiges. Smarty und das APF bieten hier sehr elegante Lösungen.

                            Kommentar


                            • #15
                              Mir wird doch geholfen. Warum soll ich das jetzt aufgeben und etwas anderes verwenden?

                              Andrerseits möchte ich das jetzt schaffen

                              Kommentar

                              Lädt...
                              X