Index: lib/cache.php =================================================================== --- lib/cache.php (revision 271) +++ lib/cache.php (revision 273) @@ -115,6 +115,8 @@ * header! Therefore consider using the convenience method print_cache_and_exit() * instead of this one or exit on yourself. - **/ - function print_cache() { + * + * @param $ignore_http_caching Don't check the clients HTTP cache + **/ + function print_cache($ignore_http_caching=false) { // make sure we already have called is_valid if($this->mtime_cache_file === null) @@ -126,5 +128,5 @@ } - if(@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $this->mtime_cache_file) { + if(!$ignore_http_caching && @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $this->mtime_cache_file) { // client already has page cached locally if($this->debug) { @@ -234,8 +236,11 @@ * will be assumed (as start_cache fires it) and content will be * extracted with ob_get_flush. - **/ - function write_cache($content=null) { + * @param $content Content to be used as cache content or OB content + * @param $clear_ob_cache Use ob_get_clean instead of flushing it. If given, + * will return $content instead of printing/keeping it. + **/ + function write_cache($content=null, $clear_ob_cache=false) { if(!$content) - $content = ob_get_flush(); + $content = ($clear_ob_cache ? ob_get_clean() : ob_get_flush()); if($this->skip) { @@ -253,4 +258,7 @@ else $this->print_error('Could not write page output cache to '.$this->cache_file); + + if($clear_ob_cache) + return $content; } Index: lib/loader.php =================================================================== --- lib/loader.php (revision 271) +++ lib/loader.php (revision 273) @@ -9,10 +9,12 @@ * **/ + +if(!defined('T29_GRAB_LOADER_DEFS')) { + $lib = dirname(__FILE__); + $webroot = realpath("$lib/../"); # file path to root of t29 web installation -$lib = dirname(__FILE__); -$webroot = realpath("$lib/../"); # file path to root of t29 web installation - -if(!isset($_GET['type'])) { - die("Read manual."); + if(!isset($_GET['type'])) { + die("Provide ?type=js or ?type=css."); + } } @@ -24,19 +26,26 @@ 'content_types' => array('application/javascript', 'text/css'), 'class' => array('t29JavaScriptRessourceLoader', 't29StyleSheetRessourceLoader'), + 'modules' => function($conf){ return glob($conf['module_dir'] . '/' . $conf['glob_pattern']); }, ); +$conf_for_type = function($type, $debug_flag=false) use ($conf, $types) { + $typepos = array_search($type, $types); + if($typepos === FALSE) return null; + array_walk($conf, function(&$val, $key) use($typepos) { if(is_array($val)) $val = $val[$typepos]; }); + $conf['type'] = $type; + $conf['modules'] = call_user_func($conf['modules'], $conf); + $conf['debug'] = $debug_flag; // skip cache and just concat everything + return $conf; +}; + +if(defined('T29_GRAB_LOADER_DEFS')) { + return; // just grab the vars in the local scope +} $type = $_GET['type']; -$typepos = array_search($type, $types); -if($typepos === FALSE) { +$conf = $conf_for_type($type, isset($_GET['debug'])); +if($conf == null) die("Illegal type. Valid types are: ". implode($types)); -} +extract($conf); // for saving long human reading times :D -array_walk($conf, function(&$val, $key) use($typepos) { $val = $val[$typepos]; }); -$conf['modules'] = glob($conf['module_dir'] . '/' . $conf['glob_pattern']); -$conf['debug'] = isset($_GET['debug']); // skip cache and just concat everything -extract($conf); // for saving long human reading times :D -// alternative approach for direct extract in global namespace -// (no more applicable because configuration is given as array to constructor): -// foreach($conf as $var => $val) { $GLOBALS[$var] = $val[$typepos]; } require "$lib/cache.php"; Index: lib/messages.php =================================================================== --- lib/messages.php (revision 271) +++ lib/messages.php (revision 273) @@ -96,5 +96,6 @@ 'topnav-interlang-title' => array('Read this page (%s) in English', 'Diese Seite (%s) auf Deutsch lesen'), 'topnav-search-label' => array('Suchen', 'Search'), - 'topnav-search-page' => array('/de-v6/suche.php', '/en-v6/search.php'), + 'topnav-search-page' => array('/suche.php', '/search.php'), + 'opensearch-desc' => array('technikum29 (de)', 'technikum29 (en)'), 'js-menu-collapse-out' => array('MenĂ¼ ausklappen', 'Expand menu'), Index: lib/ressourceloader.php =================================================================== --- lib/ressourceloader.php (revision 271) +++ lib/ressourceloader.php (revision 273) @@ -21,19 +21,54 @@ * **/ + +/* +// test it: +$lib = dirname(__FILE__); +$webroot = realpath("$lib/../"); +$js = t29RessourceLoader::create_from_type('css'); +$js->run(); +*/ class t29RessourceLoader { /** - * expects: cache_file, module_dir, glob_pattern, content_types, class, modules, debug + * expects: type, cache_file, module_dir, glob_pattern, content_types, class, modules, debug **/ public $conf; + + const default_include_url = '/lib/loader.php'; // rel to webroot /** * Construct with configuration array. See loader.php for contents of * that array. See above for minimum elements which must be present. - **/ - /// @param $conf configuration array. + * @param $conf Configuration array + **/ function __construct($conf) { $this->conf = $conf; $this->conf['filenames'] = array_map('basename', $this->conf['modules']); // filenames like foo.js + } + + private static $conf_for_type; + static function create_from_type($type, $baseconf=null) { + global $lib, $webroot; + if(!self::$conf_for_type) { + define('T29_GRAB_LOADER_DEFS', true); + include "$lib/loader.php"; + self::$conf_for_type = $conf_for_type; + } + + $conf = call_user_func(self::$conf_for_type, $type, isset($baseconf['debug']) && $baseconf['debug']); + if($conf === null) return null; + + return new $conf['class']($conf); + } + + function get_urls($debug=null) { + global $webroot; + if(($debug !== null && $debug) || !$this->conf['debug']) { + return array(self::default_include_url . '?type=' . $this->conf['type']); + } else { + $module_dir_rel2webroot = str_replace($webroot, '', $this->conf['module_dir']); + return array_map(function($i)use($module_dir_rel2webroot){ return $module_dir_rel2webroot.$i; }, $this->conf['filenames']); + } } Index: lib/technikum29.php =================================================================== --- lib/technikum29.php (revision 271) +++ lib/technikum29.php (revision 273) @@ -30,5 +30,5 @@ $page_cache = new t29Cache(false, true); // debug, verbose $page_cache->set_cache_file($webroot, $file); -$page_cache->test_files = array( +$page_cache->test_files = array( __FILE__, $_SERVER['SCRIPT_FILENAME'], @@ -40,10 +40,40 @@ ); -$page_cache->try_cache_and_exit(); +// dynamical content: +$static_page = !isset($dynamischer_inhalt); -// cache missed, rebuild cache -require "$lib/template.php"; -$tmpl = new t29Template($GLOBALS); -$tmpl->create_cache($page_cache); +if(!$static_page) { + // Pages with dynamical content: only cache header and footer, seperately. + // they depend on same test files, so there is only one is_valid check. + $header_cache = $page_cache; + $footer_cache = clone $page_cache; + + $header_cache->set_cache_file($webroot, $file.'-header'); + $footer_cache->set_cache_file($webroot, $file.'-footer'); +} + +if($page_cache->shall_use()) { + if($static_page) + $page_cache->print_cache_and_exit(); + else { + $header_cache->print_cache(true); + register_shutdown_function(function() use ($footer_cache) { + $footer_cache->print_cache(true); + }); + // now print your dynamical stuff in your page, the + // footer content will be automatically added afterwards. + } +} else { + // cache missed, rebuild cache + require "$lib/template.php"; + $tmpl = new t29Template($GLOBALS); + if($static_page) + // rebuild complete site cache + $tmpl->create_cache($page_cache); + else + // rebuild each header and footer cache + $tmpl->create_separate_caches($header_cache, $footer_cache); +} + // end of technikum29.php Index: lib/template.php =================================================================== --- lib/template.php (revision 271) +++ lib/template.php (revision 273) @@ -10,4 +10,6 @@ * $header_cache_file, $footer_cache_file. **/ + +require dirname(__FILE__) . "/ressourceloader.php"; class t29Template { @@ -29,5 +31,7 @@ // fill up configuration - $this->conf['legal_pagename'] = $this->conf['lang_path'] . $this->msg->_('footer-legal-file'); + // Path names in messages + foreach(array('footer-legal-file', 'topnav-search-page') as $msg) + $this->conf[$msg] = $this->conf['lang_path'] . $this->msg->_($msg); // setup body classes: @@ -60,4 +64,22 @@ $cache_object->start_cache(array($this, 'print_footer')); $this->print_header(); + } + + /** + * Write header and footer in separate cache files. + **/ + function create_separate_caches($header_cache, $footer_cache) { + $header_cache->start_cache(); + $this->print_header(); + $header_cache->write_cache(); // will also print out header immediately. + + $footer_cache->start_cache(); + $this->print_footer(); + $footer_content = $footer_cache->write_cache(null, true); // don't print footer immediately. + + // print footer on exit. + register_shutdown_function(function() use ($footer_content) { + print $footer_content; + }); } @@ -89,5 +111,6 @@ ?> - + + - - '.PHP_EOL; + foreach($this->get_ressourceloader_links('css') as $css) + printf($csslinktmpl, $css); + if($this->conf['has_pagecss']) - printf('', $this->conf['pagecss']); + printf($csslinktmpl, $this->conf['pagecss']); ?> @@ -162,5 +188,5 @@ ?> -