Views and language support
Create site2 by copying site1.
- /cms
- site0
- site1
- site2
In this chapter, we are going to program how a URL is parsed and dispatched in different views depending on the requested language.
To test the result online, enter http://www.frasq.org/cms/site2 in the address bar of your navigator. End the URL with /fr to display the page in French, with /en to see it in English.
Create the folder views in site2, then the folders en and fr in site2/views.
- /cms/site2
- includes
- library
- views
- en
- fr
Modify index.php after the call to bootstrap
:
- define('ROOT_DIR', dirname(__FILE__));
- set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'library');
- set_include_path(get_include_path() . PATH_SEPARATOR . ROOT_DIR . DIRECTORY_SEPARATOR . 'includes');
- require_once 'dump.php';
- require_once 'bootstrap.php';
- bootstrap();
- require_once 'engine.php';
- dispatch($supported_languages); // see config.inc
index.php calls the function dispatch
defined in the file engine.php with in argument the list of the languages supported by the program.
Add the parameter $supported_languages
in config.inc:
- global $supported_languages;
- $supported_languages=array('fr', 'en');
The first language defined by $supported_languages
is the default language.
The code for a language must match the name of a folder in views.
Add the files engine.php, request_uri.php and locale.php in the folder library with the following contents:
- /cms/site2
- library
- engine.php
- requesturi.php
- locale.php
- library
- require_once 'requesturi.php';
- define('VIEWS_DIR', ROOT_DIR . DIRECTORY_SEPARATOR . 'views');
Loads the code of the request_uri
function. Defines the folder in which the files which generate the views are grouped.
- function dispatch($languages) {
dispatch
determines how the document corresponding to the URL of the request is generated according to the supported languages specified by $languages
.
- global $base_path;
- $req = $base_path ? substr(request_uri(), strlen($base_path)) : request_uri();
- $url = parse_url($req);
- $path = isset($url['path']) ? trim(urldecode($url['path']), '/') : false;
- $query = isset($url['query']) ? $url['query'] : false;
- if (empty($path)) {
- $path = false;
- }
Withdraws the prefix $base_path
from the normalized URL returned by the request_uri
function/ Extracts the access path and the parameters from the request.
- /* site language */
- $p = $path ? explode('/', $path) : false;
- $lang = $p ? $p[0] : false;
- if ($lang && in_array($lang, $languages, true)) {
- array_shift($p);
- $path = implode('/', $p);
- }
- else {
- require_once 'locale.php';
- $lang=locale();
- if (!$lang or !in_array($lang, $languages, true)) {
- $lang = $languages[0];
- }
- }
Computes the display language of the site. If $path
begins by one of the languages contained in $languages
, the language is extracted from the URL. Otherwise, $lang
is set to the value returned by the locale
function if it is supported or by default to the first language listed in $languages
.
- if (!$path)
- $path='home';
- $output=view($path, $lang);
- if ($output) {
- echo $output;
- }
- }
Takes the view called home
by default.
Generates the document by calling the function view
with the name of the view and the language in argument.
- function view($view, $lang=false) {
- $file = $lang ? VIEWS_DIR.DIRECTORY_SEPARATOR.$lang.DIRECTORY_SEPARATOR.$view.'.phtml' : VIEWS_DIR.DIRECTORY_SEPARATOR.$view.'.phtml';
- if (!file_exists($file)) {
- header('HTTP/1.0 404 Not Found');
- exit;
- }
- return render($file);
- }
view
locates the file corresponding to $view
depending on the language specified by $lang
.
view
returns the rendering of the file.
If no file is found, view
returns an HTTP 404 Not Found error document.
- function render($file) {
- global $base_path, $base_url, $base_root;
- ob_start();
- require $file;
- return ob_get_clean();
- }
render
places the variables $base_path
, $base_url
and $base_root
in the global context before loading the file $file
.
render
returns the document generated by $file
.
- function request_uri() {
- if (isset($_SERVER['REQUEST_URI'])) {
- $uri = $_SERVER['REQUEST_URI'];
- }
- else {
- if (isset($_SERVER['argv'])) {
- $uri = $_SERVER['SCRIPT_NAME'] .'?'. $_SERVER['argv'][0];
- }
- elseif (isset($_SERVER['QUERY_STRING'])) {
- $uri = $_SERVER['SCRIPT_NAME'] .'?'. $_SERVER['QUERY_STRING'];
- }
- else {
- $uri = $_SERVER['SCRIPT_NAME'];
- }
- }
- $uri = '/'. ltrim($uri, '/');
- return $uri;
- }
request_uri
normalizes the format of the request passed in a URL.
- function locale() {
- if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
- return false;
- }
- $httplanguages = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
- if (empty($httplanguages) === true) {
- return false;
- }
- $lang = false;
- $quality = 0.0;
- $accepted = preg_split('/,\s*/', $httplanguages);
- foreach ($accepted as $accept) {
- $match = null;
- $result = preg_match('/^([a-z]{1,8}(?:[-_][a-z]{1,8})*)(?:;\s*q=(0(?:\.[0-9]{1,3})?|1(?:\.0{1,3})?))?$/i', $accept, $match);
- if ($result < 1) {
- continue;
- }
- $q = isset($match[2]) ? (float) $match[2] : 1.0;
- if ($q > $quality) {
- $quality = $q;
- $lang = current(explode('_', current(explode('-', $match[1]))));
- if ($quality == 1.0) {
- break;
- }
- }
- }
- return $lang;
- }
locale
analyzes the PHP variable $_SERVER['HTTP_ACCEPT_LANGUAGE']
to extract the preferred language of the sender of an HTTP request.
The home page displays a version in English and a version in French. The content of each version is placed in a file called home.phtml in the folders en and fr of the views folder. A file with a .phtml extension contains code in HTML and some code in PHP limited to inserting computed data. In a view, only the presentation of the data is taken care of.
- /cms/site2
- views
- fr
- home.phtml
- en
- home.phtml
- fr
- views
Start by writing the version in English:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>Home</title>
- </head>
- <body>
- <h3>Welcome</h3>
- </body>
- </html>
Add the translation in French:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>Accueil</title>
- </head>
- <body>
- <h3>Bienvenue</h3>
- </body>
- </html>
Try different addresses like http://localhost/cms/site2, http://localhost/cms/site2/en, http://localhost/cms/site2/fr or http://localhost/cms/site2/en/nowhere.
Comments