Template engine: transform template syntax to PHP

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Agirre
Forum Newbie
Posts: 7
Joined: Wed Jan 23, 2008 1:05 pm
Location: Amsterdam, The Netherlands

Template engine: transform template syntax to PHP

Post by Agirre »

For my current site I'm developing a template engine. Let me explan the basics: my template syntax consist out of:

Code: Select all

{variables}
 
{include: file}
 
{* comments *}
 
{block: blockname}
[i]block-content[/i]
{blockname/}
 
Looks a bit like TemplatePower, which I would have used if it did support cache. On the other hand, writing your own is a great experience. I like the caching system of PHPBB, where template syntax is converted to PHP and then saved in cache. Exactly what I want.

But I've ran into the following problem: how to code nested blocks in PHP? I tried:

Code: Select all

 
for($blockname = 0; $blockname < $this->_blocks['blockname'][$parent1iteration][$parent2iteration]; $blockname++) ...
 
This works, but it looks all messy and ugly to me. It uses a lot of arrays and I'm quite sure there has to be a more efficient and cleaner way to program this, because now the script has to remember the blocks structure (who the parents are). Hopefully someone has an idea how to code it properly?

My current _parse() of the template class (I excluded all the non-block parsing parts):

Code: Select all

    /**
    * Parses content, $this->_content is the raw template file
    */
    private function _parse() {
        /**
        * Parse blocks
        */
        $this->_content = preg_replace_callback($this->_regex['block'], array('self', '_parseBlock'), $this->_content);
 
        /**
        * Put files block structure on top, because we have to remember our blockstructure
        */
        $structure = '/*block structure*/ $this->_blocks = array_merge($this->_blocks, array(';
        foreach($this->_blocks as $block => $childs) {
            $structure .= '\'' . $block . '\'=>\'' . $childs . '\',';
        }
        $structure .= '));';
 
        $this->_content = $this->_phpOpen . $structure . $this->_phpClose . $this->_content;
    }
 
    /**
    * Parses blocks
    * @param $blockContent
    * @param $root
    * @return parsed block
    */
    public function _parseBlock($blockContent, $root = NULL) {
 
        $block = $blockContent[1];
 
        if(!isset($root)) {
            $root = $block;
        }
        else {
            $root .= '.' . $block;
        }
        $this->_blocks[$block] = $root;
 
        /**
        * Find child blocks (continue while match found)
        */
        $childContent = $blockContent[2];
        if(preg_match($this->_regex['block'], $childContent) == 1) {
            $childContent = preg_replace_callback($this->_regex['block'], create_function('$matches','global $tpl; return $tpl->_parseBlock($matches, \'' . $root . '\');'), $childContent);
        }
 
        /**
        * Now make the real code change, first we get the root needed by for-statements
        */
        $blockRoot = explode('.', $this->_blocks[$block], -1);
        $blockRoot = (!empty($blockRoot) ? '[$' . implode('][$', $blockRoot) . ']' : '');
        $blockRoot = '$this->_blockCount[\'' . $block . '\']' . $blockRoot;
 
        return $this->_phpOpen . 'for($' . $block . ' = 0; $' . $block . ' < ' . $blockRoot . '; $' . $block . '++) {' . $this->_phpClose . $block . $childContent . $this->_phpOpen . '} /*end ' . $block .' loop*/' . $this->_phpClose;
 
    }
 
As you can see, it uses create_function (with global $tpl (we assume $tpl->new Template()) ), which is like eval = evil, so I'm not happy with what I've coded here, although it might work if I work it out completely.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Template engine: transform template syntax to PHP

Post by Christopher »

Search these forums. There are some good threads on how to do nested block parsing.
(#10850)
User avatar
Zoxive
Forum Regular
Posts: 974
Joined: Fri Apr 01, 2005 4:37 pm
Location: Bay City, Michigan

Re: Template engine: transform template syntax to PHP

Post by Zoxive »

Why not skip the whole "template" engine, and just use php.

PHP itself is a template language, just use php's alternative syntax.

It will save you alot of hassle, and CPU Cycles.
User avatar
Agirre
Forum Newbie
Posts: 7
Joined: Wed Jan 23, 2008 1:05 pm
Location: Amsterdam, The Netherlands

Re: Template engine: transform template syntax to PHP

Post by Agirre »

arborint wrote:Search these forums. There are some good threads on how to do nested block parsing.
First thing I did, it came up with some interesting pages (viewtopic.php?f=1&t=76278&hilit=nested+template), but I still get stuck in the part on how to code these nested blocks in PHP. Splitting them is no problem.
Zoxive wrote:Why not skip the whole "template" engine, and just use php.

PHP itself is a template language, just use php's alternative syntax.

It will save you alot of hassle, and CPU Cycles.
I know, but I most likely will sell my site when it's finished, so I need a way to keep designing and coding seperate.
User avatar
Zoxive
Forum Regular
Posts: 974
Joined: Fri Apr 01, 2005 4:37 pm
Location: Bay City, Michigan

Re: Template engine: transform template syntax to PHP

Post by Zoxive »

Agirre wrote:I know, but I most likely will sell my site when it's finished, so I need a way to keep designing and coding seperate.
You still can. Most commonly with a Model View Controller (MVC).
Just keep your logic outside of the view.

But there is always some type of basic logic in templates.
Last edited by Zoxive on Sun Jan 27, 2008 10:25 am, edited 1 time in total.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Template engine: transform template syntax to PHP

Post by Christopher »

Agirre wrote:First thing I did, it came up with some interesting pages (viewtopic.php?f=1&t=76278&hilit=nested+template), but I still get stuck in the part on how to code these nested blocks in PHP. Splitting them is no problem.
I do something like

Code: Select all

$output = $template->render('blockname');
(#10850)
User avatar
Agirre
Forum Newbie
Posts: 7
Joined: Wed Jan 23, 2008 1:05 pm
Location: Amsterdam, The Netherlands

Re: Template engine: transform template syntax to PHP

Post by Agirre »

arborint wrote: I do something like

Code: Select all

$output = $template->render('blockname');
Thought about the basics in the last couple of days. It seems best to render each block after it's 'complete'. Going to examine XTemplate, because I like the way it works. After, I'm going to rewrite my class with the ideas I've now.

Btw, to avoid calling render('blockname') I think about parsing the previous block when the block is called again. Works the same and avoid some extra code.
Post Reply