[PHP] problemen met simpel template systeem

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • wilcodl
  • Registratie: September 2004
  • Laatst online: 24-06 21:35
Hallo,
ik heb een raar probleem met een simpel eigen geschreven tempate systeem in php. Het probleem is dat de tekst die tussen de top en de footer op de verkeerde plek terecht komt, namelijk onder de </html> tag. Het probleem is hier te zien: http://dev.wilcodl.nl/test/layout/index.php

Kan iemand mij hier mee helpen?

De code van index.php:
PHP:
1
2
3
4
5
6
7
8
9
10
11
<?php
include "design.inc.php";

echo makeHeader();
echo "Tekst tussen header en top. (###BODY###)";
echo makeTop();

echo "Deze tekst zou tussen de top en footer moeten. op plek van ###CONTENT### dus.";

echo makeFooter();
?>


De code van design.inc.php: (de fout zit ergens in de functie replace() lijkt mij)
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
$start = 0;
$design = file_get_contents("design.html");

function replace($sep_label, array $labels = array()){
    global $start, $design;
    
    if ($sep_label != "END"){
        $sep_label = '###'.$sep_label.'###';
    
        $pos = strpos($design, $sep_label);

        $rv = substr($design, $start, $pos);
    
        $start += strlen($sep_label) + strlen($rv);
    } else {
        $rv = substr($design, $start);
    }

    foreach ($labels as $key => $value){
        $rv = str_replace('###'.$key.'###', $value, $rv);
    }
    
    return $rv;
}

function makeHeader(){  
    $rep = array(
        "HEADER" => '<link rel="stylesheet" type="text/css" href="default.css" />'
    );
    
    return replace("BODY", $rep);
}

function makeTop(){
    $rep = array(
        "MENU" => "het menu",
        "LANG" => "taaliconen"
    );

    return replace("CONTENT", $rep);
}

function makeFooter(){  
    $rep = array(
        "FOOTER" => '&copy;2009 sitenaam | <a href="http://www.wilcodl.nl">WDL Webdevelopment</a>'
    );

    return replace("END", $rep);
}
?>


De gebruikte html template (design.html):
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
Design by Free CSS Templates
http://www.freecsstemplates.org
Released for free under a Creative Commons Attribution 2.5 License
-->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>###TITLE###</title>
<meta name="keywords" content="" />
<meta name="description" content="" />
###HEADER###
</head>
<body>
###BODY###
<div id="header">
    <div id="logo">
        <h1><a href="#">Websitenaam</a></h1>
        <h2><a href="http://www.freecsstemplates.org/">Ondertitel</a></h2>
    </div>
    <div id="menu">
        <ul>
            <li class="first"><a href="#">My Blog</a></li>
            <li><a href="#">My Photos</a></li>
            <li><a href="#">My Favorites</a></li>
            <li><a href="#">About Me</a></li>
            <li><a href="#">Contact Me</a></li>
        </ul>
    </div>
</div>
<div id="content">
    <div id="colOne">
        <div class="post">
            <h2 class="title">Welcome to Neonix!</h2>
            ###CONTENT###
        </div>
    </div>
    <div id="colTwo">
        Lorem ipsum.
        <div style="clear: both;">&nbsp;</div>
    </div>
</div>
<div id="footer">
    <p>###FOOTER###</p>
</div>
</body>
</html>

Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:47

Creepy

Tactical Espionage Splatterer

En ben je zelf al aan het debuggen geslagen? Als je denkt te weten waar het zit kan me stap voor stap door je code heenlopen of op wat plekken wat echo's neerzetten zodat je kan zien wat er nu wordt vervangen op welke plek. Het is in elk geval niet de bedoeling om je code hier te dumpen en te wachten totdat wij het voor je gaan fixen.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • wilcodl
  • Registratie: September 2004
  • Laatst online: 24-06 21:35
Ja, ik ben al een paar uur bezig geweest met het debuggen. Overal allerlei echo's neergezet, maar ik kwam er niet uit. Het rare is dat het bij het eerste label (BODY) wel goed gaat, maar bij CONTENT niet. het lijkt erop dat het start karakternummer van het content label niet goed wordt berekend.

Acties:
  • 0 Henk 'm!

Verwijderd

Waarom noem je dit een simpel template systeem?

Waarom verzamel je niet gewoon eerst alle "variabelen" die vervangen moeten worden, en vervang je ze niet in één keer aan het eind?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

function apply_template ( $filename , $vars ) {
   $keys = array ();
   $values = array ();
   foreach ( $vars as $varname => $value ) {
      $keys [] = '###' . strtoupper ( $varname ) . '###';
      $values [] = $vars [ $varname ];
   }
   return str_replace ( $keys, $values, file_get_contents ( $filename ) );
}

$tplvars = array (
   'header' => '<link rel="stylesheet" type="text/css" href="default.css" />',
   'menu' => 'het menu',
   'lang' => 'taaliconen',
   'footer' => '&copy;2009 sitenaam | <a href="http://www.wilcodl.nl">WDL Webdevelopment</a>'
);
echo apply_template ( 'design.html', $tplvars );

?>

De meeste code zit hem dan nog in het omvormen van 'header' naar '###HEADER###' etc... De rest is pas écht simpel.

Overigens snap ik niet waarom je niet "gewoon" PHP gebruikt als template systeem, of anders Smarty.

Acties:
  • 0 Henk 'm!

  • wilcodl
  • Registratie: September 2004
  • Laatst online: 24-06 21:35
Ik noem dit een simpel template systeem omdat het toch een stuk simpeler is als bv Smarty. Ik heb de html code hiervoor altijd in de php code gehad, maar dit is erg onoverzichtelijk, vooral als er iets in de template moet worden aangepast. Ook is het vervangen van een template zo makkelijker.

Ik wil geen Smarty gebruiken omdat ik dit systeem wil inpassen in huidige websites, deze gebruiken allemaal de structuur zoals in index.php. Deze structuur vind ik prettig werken.

Het is inderdaad mogelijk om eerst de labels te vervangen, maar dat is niet de aard van het probleem. Het gaat om de 'speciale' labels ###BODY en ###CONTENT###.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Het lullige aan het systeem wat je nu maakt is dat je het bijna voor elke site kan herschrijven. De site die je nu maakt heeft misschien iets aan een MakeHeader, MakeFooter en MakeTop, maar wat als je later voor een andere site je menu aan de zijkant wil hebben? Maak je dan een nieuwe functie? De oplossing die Cheatah noemt is veel generieker en geeft je veel minder hoofdpijn omdat je niet per site aan je template engine hoeft te sleutelen, maar alleen aan je templates.

Wat Cheatah bedoelt met PHP gebruiken als template systeem is trouwens niet wat jij nou denkt dat het is. Hij bedoelt (bijvoorbeeld) dit:
PHP:
1
2
3
4
5
6
7
8
9
$tplvars['header'] = '<link rel="stylesheet" type="text/css" href="default.css" />';
$tplvars['menu']   = 'het menu';
$tplvars['lang']   = 'taaliconen';
$tplvars['footer'] = '&copy;2009 sitenaam | <a href="http://www.wilcodl.nl">WDL Webdevelopment</a>';

// rest van je logica

extract($tplvars);
include 'templatebestand.php';

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title><?php echo $title; ?></title>
<meta name="keywords" content="" />
<meta name="description" content="" />
<?php echo $header; ?>
</head>
<body>
<!-- enz -->
<div id="footer">
    <p><?php echo $footer; ?></p>
</div>
</body>
</html>

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • wilcodl
  • Registratie: September 2004
  • Laatst online: 24-06 21:35
Daar ben ik het niet helemaal mee eens. Het huidige systeem is met toevoeging van labels erg flexibel. Ik kan mijn menu dan overal waar ik wil neer zetten door alleen het label in de template te verplaatsen. Wel zou ik dan zoals er werd voorsteld de labels globaal moeten definieeren.

De 'php manier' zou ik inderdaad kunnen gebruiken, maar dan moet ik wel de hele structuur van een aantal bestaande sites omgooien. Dat is niet reeel. Het werken met labels in een html bestand vind ik ook netter.

De code van design.inc.php is nu zo:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
$start = 0;
$design = file_get_contents("design.html");

$labels = array(
    "HEADER" => '<link rel="stylesheet" type="text/css" href="default.css" />',
    "MENU" => "het menu",
    "LANG" => "taaliconen", 
    "FOOTER" => '&copy;2009 sitenaam'
);

foreach ($labels as $key => $value){
    $design = str_replace('###'.$key.'###', $value, $design);
}

function replace($sep_label, array $labels = array()){
    global $start, $design;

    if ($sep_label != "END"){
        $sep_label = '###'.$sep_label.'###';

        $pos = strpos($design, $sep_label);

        $rv = substr($design, $start, $pos);

        $start += strlen($sep_label) + strlen($rv);
    } else {
        $rv = substr($design, $start);
    }

    return $rv;
}

function makeHeader(){
    return replace("BODY");
}

function makeTop(){
    return replace("CONTENT");
}

function makeFooter(){
    return replace("END");
}
?>


De tekst blijft dus nog steeds onder de </html> tag staan...

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

wilcodl schreef op zaterdag 21 maart 2009 @ 18:02:
Daar ben ik het niet helemaal mee eens. Het huidige systeem is met toevoeging van labels erg flexibel. Ik kan mijn menu dan overal waar ik wil neer zetten door alleen het label in de template te verplaatsen. Wel zou ik dan zoals er werd voorsteld de labels globaal moeten definieeren.
Heb je Cheatah's code doorgelezen? Je kan met zijn code gewoon óók met diezelfde labels blijven werken. :o

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • wilcodl
  • Registratie: September 2004
  • Laatst online: 24-06 21:35
wilcodl schreef op zaterdag 21 maart 2009 @ 13:13:
Ik wil geen Smarty gebruiken omdat ik dit systeem wil inpassen in huidige websites, deze gebruiken allemaal de structuur zoals in index.php. Deze structuur vind ik prettig werken.
Zoals hierboven blijkt, hebben de bestaande sites de structuur zoals in index.php, ik doel dus niet op de labels. De code van Cheetah is niet toe te passen op deze structuur.

[ Voor 6% gewijzigd door wilcodl op 21-03-2009 18:13 . Reden: typos ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Natuurlijk wel. Je kan óók andere templates in een template includen, enz. Ik krijg vooral het idee dat je niet begrijpt dat Cheatah doet, want wat hij zegt is in essentie precies wat jij wil bereiken op een meer generieke manier.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Wat ik bedoel is inderdaad precies wat NMe zegt. Wat maakt een "eenvoudige template parser" nou zo moeilijk als je niets anders wilt dan wat variabelen vervangen? Het resultaat kun je weer opvangen in een variabele om dit in een andere template te kunnen gebruiken.

Je kunt bij hoog en bij laag gaan beweren dat jouw systeem oneindig veel keer beter is. Dat is simpelweg niet zo. Als je een goede, beproefde template engine wilt gebruiken, gebruik dan Smarty (dat helemaal niet zo moeilijk is) of anders PHP. Met alle respect, wie de code die ik gaf wil gaan gebruiken in zijn systeem is niet helemaal wijs.

NMe's reactie daarop met extract en include is precies zijn wat mijn volgende hint zou zijn geweest, ware het niet dat ik het in een functie zou hebben gezet zodat je scope gegarandeerd "schoon" is.

Het gaat helemaal niet om mijn code, het gaat erom dat je blijkbaar niets meer of minder wilt dan wat variabelen vervangen. Dat doe je zelf namelijk op een nogal onhandige manier.

Acties:
  • 0 Henk 'm!

  • wilcodl
  • Registratie: September 2004
  • Laatst online: 24-06 21:35
Ik heb nooit gezegt dat mijn systeem beter is. Alleen in de huidige situatie met een structuur met makeHeader(), makeTop() en makeFooter() is Cheeta's code niet toe te passen zonder de template in meerdere bestanden te zetten (bv header.html, top.html en footer.html). Misschien zit ik er helemaal naast, maar dan zou ik graag zien hoe de code van Cheetah in die 3 functies zou moeten worden verwerkt.

Acties:
  • 0 Henk 'm!

  • H004
  • Registratie: Maart 2006
  • Laatst online: 28-05 19:55
Waarom zou je 3x (makeHeader, makeTop, en makeFooter) je template gedeeltelijk willen parsen?

Je kan toch veel beter een globale array definiëren en in de functies makeHeader, makeTop, en makeFooter keys en values toevoegen aan die globale array? Het enige wat je daarna nog moet doen is zorgen dat je template geparst wordt.

PHP:
1
2
3
4
5
6
7
8
9
10
$tplvars = array();

function makeHeader(){
    global $tplvars;
    $tplvars['header'] = '<link rel="stylesheet" type="text/css" href="default.css" />'; 
} 

// helemaal aan het einde van je code
extract($tplvars);
include 'templatebestand.php';
Pagina: 1