Ce site est construit sur le modèle MVC.
Il pourrait n'être qu'un ensemble de page statique HTML, mais il est plus rapide, plus simple à faire évoluer et beaucoup plus ouvert en terme de possibilité de partir dès le début d'un tel modèle.
Dans ce cas il est relativement simplifié par rapport à une grosse application, qui utiliserait le module MVC de Zend par exemple. La partie modèle (de données), en particulier, est réduite au plus simple : quelques variables de sessions.
Cette page, comme toutes celles de ce site, utilise les fichiers suivants :
PHP
.
Il existe autant de variantes de ce fichier que de traductions disponibles.
Les éléments de texte des fichiers PHP
sont traduits par le module "translate" du Zend Framework.
Invoqué par le précédent, spécifique à chaque page, domaine "Vues".Enfin, le contrôleur ajax, qui se substitue au contrôleur principal quand la page est modifiée par le menu « automatique ».
Toute cette mécanique n'est invoquée que si la page n'est pas en cache, c'est à dire seulement suite à une modification dans notre cas. Quand le contenu est en cache, seul un contrôleur frontal est activé.
# php_flag display_errors off # php_flag session.use_only_cookies 1 # php_value session.use_trans_sid 0 # # php_flag register_globals off AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-javascript text/css SetOutputFilter DEFLATE SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|mp4)$ no-gzip dont-vary RewriteEngine on RewriteBase / # RewriteRule ^a_x/(.*) $1 [QSA] RewriteRule ^ajax/([^/]*).html ajax_.php?sujet=$1 [QSA] RewriteRule ^([^/]*).html index.php?sujet=$1 [QSA]
<?php if (isset($_SERVER["HTTP_ACCEPT"]) and stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml")) { header('Content-type: application/xhtml+xml'); } else header ('content-type: text/html; charset="utf-8"'); error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE); // error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); set_include_path(get_include_path() . PATH_SEPARATOR . '../includes/:..'); require_once 'lib/functions.php'; //session require_once 'Zend/Session/Namespace.php'; $session = new Zend_Session_Namespace(); //languages, define available translation require_once("Zend/Translate.php"); $tr = new Zend_Translate('gettext', 'i18n/fr.mo', 'fr'); $tr->addTranslation('i18n/en.mo', 'en'); if ($request->lang and in_array($request->lang, $tr->getList())) { //lang in request parameter $tr->setLocale($request->lang); // in session $session->lang = $request->lang; } elseif (isset($session->lang) ) $tr->setLocale($session->lang); // lang already set in session else { //get best gess language from browser require_once 'Zend/Locale.php'; $locale = new Zend_locale(); if (in_array($locale->getLanguage(), $tr->getList())) $tr->setLocale($locale->getLanguage()); else $tr->setLocale('en'); // in session $session->lang = $tr->getLocale(); } require_once 'hop/hop.php'; // target page $sujet = $request->get('sujet', 'accueil'); if ($sujet == 'hop') $sujet_lang = "views/{$sujet}_en.html"; else $sujet_lang = "views/{$sujet}_{$session->lang}.html"; include 'adm/compteurs.php'; // cache management require_once 'Zend/Cache.php'; $ref_file = "views/$sujet.php"; //check for most recently modified file if (file_exists($sujet_lang)) { if (filemtime($sujet_lang) > filemtime($ref_file)) $ref_file = $sujet_lang; } elseif (file_exists("views/{$sujet}_fr.html") and filemtime("views/{$sujet}_fr.html") > filemtime($ref_file)) $ref_file = "views/{$sujet}_fr.html"; if (filemtime("views/theme.php") > filemtime($ref_file)) $ref_file = "views/theme.php"; $cache_page = Zend_Cache::factory('File', 'File', array('lifetime' => null, 'master_file' => $ref_file), array('cache_dir' => 'cache')); //, 'automatic_serialization' => true $cache_page_id = "theme_{$sujet}_{$session->lang}"; if (!(isset($session->style) and $session->style != 'views/a_x.css') and $cache_page->test($cache_page_id)) { $page_h = $cache_page->load($cache_page_id); } else { // page generation $page = include 'views/theme.php'; //save in cache if (!$cache_page->test($cache_page_id)) $cache_page->save($page_h = $page->render(), $cache_page_id); //render and save if needed //no cache if (isset($session->style) and $session->style != 'views/a_x.css') { $page->head->feuille_style->set_href($session->style); if ($session->style == 'views/vide.css') $page->head->hop_menu->set_href($session->style); $page_h = $page->render(); } } // output html echo $page_h; ?>
<?php // génération page // require_once 'hop/hop.php'; $page = Hop_page::factory(array('title' =>"a/X : {$tr->_("développement web 2")} - {$tr->_($sujet)}", 'lang' => $session->lang)); $page->head->add($hop->meta('keywords')->auto_name()->set_attr('content', $tr->_("développement web, indépendant, web2, web 2, xhtml, php, javascript, ajax, jquery, prototype, mysql"))); $page->head->add($hop->link('feuille_style')->auto_id() ->set_rel('stylesheet')->set_type('text/css')->set_media('screen')->set_href('views/a_x.css')); $page->head ->add($hop->link()->rel('alternate')->type('text/html')->hreflang('fr')->href('?lang=fr')->title('français')) ->add($hop->link()->rel('alternate')->type('text/html')->hreflang('en')->href('?lang=en')->title('English')) ->add($hop->script()->set_type('text/javascript')->set_src('lib_js/prototype.js')) ->add($hop->script()->set_type('text/javascript')->set_src('lib_js/effects.js')) ->add($hop->script()->set_type('text/javascript')->set_src('lib_js/dragdrop.js')) ->add($hop->script()->set_type('text/javascript')->set_src('js/a_x.js')) ->add($hop->script()->set_type('text/javascript')->set_src('js/ajax_menu.js')) ; //SVG vector image //commented out : Safari is the only browser to display and scale // $page->body->add($hop->object('fond_logo')->auto_id() // ->set_type('image/svg+xml') // ->set_data('views/logo.svg') // ); //titre page $page->body ->add($hop->p($hop->a($tr->getLocale() == 'en' ? 'français' : 'English')->set_href($tr->getLocale() == 'en' ? '?lang=fr' : '?lang=en'), 'lang')->auto_id()) ->add($hop->h1('<span class="a_X">a/X</span> ' . $tr->_("développeur en vacances"),'titre_page')->auto_id()) ; // menu $menu = Hop_menu::factory(array( 'id' => 'menu_g', 'page' => $page, 'css' => 'views/hop_menu_IE6.css', 'items' => array( 'accueil' => $hop->a($tr->_("accueil"))->set_href('accueil.html'), 'contributions' => $tr->_("contributions") // ,'web2' => $hop->a("Ajax, web 2")->set_href('web2.html'), // 'xhtml' => $hop->a("XHTML")->set_href('xhtml.html'), // 'css' => $hop->a("CSS")->set_href('css.html'), // 'javascript' => $hop->a("JavaScript")->set_href('javascript.html'), // 'php' => $hop->a("PHP")->set_href('php.html'), // 'zend' => $hop->a("Zend framework")->set_href('zend.html'), // 'mvc' => $hop->a("MVC")->set_href('mvc.html'), // 'mysql' => $hop->a("MySQL")->set_href('mysql.html'), // 'i18n' => $hop->a("i18n")->set_href('i18n.html'), // 'spip' => $hop->a("CMS, SPIP")->set_href('spip.html') ))) ->sub_menu(Hop_menu::factory(array( 'id'=>'logiciels', 'items' => array( 'hop' => $hop->a("Ho<sub>in</sub>P")->set_href('hop.html') // ,'menus' => $hop->a($tr->_("menus en CSS"))->set_href('menus.html') ))) , 'contributions') ->auto_id() ; if (isset($hop->pool()->$sujet)) $hop->pool()->$sujet->add_class('actif'); //pool access for submenu items $page->head->hop_menu->auto_id(); //for javascript vivibility //menu div $page->body->add($hop->div('menu')->auto_id()->add($menu)); // subject zone $page->body->add($hop->div('travail')->auto_id()->add(include('cache_sujet.php'))); //footer $page->body->add($hop->p('<a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Strict" height="15" width="44" /></a>') ->set_class('pied')); // return as object return $page; ?>
<?php // gestion cache require_once 'Zend/Cache.php'; //test si modif sur sujet $ref_file = "views/$sujet.php"; if (file_exists($sujet_lang)) { if (filemtime($sujet_lang) > filemtime($ref_file)) $ref_file = $sujet_lang; } else if (file_exists("views/{$sujet}_fr.html") and filemtime("views/{$sujet}_fr.html") > filemtime($ref_file)) $ref_file = "views/{$sujet}_fr.html"; $cache_sujet = Zend_Cache::factory('File', 'File', array('lifetime' => null, 'master_file' => $ref_file), array('cache_dir' => 'cache')); //, 'automatic_serialization' => true $cache_id = "{$sujet}_{$session->lang}"; if ($cache_sujet->test($cache_id)) { //en cache // echo "sujet issu du cache\n"; return $cache_sujet->load($cache_id); } // génération page $html_obj = include("views/$sujet.php"); $html = $html_obj->render(); //mise à jour cache if ($cache_sujet) $cache_sujet->save($html); //return html string return $html; ?>
<?php require_once 'lib/widgets.php'; $xhtml = new Hop_node; if (file_exists("views/{$sujet}_{$session->lang}.html")) $f_source = "views/{$sujet}_{$session->lang}.html"; else $f_source = "views/{$sujet}_fr.html"; $xhtml->add(new Hop_node_from_file($f_source)); $xhtml->add(div_masque('htaccess', htmlspecialchars(file_get_contents(file_exists(".htaccess") ? '.htaccess' : 'htaccess.fi')), ".htaccess")); $xhtml->add(div_masque('index', htmlspecialchars(file_get_contents("index.php")), "index.php")); $xhtml->add(div_masque('theme', htmlspecialchars(file_get_contents("views/theme.php")), 'views/theme.php')); $xhtml->add(div_masque('sujet', htmlspecialchars(file_get_contents("cache_sujet.php")), 'cache_sujet.php')); $xhtml->add(div_masque('mvc_', htmlspecialchars(file_get_contents("views/mvc.php")), "views/mvc.php")); $xhtml->add(div_masque('html_', htmlspecialchars(file_get_contents("views/mvc_fr.html")), "views/mvc_fr.html")); // $xhtml->add(div_masque('html_', htmlspecialchars(file_get_contents("views/mvc_{$session->lang}.html")), "views/mvc_{$session->lang}.html")); $xhtml->add(div_masque('ajax', htmlspecialchars(file_get_contents("ajax_.php")), "ajax.php")); return $xhtml; ?>
<p>Ce site est construit sur le modèle <abbr title="Modèle Vues Contrôleurs">MVC</abbr>.</p> <p>Il pourrait n'être qu'un ensemble de page statique <abbr title="HyperText Markup Language">HTML</abbr>, mais il est plus rapide, plus simple à faire évoluer et beaucoup plus ouvert en terme de possibilité de partir dès le début d'un tel modèle.</p> <p>Dans ce cas il est relativement simplifié par rapport à une grosse application, qui utiliserait le module MVC de Zend par exemple. La partie modèle (de données), en particulier, est réduite au plus simple : quelques variables de sessions.</p> <p class="clear">Cette page, comme toutes celles de ce site, utilise les fichiers suivants :</p> <ul> <li>Le fichier <a href="#htaccess" onclick="Element.show($('htaccess'))">.htacces</a>, qui aiguille toutes les pages vers les contrôleurs d'entrée. Global au site.</li> <li><a href="#index" onclick="Element.show($('index'))">index.php</a>, le contrôleur d'entrée. Il gère la session, le choix de langue, le cache en fonction de la page visée. Global au site.</li> <li><a href="#theme" onclick="Element.show($('theme'))">views/theme.php</a>, invoqué par le précédent il construit le modèle du contenu de la page. Global au site, domaine "Vues".</li> <li><a href="#sujet" onclick="Element.show($('sujet'))">cache_sujet.php</a>, le contrôleur secondaire de la partie évolutive de la page. Il est distinct du contrôleur principal, car il est utilisé par les requêtes Ajax qui ne modifient que cette partie. Global au site, domaine "Contrôleurs".</li> <li><a href="#mvc_" onclick="Element.show($('mvc_'))">Un fichier php</a>, spécifique de chaque page, qui complémente la page globale avec les éléments nécessaires. Spécifique à chaque page, domaine "Vues".</li> <li><a href="#html_" onclick="Element.show($('html_'))">Un fichier html</a>, contenant le texte et les éléments html qui sont plus faciles à écrire en <abbr title="HyperText Markup Language">HTML</abbr> qu'en <code>PHP</code>. Il existe autant de variantes de ce fichier que de traductions disponibles. Les éléments de texte des fichiers <code>PHP</code> sont traduits par le module "translate" du <span class="contrib">Zend Framework</span>. Invoqué par le précédent, spécifique à chaque page, domaine "Vues".</li> </ul> <p>Enfin, <a href="#ajax" onclick="Element.show($('ajax'))">le contrôleur ajax</a>, qui se substitue au contrôleur principal quand la page est modifiée par le menu « automatique ».</p> <p>Toute cette mécanique n'est invoquée que si la page n'est pas en cache, c'est à dire seulement suite à une modification dans notre cas. Quand le contenu est en cache, seul un contrôleur frontal est activé.</p>
<?php if (isset($_SERVER["HTTP_ACCEPT"]) and stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml")) { header('Content-type: application/xhtml+xml'); } else if (isset($_SERVER["HTTP_ACCEPT"]) and stristr($_SERVER["HTTP_ACCEPT"],"application/xml")) { header('Content-type: application/xml'); } else header ('content-type: text/html; charset="utf-8"'); set_include_path(get_include_path() . PATH_SEPARATOR . '..'); require_once 'lib/functions.php'; //session require_once 'Zend/Session/Namespace.php'; $session = new Zend_Session_Namespace(); //langues require_once("Zend/Translate.php"); $tr = new Zend_Translate('gettext', 'i18n/fr.mo', 'fr'); $tr->addTranslation('i18n/en.mo', 'en'); if (isset($session->lang) ) $tr->setLocale($session->lang); else $tr->setLocale('en'); require_once 'hop/hop.php'; //page visée $sujet = $request->get('sujet', 'accueil'); if ($sujet == 'hop') $sujet_lang = "views/{$sujet}_en.html"; else $sujet_lang = "views/{$sujet}_{$session->lang}.html"; include 'adm/compteurs.php'; // contenu page echo include('cache_sujet.php'); ?>