56

Controlling actions

Create site6 by copying site5.

  1. /cms
    1. ...
    2. site5
    3. site6

In this chapter, we are going to program how a URL is interpreted and converted into an action.

To test the result online, enter http://www.frasq.org/cms/site6 in the address bar of your navigator.

Create the folder actions in site6.

  1. /cms/site6
    1. actions

Add the file home.php in the folder actions with the following content:

  1. /cms/site6
    1. actions
      1. home.php
  1. function home($lang) {
  2.     head('title', translate('home:title', $lang));
  3.  
  4.     $footer = view('footer', $lang);
  5.  
  6.     $content = view('home', $lang);
  7.  
  8.     $output = layout('standard', compact('footer', 'content'));
  9.  
  10.     return $output;
  11. }

The function home has one argument, $lang, the display language of the content. home starts by adding the title of the page to the head section of the document then generates the views for the central part and footer of the page. The whole thing is assembled with the layout function. home returns the body of the document.

Add the title of the home page in strings.inc.

  1. global $strings;
  2.  
  3. $strings = array(
  4.     array('title'               => 'frasq.org',
  5.     ),
  6.     'fr' => array(
  7.         'description'           => 'frasq.org : Apprenez comment √©crire votre propre CMS en PHP.',
  8.         'keywords'              => 'PHP HTML CSS CMS MVC site web language programmation tutoriel manuel cours exemple',
  9.         'home:title'            => 'Accueil',
  10.     ),
  11.     'en' => array(
  12.         'description'           => 'frasq.org : Learn how to write your own CMS in PHP.',
  13.         'keywords'              => 'PHP HTML CSS CMS MVC web site langage programming tutorial manual course example',
  14.         'home:title'            => 'Home',
  15.     ),
  16. );

description and keywords define the default contents of the tags meta name="description" and meta name="keywords", essential to search engines.

Add the file aliases.inc in the folder includes with the following content:

  1. /cms/site6
    1. includes
      1. aliases.inc
  1. global $aliases;
  2.  
  3. $aliases = array(
  4.     'fr' => array(
  5.         'accueil'               => 'home',
  6.     ),
  7.     'en' => array(
  8.         'home'                  => 'home',
  9.     ),
  10. );

aliases.inc defines the global array $aliases which associates, depending on a language, a path in a URL to an action.

All the work of reading or writing URLs is realized in engine.php.

  1. global $aliases;
  2.  
  3. $aliases = array();
  4.  
  5. @include 'aliases.inc';

Loads the global array $aliases.

  1. define('ACTIONS_DIR', ROOT_DIR . DIRECTORY_SEPARATOR . 'actions');

Defines where all actions are stored. An action is a function defined in a file with the same name.

  1. function url($action, $lang=false, $args=false) {
  2.     global $base_path;
  3.  
  4.     return $base_path.'/'.alias($action, $lang, $args);
  5. }

url returns the URL of an action, depending on a language.

  1. function alias($action, $lang=false, $args=false) {
  2.     $path = detour($action, $lang);
  3.  
  4.     if ($args) {
  5.         if ($path) {
  6.             $path .= '/';
  7.         }
  8.         $path .= implode('/', $args);
  9.     }
  10.  
  11.     return $lang ? $lang.'/'.$path : $path;
  12. }

alias returns the path in URL for an action, depending on a language.

  1. function detour($action, $lang=false) {
  2.     global $aliases;
  3.  
  4.     if ($lang && array_key_exists($lang, $aliases)) {
  5.         if (($path = array_search($action, $aliases[$lang]))) {
  6.             return $path;
  7.         }
  8.     }
  9.     if (array_key_exists(0, $aliases)) {
  10.         if (($path = array_search($action, $aliases[0]))) {
  11.             return $path;
  12.         }
  13.     }
  14.  
  15.     return false;
  16. }

detour returns the alias of an action, depending on a language.

  1. function route($query, $lang=false) {
  2.     global $aliases;
  3.  
  4.     $args = array();
  5.  
  6.     if (empty($query)) {
  7.         return array('home', false);
  8.     }
  9.  
  10.     $s = explode('/', $query);
  11.  
  12.     while (count($s) > 0) {
  13.         $p = implode('/', $s);
  14.         if ($lang && array_key_exists($lang, $aliases) && array_key_exists($p, $aliases[$lang])) {
  15.             return array($aliases[$lang][$p], $args);
  16.         }
  17.         if (array_key_exists(0, $aliases) && array_key_exists($p, $aliases[0])) {
  18.             return array($aliases[0][$p], $args);
  19.         }
  20.         array_unshift($args, array_pop($s));
  21.     }
  22.  
  23.     return false;
  24. }

route returns the action associated to a path in a URL, depending on a language. The rest of the path is also returned as a list of arguments. If the path is empty, route refers to the home page. If the path isn't matched with an action, route returns false.

  1.     $action=$args=false;
  2.     $r = route($path, $lang);
  3.     if (!$r) {
  4.         header('HTTP/1.0 404 Not Found');
  5.         exit;
  6.     }
  7.     else {
  8.         list($action, $args) = $r;
  9.     }
  10.    
  11.     run($action, $lang, $args);
  12. }

The end of dispatch now calls route to obtain the name of an action and a list of arguments and passes them with the display language to run. If no action is associated to the URL, an HTTP 404 error is sent back to the requester.

  1. function run($action, $lang=false, $args=false) {
  2.     head('lang', $lang);
  3.     head('title', translate('title', $lang));
  4.     head('description', translate('description', $lang));
  5.     head('keywords', translate('keywords', $lang));
  6.     head('favicon', 'favicon');
  7.  
  8.     $file = ACTIONS_DIR.DIRECTORY_SEPARATOR.$action.'.php';
  9.     require_once $file;
  10.  
  11.     $func = basename($action);
  12.  
  13.     if ($lang) {
  14.         if ($args) {
  15.             array_unshift($args, $lang);
  16.         }
  17.         else {
  18.             $args = array($lang);
  19.         }
  20.     }
  21.  
  22.     $output = $args ? call_user_func_array($func, $args) : call_user_func($func);
  23.    
  24.     if ($output) {
  25.         echo $output;
  26.     }
  27.    
  28.     exit;
  29. }

run begins by filling some meta tags of the head section of the document with their default values. The rest of the code loads the file corresponding the requested action then calls the function with the same name with the language and the arguments of the action as parameters. run sends back all the generated document and terminates the execution of the request.

Enter http://localhost/cms/site6 in the address bar of your navigator. Display the source code of the document. Check the result, in particular the head section.

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="content-type" content="text/html; charset=utf-8" lang="en" />
  5. <meta name="description" content="frasq.org : Learn how to write your own CMS in PHP." />
  6. <meta name="keywords" content="PHP HTML CSS CMS MVC web site langage programming tutorial manual course example" />
  7. <meta name="robots" content="index, follow" />
  8. <link href="/cms/site6/css/zero.css" rel="stylesheet" type="text/css" media="screen" />
  9. <link href="/cms/site6/css/screen.css" rel="stylesheet" type="text/css" media="screen" />
  10. <link href="/cms/site6/css/theme.css" rel="stylesheet" type="text/css" media="screen" />
  11. <link href="/cms/site6/css/print.css" rel="stylesheet" type="text/css" media="print" />
  12. <link rel="shortcut icon" href="/cms/site6/favicon.ico" type="image/x-icon" />
  13. <title>Home</title>
  14. </head>
  15. <body>
  16. <div id="content">
  17. <h3>Welcome</h3>
  18. </div>
  19. <div id="footer">
  20. <p>&copy;2010 frasq.org - All rights reserved - <a href="http://www.frasq.org">www.frasq.org</a> - May 13th, 2010</p>
  21. <p><img src="/cms/site6/images/ubuntu.png" alt="" width="16" height="16"/>&nbsp;<a href="http://www.ubuntu.com" target="_blank">Ubuntu</a></p>
  22. </div>
  23. </body>
  24. </html>

Comments

To add a comment, click here.