mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge pull request #2557 from camspiers/template-parser-configurable
Feature to allow changing the SSTemplateParser used in SSViewer
This commit is contained in:
commit
77696e207a
@ -634,6 +634,13 @@ class i18nTextCollector_Parser extends SSTemplateParser {
|
||||
|
||||
private static $currentEntity = array();
|
||||
|
||||
public function __construct($string) {
|
||||
$this->string = $string;
|
||||
$this->pos = 0;
|
||||
$this->depth = 0;
|
||||
$this->regexps = array();
|
||||
}
|
||||
|
||||
public function Translate__construct(&$res) {
|
||||
self::$currentEntity = array(null,null,null); //start with empty array
|
||||
}
|
||||
|
@ -65,14 +65,20 @@ class SSTemplateParseException extends Exception {
|
||||
* Angle Bracket: angle brackets "<" and ">" are used to eat whitespace between template elements
|
||||
* N: eats white space including newlines (using in legacy _t support)
|
||||
*/
|
||||
class SSTemplateParser extends Parser {
|
||||
class SSTemplateParser extends Parser implements TemplateParser {
|
||||
|
||||
/**
|
||||
* @var bool - Set true by SSTemplateParser::compileString if the template should include comments intended
|
||||
* for debugging (template source, included files, etc)
|
||||
*/
|
||||
protected $includeDebuggingComments = false;
|
||||
|
||||
|
||||
/**
|
||||
* Override the Parser constructor to change the requirement of setting a string
|
||||
*/
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the function that constructs the result arrays to also prepare a 'php' item in the array
|
||||
*/
|
||||
@ -1757,7 +1763,7 @@ class SSTemplateParser extends Parser {
|
||||
/* CacheBlockArgument:
|
||||
!( "if " | "unless " )
|
||||
(
|
||||
:DollarMarkedLookup |
|
||||
:DollarMarkedLookup |
|
||||
:QuotedString |
|
||||
:Lookup
|
||||
) */
|
||||
@ -4548,7 +4554,8 @@ class SSTemplateParser extends Parser {
|
||||
// non-dynamically calculated
|
||||
$text = preg_replace(
|
||||
'/href\s*\=\s*\"\#/',
|
||||
'href="\' . (Config::inst()->get(\'SSViewer\', \'rewrite_hash_links\') ? strip_tags( $_SERVER[\'REQUEST_URI\'] ) : "") .
|
||||
'href="\' . (Config::inst()->get(\'SSViewer\', \'rewrite_hash_links\') ?' .
|
||||
' strip_tags( $_SERVER[\'REQUEST_URI\'] ) : "") .
|
||||
\'#',
|
||||
$text
|
||||
);
|
||||
@ -4563,29 +4570,28 @@ class SSTemplateParser extends Parser {
|
||||
/**
|
||||
* Compiles some passed template source code into the php code that will execute as per the template source.
|
||||
*
|
||||
* @static
|
||||
* @throws SSTemplateParseException
|
||||
* @param $string The source of the template
|
||||
* @param string $templateName The name of the template, normally the filename the template source was loaded from
|
||||
* @param bool $includeDebuggingComments True is debugging comments should be included in the output
|
||||
* @return mixed|string The php that, when executed (via include or exec) will behave as per the template source
|
||||
*/
|
||||
static function compileString($string, $templateName = "", $includeDebuggingComments=false) {
|
||||
public function compileString($string, $templateName = "", $includeDebuggingComments=false) {
|
||||
if (!trim($string)) {
|
||||
$code = '';
|
||||
}
|
||||
else {
|
||||
// Construct a parser instance
|
||||
$parser = new SSTemplateParser($string);
|
||||
$parser->includeDebuggingComments = $includeDebuggingComments;
|
||||
parent::__construct($string);
|
||||
|
||||
$this->includeDebuggingComments = $includeDebuggingComments;
|
||||
|
||||
// Ignore UTF8 BOM at begining of string. TODO: Confirm this is needed, make sure SSViewer handles UTF
|
||||
// (and other encodings) properly
|
||||
if(substr($string, 0,3) == pack("CCC", 0xef, 0xbb, 0xbf)) $parser->pos = 3;
|
||||
if(substr($string, 0,3) == pack("CCC", 0xef, 0xbb, 0xbf)) $this->pos = 3;
|
||||
|
||||
// Match the source against the parser
|
||||
$result = $parser->match_TopTemplate();
|
||||
if(!$result) throw new SSTemplateParseException('Unexpected problem parsing template', $parser);
|
||||
$result = $this->match_TopTemplate();
|
||||
if(!$result) throw new SSTemplateParseException('Unexpected problem parsing template', $this);
|
||||
|
||||
// Get the result
|
||||
$code = $result['php'];
|
||||
@ -4593,7 +4599,7 @@ class SSTemplateParser extends Parser {
|
||||
|
||||
// Include top level debugging comments if desired
|
||||
if($includeDebuggingComments && $templateName && stripos($code, "<?xml") === false) {
|
||||
$code = $parser->includeDebuggingComments($code, $templateName);
|
||||
$code = $this->includeDebuggingComments($code, $templateName);
|
||||
}
|
||||
|
||||
return $code;
|
||||
@ -4640,7 +4646,7 @@ class SSTemplateParser extends Parser {
|
||||
* @param $template - A file path that contains template source code
|
||||
* @return mixed|string - The php that, when executed (via include or exec) will behave as per the template source
|
||||
*/
|
||||
static function compileFile($template) {
|
||||
return self::compileString(file_get_contents($template), $template);
|
||||
public function compileFile($template) {
|
||||
return $this->compileString(file_get_contents($template), $template);
|
||||
}
|
||||
}
|
||||
|
@ -86,14 +86,20 @@ class SSTemplateParseException extends Exception {
|
||||
* Angle Bracket: angle brackets "<" and ">" are used to eat whitespace between template elements
|
||||
* N: eats white space including newlines (using in legacy _t support)
|
||||
*/
|
||||
class SSTemplateParser extends Parser {
|
||||
class SSTemplateParser extends Parser implements TemplateParser {
|
||||
|
||||
/**
|
||||
* @var bool - Set true by SSTemplateParser::compileString if the template should include comments intended
|
||||
* for debugging (template source, included files, etc)
|
||||
*/
|
||||
protected $includeDebuggingComments = false;
|
||||
|
||||
|
||||
/**
|
||||
* Override the Parser constructor to change the requirement of setting a string
|
||||
*/
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the function that constructs the result arrays to also prepare a 'php' item in the array
|
||||
*/
|
||||
@ -462,7 +468,7 @@ class SSTemplateParser extends Parser {
|
||||
CacheBlockArgument:
|
||||
!( "if " | "unless " )
|
||||
(
|
||||
:DollarMarkedLookup |
|
||||
:DollarMarkedLookup |
|
||||
:QuotedString |
|
||||
:Lookup
|
||||
)
|
||||
@ -1018,29 +1024,28 @@ class SSTemplateParser extends Parser {
|
||||
/**
|
||||
* Compiles some passed template source code into the php code that will execute as per the template source.
|
||||
*
|
||||
* @static
|
||||
* @throws SSTemplateParseException
|
||||
* @param $string The source of the template
|
||||
* @param string $templateName The name of the template, normally the filename the template source was loaded from
|
||||
* @param bool $includeDebuggingComments True is debugging comments should be included in the output
|
||||
* @return mixed|string The php that, when executed (via include or exec) will behave as per the template source
|
||||
*/
|
||||
static function compileString($string, $templateName = "", $includeDebuggingComments=false) {
|
||||
public function compileString($string, $templateName = "", $includeDebuggingComments=false) {
|
||||
if (!trim($string)) {
|
||||
$code = '';
|
||||
}
|
||||
else {
|
||||
// Construct a parser instance
|
||||
$parser = new SSTemplateParser($string);
|
||||
$parser->includeDebuggingComments = $includeDebuggingComments;
|
||||
parent::__construct($string);
|
||||
|
||||
$this->includeDebuggingComments = $includeDebuggingComments;
|
||||
|
||||
// Ignore UTF8 BOM at begining of string. TODO: Confirm this is needed, make sure SSViewer handles UTF
|
||||
// (and other encodings) properly
|
||||
if(substr($string, 0,3) == pack("CCC", 0xef, 0xbb, 0xbf)) $parser->pos = 3;
|
||||
if(substr($string, 0,3) == pack("CCC", 0xef, 0xbb, 0xbf)) $this->pos = 3;
|
||||
|
||||
// Match the source against the parser
|
||||
$result = $parser->match_TopTemplate();
|
||||
if(!$result) throw new SSTemplateParseException('Unexpected problem parsing template', $parser);
|
||||
$result = $this->match_TopTemplate();
|
||||
if(!$result) throw new SSTemplateParseException('Unexpected problem parsing template', $this);
|
||||
|
||||
// Get the result
|
||||
$code = $result['php'];
|
||||
@ -1048,7 +1053,7 @@ class SSTemplateParser extends Parser {
|
||||
|
||||
// Include top level debugging comments if desired
|
||||
if($includeDebuggingComments && $templateName && stripos($code, "<?xml") === false) {
|
||||
$code = $parser->includeDebuggingComments($code, $templateName);
|
||||
$code = $this->includeDebuggingComments($code, $templateName);
|
||||
}
|
||||
|
||||
return $code;
|
||||
@ -1095,7 +1100,7 @@ class SSTemplateParser extends Parser {
|
||||
* @param $template - A file path that contains template source code
|
||||
* @return mixed|string - The php that, when executed (via include or exec) will behave as per the template source
|
||||
*/
|
||||
static function compileFile($template) {
|
||||
return self::compileString(file_get_contents($template), $template);
|
||||
public function compileFile($template) {
|
||||
return $this->compileString(file_get_contents($template), $template);
|
||||
}
|
||||
}
|
||||
|
@ -614,6 +614,11 @@ class SSViewer {
|
||||
*/
|
||||
protected $includeRequirements = true;
|
||||
|
||||
/**
|
||||
* @var TemplateParser
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* Create a template from a string instead of a .ss file
|
||||
*
|
||||
@ -691,7 +696,9 @@ class SSViewer {
|
||||
* array('MySpecificPage', 'MyPage', 'Page')
|
||||
* </code>
|
||||
*/
|
||||
public function __construct($templateList) {
|
||||
public function __construct($templateList, TemplateParser $parser = null) {
|
||||
$this->setParser($parser ?: Injector::inst()->get('SSTemplateParser'));
|
||||
|
||||
// flush template manifest cache if requested
|
||||
if (isset($_GET['flush']) && $_GET['flush'] == 'all') {
|
||||
if(Director::isDev() || Director::is_cli() || Permission::check('ADMIN')) {
|
||||
@ -728,7 +735,25 @@ class SSViewer {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the template parser that will be used in template generation
|
||||
* @param \TemplateParser $parser
|
||||
*/
|
||||
public function setParser(TemplateParser $parser)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parser that is set for template generation
|
||||
* @return \TemplateParser
|
||||
*/
|
||||
public function getParser()
|
||||
{
|
||||
return $this->parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if at least one of the listed templates exists.
|
||||
*
|
||||
@ -970,7 +995,7 @@ class SSViewer {
|
||||
|
||||
if(!file_exists($cacheFile) || filemtime($cacheFile) < $lastEdited || isset($_GET['flush'])) {
|
||||
$content = file_get_contents($template);
|
||||
$content = SSViewer::parseTemplateContent($content, $template);
|
||||
$content = $this->parseTemplateContent($content, $template);
|
||||
|
||||
$fh = fopen($cacheFile,'w');
|
||||
fwrite($fh, $content);
|
||||
@ -983,7 +1008,7 @@ class SSViewer {
|
||||
// through $Content and $Layout placeholders.
|
||||
foreach(array('Content', 'Layout') as $subtemplate) {
|
||||
if(isset($this->chosenTemplates[$subtemplate])) {
|
||||
$subtemplateViewer = new SSViewer($this->chosenTemplates[$subtemplate]);
|
||||
$subtemplateViewer = new SSViewer($this->chosenTemplates[$subtemplate], $this->parser);
|
||||
$subtemplateViewer->includeRequirements(false);
|
||||
$subtemplateViewer->setPartialCacheStore($this->getPartialCacheStore());
|
||||
|
||||
@ -1028,10 +1053,10 @@ class SSViewer {
|
||||
return $v->process($data, $arguments, $scope);
|
||||
}
|
||||
|
||||
public static function parseTemplateContent($content, $template="") {
|
||||
return SSTemplateParser::compileString(
|
||||
$content,
|
||||
$template,
|
||||
public function parseTemplateContent($content, $template="") {
|
||||
return $this->parser->compileString(
|
||||
$content,
|
||||
$template,
|
||||
Director::isDev() && Config::inst()->get('SSViewer', 'source_file_comments')
|
||||
);
|
||||
}
|
||||
@ -1079,7 +1104,8 @@ class SSViewer {
|
||||
class SSViewer_FromString extends SSViewer {
|
||||
protected $content;
|
||||
|
||||
public function __construct($content) {
|
||||
public function __construct($content, TemplateParser $parser = null) {
|
||||
$this->setParser($parser ?: Injector::inst()->get('SSTemplateParser'));
|
||||
$this->content = $content;
|
||||
}
|
||||
|
||||
@ -1091,7 +1117,7 @@ class SSViewer_FromString extends SSViewer {
|
||||
$arguments = null;
|
||||
}
|
||||
|
||||
$template = SSViewer::parseTemplateContent($this->content, "string sha1=".sha1($this->content));
|
||||
$template = $this->parseTemplateContent($this->content, "string sha1=".sha1($this->content));
|
||||
|
||||
$tmpFile = tempnam(TEMP_FOLDER,"");
|
||||
$fh = fopen($tmpFile, 'w');
|
||||
|
19
view/TemplateParser.php
Normal file
19
view/TemplateParser.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This interface needs to be implemented by any template parser that is used in SSViewer
|
||||
*
|
||||
* @package framework
|
||||
* @subpackage view
|
||||
*/
|
||||
interface TemplateParser {
|
||||
/**
|
||||
* Compiles some passed template source code into the php code that will execute as per the template source.
|
||||
*
|
||||
* @param $string The source of the template
|
||||
* @param string $templateName The name of the template, normally the filename the template source was loaded from
|
||||
* @param bool $includeDebuggingComments True is debugging comments should be included in the output
|
||||
* @return mixed|string The php that, when executed (via include or exec) will behave as per the template source
|
||||
*/
|
||||
public function compileString($string, $templateName = "", $includeDebuggingComments = false);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user