Quick Start Guide
Last update 2011-02-22. Get older docs here: 0.2.
Phraw is very useful for building small web sites because it don't need special installations, don't require a database and permit you to begin to code in HTML in one minute. Phraw is indicated for small web sites and small applications because is fast to learn, fast to bootstrap and fast to serve requests.
The simpler way is to copy one of the two examples found in the Phraw's package: in only one minute you will have a website ready to run.
This guide helps to learn the base concepts in order to build a new, little, web site.
Requirements:
- This guide needs only Smarty as template engine. You can download it here.
- The stable version of Phraw can be downloaded here.
The structure
The files structure looks like that:
lib/ -- the directory where put the libraries, like Phraw and Smarty
media/ -- the directory where put the static files like images, JS, CSS
resources/ -- a protected directory where put your source files of the website
cached/ -- the Smarty's directory for cached templates
compiled/ -- the Smarty's directory for compiled files
templates/ -- the directory where put the templates
.htaccess -- the web server configuration used for rewriting the urls
index.php -- the file where build the configuration, the initialization and the routing mechanism
Create the directory structure
Create this directory structure:
lib/
media/
resources/
cached/
compiled/
templates/
The resources/cached/ and resources/compiled/ directories have to be writable by PHP.
Install the requirements
Extract the Phraw package in the lib/phraw directory.
Extract the Smarty package in the lib/smarty directory.
The lib directory will looks like this:
lib/
phraw/ -- Phraw files
extensions/
phraw.php
smarty/ -- Smarty files
plugins/
sysplugins/
debug.tpl
Smarty.class.php
Create a "hello world" template
Create a base.html file and put it on the resources/templates/ directory. This will be the main template framework for all the pages, but for now we use it as a normal template.
This is the source of the resources/templates/base.html file:
<html>
<head>
<title>Base title</title>
</head>
<body>
<p>Hello world!</p>
</body>
</html>
Create the main file
The web site logic is written in the index.php file. Create it and write the following:
<?php
# Global variables: place here your global settings
define('DEBUG', true); # Activate the debug mode
# Load Phraw with the starter shortcut
require_once('lib/phraw/phraw.php');
$phraw = new Phraw();
$phraw->add_include_path('lib'); # Add the "lib" directory to the include path
# Load the Smarty extension
require_once('phraw/extensions/smarty.php');
$smarty = new SmartyTemplateEngine();
# Routing
if ($phraw->route('')) { # root URL
$smarty->display('base.html');
}
?>
The first block is where set the global and custom configuration variables. Some globals will be read by Phraw.
The second block load a Phraw instance. Phraw read the configuration variables and activate the debugging code.
The lib directory is added to the include path in order to load the libraries, if are not in the current directory.
The third block load Smarty through an extension for Phraw. The extension helps to set up Smarty correctly. (The use of the extension is not required so you can write your own code in order to load Smarty)
The fourth block is your custom routing mechanism. The "if" method is the simpler way to create complex routing structures. It is possible to manage hundreds or thousand of URLs with few lines of code but for this guide we will manage few in the simplest way.
Ok, now it is possible to run the browser and see the "hello world" page!
Do you want to see more? Continue to read.
The routing mechanism
The URI path to the root page "" (a void string) is inside the standard u GET variable, the value is captured in the $phraw->url variable for you. For example, to view a page you should use someting like http://127.0.0.1/?u=mypage, so the $phraw->url variable will contain mypage. This is only in order to understand the concept and really a lot of web sites use this mechanism, we will optimize this behavior in this guide.
The $phraw->route function only help you to see if the $phraw->url variable contain a "" or "/" string. The function uses a simplified regular expression match (it add a standard head and tail of an URL regex string). It is possible to use the full power of a regular exmpression with the parameter $simple=false (Eg. $phraw->route('my path', $simple=false)).
The route function is case-sensitive for SEO reasons.
If the route match this pattern it will diplay the base.html page with the help of Smarty.
Add an error page
If we point to or web site with a wrong URI (like http://127.0.0.1/?u=foobar) we get a blank page, so we start adding a 404 error page. It is very simple.
Create the resources/templates/404.html file:
<html>
<head>
<title>Error 404</title>
</head>
<body>
<h1>Error 404</h1>
<p>Page not found!</p>
</body>
</html>
Now we connect it to the routing mechanism:
<?php
# ... other code
# Routing
if ($phraw->route('')) { # root URL
$smarty->display('base.html');
} else { # ADDED!
$smarty->display_error(); # ADDED!
}
?>
Perfect, now we have a customized 404 error page. Try it! (Eg. http://127.0.0.1/?u=foobar)
Leverage the base.html file
All the pages of the web site should have the same structure, at least for the header and the footer. So we will declare some blocks in the base.html file that will be replaced by the other pages of the web site. This will result in much less code to write and a flexible way to do the things.
Here the new resources/templates/base.html file with the named blocks:
<html>
<head>
<title>{block name='title'}Base title{/block}</title>
</head>
<body>
<p>[header]</p>
{block name='content'}Hello world!{/block}
<p>[footer]</p>
</body>
</html>
The modified resources/templates/404.html file is:
{extends file='base.html'}
{block name='title'}Error 404{/block}</title>
{block name='content'}
<h1>Error 404</h1>
<p>Page not found!</p>
{/block}
Yes, that's all the code, this is Smarty!
The first line load the base.html file and use it as a framework.
The second line replace the "title" block.
The third line replace the "content" block.
Now try it, you see that the 404 error page is engaged on the base page.
Dynamic pages
Now we add a new page with a dynamic variable. (Phraw have also a shortcut that leverage an array in order to display these static pages, but it's not important now)
Create a new page resources/templates/flatpages/hello-new.php:
{extends file='base.html'}
{block name='title'}Hello new world{/block}</title>
{block name='content'}
<h1>Hello new world!</h1>
<p>{$myvariable}</p>
{/block}
Connect the URI to the page:
<?php
# ... other code
# Routing
if ($phraw->route('')) { # root URL
$smarty->display('base.html');
} else if ($phraw->route('hello')) { # ADDED!
$smarty->assign('myvariable', 'This is a great place to live.'); # ADDED!
$smarty->display('flatpages/hello-new.html'); # ADDED!
} else {
$smarty->display_error();
}
?>
Now the new page is ready and the myvariable variable is placed inside the template.
For a more complex example we can use an external view function in order to use more complex assignments. Create the file resources/views.php where store your view functions:
<?php
function say_view($phraw, $smarty) {
# Load an URL parameter
$contexts = array(
'say' => $_GET['say']
);
# Publish
$smarty->assign($contexts);
$smarty->display('dynamic/say.html');
}
?>
This simple view will display the say GET variable. You can put more complex things inside like a database queries or so on.
Now create the resources/templates/dynamic/say.html template:
{extends file='base.html'}
{block name='title'}What I have to say{/block}</title>
{block name='content'}
<h1>Hear me.</h1>
<p>I have to say that {$say}.</p>
{/block}
And write the routing:
<?php
# ... other code
# Routing
if ($phraw->route('')) { # root URL
#$smarty->display('base.html');
} else if ($phraw->route('hello')) {
$smarty->assign('myvariable', 'This is a great place to live.');
$smarty->display('flatpages/hello-new.html');
} else if ($phraw->route('say')) { # ADDED!
require('./resources/views.php'); # ADDED!
say_view($phraw, $smarty); # ADDED!
} else {
$smarty->display_error();
}
?>
Try the page with an URL like http://127.0.0.1/?u=say&say=the world is little
Remember that you are free to rename directories, files and functions. You have the full control of your application.
URL rewriting
In order to improve the readability of the URL create the file .htaccess in the main directory (where there is the index.php file):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteRule ^(.*)$ index.php?u=$1 [L,QSA]
This file tells the web server (Apache) to redirect the URI to the u GET parameter.
Now the URLs become:
- http://127.0.0.1/ remain http://127.0.0.1/
- http://127.0.0.1/?u=hello become http://127.0.0.1/hello/
- http://127.0.0.1/?u=say&say=the world is little become http://127.0.0.1/say/?say=the world is little
A lot better and great for SEO!
Get values from the URL
Phraw can get the values from the URL path. Here an example: it will get the value "2011" from the URL http://127.0.0.1/year/2011/:
<?php
# ... inside the routing
} else if ($phraw->route('year\/(?P<year>\d*)') ){
echo $phraw->request['year'];
}
...
?>
The $phraw->request variable contains all the matched groups from the $phraw->route function.
Redirects
This functionality is stable but in the beta version.
Simple as:
$phraw->redirect($your_url); # For default it is a 301 permanent redirect
$phraw->redirect($your_url, 302); # Temporary redirect
This function does not force an immediate redirect, so you can add some code after it.
Trailing slash fix for SEO
This functionality is stable but in the beta version.
The search engines may think that there is a duplication of content if the same page can reached both by http://www.yoursite.com/page/ and http://www.yoursite.com/page, this may penalize that page.
This feature detect when there is not the trailing slash at the end of the URLs. A special function can be used to redirect the user to the correct page.
Add the detection to the routing and use the fixer function:
<?php
# ... other code
# Routing
if ($phraw->detect_no_trailing_slash()) { # Detect the absence of the trailing slash
$phraw->fix_trailing_slash(); # Redirect the user to the correct URL
} else if (/* ... other rules ... */) {
# ... other code
?>
Sessions
This functionality is stable but in the beta version.
The method session_start() take a class string, that handle the sessions, and some parameters. The session class is loaded automatically with the given parameters. The session start immediately.
The sessions are usable like the common way.
The session handler object is stored in the $session_handler property inside the Phraw object.
Store sessions in files
The Phraw extension SessionFileHandler saves the session data in your custom directory.
<?php
# Load Phraw
require_once('phraw/phraw.php');
$phraw = new Phraw();
# Sessions
require_once('lib/phraw/extensions/sessions_files.php');
$phraw->session_start('SessionFilesHandler', '/home/user/tmp');
# Set a session variable
$_SESSION['foo'] = 'bar';
# ...
# Use the session variable
echo $_SESSION['foo'];
?>
It can take also an encription object, that must have the encrypt() and decrypt() methods. You can easly use your preferred encryption library.
Create custom session handlers
To create a new session handler, simply extend the SessionSaveHandler class. See the SessionFilesHandler for an example (in phraw/extensions/session_files.php).