[PHP] Template engine w/ MVC software

Status
Not open for further replies.

Kryptos

prjRev.com
Jul 21, 2010
2,205
1,252
Hey guys,

So in the paste few days I've been learning more about the MVC pattern/architecture and I think I've really gotten the grasp of it.

So, the problem is I have no idea how to create a nice template engine that would be easily editable for someone with no PHP knowledge.

So, I'm at the moment picking which function the controller should call with a $_GET var(1 function per file/page), I think this is the best way to do it, instead of picking which class the controller should call(1 class per file/page) or any other alternative.

So, I don't know if you guys had any approach at this, since I wouldn't like for the users using the software to have to add a function and code in it for their page, I guess I could just limit them to use the already picked name files, but I really want to find another way.

Anyone?
 

TheJacob

Member
Sep 3, 2010
70
0
Here's a small trick you can use that I personally am using for ICECRON 2.x.x which is pretty sexy.

(all of the below is assuming the user is familiar with HTML and/or a SQL client if you don't have a backend panel to support template modifications/creations, as well that they are running on Apache.)

If a user wants to make a page to your system such as "index" "aboutus" or "stafflist" then here's how it would work. They enter in a table you provide (e.x. templates) the template name and the HTML content. Then here is how your template engine would handle it.

In the htaccess file of the root directory you would have something like this:

Code:
RewriteEngine on

RewriteRule ^Index$ index.php
RewriteRule ^([a-zA-Z])$ templates.php?template=$1

The first line handles your index file, it will be written by you to handle all the includes and all that and the HTML will already be pre-uploaded in the database. The second line handles their custom templates, so when they made the "aboutus" or "stafflist" page it will be and that will redirect to .

Then in your templates.php file you'll have a bunch of functions to filter parameters so they can put php function results in their HTML (e.x. %usersonline%, %username%, etc.). Then you'll also have something like $_GET['template'] (with your string security (probaby regex)) to determine what template to fetch from the database then display its contents.

With this all the user needs to do is add it to the db and enter the html for the page then voila. You should also look into some caching or unbuffered queries if you plan to do this method.

Enjoy!
 

Kryptos

prjRev.com
Jul 21, 2010
2,205
1,252
Thanks for the reply, but I have a very similar method for the template engine, but the problem is that if the users want to create a custom page, they'll have to create a function for the page, thing I don't want them to do - So is there a different approach for this?
 

TheJacob

Member
Sep 3, 2010
70
0
Thanks for the reply, but I have a very similar method for the template engine, but the problem is that if the users want to create a custom page, they'll have to create a function for the page, thing I don't want them to do - So is there a different approach for this?

They don't have to create a function php sided for my method above? It redirects all page requests to template.php then with the value of the get variable you fetch the HTML from the templates table. Then you have some html parsing functions that let them include stuff like %usersonline% = 192 or %username% = TheJacob in their HTML that they put into the database. Then on other pages that they make like "Index" or what ever they add a link to the new page.

I don't understand what you mean exactly?
 

Kryptos

prjRev.com
Jul 21, 2010
2,205
1,252
That would work if it was a normal OOP software like yours or RevCMS, but since this is using the MVC architecture/pattern it is different, I'll try to explain it:

When a user goes to it is actually going to , since the MVC pattern is how it is, I call a controller for the page, usually there is 1 class per file/page, but I use 1 method/function per file/page, so I use the $_GET['url'] var to pick which controller it should call, in this case it would call $controller->member, what's good about this is that I can also create other classes, suchas userController and implement it easily into $controller->member, instead of creating a whole class for the file.

So, if I do it your way, for every new page they do they would have to create a function, else the software would throw an error regarding no finding the function Controller::$_GET['url'], i.e Controller::mycustompage.

I have given it a lot of thinking, but with the way I'm doing it now I can't find an answer, so I'm asking for another approach for either finding a solution for the template, or to calling the controller giving me the freedom to create a custom page.

Ok, just got an idea:
Perhaps I could do a global controller caller and check if the controller function exists, if it exists - call it. if it doesn't - don't do anything.

Now, about filtering parameters like %name%, I know what you mean.

Thanks for your help, I'll be working on it further.
 

Kryptos

prjRev.com
Jul 21, 2010
2,205
1,252
Ok, so yesterday I started working on it again, the base is look pretty good right now, gotta fix errors here and there but the code is awesome.

So, the template engine, is like the one on RevCMS 1.X, I will choose what file to call with a $_GET var, since it works pretty fast and is very efficient IMHO, now, the problem that is with that template engine is that, every file suchas index, needs a function called, suchas $users->login();, that executes the PHP needed for login, since this PHP code has a header() function, I can't put the code within <html> tags, so I need to put it before them, which is kinda difficult because what I want to do is something like on RevCMS 1.0..:

PHP:
<?php

/**
* The template is generated.
*
* @author Kryptos
*/

require_once 'config.php';

$Application->Controller->View->write('<html>');

    $Application->Controller->View->write('<head>');

        $Application->Controller->View->renderCSS(); //Call all CSS files

        $Application->Controller->View->renderJS(); //Call all JS files

    $Application->Controller->View->write('</head>');

    $Application->Controller->View->write('<body>');

        $Application->Controller->View->render($_GET['url']); //Call PHP file by $_GET['url']

    $Application->Controller->View->write('</body>');

$Application->Controller->View->write('</html>');

$Application->Controller->View->output();

?>

Example:
Views/skins/default/index.php:
PHP:
<?php

/*
* Set the required controller to call.
* @Example - login / register / forgot
*/
global $Application;
$Application->Controller->setController('login');
?>

Hello, World!
So, setController sets what function to call from the user controller, and calls it, this would work without the header();
So, I think I can just work around, but instead of using the header() on the function, just assign the logged in session and make a function on the top to handle what happens if the user is in index and is logged in, etc.
I know this might be complicated for most of you, but I'm dying for feedback and better ideas than mine.

Ok, I think I am finally satisfied with the template engine, I'll try to explain it so I can get feedback from you guys.

The template engine has changed a lot from RevCMS 1.0, now the main index.php file looks like this..

PHP:
<?php

/**
* Initialize controllers.
* Build, generate and output template data.
*
* @author Kryptos
*/

define('IN_INDEX', 1);

/**
* Initialize Environment.
*/
include 'config.php';

/**
  * Call the respective controller and build the template
  */

    $Application->Controller->init();

/**
* Output the template
*/

  $Application->Controller->View->outputTPL();

?>

So, the tricky part is at $Application->Controller->init(), it's something like this...

PHP:
        /**
        * Build the template and assign a controller to the page.
        */
        public function init()
        {
            $url = explode('/', rtrim($_GET['url'], '/'));
                $this->View->render(isset($url[1]) ? $url[0] . '-' . $url[1] : $url[0]);
        }

So, that method renders the template, guiding itself with the $_GET['url'] var.
Lets say, the $_GET['url'] is equal to: index

Then, that method would call Skins/myskiname/index.html - All files are .html instead of .php like in RevCMS 1.0, since it's faster(from what I've heard) and I don't plan on using PHP there.

index.html would look something like this...

HTML:
{controller_login}

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        {title}
        [FONT=arial][COLOR=#000000]<link rel="stylesheet" type="text/css" href="Skins/Mango/styles/login.css" />[/COLOR][/FONT]
    </head>
    <body>
        <div id="loginbox">
            <img src="Skins/Mango/images/logo.png" id="logo"/>
            <span id="stats">{online} Users Online!</span>
            <div id="clear"></div>
            <hr/>

            <div id="login_image">
                <div id="main_login">
                    {error}
                    <strong>Welcome to {hotelName}!</strong><br/>
                        Please login with your account or click Register to create one
                        <div style="height:5px;"></div>

                        <form action="index" method="post">
                        <table width="200" border="0">
                        <tr>
                            <td>Username<br/>
                            <input type="text" name="log_username" id="username"/></td>
                        </tr>
                        <tr>
                            <td>Password<br/>
                            <input type="password" name="log_password" id="password"/></td>
                        </tr>
                        <tr>
                            <td>
                            <input type="submit" name="login" id="button" value="Login" style="margin-right:2px; width: 104px;"/><input type="button" style="width: 104px;" name="button2" id="button" value="Register" onclick='window.location="register"'/> </td>
                        </tr>
                        </table>
                        </form>
                </div>
            </div>
            <hr/>

            <center>Powered by <b></b><a href="http://devbest.com/threads/1-x-revcms-php-mysql.8746/">RevCMS</a></b> coded by <b>Kryptos</b> | Design by <b>dannyy94</b> | Copyright &copy {hotelName} Hotel</center>
        </div>
    </body>
</html>

Ok, so, the key line here is {controller_login} and well, when the controller class is instantiated it makes a list from every method in the user's class, and then assigns a template tool for it, so the value of {controller_login} is equal to: $this->setController('login')

setController looks like this...

PHP:
        /*
        * Set the current controller needed for the page
        */
        public function setController($controller)
        {
            if($controller != null && method_exists($this->U_Controller, $controller))
            {
                $this->controller = $controller;
                $this->controllerManager();
            }
        }

After setting the controller needed for the page, it calls the controller's maneger, which looks like this...

PHP:
      /**
        * Call the View to render the template and assign a controller to the page.
        *
        * @param type $controller - Sent by each file, it tells the controller which controller to choose
        */
        public function controllerManager()
        {
            $url = explode('/', rtrim($_GET['url'], '/'));
                $this->U_Controller->{$this->controller}(isset($url[1]) ? $url[1] : null);
        }

So, this calls the controller, before the <html> tags, so I can use header() in them, it's pretty nice, I really like it and IMHO, I think it's very user friendly.

Alright, I really think this one's a winner. BUT, anyone has some suggestions? As this is what I'm looking for in this thread.

Thread closed, if you want to give feedback please check out this thread:
 
Status
Not open for further replies.

Users who are viewing this thread

Top