SSTemplateParser
class SSTemplateParser extends Parser implements TemplateParser
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 explictly 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)
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
Set the open 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
No description
No description
No description
No description
No description
No description
No description
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.
No description
No description
No description
No description
No description
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.
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
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.
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
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
No description
No description
This is an example of a block handler function. This one handles the loop tag.
The closed block handler for with blocks
No description
No description
No description
No description
This is an open block handler, for the <% debug %> utility tag
This is an open block handler, for the <% base_tag %> tag
This is an open block handler, for the <% current_page %> tag
No description
No description
No description
No description
No description
No description
No description
No description
No description
No description
The TopTemplate also includes the opening stanza to start off the template
No description
We convert text
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
at line 91
__construct(array $closedBlocks = array(), array $openBlocks = array())
Allow the injection of new closed & open block callables
at line 101
construct($matchrule, $name, $arguments = null)
Override the function that constructs the result arrays to also prepare a 'php' item in the array
at line 118
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
at line 134
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
at line 148
addClosedBlock(string $name, callable $callable)
Add a closed block callable to allow <% name %><% end_name %> syntax
at line 160
addOpenBlock(string $name, callable $callable)
Add a closed block callable to allow <% name %> syntax
at line 196
match_Template($stack = array())
at line 444
Template_STR($res, $sub)
at line 451
match_Word($stack = array())
at line 463
match_NamespacedWord($stack = array())
at line 475
match_Number($stack = array())
at line 487
match_Value($stack = array())
at line 499
match_CallArguments($stack = array())
at line 552
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.
at line 564
match_Call($stack = array())
at line 622
match_LookupStep($stack = array())
at line 655
match_LastLookupStep($stack = array())
at line 669
match_Lookup($stack = array())
at line 745
Lookup__construct($res)
at line 756
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.
at line 770
Lookup_LookupStep($res, $sub)
at line 775
Lookup_LastLookupStep($res, $sub)
at line 784
match_Translate($stack = array())
at line 897
match_InjectionVariables($stack = array())
at line 942
match_Entity($stack = array())
at line 954
Translate__construct($res)
at line 959
Translate_Entity($res, $sub)
at line 964
Translate_Default($res, $sub)
at line 969
Translate_Context($res, $sub)
at line 974
Translate_InjectionVariables($res, $sub)
at line 979
Translate__finalise($res)
at line 984
InjectionVariables__construct($res)
at line 989
InjectionVariables_InjectionName($res, $sub)
at line 994
InjectionVariables_Argument($res, $sub)
at line 999
InjectionVariables__finalise($res)
at line 1010
match_SimpleInjection($stack = array())
at line 1035
match_BracketInjection($stack = array())
at line 1062
match_Injection($stack = array())
at line 1093
Injection_STR($res, $sub)
at line 1100
match_DollarMarkedLookup($stack = array())
at line 1113
DollarMarkedLookup_STR($res, $sub)
at line 1120
match_QuotedString($stack = array())
at line 1156
match_Null($stack = array())
at line 1168
match_Boolean($stack = array())
at line 1180
match_Sign($stack = array())
at line 1192
match_Float($stack = array())
at line 1204
match_Hexadecimal($stack = array())
at line 1216
match_Octal($stack = array())
at line 1228
match_Binary($stack = array())
at line 1240
match_Decimal($stack = array())
at line 1252
match_IntegerOrFloat($stack = array())
at line 1369
match_FreeString($stack = array())
at line 1388
match_Argument($stack = array())
at line 1555
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
at line 1561
Argument_QuotedString($res, $sub)
at line 1567
Argument_Null($res, $sub)
at line 1573
Argument_Boolean($res, $sub)
at line 1579
Argument_IntegerOrFloat($res, $sub)
at line 1585
Argument_Lookup($res, $sub)
at line 1597
Argument_FreeString($res, $sub)
at line 1605
match_ComparisonOperator($stack = array())
at line 1716
match_Comparison($stack = array())
at line 1749
Comparison_Argument($res, $sub)
at line 1762
Comparison_ComparisonOperator($res, $sub)
at line 1769
match_PresenceCheck($stack = array())
at line 1812
PresenceCheck_Not($res, $sub)
at line 1817
PresenceCheck_Argument($res, $sub)
at line 1831
match_IfArgumentPortion($stack = array())
at line 1862
IfArgumentPortion_STR($res, $sub)
at line 1869
match_BooleanOperator($stack = array())
at line 1897
match_IfArgument($stack = array())
at line 1946
IfArgument_IfArgumentPortion($res, $sub)
at line 1951
IfArgument_BooleanOperator($res, $sub)
at line 1958
match_IfPart($stack = array())
at line 2001
match_ElseIfPart($stack = array())
at line 2044
match_ElsePart($stack = array())
at line 2079
match_If($stack = array())
at line 2135
If_IfPart($res, $sub)
at line 2143
If_ElseIfPart($res, $sub)
at line 2151
If_ElsePart($res, $sub)
at line 2161
match_Require($stack = array())
at line 2222
Require_Call($res, $sub)
at line 2237
match_CacheBlockArgument($stack = array())
at line 2334
CacheBlockArgument_DollarMarkedLookup($res, $sub)
at line 2339
CacheBlockArgument_QuotedString($res, $sub)
at line 2344
CacheBlockArgument_Lookup($res, $sub)
at line 2351
match_CacheBlockArguments($stack = array())
at line 2399
CacheBlockArguments_CacheBlockArgument($res, $sub)
at line 2413
match_CacheBlockTemplate($stack = array())
at line 2631
match_UncachedBlock($stack = array())
at line 2784
UncachedBlock_Template($res, $sub)
at line 2792
match_CacheRestrictedTemplate($stack = array())
at line 3040
CacheRestrictedTemplate_CacheBlock($res, $sub)
at line 3046
CacheRestrictedTemplate_UncachedBlock($res, $sub)
at line 3058
match_CacheBlock($stack = array())
at line 3294
CacheBlock__construct($res)
at line 3299
CacheBlock_CacheBlockArguments($res, $sub)
at line 3304
CacheBlock_Condition($res, $sub)
at line 3309
CacheBlock_CacheBlock($res, $sub)
at line 3314
CacheBlock_UncachedBlock($res, $sub)
at line 3319
CacheBlock_CacheBlockTemplate($res, $sub)
at line 3356
match_OldTPart($stack = array())
at line 3466
match_N($stack = array())
at line 3477
OldTPart__construct($res)
at line 3482
OldTPart_QuotedString($res, $sub)
at line 3492
OldTPart_CallArguments($res, $sub)
at line 3497
OldTPart__finalise($res)
at line 3504
match_OldTTag($stack = array())
at line 3529
OldTTag_OldTPart($res, $sub)
at line 3536
match_OldSprintfTag($stack = array())
at line 3589
OldSprintfTag__construct($res)
at line 3594
OldSprintfTag_OldTPart($res, $sub)
at line 3599
OldSprintfTag_CallArguments($res, $sub)
at line 3606
match_OldI18NTag($stack = array())
at line 3637
OldI18NTag_STR($res, $sub)
at line 3644
match_NamedArgument($stack = array())
at line 3674
NamedArgument_Name($res, $sub)
at line 3679
NamedArgument_Value($res, $sub)
at line 3698
match_Include($stack = array())
at line 3775
Include__construct($res)
at line 3780
Include_Template($res, $sub)
at line 3785
Include_NamedArgument($res, $sub)
at line 3790
Include__finalise($res)
at line 3809
match_BlockArguments($stack = array())
at line 3858
match_NotBlockTag($stack = array())
at line 4013
match_ClosedBlock($stack = array())
at line 4121
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.
at line 4126
ClosedBlock_BlockArguments($res, $sub)
at line 4137
ClosedBlock__finalise($res)
at line 4155
ClosedBlock_Handle_Loop($res)
This is an example of a block handler function. This one handles the loop tag.
at line 4186
ClosedBlock_Handle_With($res)
The closed block handler for with blocks
at line 4207
match_OpenBlock($stack = array())
at line 4269
OpenBlock__construct($res)
at line 4274
OpenBlock_BlockArguments($res, $sub)
at line 4285
OpenBlock__finalise($res)
at line 4303
OpenBlock_Handle_Debug($res)
This is an open block handler, for the <% debug %> utility tag
at line 4324
OpenBlock_Handle_Base_tag($res)
This is an open block handler, for the <% base_tag %> tag
at line 4335
OpenBlock_Handle_Current_page($res)
This is an open block handler, for the <% current_page %> tag
at line 4345
match_MismatchedEndBlock($stack = array())
at line 4372
MismatchedEndBlock__finalise($res)
at line 4381
match_MalformedOpenTag($stack = array())
at line 4459
MalformedOpenTag__finalise($res)
at line 4467
match_MalformedCloseTag($stack = array())
at line 4524
MalformedCloseTag__finalise($res)
at line 4533
match_MalformedBlock($stack = array())
at line 4567
match_Comment($stack = array())
at line 4618
Comment__construct($res)
at line 4626
match_TopTemplate($stack = array())
at line 4898
TopTemplate__construct($res)
The TopTemplate also includes the opening stanza to start off the template
at line 4912
match_Text($stack = array())
at line 5119
Text__finalise($res)
We convert text
at line 5158
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.
at line 5237
mixed|string
compileFile($template)
Compiles some file that contains template source code, and returns the php code that will execute as per that source