Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

API Explicitly load project template files after modules

Resolves an issue where if not using the themes directory (i.e just a single app folder) you cannot override module templates.
Changes the SS_TemplateManifest constructor with a new $project argument.
  • Loading branch information...
commit 683db8dc1d9f2133af447d763df47713c2a0f0e2 1 parent a108f67
@wilr wilr authored chillu committed
View
2  core/Core.php
@@ -290,7 +290,7 @@
Config::inst()->pushConfigManifest($configManifest);
SS_TemplateLoader::instance()->pushManifest(new SS_TemplateManifest(
- BASE_PATH, false, isset($_GET['flush'])
+ BASE_PATH, project(), false, isset($_GET['flush'])
));
// If in live mode, ensure deprecation, strict and notices are not reported
View
26 core/manifest/TemplateLoader.php
@@ -49,7 +49,8 @@ public function popManifest() {
/**
* Attempts to find possible candidate templates from a set of template
- * names and a theme.
+ * names from modules, current theme directory and finally the application
+ * folder.
*
* 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
@@ -57,10 +58,12 @@ public function popManifest() {
*
* @param string|array $templates
* @param string $theme
+ *
* @return array
*/
public function findTemplates($templates, $theme = null) {
$result = array();
+ $project = project();
foreach ((array) $templates as $template) {
$found = false;
@@ -71,21 +74,14 @@ public function findTemplates($templates, $theme = null) {
$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);
+ if ($found = $this->getManifest()->getCandidateTemplate($template, $theme)) {
+ if ($type && isset($found[$type])) {
+ $found = array(
+ 'main' => $found[$type]
+ );
}
+
+ $result = array_merge($found, $result);
}
}
View
43 core/manifest/TemplateManifest.php
@@ -14,6 +14,7 @@ class SS_TemplateManifest {
protected $tests;
protected $cache;
protected $cacheKey;
+ protected $project;
protected $inited;
protected $forceRegen;
protected $templates = array();
@@ -23,13 +24,17 @@ class SS_TemplateManifest {
* or loaded from cache until needed.
*
* @param string $base The base path.
+ * @param string $project Path to application code
+ *
* @param bool $includeTests Include tests in the manifest.
* @param bool $forceRegen Force the manifest to be regenerated.
*/
- public function __construct($base, $includeTests = false, $forceRegen = false) {
+ public function __construct($base, $project, $includeTests = false, $forceRegen = false) {
$this->base = $base;
$this->tests = $includeTests;
+ $this->project = $project;
+
$this->cacheKey = $this->tests ? 'manifest_tests' : 'manifest';
$this->forceRegen = $forceRegen;
@@ -97,6 +102,30 @@ public function getTemplate($name) {
}
/**
+ * Returns the correct candidate template. In order of importance, application
+ * project code, current theme and finally modules.
+ *
+ * @param string $name
+ * @param string $theme - theme name
+ *
+ * @return array
+ */
+ public function getCandidateTemplate($name, $theme = null) {
+ $candidates = $this->getTemplate($name);
+
+ if ($this->project && isset($candidates[$this->project])) {
+ $found = $candidates[$this->project];
+ } else if ($theme && isset($candidates['themes'][$theme])) {
+ $found = $candidates['themes'][$theme];
+ } else {
+ unset($candidates['themes']);
+ $found = $candidates;
+ }
+
+ return $found;
+ }
+
+ /**
* Regenerates the manifest by scanning the base path.
*
* @param bool $cache
@@ -109,6 +138,7 @@ public function regenerate($cache = true) {
'ignore_tests' => !$this->tests,
'file_callback' => array($this, 'handleFile')
));
+
$finder->find($this->base);
if ($cache) {
@@ -119,13 +149,16 @@ public function regenerate($cache = true) {
}
public function handleFile($basename, $pathname, $depth) {
+ $projectFile = false;
+ $theme = null;
+
if (strpos($pathname, $this->base . '/' . THEMES_DIR) === 0) {
$start = strlen($this->base . '/' . THEMES_DIR) + 1;
$theme = substr($pathname, $start);
$theme = substr($theme, 0, strpos($theme, '/'));
$theme = strtok($theme, '_');
- } else {
- $theme = null;
+ } else if($this->project && (strpos($pathname, $this->base . '/' . $this->project .'/') === 0)) {
+ $projectFile = true;
}
$type = basename(dirname($pathname));
@@ -137,9 +170,12 @@ public function handleFile($basename, $pathname, $depth) {
if ($theme) {
$this->templates[$name]['themes'][$theme][$type] = $pathname;
+ } else if($projectFile) {
+ $this->templates[$name][$this->project][$type] = $pathname;
} else {
$this->templates[$name][$type] = $pathname;
}
+
}
protected function init() {
@@ -150,5 +186,4 @@ protected function init() {
$this->regenerate();
}
}
-
}
View
2  dev/TestRunner.php
@@ -94,7 +94,7 @@ public static function use_test_manifest() {
SapphireTest::set_test_class_manifest($classManifest);
SS_TemplateLoader::instance()->pushManifest(new SS_TemplateManifest(
- BASE_PATH, true, isset($_GET['flush'])
+ BASE_PATH, project(), true, isset($_GET['flush'])
));
}
View
18 tests/core/manifest/TemplateLoaderTest.php
@@ -9,7 +9,7 @@ class TemplateLoaderTest extends SapphireTest {
public function testFindTemplates() {
$base = dirname(__FILE__) . '/fixtures/templatemanifest';
- $manifest = new SS_TemplateManifest($base, false, true);
+ $manifest = new SS_TemplateManifest($base, 'myproject', false, true);
$loader = new SS_TemplateLoader();
$manifest->regenerate(false);
@@ -40,7 +40,23 @@ public function testFindTemplates() {
'main' => "$base/module/templates/Page.ss",
'Layout' => "$base/module/templates/Layout/CustomPage.ss"
);
+
$this->assertEquals($expectCustomPage, $loader->findTemplates(array('CustomPage', 'Page')));
}
+ public function testFindTemplatesApplicationOverridesModule() {
+ $base = dirname(__FILE__) . '/fixtures/templatemanifest';
+ $manifest = new SS_TemplateManifest($base, 'myproject', false, true);
+ $loader = new SS_TemplateLoader();
+
+ $manifest->regenerate(false);
+ $loader->pushManifest($manifest);
+
+ $expectPage = array(
+ 'main' => "$base/myproject/templates/CustomTemplate.ss"
+ );
+
+ $this->assertEquals($expectPage, $loader->findTemplates('CustomTemplate'));
+ }
+
}
View
16 tests/core/manifest/TemplateManifestTest.php
@@ -15,8 +15,8 @@ public function setUp() {
parent::setUp();
$this->base = dirname(__FILE__) . '/fixtures/templatemanifest';
- $this->manifest = new SS_TemplateManifest($this->base);
- $this->manifestTests = new SS_TemplateManifest($this->base, true);
+ $this->manifest = new SS_TemplateManifest($this->base, 'myproject');
+ $this->manifestTests = new SS_TemplateManifest($this->base, 'myproject', true);
$this->manifest->regenerate(false);
$this->manifestTests->regenerate(false);
@@ -38,6 +38,12 @@ public function testGetTemplates() {
'custompage' => array(
'Layout' => "{$this->base}/module/templates/Layout/CustomPage.ss"
),
+ 'customtemplate' => array(
+ 'main' => "{$this->base}/module/templates/CustomTemplate.ss",
+ 'myproject' => array(
+ 'main' => "{$this->base}/myproject/templates/CustomTemplate.ss"
+ )
+ ),
'subfolder' => array(
'main' => "{$this->base}/module/subfolder/templates/Subfolder.ss"
),
@@ -93,6 +99,12 @@ public function testGetTemplate() {
$this->assertEquals(array(), $this->manifest->getTemplate('Test'));
$this->assertEquals($expectTests, $this->manifestTests->getTemplate('Test'));
+
+ $this->assertEquals(array(
+ 'main' => "{$this->base}/module/templates/CustomTemplate.ss",
+ 'myproject' => array(
+ 'main' => "{$this->base}/myproject/templates/CustomTemplate.ss"
+ )), $this->manifestTests->getTemplate('CustomTemplate'));
}
}
View
1  tests/core/manifest/fixtures/templatemanifest/module/templates/CustomTemplate.ss
@@ -0,0 +1 @@
+Custom Template
View
1  tests/core/manifest/fixtures/templatemanifest/myproject/_config.php
@@ -0,0 +1 @@
+<?php
View
1  tests/core/manifest/fixtures/templatemanifest/myproject/templates/CustomTemplate.ss
@@ -0,0 +1 @@
+App version
View
4 tests/i18n/i18nSSLegacyAdapterTest.php
@@ -15,13 +15,13 @@ public function setUp() {
Director::setBaseFolder($this->alternateBasePath);
// Push a template loader running from the fake webroot onto the stack.
- $templateManifest = new SS_TemplateManifest($this->alternateBasePath, false, true);
+ $templateManifest = new SS_TemplateManifest($this->alternateBasePath, null, false, true);
$templateManifest->regenerate(false);
SS_TemplateLoader::instance()->pushManifest($templateManifest);
$this->_oldTheme = SSViewer::current_theme();
SSViewer::set_theme('testtheme1');
- $classManifest = new SS_ClassManifest($this->alternateBasePath, true, true, false);
+ $classManifest = new SS_ClassManifest($this->alternateBasePath, null, true, true, false);
SS_ClassLoader::instance()->pushManifest($classManifest);
$this->originalLocale = i18n::get_locale();
View
2  tests/i18n/i18nTest.php
@@ -34,7 +34,7 @@ public function setUp() {
Director::setBaseFolder($this->alternateBasePath);
// Push a template loader running from the fake webroot onto the stack.
- $templateManifest = new SS_TemplateManifest($this->alternateBasePath, false, true);
+ $templateManifest = new SS_TemplateManifest($this->alternateBasePath, null, false, true);
$templateManifest->regenerate(false);
SS_TemplateLoader::instance()->pushManifest($templateManifest);
$this->_oldTheme = SSViewer::current_theme();
View
2  tests/i18n/i18nTextCollectorTest.php
@@ -33,7 +33,7 @@ public function setUp() {
$this->alternateBasePath, false, true, false
);
- $manifest = new SS_TemplateManifest($this->alternateBasePath, false, true);
+ $manifest = new SS_TemplateManifest($this->alternateBasePath, null, false, true);
$manifest->regenerate(false);
SS_TemplateLoader::instance()->pushManifest($manifest);
}
Please sign in to comment.
Something went wrong with that request. Please try again.