SSTemplateParser
class SSTemplateParser extends Parser implements TemplateParser (View source)
This is the parser for the SilverStripe template language. It gets called on a string and uses a php-peg parser to match that string against the language structure, building up the PHP code to execute that structure as it parses
The $result array that is built up as part of the parsing (see thirdparty/php-peg/README.md for more on how parsers build results) has one special member, 'php', which contains the php equivalent of that part of the template tree.
Some match rules generate alternate php, or other variations, so check the per-match documentation too.
Terms used:
Marked: A string or lookup in the template that has been explicitly marked as such - lookups by prepending with "$" (like $Foo.Bar), strings by wrapping with single or double quotes ('Foo' or "Foo")
Bare: The opposite of marked. An argument that has to has it's type inferred by usage and 2.4 defaults.
Example of using a bare argument for a loop block: <% loop Foo %>
Block: One of two SS template structures. The special characters "<%" and "%>" are used to wrap the opening and (required or forbidden depending on which block exactly) closing block marks.
Open Block: An SS template block that doesn't wrap any content or have a closing end tag (in fact, a closing end tag is forbidden)
Closed Block: An SS template block that wraps content, and requires a counterpart <% end_blockname %> tag
Angle Bracket: angle brackets "<" and ">" are used to eat whitespace between template elements N: eats white space including newlines (using in legacy _t support)
Properties
| protected | bool | $includeDebuggingComments | ||
| protected | array | $closedBlocks | Stores the user-supplied closed block extension rules in the form: [ 'name' => function (&$res) {} ] See SSTemplateParser::ClosedBlock_Handle_Loop for an example of what the callable should look like  | 
                |
| protected | array | $openBlocks | Stores the user-supplied open block extension rules in the form: [ 'name' => function (&$res) {} ] See SSTemplateParser::OpenBlock_Handle_Base_tag for an example of what the callable should look like  | 
                |
| protected | $match_Template_typestack | |||
| protected | $match_Word_typestack | |||
| protected | $match_NamespacedWord_typestack | |||
| protected | $match_Number_typestack | |||
| protected | $match_Value_typestack | |||
| protected | $match_CallArguments_typestack | |||
| protected | $match_Call_typestack | |||
| protected | $match_LookupStep_typestack | |||
| protected | $match_LastLookupStep_typestack | |||
| protected | $match_Lookup_typestack | |||
| protected | $match_Translate_typestack | |||
| protected | $match_InjectionVariables_typestack | |||
| protected | $match_Entity_typestack | |||
| protected | $match_MalformedBracketInjection_typestack | |||
| protected | $match_SimpleInjection_typestack | |||
| protected | $match_BracketInjection_typestack | |||
| protected | $match_Injection_typestack | |||
| protected | $match_DollarMarkedLookup_typestack | |||
| protected | $match_QuotedString_typestack | |||
| protected | $match_FreeString_typestack | |||
| protected | $match_Argument_typestack | |||
| protected | $match_ComparisonOperator_typestack | |||
| protected | $match_Comparison_typestack | |||
| protected | $match_PresenceCheck_typestack | |||
| protected | $match_IfArgumentPortion_typestack | |||
| protected | $match_BooleanOperator_typestack | |||
| protected | $match_IfArgument_typestack | |||
| protected | $match_IfPart_typestack | |||
| protected | $match_ElseIfPart_typestack | |||
| protected | $match_ElsePart_typestack | |||
| protected | $match_If_typestack | |||
| protected | $match_Require_typestack | |||
| protected | $match_CacheBlockArgument_typestack | |||
| protected | $match_CacheBlockArguments_typestack | |||
| protected | $match_CacheBlockTemplate_typestack | |||
| protected | $match_UncachedBlock_typestack | |||
| protected | $match_CacheRestrictedTemplate_typestack | |||
| protected | $match_CacheBlock_typestack | |||
| protected | $match_OldTPart_typestack | |||
| protected | $match_N_typestack | |||
| protected | $match_OldTTag_typestack | |||
| protected | $match_OldSprintfTag_typestack | |||
| protected | $match_OldI18NTag_typestack | |||
| protected | $match_NamedArgument_typestack | |||
| protected | $match_Include_typestack | |||
| protected | $match_BlockArguments_typestack | |||
| protected | $match_NotBlockTag_typestack | |||
| protected | $match_ClosedBlock_typestack | |||
| protected | $match_OpenBlock_typestack | |||
| protected | $match_MismatchedEndBlock_typestack | |||
| protected | $match_MalformedOpenTag_typestack | |||
| protected | $match_MalformedCloseTag_typestack | |||
| protected | $match_MalformedBlock_typestack | |||
| protected | $match_CommentWithContent_typestack | |||
| protected | $match_EmptyComment_typestack | |||
| protected | $match_Comment_typestack | |||
| protected | $match_TopTemplate_typestack | |||
| protected | $match_Text_typestack | 
Methods
Allow the injection of new closed & open block callables
Override the function that constructs the result arrays to also prepare a 'php' item in the array
Set the closed blocks that the template parser should use
Add a closed block callable to allow <% name %><% end_name %> syntax
Add a closed block callable to allow <% name %> syntax
Ensures that the arguments to addOpenBlock and addClosedBlock are valid
Values are bare words in templates, but strings in PHP. We rely on PHP's type conversion to back-convert strings to numbers when needed.
The basic generated PHP of LookupStep and LastLookupStep is the same, except that LookupStep calls 'obj' to get the next ViewableData in the sequence, and LastLookupStep calls different methods (XML_val, hasValue, obj) depending on the context the lookup is used in.
If we get a bare value, we don't know enough to determine exactly what php would be the translation, because we don't know if the position of use indicates a lookup or a string argument.
As mentioned in the parser comment, block handling is kept fairly generic for extensibility. The match rule builds up two important elements in the match result array: 'ArgumentCount' - how many arguments were passed in the opening tag 'Arguments' an array of the Argument match rule result arrays
This is an example of a block handler function. This one handles the loop tag.
This is an open block handler, for the <% current_page %> tag
The TopTemplate also includes the opening stanza to start off the template
Compiles some passed template source code into the php code that will execute as per the template source.
Compiles some file that contains template source code, and returns the php code that will execute as per that source
Details
        
                            
    __construct(array $closedBlocks = [], array $openBlocks = [])
        
    
    Allow the injection of new closed & open block callables
        
                            
    construct($matchrule, $name, $arguments = null)
        
    
    Override the function that constructs the result arrays to also prepare a 'php' item in the array
        
                            
    setClosedBlocks(array $closedBlocks)
        
    
    Set the closed blocks that the template parser should use
This method will delete any existing closed blocks, please use addClosedBlock if you don't want to overwrite
        
                            
    setOpenBlocks(array $openBlocks)
        
    
    Set the open blocks that the template parser should use
This method will delete any existing open blocks, please use addOpenBlock if you don't want to overwrite
        
                            
    addClosedBlock(string $name, callable $callable)
        
    
    Add a closed block callable to allow <% name %><% end_name %> syntax
        
                            
    addOpenBlock(string $name, callable $callable)
        
    
    Add a closed block callable to allow <% name %> syntax
        
                    protected        
    validateExtensionBlock($name, $callable, $type)
        
    
    Ensures that the arguments to addOpenBlock and addClosedBlock are valid
        
                            
    match_Template($stack = array())
        
    
    No description
        
                            
    Template_STR($res, $sub)
        
    
    No description
        
                            
    match_Word($stack = array())
        
    
    No description
        
                            
    match_NamespacedWord($stack = array())
        
    
    No description
        
                            
    match_Number($stack = array())
        
    
    No description
        
                            
    match_Value($stack = array())
        
    
    No description
        
                            
    match_CallArguments($stack = array())
        
    
    No description
        
                            
    CallArguments_Argument($res, $sub)
        
    
    Values are bare words in templates, but strings in PHP. We rely on PHP's type conversion to back-convert strings to numbers when needed.
        
                            
    match_Call($stack = array())
        
    
    No description
        
                            
    match_LookupStep($stack = array())
        
    
    No description
        
                            
    match_LastLookupStep($stack = array())
        
    
    No description
        
                            
    match_Lookup($stack = array())
        
    
    No description
        
                            
    Lookup__construct($res)
        
    
    No description
        
                            
    Lookup_AddLookupStep($res, $sub, $method)
        
    
    The basic generated PHP of LookupStep and LastLookupStep is the same, except that LookupStep calls 'obj' to get the next ViewableData in the sequence, and LastLookupStep calls different methods (XML_val, hasValue, obj) depending on the context the lookup is used in.
        
                            
    Lookup_LookupStep($res, $sub)
        
    
    No description
        
                            
    Lookup_LastLookupStep($res, $sub)
        
    
    No description
        
                            
    match_Translate($stack = array())
        
    
    No description
        
                            
    match_InjectionVariables($stack = array())
        
    
    No description
        
                            
    match_Entity($stack = array())
        
    
    No description
        
                            
    Translate__construct($res)
        
    
    No description
        
                            
    Translate_Entity($res, $sub)
        
    
    No description
        
                            
    Translate_Default($res, $sub)
        
    
    No description
        
                            
    Translate_Context($res, $sub)
        
    
    No description
        
                            
    Translate_InjectionVariables($res, $sub)
        
    
    No description
        
                            
    Translate__finalise($res)
        
    
    No description
        
                            
    InjectionVariables__construct($res)
        
    
    No description
        
                            
    InjectionVariables_InjectionName($res, $sub)
        
    
    No description
        
                            
    InjectionVariables_Argument($res, $sub)
        
    
    No description
        
                            
    InjectionVariables__finalise($res)
        
    
    No description
        
                            
    match_MalformedBracketInjection($stack = array())
        
    
    No description
        
                            
    MalformedBracketInjection__finalise($res)
        
    
    No description
        
                            
    match_SimpleInjection($stack = array())
        
    
    No description
        
                            
    match_BracketInjection($stack = array())
        
    
    No description
        
                            
    match_Injection($stack = array())
        
    
    No description
        
                            
    Injection_STR($res, $sub)
        
    
    No description
        
                            
    match_DollarMarkedLookup($stack = array())
        
    
    No description
        
                            
    DollarMarkedLookup_STR($res, $sub)
        
    
    No description
        
                            
    match_QuotedString($stack = array())
        
    
    No description
        
                            
    match_FreeString($stack = array())
        
    
    No description
        
                            
    match_Argument($stack = array())
        
    
    No description
        
                            
    Argument_DollarMarkedLookup($res, $sub)
        
    
    If we get a bare value, we don't know enough to determine exactly what php would be the translation, because we don't know if the position of use indicates a lookup or a string argument.
Instead, we record 'ArgumentMode' as a member of this matches results node, which can be:
- lookup if this argument was unambiguously a lookup (marked as such)
 - string is this argument was unambiguously a string (marked as such, or impossible to parse as lookup)
 - default if this argument needs to be handled as per 2.4
 
In the case of 'default', there is no php member of the results node, but instead 'lookup_php', which should be used by the parent if the context indicates a lookup, and 'string_php' which should be used if the context indicates a string
        
                            
    Argument_QuotedString($res, $sub)
        
    
    No description
        
                            
    Argument_Lookup($res, $sub)
        
    
    No description
        
                            
    Argument_FreeString($res, $sub)
        
    
    No description
        
                            
    match_ComparisonOperator($stack = array())
        
    
    No description
        
                            
    match_Comparison($stack = array())
        
    
    No description
        
                            
    Comparison_Argument($res, $sub)
        
    
    No description
        
                            
    Comparison_ComparisonOperator($res, $sub)
        
    
    No description
        
                            
    match_PresenceCheck($stack = array())
        
    
    No description
        
                            
    PresenceCheck_Not($res, $sub)
        
    
    No description
        
                            
    PresenceCheck_Argument($res, $sub)
        
    
    No description
        
                            
    match_IfArgumentPortion($stack = array())
        
    
    No description
        
                            
    IfArgumentPortion_STR($res, $sub)
        
    
    No description
        
                            
    match_BooleanOperator($stack = array())
        
    
    No description
        
                            
    match_IfArgument($stack = array())
        
    
    No description
        
                            
    IfArgument_IfArgumentPortion($res, $sub)
        
    
    No description
        
                            
    IfArgument_BooleanOperator($res, $sub)
        
    
    No description
        
                            
    match_IfPart($stack = array())
        
    
    No description
        
                            
    match_ElseIfPart($stack = array())
        
    
    No description
        
                            
    match_ElsePart($stack = array())
        
    
    No description
        
                            
    match_If($stack = array())
        
    
    No description
        
                            
    If_IfPart($res, $sub)
        
    
    No description
        
                            
    If_ElseIfPart($res, $sub)
        
    
    No description
        
                            
    If_ElsePart($res, $sub)
        
    
    No description
        
                            
    match_Require($stack = array())
        
    
    No description
        
                            
    Require_Call($res, $sub)
        
    
    No description
        
                            
    match_CacheBlockArgument($stack = array())
        
    
    No description
        
                            
    CacheBlockArgument_DollarMarkedLookup($res, $sub)
        
    
    No description
        
                            
    CacheBlockArgument_QuotedString($res, $sub)
        
    
    No description
        
                            
    CacheBlockArgument_Lookup($res, $sub)
        
    
    No description
        
                            
    match_CacheBlockArguments($stack = array())
        
    
    No description
        
                            
    CacheBlockArguments_CacheBlockArgument($res, $sub)
        
    
    No description
        
                            
    match_CacheBlockTemplate($stack = array())
        
    
    No description
        
                            
    match_UncachedBlock($stack = array())
        
    
    No description
        
                            
    UncachedBlock_Template($res, $sub)
        
    
    No description
        
                            
    match_CacheRestrictedTemplate($stack = array())
        
    
    No description
        
                            
    CacheRestrictedTemplate_CacheBlock($res, $sub)
        
    
    No description
        
                            
    CacheRestrictedTemplate_UncachedBlock($res, $sub)
        
    
    No description
        
                            
    match_CacheBlock($stack = array())
        
    
    No description
        
                            
    CacheBlock__construct($res)
        
    
    No description
        
                            
    CacheBlock_CacheBlockArguments($res, $sub)
        
    
    No description
        
                            
    CacheBlock_Condition($res, $sub)
        
    
    No description
        
                            
    CacheBlock_CacheBlock($res, $sub)
        
    
    No description
        
                            
    CacheBlock_UncachedBlock($res, $sub)
        
    
    No description
        
                            
    CacheBlock_CacheBlockTemplate($res, $sub)
        
    
    No description
        
                            
    match_OldTPart($stack = array())
        
    
    No description
        
                            
    match_N($stack = array())
        
    
    No description
        
                            
    OldTPart__construct($res)
        
    
    No description
        
                            
    OldTPart_QuotedString($res, $sub)
        
    
    No description
        
                            
    OldTPart_CallArguments($res, $sub)
        
    
    No description
        
                            
    OldTPart__finalise($res)
        
    
    No description
        
                            
    match_OldTTag($stack = array())
        
    
    No description
        
                            
    OldTTag_OldTPart($res, $sub)
        
    
    No description
        
                            
    match_OldSprintfTag($stack = array())
        
    
    No description
        
                            
    OldSprintfTag__construct($res)
        
    
    No description
        
                            
    OldSprintfTag_OldTPart($res, $sub)
        
    
    No description
        
                            
    OldSprintfTag_CallArguments($res, $sub)
        
    
    No description
        
                            
    match_OldI18NTag($stack = array())
        
    
    No description
        
                            
    OldI18NTag_STR($res, $sub)
        
    
    No description
        
                            
    match_NamedArgument($stack = array())
        
    
    No description
        
                            
    NamedArgument_Name($res, $sub)
        
    
    No description
        
                            
    NamedArgument_Value($res, $sub)
        
    
    No description
        
                            
    match_Include($stack = array())
        
    
    No description
        
                            
    Include__construct($res)
        
    
    No description
        
                            
    Include_Template($res, $sub)
        
    
    No description
        
                            
    Include_NamedArgument($res, $sub)
        
    
    No description
        
                            
    Include__finalise($res)
        
    
    No description
        
                            
    match_BlockArguments($stack = array())
        
    
    No description
        
                            
    match_NotBlockTag($stack = array())
        
    
    No description
        
                            
    match_ClosedBlock($stack = array())
        
    
    No description
        
                            
    ClosedBlock__construct($res)
        
    
    As mentioned in the parser comment, block handling is kept fairly generic for extensibility. The match rule builds up two important elements in the match result array: 'ArgumentCount' - how many arguments were passed in the opening tag 'Arguments' an array of the Argument match rule result arrays
Once a block has successfully been matched against, it will then look for the actual handler, which should be on this class (either defined or extended on) as ClosedBlock_Handler_Name(&$res), where Name is the tag name, first letter captialized (i.e Control, Loop, With, etc).
This function will be called with the match rule result array as it's first argument. It should return the php result of this block as it's return value, or throw an error if incorrect arguments were passed.
        
                            
    ClosedBlock_BlockArguments($res, $sub)
        
    
    No description
        
                            
    ClosedBlock__finalise($res)
        
    
    No description
        
                            
    ClosedBlock_Handle_Loop($res)
        
    
    This is an example of a block handler function. This one handles the loop tag.
        
                            
    ClosedBlock_Handle_With($res)
        
    
    The closed block handler for with blocks
        
                            
    match_OpenBlock($stack = array())
        
    
    No description
        
                            
    OpenBlock__construct($res)
        
    
    No description
        
                            
    OpenBlock_BlockArguments($res, $sub)
        
    
    No description
        
                            
    OpenBlock__finalise($res)
        
    
    No description
        
                            
    OpenBlock_Handle_Debug($res)
        
    
    This is an open block handler, for the <% debug %> utility tag
        
                            
    OpenBlock_Handle_Base_tag($res)
        
    
    This is an open block handler, for the <% base_tag %> tag
        
                            
    OpenBlock_Handle_Current_page($res)
        
    
    This is an open block handler, for the <% current_page %> tag
        
                            
    match_MismatchedEndBlock($stack = array())
        
    
    No description
        
                            
    MismatchedEndBlock__finalise($res)
        
    
    No description
        
                            
    match_MalformedOpenTag($stack = array())
        
    
    No description
        
                            
    MalformedOpenTag__finalise($res)
        
    
    No description
        
                            
    match_MalformedCloseTag($stack = array())
        
    
    No description
        
                            
    MalformedCloseTag__finalise($res)
        
    
    No description
        
                            
    match_MalformedBlock($stack = array())
        
    
    No description
        
                            
    match_CommentWithContent($stack = array())
        
    
    No description
        
                            
    match_EmptyComment($stack = array())
        
    
    No description
        
                            
    match_Comment($stack = array())
        
    
    No description
        
                            
    Comment__construct($res)
        
    
    No description
        
                            
    match_TopTemplate($stack = array())
        
    
    No description
        
                            
    TopTemplate__construct($res)
        
    
    The TopTemplate also includes the opening stanza to start off the template
        
                            
    match_Text($stack = array())
        
    
    No description
        
                            
    Text__finalise($res)
        
    
    We convert text
        
                            string
    compileString(string $string, string $templateName = "", bool $includeDebuggingComments = false, bool $topTemplate = true)
        
    
    Compiles some passed template source code into the php code that will execute as per the template source.
        
                    protected        string
    includeDebuggingComments(string $code, string $templateName)
        
    
    No description
        
                static            mixed|string
    compileFile($template)
        
    
    Compiles some file that contains template source code, and returns the php code that will execute as per that source