\Tale\JadeCompiler

Compiles an AST got from the parser to valid PHTML, HTML or XML.

You can control the output-style via the options passed to the constructor.

Different output types are possible (Currently, XML and HTML)

The main entry point is the compile method

The generated PHTML should be evaluated, the best method is a simple include of a generated file

Usage example:

use Tale\Jade\Compiler;

$compiler = new Compiler();

$phtml = $compiler->compile($jadeInput);
//or
$phtml = $compiler->compileFile($jadeFilePath);

There are different approachs to handle the compiled PHTML. The best and most explaining one is saving the PHTML to a file and including it like this:

file_put_contents('rendered.phtml', $phtml);

//Define some variables to pass to our template $variables = [ 'title' => 'My Page Title!', 'posts' => [] ];

//Make sure the variables are accessible by the included template extract($variables);

//Compiler needs an $args variable to pass arguments on to mixins $args = $variables;

//Include the rendered PHTML directly include('rendered.phtml');

You may fetch the included content with ob_start() and ob_get_clean() and pass it on to anything, e.g. a cache handler or return it as an AJAX response.

Summary

Methods
Properties
Constants
__construct()
getOptions()
getLexer()
getParser()
addPath()
addFilter()
compile()
compileFile()
resolvePath()
buildValue()
buildDataValue()
buildStyleValue()
buildClassValue()
isNullOrFalse()
isArrayNullOrFalse()
isObjectOrArray()
flatten()
No public properties found
MODE_HTML
MODE_XML
isScalar()
compileScalar()
isVariable()
interpolate()
newLine()
indent()
createCode()
createShortCode()
createPhpComment()
createMarkupComment()
compileNode()
compileDocument()
compileDoctype()
handleImports()
handleImport()
handleBlocks()
handleBlock()
handleMixins()
handleMixin()
compileMixins()
compileMixinCall()
compileBlock()
compileConditional()
compileCase()
compileWhen()
compileEach()
compileWhile()
compileDo()
compileFilter()
compileChildren()
compileElement()
compileText()
compileExpression()
compileComment()
compileErrorHandlerHelper()
throwException()
No protected properties found
N/A
No private methods found
$_options
$_lexer
$_parser
$_files
$_mixins
$_calledMixins
$_blocks
$_level
N/A

Constants

MODE_HTML

MODE_HTML

The Mode for HTML.

Recognizes self-closing tags, self-repeating attributes etc.

MODE_XML

MODE_XML

The Mode of XML.

Doesn't do whatever MODE_HTML does

Properties

$_options

$_options : array

An array of options.

Type

array

$_lexer

$_lexer : \Tale\Jade\Lexer

The lexer that is given to the parser.

Type

\Tale\Jade\Lexer

$_parser

$_parser : \Tale\Jade\Parser

The parse this compiler instance gets its nodes off.

Type

\Tale\Jade\Parser

$_files

$_files : array<mixed,string>

The current file stack.

The bottom file is the file that is currently compiled. This is needed for recursive path resolving in imports

Type

array<mixed,string>

$_mixins

$_mixins : array

The mixins we found in the whole input.

We use this to check if a mixin exists upon call and to compile them all at the and (with checking, if they are even called)

The array looks like this:

[ ['node' => Node, 'phtml' => ], ['node' => Node, 'phtml' => ], ['node' => Node, 'phtml' => ] ]

Keys are the name of the mixin

Type

array

$_calledMixins

$_calledMixins : array<mixed,string>

A stack of names of the mixins we actually called in the code.

Type

array<mixed,string>

$_blocks

$_blocks : array<mixed,\Tale\Jade\Parser\Node>

A list of all blocks in our whole input.

They are only used in handleBlocks and handleBlock

Type

array<mixed,\Tale\Jade\Parser\Node>

$_level

$_level : integer

The level we're currently in.

This doesn't equal the current level in the parser or lexer, it rather represents the current indentation level for pretty compiling

Type

integer

Methods

__construct()

__construct(array|null  $options = null, \Tale\Jade\Parser|null  $parser = null, \Tale\Jade\Lexer|null  $lexer = null) 

Creates a new compiler instance.

You can pass a modified parser or lexer. Notice that if you pass both, the lexer inside the parser will be used.

Valid options are:

pretty: Use indentation and new-lines or compile everything into a single line indentStyle: The character that is used for indentation (Space by default) indentWidth: The amount of characters to repeat for indentation (Default 2 for 2-space-indentation) mode: Compile in HTML or XML mode selfClosingTags: The tags that don't need any closing in HTML-style languages selfRepeatingAttributes: The attributes that repeat their value to set them to true in HTML-style languages doctypes: The different doctypes you can use via the "doctype"-directive [name => doctype-string] filters: The different filters you can use via the ":"-directive [name => callback] filterMap: The extension-to-filter-map for include-filters [extension => filter] escapeSequences: The escape-sequences that are possible in scalar strings handleErrors: Should the error-handler-helper be appended to the PTHML or not compileUncalledMixins: Always compile all mixins or leave out those that aren't called? allowImports: Set to false to disable imports for this compiler instance. Importing will throw an exception. Great for demo-pages defaultTag: The tag to default to for class/id/attribute-initiated elements (.abc, #abc, (abc)) quoteStyle: The quote-style in the markup (default: ") replaceMixins: Replaces mixins from top to bottom if they have the same name. Allows duplicated mixin names. paths: The paths to resolve paths in. If none set, it will default to get_include_path() extension: The extension for Jade files (default: .jade), .jd is pretty cool as an example parserOptions: The options for the parser if none given lexerOptions: The options for the lexer if none given.

Parameters

array|null $options

an array of options

\Tale\Jade\Parser|null $parser

an existing parser instance

\Tale\Jade\Lexer|null $lexer

an existing lexer instance

getOptions()

getOptions() : array

Returns the current options for the parser.

Returns

array

getLexer()

getLexer() : \Tale\Jade\Lexer

Returns the current lexer used.

Returns

\Tale\Jade\Lexer

getParser()

getParser() : \Tale\Jade\Parser

Returns the current parser used.

Returns

\Tale\Jade\Parser

addPath()

addPath(string  $path) : $this

Adds a path to the compiler.

Files will be loaded from this path (or other paths you added before)

Parameters

string $path

the directory path

Returns

$this

addFilter()

addFilter(string  $name, callable  $callback) : $this

Adds a filter to the compiler.

This filter can then be used inside jade with the : directive

The callback should have the following signature: (\Tale\Jade\Parser\Node $node, $indent, $newLine) where $node is the filter-Node found, $indent is the current indentation respecting level and pretty-option and newLine is a new-line respecting the pretty-option

It should return either a PHTML string or a Node-instance

Parameters

string $name

the name of the filter

callable $callback

the filter handler callback

Returns

$this

compile()

compile(string  $input, string|null  $path = null) : mixed|string

Compiles a Jade-string to PHTML.

The result can then be evaluated, the best method is a simple PHP include

Look at Renderer to get this done for you

Before evaluating you should set a $__args variable that will be passed through mixins. It like a global scope.

If you give it a path, the directory of that path will be used for relative includes.

Parameters

string $input

the jade input string

string|null $path

the path for relative includes

Throws

\Tale\Jade\Compiler\Exception

when the compilation fails

\Tale\Jade\Parser\Exception

when the parsing fails

\Tale\Jade\Lexer\Exception

when the lexing fails

Returns

mixed|string —

a PHTML string containing HTML and PHP

compileFile()

compileFile(string  $path) : mixed|string

Compiles a file to PHTML.

The given path will automatically passed as compile()'s $path argument

The path should always be relative to the paths-option paths

Parameters

string $path

the path to the jade file

Throws

\Exception

when the file is not found

\Tale\Jade\Compiler\Exception

when the compilation fails

\Tale\Jade\Parser\Exception

when the parsing fails

\Tale\Jade\Lexer\Exception

when the lexing fails

Returns

mixed|string —

the compiled PHTML

resolvePath()

resolvePath(string  $path, null  $extension = null) : string|false

Resolves a path respecting the paths given in the options.

The final paths for resolving are put together as follows:

when paths options not empty => Add paths of paths-option when paths option empty => Add paths of get_include_path() when current file stack not empty => Add directory of last file we were compiling

We then look for a path with the given extension inside all paths we work on currently

Parameters

string $path

the relative path to resolve

null $extension

the extension to resolve with

Returns

string|false —

the resolved full path or false, if not found

buildValue()

buildValue(mixed  $value, string  $quoteStyle, boolean  $escaped) : string

Builds an attribute or argument value.

Objects get converted to arrays Arrays will be imploded by '' (values are concatenated)

['a', 'b', ['c', ['d']]] will become 'abcd'

The result will be enclosed by the quotes passed to $quoteStyle

Parameters

mixed $value

The value to build

string $quoteStyle

The quoting style to use

boolean $escaped

Escape the value or not

Returns

string —

The built value

buildDataValue()

buildDataValue(mixed  $value, string  $quoteStyle, boolean  $escaped) : string

Builds a data-attribute value.

If it's an object or an array, it gets converted to JSON automatically If not, the value stays scalar

JSON will automatically be enclosed by ', other results will use $quoteStyle respectively

'a' will become 'a'

['a', 'b'] will become '["a", "b"]' (JSON)

Parameters

mixed $value

The value to build

string $quoteStyle

The quoting style to use

boolean $escaped

Escape the value or not

Returns

string —

The built value

buildStyleValue()

buildStyleValue(mixed  $value, string  $quoteStyle) : string

Builds a style-attribute string from a value.

['color' => 'red', 'width: 100%', ['height' => '20px']] will become 'color: red; width: 100%; height: 20px;'

Parameters

mixed $value

The value to build

string $quoteStyle

The quoting style to use

Returns

string —

The built value

buildClassValue()

buildClassValue(mixed  $value, string  $quoteStyle) : string

Builds a class-attribute string from a value.

['a', 'b', ['c', ['d', 'e']]] will become 'a b c d e'

Parameters

mixed $value

The value to build

string $quoteStyle

The quoting style to use

Returns

string —

The built value

isNullOrFalse()

isNullOrFalse(mixed  $value) : boolean

Checks if a value is _exactly_ either null or false.

Parameters

mixed $value

The value to check

Returns

boolean

isArrayNullOrFalse()

isArrayNullOrFalse(array  $value) : boolean

Checks if a whole array is _exactly_ null or false.

Not the array itself, but all values in the array

Parameters

array $value

The array to check

Returns

boolean

isObjectOrArray()

isObjectOrArray(mixed  $value) : boolean

Checks if a value is either an object or an array.

Kind of like !isScalar && !isExpression

Parameters

mixed $value

The value to check

Returns

boolean

flatten()

flatten(array  $array, string  $separator = ' ', string  $argSeparator = '=') : string

Flattens an array and combines found values with $separator.

If there are string-keys and an $argSeparator is set, it will also implode those to to a single value

With the default options ['a', 'b' => 'c', ['d', 'e' => 'f', ['g' => 'h']]] will become 'a b=c d e=f g=h'

Parameters

array $array

The array to flatten

string $separator

The separator to implode pairs with

string $argSeparator

The separator to implode keys and values with

Returns

string —

The compiled string

isScalar()

isScalar(string  $value) : boolean

Checks if a variable is scalar (or "not an expression").

These values don't get much special handling, they are mostly simple attributes values like type="button" or method='post'

A scalar value is either a closed string containing only a-z, A-Z, 0-9, _ and -, e.g. Some-Static_Value or a quote-enclosed string that can contain anything except the quote style it used e.g. "Some Random String", 'This can" contain quotes"'

Parameters

string $value

the value to be checked

Returns

boolean

compileScalar()

compileScalar(string  $value, boolean|false  $attribute = false) : string

Compiles and sanitizes a scalar value.

Parameters

string $value

the scalar value

boolean|false $attribute

is this an attribute value or not

Returns

string

isVariable()

isVariable(string  $value) : boolean

Checks if a value is a variable.

A variable needs to start with $. After that only a-z, A-Z and can follow After that you can use any character of a-z, A-Z, 0-9, , [, ], -, >, ' and " This will match all of the following:

$__someVar $obj->someProperty $arr['someKey'] $arr[0] $obj->someArray['someKey'] etc.

Parameters

string $value

the value to be checked

Returns

boolean

interpolate()

interpolate(string  $string, boolean|false  $attribute = false) : string

Interpolates a string value.

Interpolation is initialized with # (escaped) or ! (not escaped)

After that use either {} brackets for variable expressions or [] for Jade-expressions

e.g.

{$someVariable}

!{$someObj->someProperty}

[p This is some paragraph]

If the second paragraph is true, the result will act like it is inside a string respecting the quoteStyle-option

Parameters

string $string

The string to interpolate

boolean|false $attribute

Is this an attribute value or not

Returns

string —

the interpolated PHTML

newLine()

newLine() : string

Returns a new line character respecting the pretty-option.

Returns

string

indent()

indent(integer  $offset) : string

Returns indentation respecting the current level and the pretty-option.

The $offset will be added to the current level

Parameters

integer $offset

an offset added to the level

Returns

string

createCode()

createCode(string  $code, string  $prefix = '<?php ', string  $suffix = '?>') : string

Creates a PHP code expression.

By default it will have <?php ? >-style

Parameters

string $code

the PHP code

string $prefix

the PHP start tag

string $suffix

the PHP end tag

Returns

string —

the PHP expression

createShortCode()

createShortCode(string  $code) : string

Creates a <?=?>-style PHP expression.

Parameters

string $code

the PHP expression to output

Returns

string —

The PHP expression

createPhpComment()

createPhpComment(string  $text) : string

Creates a PHP comment surrounded by PHP code tags.

This creates a "hidden" comment thats still visible in the PHTML

Parameters

string $text

the text to wrap into a comment

Returns

string —

the compiled PHP comment

createMarkupComment()

createMarkupComment(string  $text) : string

Creates a XML-style comment (<!-- -->).

Parameters

string $text

the text to wrap into a comment

Returns

string —

the compiled XML comment

compileNode()

compileNode(\Tale\Jade\Parser\Node  $node) : string

Compiles any Node that has a matching method for its type.

e.g. type: document, method: compileDocument type: element, method: compileElement

The result will be PHTML

Parameters

\Tale\Jade\Parser\Node $node

the Node to compile

Throws

\Tale\Jade\Compiler\Exception

when the compilation fails

Returns

string —

the compiled PHTML

compileDocument()

compileDocument(\Tale\Jade\Parser\Node  $node) : string

Compiles a document Node to PHTML.

Parameters

\Tale\Jade\Parser\Node $node

The document-type node

Returns

string —

the compiled PHTML

compileDoctype()

compileDoctype(\Tale\Jade\Parser\Node  $node) : string

Compiles a doctype Node to PHTML.

Parameters

\Tale\Jade\Parser\Node $node

the doctype-type node

Returns

string —

the compiled PHTML

handleImports()

handleImports(\Tale\Jade\Parser\Node  $node) : $this

Collects all imports and handles them via ->handleImport.

Parameters

\Tale\Jade\Parser\Node $node

the root Node to search imports in

Throws

\Tale\Jade\Compiler\Exception

when the allowImports-options is set to false

Returns

$this

handleImport()

handleImport(\Tale\Jade\Parser\Node  $node) : $this

Loads an imported file and merges the nodes with the current tree.

Parameters

\Tale\Jade\Parser\Node $node

the node to import

Throws

\Tale\Jade\Compiler\Exception

Returns

$this

handleBlocks()

handleBlocks(\Tale\Jade\Parser\Node  $node) : $this

Collects all blocks and saves them into $_blocks.

After that it calls handleBlock on each $block

Parameters

\Tale\Jade\Parser\Node $node

the node to search blocks in

Returns

$this

handleBlock()

handleBlock(\Tale\Jade\Parser\Node  $node) : $this

Stacks blocks into each other.

The first block found is always the container, all other blocks either to append, replace or prepend to/the first block.

Parameters

\Tale\Jade\Parser\Node $node

the block node to handle

Returns

$this

handleMixins()

handleMixins(\Tale\Jade\Parser\Node  $node) : $this

Finds all mixins and loops them through handleMixin.

Duplicated mixins will throw an exception if the replaceMixins-options is false

Parameters

\Tale\Jade\Parser\Node $node

the node to search mixins in

Throws

\Tale\Jade\Compiler\Exception

when a mixin name occurs twice and replaceMixins is false

Returns

$this

handleMixin()

handleMixin(\Tale\Jade\Parser\Node  $node) : $this

Pre-compiles a mixin into the $_mixin array.

Only the block content of the mixin will be compiled, not the mixin itself

The actual mixins get compiled in compileMixins

Parameters

\Tale\Jade\Parser\Node $node

the mixin node to compile

Returns

$this

compileMixins()

compileMixins() : string

Compiles found mixins under each other into a single PHTML block.

Mixins will be anonymous functions inside a $mixins array The mixins also pass the global $args variable on (so that it is global)

Returns

string —

The compile PHTML

compileMixinCall()

compileMixinCall(\Tale\Jade\Parser\Node  $node) : string

Compiles a mixin call referencing the mixins in $_mixins.

Parameters

\Tale\Jade\Parser\Node $node

the mixin call node to compile

Throws

\Tale\Jade\Compiler\Exception

when the called mixin doesnt exist in this instance

Returns

string —

The compiled PHTML

compileBlock()

compileBlock(\Tale\Jade\Parser\Node  $node) : string

Compiles a block node into PHTML.

A single block node without a name or mode will act as a wrapper for blocks inside mixins

Parameters

\Tale\Jade\Parser\Node $node

the block node to compile

Returns

string —

The compiled PHTML

compileConditional()

compileConditional(\Tale\Jade\Parser\Node  $node) : string

Compiles a conditional, either if, elseif, else if or else into PHTML.

Parameters

\Tale\Jade\Parser\Node $node

the conditional node to compile

Returns

string —

The compiled PHTML

compileCase()

compileCase(\Tale\Jade\Parser\Node  $node) : string

Compiles a case-node into PHTML.

This also checks if all sub-nodes of the case are when-children, nothing else is allowed

compileCase interacts with compileWhen to skip ?><?php after the switch {

Parameters

\Tale\Jade\Parser\Node $node

the case node to compile

Throws

\Tale\Jade\Compiler\Exception

Returns

string —

The compiled PHTML

compileWhen()

compileWhen(\Tale\Jade\Parser\Node  $node) : string

Compiles a when-node into PHTML.

This also checks, if the when node is defined on a case-parent

When interacts with compileCase to skip the first ?><?php after the switch{

Parameters

\Tale\Jade\Parser\Node $node

the when-node to compile

Throws

\Tale\Jade\Compiler\Exception

Returns

string —

The compiled PHTML

compileEach()

compileEach(\Tale\Jade\Parser\Node  $node) : string

Compiles a each-instruction into a foreach-loop PHTML block.

the $ in the variable names are optional

Parameters

\Tale\Jade\Parser\Node $node

the each-node to compile

Returns

string —

The compiled PHTML

compileWhile()

compileWhile(\Tale\Jade\Parser\Node  $node) : string

Compiles a while-loop into PHTML.

Notice that if it has no children, we assume it's a do/while loop and don't print brackets

Parameters

\Tale\Jade\Parser\Node $node

the while-node to compile

Returns

string —

The compiled PHTML

compileDo()

compileDo(\Tale\Jade\Parser\Node  $node) : string

Compiles a do-instruction into PHTML.

Parameters

\Tale\Jade\Parser\Node $node

the do-node to compile

Throws

\Tale\Jade\Compiler\Exception

Returns

string —

The compiled PHTML

compileFilter()

compileFilter(\Tale\Jade\Parser\Node  $node) : string

Compiles a filter-node intp PHTML.

The filters are drawn from the filters-option

Parameters

\Tale\Jade\Parser\Node $node

the filter node to compile

Throws

\Tale\Jade\Compiler\Exception

Returns

string —

The compiled PHTML

compileChildren()

compileChildren(array<mixed,\Tale\Jade\Parser\Node>  $nodes, boolean|true  $indent = true, boolean|false  $allowInline = false) : string

Compiles an array of nodes like they are children of some other node.

if $indent is true, the level will be increased

Parameters

array<mixed,\Tale\Jade\Parser\Node> $nodes
boolean|true $indent
boolean|false $allowInline

Returns

string

compileElement()

compileElement(\Tale\Jade\Parser\Node  $node) : string

Compiles an element-node containing a tag, attributes and assignments.

Parameters

\Tale\Jade\Parser\Node $node

the element node to compile

Returns

string —

The compiled PHTML

compileText()

compileText(\Tale\Jade\Parser\Node  $node) : string

Compiles a text-node to PTHML.

Texts get interpolated

Parameters

\Tale\Jade\Parser\Node $node

the text-node to compile

Returns

string —

The compiled PHTML

compileExpression()

compileExpression(\Tale\Jade\Parser\Node  $node) : string

Compiles an expression node and it's descending text nodes into a single PHP expression.

Parameters

\Tale\Jade\Parser\Node $node

the expression node to compile

Returns

string

compileComment()

compileComment(\Tale\Jade\Parser\Node  $node) : string

Compiles a comment-node based on if its rendered or not.

If it's rendered, it will be compiled as a HTML-comment, if not it will be compiled as a hidden PHP comment

Parameters

\Tale\Jade\Parser\Node $node

the comment-node to compile

Returns

string —

The compiled PHTML

compileErrorHandlerHelper()

compileErrorHandlerHelper() : string

Compiles a simple error helper in a string to be prepended to the final PHTML.

Returns

string —

The compiled PHTML for the error handler

throwException()

throwException(string  $message, \Tale\Jade\Parser\Node|null  $relatedNode = null) 

Throws a Compiler-Exception.

Parameters

string $message

A meaningful exception message

\Tale\Jade\Parser\Node|null $relatedNode

The node the exception occured on

Throws

\Tale\Jade\Compiler\Exception