Versio

Template parser parst teveel

Overzicht Reageren

Pagina: 1 2 volgende »

Hendel Berg

Hendel Berg

10/12/2009 20:21:00
Quote Anchor link
Goedenavond allen,

Op 2 december j.l. heb ik alhier een template parser class geplaatst. Hierop heb ik van Jelmer feedback gekregen, welke ik wil verwerken, maar kom er niet uit.

Hergebruik instellingen
Ik wil graag ondervangen dat instellingen nogmaals gebruikt kunnen worden bij andere instellingen i.v.m. veiligheidsproblemen.

Voorbeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
$data
= array(
   array(
      "username" => "Jan {password}",
      "password" => "henk24"
   )
);


// Uitkomst:
// Jan henk24

?>


Hoe kan ik dit ondervangen??

Onbeperkt diepe array's
De instellingen (settings) en loops zijn respectievelijk maximaal 3 en 2 niveaus diep. Door middel van o.a. preg_replace_callback zou dit te ondervangen zijn. Hierdoor moet het dan ook mogelijk worden om loop in loop te maken.

Voorbeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php //kleurtjes
<body>
   <
div class="menu">

      <!--
loop menu start -->
         <
div class="menu">

            <!--
loop item start -->
               <
div class="item"></div>
            <!--
loop item start -->

         <
/div>
      <!--
loop menu end -->

   <
/div>
<
/body>
?>


Maar hoe?
Gewijzigd op 01/01/1970 01:00:00 door Hendel Berg
 
PHP hulp

PHP hulp

25/05/2012 16:14:46
Gesponsorde koppelingen:
BHosted Hosting al vanaf € 1,- per maand

Controleer nu gratis jouw domeinnaam:

  
 
Jelmer rrrr

Jelmer rrrr

10/12/2009 20:56:00
Quote Anchor link
Vraag 1 zou je kunnen oplossen door alle variabelen in één keer te vervangen. Bijvoobeeld, heel gemakkelijk, met preg_replace_callback. Daarmee kan je ook ingewikkeldere patterns maken, om bijvoorbeeld tags a la {username|escape} (variabele + filter) te gebruiken:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

$values
= array('alfa' => '{beta}', 'beta' => 'gamma');

function
find_replacement($matches)
{

    global $values;
    
    return $values[$matches[1]];
}


$template = 'Hey {alfa} {beta} gamma';

echo preg_replace_callback('{\{(\w+?)\}}', 'find_replacement', $template);
// geeft Hey {beta} gamma gamma
?>
 
Niek s

niek s

10/12/2009 22:46:00
Quote Anchor link
De eerste vraag heeft Jelmer net al beantwoord, ga ik niet verder op in.

Je vraag 2, die snap ik echter niet. Wat bedoel je nou precies? met is_array() kan je kijken of iets een array is, en dan een recursieve functie maken? of bedoel je dat niet .. ?
 
Hendel Berg

Hendel Berg

10/12/2009 23:12:00
Quote Anchor link
@Jelmer
Wat nou in geval van een class? Onderstaande werkt n.l. niet... :s :s :s
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
class sTemplate
{
   public $dir = "./templates/"; // Templates dir
   public $ext = ".html"; // Template files extension
   public $atr = "class"; // HTML attribute, which value is name of variable

   public function parse ($template, $values)
   {

      $path = $this->dir . $template . $this->ext;
      $content = implode("", file($path));
      $result = preg_replace_callback('{\{(\w+?)\}}', 'replacement', $content);

      return $result;
   }


   private function replacement ($matches)
   {

      global $values;

      return $values[$matches[1]];
   }
}

?>


@niek
Jawel, maar zo'n recursieve functie vat ik niet echt
Gewijzigd op 01/01/1970 01:00:00 door Hendel Berg
 
Jelmer rrrr

Jelmer rrrr

11/12/2009 00:44:00
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php

$result
= preg_replace_callback(..., array($this, 'replacement'), ...);

?>


Ik heb een voorbeeldje gemaakt van hoe je loops zou kunnen afhandelen. Hopelijk is het een goed voorbeeld: Template.php

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php

error_reporting(E_ALL);

class Template
{
    private $template;
    
    private $data_stack;
    
    public function __construct($template)
    {

        $this->template = $template;
        
        // SplStack is PHP 5.3.
        // Voor PHP < 5.3, gebruik http://phphulp.ikhoefgeen.nl/SplStack.phps

        $this->data_stack = new SplStack();
    }

    
    public function apply($data)
    {

        return $this->parse($this->template, $data);
    }

    
    private function parse($template, $data)
    {

        // push data op de stack, zodat de replace-functies weten in welke data ze moeten zoeken voor het vervangen van variabelen.
        $this->data_stack->push($data);
        
        // parse alle blokken, recursief. Ieder blok komt weer door deze zelfde method heen.
        $result = preg_replace_callback('{\{(\w+?)\}(.+?)\{/\\1\}}', array($this, 'parse_block'), $template);
        
        // Werk van binnen naar buiten. Handel eerst de blokken af (hierboven) en dan pas de variabelen
        $result = preg_replace_callback('{\{(\w+)\}(?!.*\{/\\1\})}', array($this, 'parse_placeholder'), $result);
        
        // haal de verwijzing naar de data weer weg, zodat we in het omliggende blok weer bij de goeie data komen.
        $this->data_stack->pop();
        
        return $result;
    }

    
    private function parse_block($matches)
    {

        list(, $block_name, $block_code) = $matches;
    
        $data = $this->data_stack->top();
        
        $block_data = $data[$block_name];
    
        $results = array();
    
        foreach($block_data as $step_data)
        {

            $results[] = $this->parse($block_code, $step_data);
        }

        
        return implode($results);
    }

    
    private function parse_placeholder($matches)
    {

        list(, $placeholder_name) = $matches;
        
        $data = $this->data_stack->top();
        
        return $data[$placeholder_name];
    }
    
}


// Dit is de meest onbegrijpelijke test-data ooit. Trust me.

$template = 'Hoi {block1} (begin-block1) {var_y} {block2} (begin-block2) {var_x} (eind-block2) {/block2} test2 (eind-block1) {/block1} Hoi2';

$data = array(
    'block1' => array(
        0 => array(
            'var_y' => 'XXvar_y1XX',
            'block2' => array(
                0 => array('var_x' => 'XXvar_x11'),
                1 => array('var_x' => 'XXvar_x12'),
                2 => array('var_x' => 'XXvar_x13'),
            )
        ),

        1 => array(
            'var_y' => 'XXvar_y2XX',
            'block2' => array(
                0 => array('var_x' => 'XXvar_x21'),
                1 => array('var_x' => 'XXvar_x22'),
                2 => array('var_x' => 'XXvar_x23'),
            )
        )
    )
);


$x = new Template($template);

echo $x->apply($data);

?>


Kort samengevat, ik loop de code af op zoek naar {block} {/block}, en zodra ik dat vind, beschouw ik dat block als een nieuw template, met een eigen setje variabelen, en ga ik dat op dezelfde manier parsen. (Dus eerst weer de blokken daarin, en dan de variabelen daarin).

De stack is voor de callback-functies om bij te houden welke data ze moeten gebruiken. In andere programmeertalen kan je dat wel met closures doen (PHP 5.3 bijvoorbeeld ;) ) maar voor PHP moet het maar even zo. De stack is zeg maar een tijdelijke verwijzing naar $data, maar hij moet ook de voorgaande waarden van $data onthouden omdat de functie zichzelf binnen zichzelf aanroept.

(Die class maakt gebruik van een class genaamd SplStack, een class die alleen in PHP 5.3 zit. Gebruik je die niet, dan moet je even SplStack.php includen.)

edit: code even hier geplakt.
Gewijzigd op 01/01/1970 01:00:00 door Jelmer rrrr
 
Jelmer rrrr

Jelmer rrrr

11/12/2009 09:48:00
Quote Anchor link
Hmm, die code van gisteravond heeft hetzelfde probleem als jou vorige versie. Als ik een van die var_x waarden in $data aanpas naar '{var_y}', wordt hij vervangen.

Deze heeft daar geen last van Template_r2.phps. Die vervangt de blokken niet direct, maar vervangt ze door variabelen, waardoor ze tegelijkertijd met de andere variabelen pas in $result komen. En de variabelen binnen de waarden van de variabelen worden niet vervangen. Probleem opgelost. (En hij maakt geen gebruik meer van SplStack, omdat die niet werkt met references, wat helaas wel nodig is omdat ik geen closure heb gebruikt)
 
Hendel Berg

Hendel Berg

14/12/2009 17:06:00
Quote Anchor link
Jelmer, bedankt voor je geweldig uitgebreide reactie! Afgelopen dagen even met wat andere zaken bezig geweest. Jouw script brengt het idee een stuk dichter in de buurt. Nadeel daarvan wel, dat de match met HTML weg is.

Heb de regex voor de block's aangepast, nu heb je een duidelijkere scheiding tussen de variabelen en block's. Dit is alleen een nadeel zodra je de array voor instellingen wilt gebruiken.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
 //Ge-edit
?>


Het idee met die instellingen en loops etc.:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
$data
= array(
   'block1' => array(
      0 => array(
         'var_y' => 'XXvar_y1XX',
         'block2' => array(
            0 => array('var_x' => 'XXvar_x11'),
            1 => array('var_x' => 'XXvar_x12'),
            2 => array('var_x' => 'XXvar_x13'),
         )
      ),

      1 => array(
         'var_y' => 'XXvar_y2XX',
         'block2' => array(
            0 => array('var_x' => 'XXvar_x21'),
            1 => array('var_x' => '{var_y}'), // Deze verwijst terug naar 'var-y' hierboven. Zou niet moeten!
            2 => array('var_x' => 'XXvar_x23'),
         )
      )
   ),

   'block3' => 'XXvar_uXX'
);

// Drie mogelijkheden om bovenstaande array's in de template te verwerken:
$optie_1 = 'Hoi <!-- loop block1 start --> <div class="block1"> <!-- loop block2 start --> <div class="block2"></div> <!--/block2--> </div> <!-- loop block1 end-->';

$optie_2 = 'Hoi <!-- loop block1 start --> <div class="block1"> {var_y) is tegenovergesteld aan {block3}, want {block2:1:var_x} mag niet! </div> <!-- loop block1 end-->';

$optie_3 = '<meta name="version" content="{block2:0:var_x}" />';
?>
Gewijzigd op 01/01/1970 01:00:00 door Hendel Berg
 
Hendel Berg

Hendel Berg

15/12/2009 01:44:00
Quote Anchor link
Het is nu mogelijk om een template-file te laden, óf om een losse string in te voeren. Tevens worden de HTML elementen nu geparst.

ToDo:
1. <DIV> in <DIV> werkt nog niet helemaal zoals het hoort
2. Waarden in placeholder kunnen laten combineren m.b.v. scheidingsteken ':'

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
error_reporting(E_ALL);

class TemplateStack
{
   private $data = array();
    
   public function push(&$data)
   {

      return $this->data[] =& $data;
   }


   public function &pop()
   {

      $reference =& $this->top();

      // TemplateStack::top() verplaatst de cursor al naar het einde, dus key() zal de juiste key pakken.
      unset($this->data[key($this->data)]);

      return $reference;
   }


   public function &top()
   {

      // Cursor naar einde bewegen, zodat key() de index van het laatste element pakt.
      end($this->data);

      return $this->data[key($this->data)];
   }
}


class Template
{
   private $template;
   private $data_stack;

   public $atr = 'class';
   public $dir = './';
   public $ext = '.tpl';

   public function __construct($template, $file = true)
   {

      if ($file == true)
      {

         $path = $this->dir . $template . $this->ext;
         $this->template = file(implode("", $path));
      }

      else
      {
         $this->template = $template;
      }


      $this->data_stack = new TemplateStack();
   }

    
   public function apply($data)
   {

      return $this->parse($this->template, $data);
   }


   private function parse($template, $data)
   {

      // Push data op de stack, zodat de replace-functies weten in welke data ze moeten zoeken voor het vervangen van variabelen.
      $this->data_stack->push($data);

      // Parse alle blokken, recursief. Ieder blok komt weer door deze zelfde method heen.
      // Ieder geparsed block wordt onthouden aan een unieke placeholder. Deze wordt later weer teruggeplaatst
      // om er zo voor te zorgen dat bij het variabelen vervangen niet binnen dit al verwerkte blok wordt gezocht.

      $result = preg_replace_callback('{\<\!\-\-(\s?)loop (\w+?) start(\s?)\-\-\>(.+?)\<\!\-\-(\s?)loop (\\2) end(\s?)\-\-\>}', array($this, 'parse_block'), $template);

      // Parse de HTML elementen
      $result = preg_replace_callback('{\<([a-zA-Z0-9\"\'\.=\s]+)(.*?)'. $this->atr .'=(\'|\")(\w+)(\\3)(.*?)>(.*?)\</\\1>}', array($this, 'parse_nameholder'),  $result);

      // Werk van binnen naar buiten. Handel eerst de blokken af (hierboven) en dan pas de variabelen
      // De blokken zijn in $result vervangen door variabelen, en in $data zitten nu de geparste blokken als normale variabelen.
      //$result = preg_replace_callback('{{}}');

      $result = preg_replace_callback('{\{(\w+)\}}', array($this, 'parse_placeholder'), $result);

      // Haal de verwijzing naar de data weer weg, zodat we in het omliggende blok weer bij de goeie data komen.
      $this->data_stack->pop();

      return $result;
   }

    
   private function parse_block($matches)
   {

      list(,, $block_name,, $block_code) = $matches;

      $data =& $this->data_stack->top();
      $block_data = $data[$block_name];
      $results = array();

      foreach($block_data as $step_data)
      {

         $results[] = $this->parse($block_code, $step_data);
      }


      // Variabele-naam waar we nu het blok in stoppen.
      $block_placeholder = sprintf('block%s', uniqid());

      // Variabele-naam en de inhoud van dit blok terugstoppen in de data-array
      // Dit gaat lukken omdat $data een reference is naar de top van de stack.

      $data[$block_placeholder] = implode($results);

      return sprintf('{%s}', $block_placeholder);
   }


   private function parse_nameholder($matches)
   {

      list(, $tag_name, $a, $separator, $nameholder_name,, $b, $c) = $matches;

      $data = $this->data_stack->top();

      return '<'. $tag_name . $a . $this->atr .'='. $separator . $nameholder_name . $separator . $b .'>'. $c . $data[$nameholder_name] .'</'. $b .'>';
   }


   private function parse_placeholder($matches)
   {

      list(, $placeholder_name) = $matches;
        
      $data = $this->data_stack->top();

      return $data[$placeholder_name];
   }
}


// Dit is de meest onbegrijpelijke test-data ooit. Trust me.

$template = 'Hoi <div class="boo"></div> {block3} <!-- loop block1 start --> (begin-block1) {var_y} <!-- loop block2 start --> (begin-block2) {var_x} (eind-block2) <!-- loop block2 end --> test2 (eind-block1) <!-- loop block1 end --> Hoi2';

$data = array(
    'block1' => array(
        0 => array(
            'var_y' => 'XXvar_y1XX',
            'block2' => array(
                0 => array('var_x' => 'XXvar_x11'),
                1 => array('var_x' => 'XXvar_x12'),
                2 => array('var_x' => 'XXvar_x13'),
            )
        ),

        1 => array(
            'var_y' => 'XXvar_y2XX',
            'block2' => array(
                0 => array('var_x' => 'XXvar_x21'),
                1 => array('var_x' => '{var_y}'), // Deze verwijst terug naar 'var-y' hierboven. Zou niet moeten!
                2 => array('var_x' => 'XXvar_x23'),
            )
        )
   ),

   'block3' => 'nummer 3',
   'boo' => 'boo'
);

$x = new Template($template, false);

echo $x->apply($data);
?>
Gewijzigd op 01/01/1970 01:00:00 door Hendel Berg
 
Hendel Berg

Hendel Berg

15/12/2009 02:07:00
Quote Anchor link
@SanThe, mijn excuses! Ging niet bewust.
 
Jelmer rrrr

Jelmer rrrr

15/12/2009 08:42:00
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
$this
->template = file(implode("", $path));
?>

die regel gaat niet werken (file geeft een array van regels terug). Probeer eens
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
$this
->template = file_get_contents($path);
?>
 
Hendel Berg

Hendel Berg

15/12/2009 13:59:00
Quote Anchor link
Klopt. Had implode() en file() verkeerd om geschreven. Het nadeel van file_get_contents() is, dat de fopen wrappers ingeschakeld moeten zijn.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
$this
->template = implode("", file($path));
?>
 
Jelmer rrrr

Jelmer rrrr

15/12/2009 14:11:00
Quote Anchor link
file ondersteunt ook fopen-wrappers. En die gebruik je niet wanneer je alleen maar lokaal een bestand wil inlezen (je gebruikt alleen wrappers wanneer je een protocol meegeeft zoals file://, http://, gzip://, phar://, etc)
 
Hendel Berg

Hendel Berg

15/12/2009 14:22:00
Quote Anchor link
Jelmer, je hebt helemaal gelijk! Vaag, voorheen kreeg ik altijd een error als ik file_get_contents gebruikte, i.p.v. implode("", file()).
 
Hendel Berg

Hendel Berg

01/02/2010 17:13:00
Quote Anchor link
Aansluitend op bovenstaande, wilde ik ervoor zorgen dat er DIV's genest kunnen worden. Nu wil 'ie geen data uit de array in de DIV zetten.

sTemplate.php
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<?php
error_reporting(E_ALL);

class TemplateStack
{
   private $data = array();
    
   public function push(&$data)
   {

      return $this->data[] =& $data;
   }


   public function &pop()
   {

      $reference =& $this->top();

      // TemplateStack::top() verplaatst de cursor al naar het einde, dus key() zal de juiste key pakken.
      unset($this->data[key($this->data)]);

      return $reference;
   }


   public function &top()
   {

      // Cursor naar einde bewegen, zodat key() de index van het laatste element pakt.
      end($this->data);

      return $this->data[key($this->data)];
   }
}


class Template
{
   private $template;
   private $data_stack;

   public $dir = './';
   public $ext = '.tpl';
   public $atr = 'class';

   public function __construct($template, $file = true)
   {

      if ($file == true)
      {

         $path = $this->dir . $template . $this->ext;
         $this->template = file_get_contents($path);
      }

      else
      {
         $this->template = $template;
      }


      $this->data_stack = new TemplateStack();
   }

    
   public function apply($data)
   {

      return $this->parse($this->template, $data);
   }


   private function parse($template, $data)
   {

      // Push data op de stack, zodat de replace-functies weten in welke data ze moeten zoeken voor het vervangen van variabelen.
      $this->data_stack->push($data);

      // Parse alle blokken, recursief. Ieder blok komt weer door deze zelfde method heen.
      // Ieder geparsed block wordt onthouden aan een unieke placeholder. Deze wordt later weer teruggeplaatst
      // om er zo voor te zorgen dat bij het variabelen vervangen niet binnen dit al verwerkte blok wordt gezocht.

      $template = preg_replace_callback('{\<\!\-\-(\s?)loop (\w+?) start(\s?)\-\-\>(.+?)\<\!\-\-(\s?)loop (\\2) end(\s?)\-\-\>}', array($this, 'parse_block'), $template);

      // Parse de HTML elementen
      $template = preg_replace_callback('{\<([a-zA-Z0-9\"\'\.=\s]+)(.*?)'. $this->atr .'=(\'|\")(\w+)(\\3)(.*)>(.*)\</\\1>}', array($this, 'parse_nameholder'),  $template);

      // Werk van binnen naar buiten. Handel eerst de blokken af (hierboven) en dan pas de variabelen
      // De blokken zijn in $result vervangen door variabelen, en in $data zitten nu de geparste blokken als normale variabelen.

      $result = preg_replace_callback('{\{(\w+)\}}', array($this, 'parse_placeholder'), $template);

      // Haal de verwijzing naar de data weer weg, zodat we in het omliggende blok weer bij de goeie data komen.
      $this->data_stack->pop();

      return $result;
   }

    
   private function parse_block($matches)
   {

      list(,, $block_name,, $block_code) = $matches;

      $data =& $this->data_stack->top();
      $block_data = $data[$block_name];
      $results = array();

      foreach($block_data as $step_data)
      {

         $results[] = $this->parse($block_code, $step_data);
      }


      // Variabele-naam waar we nu het blok in stoppen.
      $block_placeholder = sprintf('block%s', uniqid());

      // Variabele-naam en de inhoud van dit blok terugstoppen in de data-array
      // Dit gaat lukken omdat $data een reference is naar de top van de stack.

      $data[$block_placeholder] = implode($results);

      return sprintf('{%s}', $block_placeholder);
   }


   private function parse_nameholder($matches)
   {

      list(, $tag_name, $a, $separator, $nameholder_name,, $b, $nameholder_code) = $matches;

      $data =& $this->data_stack->top();
      $nameholder_data = $data[$nameholder_name];
      $results = array();

      foreach($nameholder_data as $step_data)
      {

         $results[] = $this->parse($nameholder_code, $step_data);
      }


      // Variabele-naam waar we nu het blok in stoppen.
      $name_placeholder = sprintf('block%s', uniqid());

      // Variabele-naam en de inhoud van dit blok terugstoppen in de data-array
      // Dit gaat lukken omdat $data een reference is naar de top van de stack.

      $data[$name_placeholder] = implode($results);

      return '<'. $tag_name . $a . $this->atr .'='. $separator . $nameholder_name . $separator . $b .'>'. sprintf('{%s}', $name_placeholder) .'</'. $tag_name .'>';
   }


   private function parse_placeholder($matches)
   {

      list(, $placeholder_name) = $matches;
        
      $data = $this->data_stack->top();

      return $data[$placeholder_name];
   }
}


$data = array(
    'boo' => array(
       'block3' => 'nummer 3',
    ),

    'block1' => array(
        0 => array(
            'var_y' => 'XXvar_y1XX',
            'block2' => array(
                0 => array('var_x' => 'XXvar_x11'),
                1 => array('var_x' => 'XXvar_x12'),
                2 => array('var_x' => 'XXvar_x13'),
            )
        ),

        1 => array(
            'var_y' => 'XXvar_y2XX',
            'block2' => array(
                0 => array('var_x' => 'XXvar_x21'),
                1 => array('var_x' => '{var_y}'), // Deze verwijst terug naar 'var-y' hierboven. Zou niet moeten!
                2 => array('var_x' => 'XXvar_x23'),
            )
        )
   )
);


$x = new Template("test");
echo $x->apply($data);
?>


test.tpl
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Hoi

<div class="boo">
   <div class="block3">
   </div>
</div>

<!-- loop block1 start -->
   (begin-block1) {var_y}

   <!-- loop block2 start -->
      (begin-block2) {var_x} (eind-block2)
   <!-- loop block2 end -->

   test2 (eind-block1)
<!-- loop block1 end -->
Gewijzigd op 01/01/1970 01:00:00 door Hendel Berg
 
Richard van Velzen

Richard van Velzen

01/02/2010 17:27:00
Quote Anchor link
Offtopic:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
if(class_exists('SplStack'))
    return;

class SplStack {

Dit zou alsnog een foutmelding moeten geven omdat de klasse alsnog gedefinieerd (ze worden "naar boven getrokken"). Wrap de hele klasse in een if en je bent er vanaf.

En verder, voor de regex-liefhebbers (jullie hebben het nodig zie ik): http://wiki.phpfreakz.nl/Regexes:_Veelgemaakte_fouten#Het_matchen_op_.60..2A.60
 
Wim Eikelboom

Wim Eikelboom

01/02/2010 17:31:00
Quote Anchor link
Of maak gebruik van singleton class...Wel goede uitleg vind ik persoonlijk
 
Hendel Berg

Hendel Berg

01/02/2010 17:47:00
Quote Anchor link
Ter verduidelijking: de functie parse_nameholder() moet een HTML element voorzien van content. Dit moet hij doen aan de hand van de class name en overeenkomend element uit een array.

Nu is het zo dat er geen content in de HTML elementen wordt gedropt. Ik kan niet ontdekken wat de oorzaak hiervan is.

@RichardvV: Dank voor de regex wiki, inderdaad een aantal verbeterpunten! Wat bedoel je met:
RichardvV schreef op 01.02.2010 17:27:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
if(class_exists('SplStack'))
    return;

class SplStack {

Dit zou alsnog een foutmelding moeten geven omdat de klasse alsnog gedefinieerd (ze worden "naar boven getrokken"). Wrap de hele klasse in een if en je bent er vanaf.


@Wim: Goede tutorial, ga ik zeker naar kijken. Maar volgens mij is dit probleem ook wel op te lossen zonder gebruik te maken van Singleton class?


edit: Lay-out schiet wel erg snel uit z'n voegen x|
Gewijzigd op 01/01/1970 01:00:00 door Hendel Berg
 
Luuk Schakenraad

Luuk Schakenraad

01/02/2010 18:29:00
Quote Anchor link
Voting for freedom is like fucking for virginity
 
Hendel Berg

Hendel Berg

01/02/2010 18:32:00
Quote Anchor link
Revolution is commin schreef op 01.02.2010 18:29:
Voting for freedom is like fucking for virginity

Hmmm, juist, heel veel toegevoegde waarde geeft dit!
 
- SanThe -

- SanThe -

01/02/2010 18:43:00
Quote Anchor link
HendelBerg schreef op 01.02.2010 18:32:
Revolution is commin schreef op 01.02.2010 18:29:
Voting for freedom is like fucking for virginity

Hmmm, juist, heel veel toegevoegde waarde geeft dit!

De pilletjes zullen wel op zijn.
 
Jelmer rrrr

Jelmer rrrr

01/02/2010 18:49:00
Quote Anchor link
RichardvV schreef op 01.02.2010 17:27:
Offtopic:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
if(class_exists('SplStack'))
    return;

class SplStack {

Dit zou alsnog een foutmelding moeten geven omdat de klasse alsnog gedefinieerd (ze worden "naar boven getrokken"). Wrap de hele klasse in een if en je bent er vanaf.[/quote]

Geloof het of niet, maar dit trucje werkt echt. Maar het verschilt eigenlijk ook niets van jouw if-eromheen. Ook voor dat if-statement geldt dat eerst de if geëvalueerd moet worden alvorens de class beschikbaar is. Apart is dan weer dit 2x true geeft:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
 

Pagina: 1 2 volgende »



Overzicht Reageren

Get Adobe Flash player