From fa016ed6b9954fc5f1877aaf16322f4158df714c Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Fri, 12 Mar 2010 03:08:59 +0000 Subject: [PATCH] ENHANCEMENT: Parse template includes at runtime, so that recursive templates and automatic recompilation of included templates work git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@100972 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- core/SSViewer.php | 35 +++++++++++-------- tests/SSViewerTest.php | 26 ++++++++++++++ .../templates/SSViewerTestRecursiveInclude.ss | 6 ++++ 3 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 tests/templates/SSViewerTestRecursiveInclude.ss diff --git a/core/SSViewer.php b/core/SSViewer.php index 8ad716bba..4e731df21 100755 --- a/core/SSViewer.php +++ b/core/SSViewer.php @@ -388,6 +388,15 @@ class SSViewer { return $output; } + /** + * Execute the given template, passing it the given data. + * Used by the <% include %> template tag to process templates. + */ + static function execute_template($template, $data) { + $v = new SSViewer($template); + return $v->process($data); + } + static function parseTemplateContent($content, $template="") { // Remove UTF-8 byte order mark: // This is only necessary if you don't have zend-multibyte enabled. @@ -406,21 +415,6 @@ class SSViewer { } } - while(true) { - $oldContent = $content; - - // Add include filename comments on dev sites - if(Director::isDev() && self::$source_file_comments) $replacementCode = 'return "\n" - . SSViewer::getTemplateContent($matches[1]) - . "\n";'; - else $replacementCode = 'return SSViewer::getTemplateContent($matches[1]);'; - - $content = preg_replace_callback('/<' . '% include +([A-Za-z0-9_]+) +%' . '>/', create_function( - '$matches', $replacementCode - ), $content); - if($oldContent == $content) break; - } - // $val, $val.property, $val(param), etc. $replacements = array( '/<%--.*--%>/U' => '', @@ -531,6 +525,17 @@ class SSViewer { // add all requirements to the $requirements array preg_match_all('/<% require ([a-zA-Z]+)\(([^\)]+)\) %>/', $content, $requirements); $content = preg_replace('/<% require .* %>/', null, $content); + + + // Add include filename comments on dev sites + if(Director::isDev() && self::$source_file_comments) $replacementCode = 'return "\n" + . "" + . "\n";'; + else $replacementCode = 'return "";'; + + $content = preg_replace_callback('/<' . '% include +([A-Za-z0-9_]+) +%' . '>/', create_function( + '$matches', $replacementCode + ), $content); // legacy $content = ereg_replace('', 'cachedCall("\\1")) { ?>', $content); diff --git a/tests/SSViewerTest.php b/tests/SSViewerTest.php index 4a49774bc..69041f48e 100644 --- a/tests/SSViewerTest.php +++ b/tests/SSViewerTest.php @@ -280,6 +280,32 @@ after') $negotiator->xhtml($response); $this->assertRegExp('/<\/base><\/head>/', $response->getBody()); } + + + function testRecursiveInclude() { + $view = new SSViewer(array('SSViewerTestRecursiveInclude')); + + $data = new ArrayData(array( + 'Title' => 'A', + 'Children' => new DataObjectSet(array( + new ArrayData(array( + 'Title' => 'A1', + 'Children' => new DataObjectSet(array( + new ArrayData(array( 'Title' => 'A1 i', )), + new ArrayData(array( 'Title' => 'A1 ii', )), + )), + )), + new ArrayData(array( 'Title' => 'A2', )), + new ArrayData(array( 'Title' => 'A3', )), + )), + )); + + $result = $view->process($data); + // We don't care about whitespace + $rationalisedResult = trim(preg_replace('/\s+/', ' ', $result)); + + $this->assertEquals('A A1 A1 i A1 ii A2 A3', $rationalisedResult); + } } /** diff --git a/tests/templates/SSViewerTestRecursiveInclude.ss b/tests/templates/SSViewerTestRecursiveInclude.ss new file mode 100644 index 000000000..e781f09a4 --- /dev/null +++ b/tests/templates/SSViewerTestRecursiveInclude.ss @@ -0,0 +1,6 @@ +$Title +<% if Children %> +<% control Children %> +<% include SSViewerTestRecursiveInclude %> +<% end_control %> +<% end_if %> \ No newline at end of file