mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
FEATURE: Replaced the template manifest with SS_TemplateLoader, which finds templates from a stack of SS_TemplateManifest objects.
This commit is contained in:
parent
76f0fc0c92
commit
c34105438c
@ -210,6 +210,8 @@ require_once 'filesystem/FileFinder.php';
|
|||||||
require_once 'manifest/ClassLoader.php';
|
require_once 'manifest/ClassLoader.php';
|
||||||
require_once 'manifest/ClassManifest.php';
|
require_once 'manifest/ClassManifest.php';
|
||||||
require_once 'manifest/ManifestFileFinder.php';
|
require_once 'manifest/ManifestFileFinder.php';
|
||||||
|
require_once 'manifest/TemplateLoader.php';
|
||||||
|
require_once 'manifest/TemplateManifest.php';
|
||||||
require_once 'manifest/TokenisedRegularExpression.php';
|
require_once 'manifest/TokenisedRegularExpression.php';
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -227,6 +229,10 @@ $loader = SS_ClassLoader::instance();
|
|||||||
$loader->registerAutoloader();
|
$loader->registerAutoloader();
|
||||||
$loader->pushManifest($manifest);
|
$loader->pushManifest($manifest);
|
||||||
|
|
||||||
|
SS_TemplateLoader::instance()->pushManifest(new SS_TemplateManifest(
|
||||||
|
BASE_PATH, false, isset($_GET['flush'])
|
||||||
|
));
|
||||||
|
|
||||||
// If this is a dev site, enable php error reporting
|
// If this is a dev site, enable php error reporting
|
||||||
// This is necessary to force developers to acknowledge and fix
|
// This is necessary to force developers to acknowledge and fix
|
||||||
// notice level errors (you can override this directive in your _config.php)
|
// notice level errors (you can override this directive in your _config.php)
|
||||||
|
@ -183,45 +183,9 @@ class SSViewer_DataPresenter extends SSViewer_Scope {
|
|||||||
* Compiled templates are cached via {@link SS_Cache}, usually on the filesystem.
|
* Compiled templates are cached via {@link SS_Cache}, usually on the filesystem.
|
||||||
* If you put ?flush=all on your URL, it will force the template to be recompiled.
|
* If you put ?flush=all on your URL, it will force the template to be recompiled.
|
||||||
*
|
*
|
||||||
* <b>Manifest File and Structure</b>
|
|
||||||
*
|
|
||||||
* Works with the global $_TEMPLATE_MANIFEST which is compiled by {@link ManifestBuilder->getTemplateManifest()}.
|
|
||||||
* This associative array lists all template filepaths by "identifier", meaning the name
|
|
||||||
* of the template without its path or extension.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* <code>
|
|
||||||
* array(
|
|
||||||
* 'LeftAndMain' =>
|
|
||||||
* array (
|
|
||||||
* 'main' => '/my/system/path/cms/templates/LeftAndMain.ss',
|
|
||||||
* ),
|
|
||||||
* 'CMSMain_left' =>
|
|
||||||
* array (
|
|
||||||
* 'Includes' => '/my/system/path/cms/templates/Includes/CMSMain_left.ss',
|
|
||||||
* ),
|
|
||||||
* 'Page' =>
|
|
||||||
* array (
|
|
||||||
* 'themes' =>
|
|
||||||
* array (
|
|
||||||
* 'blackcandy' =>
|
|
||||||
* array (
|
|
||||||
* 'Layout' => '/my/system/path/themes/blackcandy/templates/Layout/Page.ss',
|
|
||||||
* 'main' => '/my/system/path/themes/blackcandy/templates/Page.ss',
|
|
||||||
* ),
|
|
||||||
* 'blue' =>
|
|
||||||
* array (
|
|
||||||
* 'Layout' => '/my/system/path/themes/mysite/templates/Layout/Page.ss',
|
|
||||||
* 'main' => '/my/system/path/themes/mysite/templates/Page.ss',
|
|
||||||
* ),
|
|
||||||
* ),
|
|
||||||
* ),
|
|
||||||
* // ...
|
|
||||||
* )
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* @see http://doc.silverstripe.org/themes
|
* @see http://doc.silverstripe.org/themes
|
||||||
* @see http://doc.silverstripe.org/themes:developing
|
* @see http://doc.silverstripe.org/themes:developing
|
||||||
|
|
||||||
*
|
*
|
||||||
* @package sapphire
|
* @package sapphire
|
||||||
* @subpackage view
|
* @subpackage view
|
||||||
@ -346,8 +310,6 @@ class SSViewer {
|
|||||||
* </code>
|
* </code>
|
||||||
*/
|
*/
|
||||||
public function __construct($templateList) {
|
public function __construct($templateList) {
|
||||||
global $_TEMPLATE_MANIFEST;
|
|
||||||
|
|
||||||
// flush template manifest cache if requested
|
// flush template manifest cache if requested
|
||||||
if (isset($_GET['flush']) && $_GET['flush'] == 'all') {
|
if (isset($_GET['flush']) && $_GET['flush'] == 'all') {
|
||||||
if(Director::isDev() || Director::is_cli() || Permission::check('ADMIN')) {
|
if(Director::isDev() || Director::is_cli() || Permission::check('ADMIN')) {
|
||||||
@ -360,62 +322,23 @@ class SSViewer {
|
|||||||
if(substr((string) $templateList,-3) == '.ss') {
|
if(substr((string) $templateList,-3) == '.ss') {
|
||||||
$this->chosenTemplates['main'] = $templateList;
|
$this->chosenTemplates['main'] = $templateList;
|
||||||
} else {
|
} else {
|
||||||
if(!is_array($templateList)) $templateList = array($templateList);
|
$this->chosenTemplates = SS_TemplateLoader::instance()->findTemplates(
|
||||||
|
$templateList, self::current_theme()
|
||||||
if(isset($_GET['debug_request'])) Debug::message("Selecting templates from the following list: " . implode(", ", $templateList));
|
);
|
||||||
|
|
||||||
foreach($templateList as $template) {
|
|
||||||
// if passed as a partial directory (e.g. "Layout/Page"), split into folder and template components
|
|
||||||
if(strpos($template,'/') !== false) list($templateFolder, $template) = explode('/', $template, 2);
|
|
||||||
else $templateFolder = null;
|
|
||||||
|
|
||||||
// Use the theme template if available
|
|
||||||
if(self::current_theme() && isset($_TEMPLATE_MANIFEST[$template]['themes'][self::current_theme()])) {
|
|
||||||
$this->chosenTemplates = array_merge(
|
|
||||||
$_TEMPLATE_MANIFEST[$template]['themes'][self::current_theme()],
|
|
||||||
$this->chosenTemplates
|
|
||||||
);
|
|
||||||
|
|
||||||
if(isset($_GET['debug_request'])) Debug::message("Found template '$template' from main theme '" . self::current_theme() . "': " . var_export($_TEMPLATE_MANIFEST[$template]['themes'][self::current_theme()], true));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fall back to unthemed base templates
|
|
||||||
if(isset($_TEMPLATE_MANIFEST[$template]) && (array_keys($_TEMPLATE_MANIFEST[$template]) != array('themes'))) {
|
|
||||||
$this->chosenTemplates = array_merge(
|
|
||||||
$_TEMPLATE_MANIFEST[$template],
|
|
||||||
$this->chosenTemplates
|
|
||||||
);
|
|
||||||
|
|
||||||
if(isset($_GET['debug_request'])) Debug::message("Found template '$template' from main template archive, containing the following items: " . var_export($_TEMPLATE_MANIFEST[$template], true));
|
|
||||||
|
|
||||||
unset($this->chosenTemplates['themes']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($templateFolder) {
|
|
||||||
$this->chosenTemplates['main'] = $this->chosenTemplates[$templateFolder];
|
|
||||||
unset($this->chosenTemplates[$templateFolder]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isset($_GET['debug_request'])) Debug::message("Final template selections made: " . var_export($this->chosenTemplates, true));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$this->chosenTemplates) user_error("None of these templates can be found in theme '"
|
if(!$this->chosenTemplates) user_error("None of these templates can be found in theme '"
|
||||||
. self::current_theme() . "': ". implode(".ss, ", $templateList) . ".ss", E_USER_WARNING);
|
. self::current_theme() . "': ". implode(".ss, ", $templateList) . ".ss", E_USER_WARNING);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if at least one of the listed templates exists
|
* Returns true if at least one of the listed templates exists
|
||||||
*/
|
*/
|
||||||
static function hasTemplate($templateList) {
|
public static function hasTemplate($templates) {
|
||||||
if(!is_array($templateList)) $templateList = array($templateList);
|
$manifest = SS_TemplateLoader::instance()->getManifest();
|
||||||
|
|
||||||
global $_TEMPLATE_MANIFEST;
|
foreach ((array) $templates as $template) {
|
||||||
foreach($templateList as $template) {
|
if ($manifest->getTemplate($template)) return true;
|
||||||
if(strpos($template,'/') !== false) list($templateFolder, $template) = explode('/', $template, 2);
|
|
||||||
if(isset($_TEMPLATE_MANIFEST[$template])) return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -81,13 +81,17 @@ class TestRunner extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pushes a class manifest instance that uses tests onto the top of the
|
* Pushes a class and template manifest instance that include tests onto the
|
||||||
* autoloader stack.
|
* top of the loader stacks.
|
||||||
*/
|
*/
|
||||||
public static function use_test_manifest() {
|
public static function use_test_manifest() {
|
||||||
SS_ClassLoader::instance()->pushManifest(new SS_ClassManifest(
|
SS_ClassLoader::instance()->pushManifest(new SS_ClassManifest(
|
||||||
BASE_PATH, true, isset($_GET['flush'])
|
BASE_PATH, true, isset($_GET['flush'])
|
||||||
));
|
));
|
||||||
|
|
||||||
|
SS_TemplateLoader::instance()->pushManifest(new SS_TemplateManifest(
|
||||||
|
BASE_PATH, true, isset($_GET['flush'])
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
95
manifest/TemplateLoader.php
Normal file
95
manifest/TemplateLoader.php
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Handles finding templates from a stack of template manifest objects.
|
||||||
|
*
|
||||||
|
* @package sapphire
|
||||||
|
* @subpackage manifest
|
||||||
|
*/
|
||||||
|
class SS_TemplateLoader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SS_TemplateLoader
|
||||||
|
*/
|
||||||
|
private static $instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SS_TemplateManifest[]
|
||||||
|
*/
|
||||||
|
protected $manifests = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SS_TemplateLoader
|
||||||
|
*/
|
||||||
|
public static function instance() {
|
||||||
|
return self::$instance ? self::$instance : self::$instance = new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently active template manifest instance.
|
||||||
|
*
|
||||||
|
* @return SS_TemplateManifest
|
||||||
|
*/
|
||||||
|
public function getManifest() {
|
||||||
|
return $this->manifests[count($this->manifests) - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param SS_TemplateManifest $manifest
|
||||||
|
*/
|
||||||
|
public function pushManifest(SS_TemplateManifest $manifest) {
|
||||||
|
$this->manifests[] = $manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SS_TemplateManifest
|
||||||
|
*/
|
||||||
|
public function popManifest() {
|
||||||
|
return array_pop($this->manifests);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to find possible candidate templates from a set of template
|
||||||
|
* names and a theme.
|
||||||
|
*
|
||||||
|
* The template names can be passed in as plain strings, or be in the
|
||||||
|
* format "type/name", where type is the type of template to search for
|
||||||
|
* (e.g. Includes, Layout).
|
||||||
|
*
|
||||||
|
* @param string|array $templates
|
||||||
|
* @param string $theme
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function findTemplates($templates, $theme = null) {
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
foreach ((array) $templates as $template) {
|
||||||
|
$found = false;
|
||||||
|
|
||||||
|
if (strpos($template, '/')) {
|
||||||
|
list($type, $template) = explode('/', $template, 2);
|
||||||
|
} else {
|
||||||
|
$type = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($candidates = $this->getManifest()->getTemplate($template)) {
|
||||||
|
if ($theme && isset($candidates['themes'][$theme])) {
|
||||||
|
$found = $candidates['themes'][$theme];
|
||||||
|
} else {
|
||||||
|
unset($candidates['themes']);
|
||||||
|
$found = $candidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($found) {
|
||||||
|
if ($type && isset($found[$type])) {
|
||||||
|
$found = array('main' => $found[$type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array_merge($found, $result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
tests/manifest/TemplateLoaderTest.php
Normal file
46
tests/manifest/TemplateLoaderTest.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Tests for the {@link SS_TemplateLoader} class.
|
||||||
|
*
|
||||||
|
* @package sapphire
|
||||||
|
* @subpackage tests
|
||||||
|
*/
|
||||||
|
class TemplateLoaderTest extends SapphireTest {
|
||||||
|
|
||||||
|
public function testFindTemplates() {
|
||||||
|
$base = dirname(__FILE__) . '/fixtures/templatemanifest';
|
||||||
|
$manifest = new SS_TemplateManifest($base, false, true);
|
||||||
|
$loader = new SS_TemplateLoader();
|
||||||
|
|
||||||
|
$manifest->regenerate(false);
|
||||||
|
$loader->pushManifest($manifest);
|
||||||
|
|
||||||
|
$expectPage = array(
|
||||||
|
'main' => "$base/module/templates/Page.ss",
|
||||||
|
'Layout' => "$base/module/templates/Layout/Page.ss"
|
||||||
|
);
|
||||||
|
$expectPageThemed = array(
|
||||||
|
'main' => "$base/themes/theme/templates/Page.ss",
|
||||||
|
'Layout' => "$base/themes/theme/templates/Layout/Page.ss"
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals($expectPage, $loader->findTemplates('Page'));
|
||||||
|
$this->assertEquals($expectPage, $loader->findTemplates(array('Foo', 'Page')));
|
||||||
|
$this->assertEquals($expectPage, $loader->findTemplates('PAGE'));
|
||||||
|
$this->assertEquals($expectPageThemed, $loader->findTemplates('Page', 'theme'));
|
||||||
|
|
||||||
|
$expectPageLayout = array('main' => "$base/module/templates/Layout/Page.ss");
|
||||||
|
$expectPageLayoutThemed = array('main' => "$base/themes/theme/templates/Layout/Page.ss");
|
||||||
|
|
||||||
|
$this->assertEquals($expectPageLayout, $loader->findTemplates('Layout/Page'));
|
||||||
|
$this->assertEquals($expectPageLayout, $loader->findTemplates('Layout/PAGE'));
|
||||||
|
$this->assertEquals($expectPageLayoutThemed, $loader->findTemplates('Layout/Page', 'theme'));
|
||||||
|
|
||||||
|
$expectCustomPage = array(
|
||||||
|
'main' => "$base/module/templates/Page.ss",
|
||||||
|
'Layout' => "$base/module/templates/Layout/CustomPage.ss"
|
||||||
|
);
|
||||||
|
$this->assertEquals($expectCustomPage, $loader->findTemplates(array('CustomPage', 'Page')));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user