mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
BUG Only include processed requirements at the top level. (Fixes #7847)
After each sub template was processed Requirements::includeInHTML() is included which appended requirements again.
This commit is contained in:
parent
39b2818f5f
commit
dfd3455802
7
tests/templates/SSViewerTestProcess.ss
Normal file
7
tests/templates/SSViewerTestProcess.ss
Normal file
@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<% include SSViewerTestProcessHead %>
|
||||
|
||||
<body>
|
||||
<% include SSViewerTestCommentsWithInclude %>
|
||||
</body>
|
||||
</html>
|
3
tests/templates/SSViewerTestProcessHead.ss
Normal file
3
tests/templates/SSViewerTestProcessHead.ss
Normal file
@ -0,0 +1,3 @@
|
||||
<head>
|
||||
<% require javascript(framework/tests/forms/RequirementsTest_a.js) %>
|
||||
</head>
|
@ -1025,6 +1025,42 @@ after')
|
||||
$result = $viewer->process(new ArrayData(array('List' => $list)));
|
||||
$this->assertEquals($result, '');
|
||||
}
|
||||
|
||||
public function testProcessOnlyIncludesRequirementsOnce() {
|
||||
$template = new SSViewer(array('SSViewerTestProcess'));
|
||||
$basePath = dirname($this->getCurrentRelativePath()) . '/forms';
|
||||
|
||||
$backend = new Requirements_Backend;
|
||||
$backend->set_combined_files_enabled(false);
|
||||
$backend->combine_files(
|
||||
'RequirementsTest_ab.css',
|
||||
array(
|
||||
$basePath . '/RequirementsTest_a.css',
|
||||
$basePath . '/RequirementsTest_b.css'
|
||||
)
|
||||
);
|
||||
|
||||
Requirements::set_backend($backend);
|
||||
|
||||
$this->assertEquals(1, substr_count($template->process(array()), "a.css"));
|
||||
$this->assertEquals(1, substr_count($template->process(array()), "b.css"));
|
||||
|
||||
// if we disable the requirements then we should get nothing
|
||||
$template->includeRequirements(false);
|
||||
$this->assertEquals(0, substr_count($template->process(array()), "a.css"));
|
||||
$this->assertEquals(0, substr_count($template->process(array()), "b.css"));
|
||||
}
|
||||
|
||||
public function testRequireCallInTemplateInclude() {
|
||||
$template = new SSViewer(array('SSViewerTestProcess'));
|
||||
|
||||
Requirements::set_suffix_requirements(false);
|
||||
|
||||
$this->assertEquals(1, substr_count(
|
||||
$template->process(array()),
|
||||
"tests/forms/RequirementsTest_a.js"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -563,6 +563,11 @@ class SSViewer {
|
||||
*/
|
||||
protected static $current_custom_theme = null;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $includeRequirements = true;
|
||||
|
||||
/**
|
||||
* Create a template from a string instead of a .ss file
|
||||
*
|
||||
@ -592,7 +597,7 @@ class SSViewer {
|
||||
/**
|
||||
* Returns the path to the theme folder
|
||||
*
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
public static function get_theme_folder() {
|
||||
return self::current_theme() ? THEMES_DIR . "/" . self::current_theme() : project();
|
||||
@ -667,7 +672,11 @@ class SSViewer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if at least one of the listed templates exists
|
||||
* Returns true if at least one of the listed templates exists.
|
||||
*
|
||||
* @param array $templates
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function hasTemplate($templates) {
|
||||
$manifest = SS_TemplateLoader::instance()->getManifest();
|
||||
@ -681,20 +690,25 @@ class SSViewer {
|
||||
|
||||
/**
|
||||
* Set a global rendering option.
|
||||
*
|
||||
* The following options are available:
|
||||
* - rewriteHashlinks: If true (the default), <a href="#..."> will be rewritten to contain the
|
||||
* current URL. This lets it play nicely with our <base> tag.
|
||||
* - If rewriteHashlinks = 'php' then, a piece of PHP script will be inserted before the hash
|
||||
* links: "<?php echo $_SERVER['REQUEST_URI']; ?>". This is useful if you're generating a
|
||||
* page that will be saved to a .php file and may be accessed from different URLs.
|
||||
*
|
||||
* @param string $optionName
|
||||
* @param mixed $optionVal
|
||||
*/
|
||||
public static function setOption($optionName, $optionVal) {
|
||||
SSViewer::$options[$optionName] = $optionVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param String
|
||||
* @return Mixed
|
||||
* @param string
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getOption($optionName) {
|
||||
return SSViewer::$options[$optionName];
|
||||
@ -705,6 +719,7 @@ class SSViewer {
|
||||
);
|
||||
|
||||
protected static $topLevel = array();
|
||||
|
||||
public static function topLevel() {
|
||||
if(SSViewer::$topLevel) {
|
||||
return SSViewer::$topLevel[sizeof(SSViewer::$topLevel)-1];
|
||||
@ -728,6 +743,7 @@ class SSViewer {
|
||||
/**
|
||||
* @param string $identifier A template name without '.ss' extension or path
|
||||
* @param string $type The template type, either "main", "Includes" or "Layout"
|
||||
*
|
||||
* @return string Full system path to a template file
|
||||
*/
|
||||
public static function getTemplateFileByType($identifier, $type) {
|
||||
@ -766,6 +782,7 @@ class SSViewer {
|
||||
|
||||
/**
|
||||
* Set the cache object to use when storing / retrieving partial cache blocks.
|
||||
*
|
||||
* @param Zend_Cache_Core $cache
|
||||
*/
|
||||
public function setPartialCacheStore($cache) {
|
||||
@ -773,13 +790,23 @@ class SSViewer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache object to use when storing / retrieving partial cache blocks
|
||||
* Get the cache object to use when storing / retrieving partial cache blocks.
|
||||
*
|
||||
* @return Zend_Cache_Core
|
||||
*/
|
||||
public function getPartialCacheStore() {
|
||||
return $this->partialCacheStore ? $this->partialCacheStore : SS_Cache::factory('cacheblock');
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag whether to include the requirements in this response.
|
||||
*
|
||||
* @param boolean
|
||||
*/
|
||||
public function includeRequirements($incl = true) {
|
||||
$this->includeRequirements = $incl;
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal utility function to set up variables in preparation for including a compiled
|
||||
* template, then do the include
|
||||
@ -790,6 +817,7 @@ class SSViewer {
|
||||
* @param Object $item - The item to use as the root scope for the template
|
||||
* @param array|null $overlay - Any variables to layer on top of the scope
|
||||
* @param array|null $underlay - Any variables to layer underneath the scope
|
||||
*
|
||||
* @return string - The result of executing the template
|
||||
*/
|
||||
protected function includeGeneratedTemplate($cacheFile, $item, $overlay, $underlay) {
|
||||
@ -814,15 +842,18 @@ class SSViewer {
|
||||
|
||||
/**
|
||||
* The process() method handles the "meat" of the template processing.
|
||||
* It takes care of caching the output (via {@link SS_Cache}),
|
||||
* as well as replacing the special "$Content" and "$Layout"
|
||||
* placeholders with their respective subtemplates.
|
||||
*
|
||||
* It takes care of caching the output (via {@link SS_Cache}), as well as
|
||||
* replacing the special "$Content" and "$Layout" placeholders with their
|
||||
* respective subtemplates.
|
||||
*
|
||||
* The method injects extra HTML in the header via {@link Requirements::includeInHTML()}.
|
||||
*
|
||||
* Note: You can call this method indirectly by {@link ViewableData->renderWith()}.
|
||||
*
|
||||
* @param ViewableData $item
|
||||
* @param SS_Cache $cache Optional cache backend
|
||||
* @param SS_Cache $cache Optional cache backend.
|
||||
*
|
||||
* @return String Parsed template output.
|
||||
*/
|
||||
public function process($item, $arguments = null) {
|
||||
@ -869,14 +900,18 @@ class SSViewer {
|
||||
foreach(array('Content', 'Layout') as $subtemplate) {
|
||||
if(isset($this->chosenTemplates[$subtemplate])) {
|
||||
$subtemplateViewer = new SSViewer($this->chosenTemplates[$subtemplate]);
|
||||
$subtemplateViewer->includeRequirements(false);
|
||||
$subtemplateViewer->setPartialCacheStore($this->getPartialCacheStore());
|
||||
|
||||
$underlay[$subtemplate] = $subtemplateViewer->process($item, $arguments);
|
||||
}
|
||||
}
|
||||
|
||||
$val = $this->includeGeneratedTemplate($cacheFile, $item, $arguments, $underlay);
|
||||
$output = Requirements::includeInHTML($template, $val);
|
||||
$output = $this->includeGeneratedTemplate($cacheFile, $item, $arguments, $underlay);
|
||||
|
||||
if($this->includeRequirements) {
|
||||
$output = Requirements::includeInHTML($template, $output);
|
||||
}
|
||||
|
||||
array_pop(SSViewer::$topLevel);
|
||||
|
||||
@ -890,6 +925,7 @@ class SSViewer {
|
||||
} else {
|
||||
$thisURLRelativeToBase = strip_tags($_SERVER['REQUEST_URI']);
|
||||
}
|
||||
|
||||
$output = preg_replace('/(<a[^>]+href *= *)"#/i', '\\1"' . $thisURLRelativeToBase . '#', $output);
|
||||
}
|
||||
}
|
||||
@ -903,6 +939,8 @@ class SSViewer {
|
||||
*/
|
||||
public static function execute_template($template, $data, $arguments = null) {
|
||||
$v = new SSViewer($template);
|
||||
$v->includeRequirements(false);
|
||||
|
||||
return $v->process($data, $arguments);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user