/** * Constructor * * @param string $markup * @param array $tokens * @param FileSystem $fileSystem * * @throws \Liquid\LiquidException */ public function __construct($markup, array &$tokens, FileSystem $fileSystem = null) { $syntaxRegexp = new Regexp('/(\\w+)\\s*=\\s*(' . Liquid::get('QUOTED_FRAGMENT') . '+)/'); $filterSeperatorRegexp = new Regexp('/' . Liquid::get('FILTER_SEPARATOR') . '\\s*(.*)/'); $filterSplitRegexp = new Regexp('/' . Liquid::get('FILTER_SEPARATOR') . '/'); $filterNameRegexp = new Regexp('/\\s*(\\w+)/'); $filterArgumentRegexp = new Regexp('/(?:' . Liquid::get('FILTER_ARGUMENT_SEPARATOR') . '|' . Liquid::get('ARGUMENT_SEPARATOR') . ')\\s*(' . Liquid::get('QUOTED_FRAGMENT') . ')/'); $this->filters = array(); if ($filterSeperatorRegexp->match($markup)) { $filters = $filterSplitRegexp->split($filterSeperatorRegexp->matches[1]); foreach ($filters as $filter) { $filterNameRegexp->match($filter); $filtername = $filterNameRegexp->matches[1]; $filterArgumentRegexp->matchAll($filter); $matches = Liquid::arrayFlatten($filterArgumentRegexp->matches[1]); array_push($this->filters, array($filtername, $matches)); } } if ($syntaxRegexp->match($markup)) { $this->to = $syntaxRegexp->matches[1]; $this->from = $syntaxRegexp->matches[2]; } else { throw new LiquidException("Syntax Error in 'assign' - Valid syntax: assign [var] = [source]"); } }
/** * Constructor * * @param string $markup * @param array $tokens * @param FileSystem $fileSystem * * @throws \Liquid\LiquidException */ public function __construct($markup, array &$tokens, FileSystem $fileSystem = null) { $syntax = new Regexp("/(" . Liquid::get('ALLOWED_VARIABLE_CHARS') . "+)/"); if ($syntax->match($markup)) { $this->toDecrement = $syntax->matches[0]; } else { throw new LiquidException("Syntax Error in 'decrement' - Valid syntax: decrement [var]"); } }
/** * Constructor * * @param string $markup * @param Array $tokens * @param FileSystem $fileSystem * * @throws \Liquid\LiquidException * @return \Liquid\Tag\TagBlock */ public function __construct($markup, array &$tokens, FileSystem $fileSystem = null) { $syntaxRegexp = new Regexp('/(\\w+)/'); if ($syntaxRegexp->match($markup)) { $this->block = $syntaxRegexp->matches[1]; parent::__construct($markup, $tokens, $fileSystem); } else { throw new LiquidException("Syntax Error in 'block' - Valid syntax: block [name]"); } }
/** * Constructor * * @param string $markup * @param array $tokens * @param FileSystem $fileSystem * * @throws \Liquid\LiquidException * */ public function __construct($markup, array &$tokens, FileSystem $fileSystem = null) { parent::__construct($markup, $tokens, $fileSystem); $syntax = new Regexp('/(' . Liquid::get('ALLOWED_VARIABLE_CHARS') . '+)\\s+by\\s+(\\w+)/'); if ($syntax->match($markup)) { $this->collectionName = $syntax->matches[1]; $this->numberItems = $syntax->matches[2]; $this->extractAttributes($markup); } else { throw new LiquidException("Syntax Error - Valid syntax: paginate [collection] by [items]"); } }
/** * Constructor * * @param string $markup * @param array $tokens * @param FileSystem $fileSystem * * @throws \Liquid\LiquidException */ public function __construct($markup, array &$tokens, FileSystem $fileSystem = null) { parent::__construct($markup, $tokens, $fileSystem); $syntax = new Regexp("/(\\w+)\\s+in\\s+(" . Liquid::get('ALLOWED_VARIABLE_CHARS') . "+)/"); if ($syntax->match($markup)) { $this->variableName = $syntax->matches[1]; $this->collectionName = $syntax->matches[2]; $this->extractAttributes($markup); } else { throw new LiquidException("Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"); } }
/** * Constructor * * @param string $markup * @param array $tokens * @param FileSystem $fileSystem * * @throws \Liquid\LiquidException */ public function __construct($markup, array &$tokens, FileSystem $fileSystem = null) { parent::__construct($markup, $tokens, $fileSystem); $syntaxRegexp = new Regexp('/(\\w+)\\s+in\\s+(' . Liquid::get('ALLOWED_VARIABLE_CHARS') . '+)/'); if ($syntaxRegexp->match($markup)) { $this->variableName = $syntaxRegexp->matches[1]; $this->collectionName = $syntaxRegexp->matches[2]; $this->name = $syntaxRegexp->matches[1] . '-' . $syntaxRegexp->matches[2]; $this->extractAttributes($markup); } else { throw new LiquidException("Syntax Error in 'for loop' - Valid syntax: for [item] in [collection]"); } }
/** * Constructor * * @param string $markup * @param array $tokens * @param FileSystem $fileSystem * * @throws \Liquid\LiquidException */ public function __construct($markup, array &$tokens, FileSystem $fileSystem = null) { $regex = new Regexp('/("[^"]+"|\'[^\']+\')(\\s+(with|for)\\s+(' . Liquid::get('QUOTED_FRAGMENT') . '+))?/'); if ($regex->match($markup)) { $this->templateName = substr($regex->matches[1], 1, strlen($regex->matches[1]) - 2); if (isset($regex->matches[1])) { $this->collection = isset($regex->matches[3]) ? $regex->matches[3] == "for" : null; $this->variable = isset($regex->matches[4]) ? $regex->matches[4] : null; } $this->extractAttributes($markup); } else { throw new LiquidException("Error in tag 'include' - Valid syntax: include '[template]' (with|for) [object|collection]"); } parent::__construct($markup, $tokens, $fileSystem); }
/** * @param array $tokens */ public function parse(array &$tokens) { $tagRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '\\s*(\\w+)\\s*(.*)?' . Liquid::get('TAG_END') . '$/'); $this->nodelist = array(); if (!is_array($tokens)) { return; } while (count($tokens)) { $token = array_shift($tokens); if ($tagRegexp->match($token)) { // If we found the proper block delimitor just end parsing here and let the outer block proceed if ($tagRegexp->matches[1] == $this->blockDelimiter()) { return; } } $this->nodelist[] = $token; } }
/** * Render the tag * * @param Context $context * * @throws \Liquid\LiquidException * @return string */ public function render(Context $context) { $context->push(); $logicalRegex = new Regexp('/\\s+(and|or)\\s+/'); $conditionalRegex = new Regexp('/(' . Liquid::get('QUOTED_FRAGMENT') . ')\\s*([=!<>a-z_]+)?\\s*(' . Liquid::get('QUOTED_FRAGMENT') . ')?/'); $result = ''; foreach ($this->blocks as $block) { if ($block[0] == 'else') { $result = $this->renderAll($block[2], $context); break; } if ($block[0] == 'if' || $block[0] == 'elsif') { // Extract logical operators $logicalRegex->matchAll($block[1]); $logicalOperators = $logicalRegex->matches; $logicalOperators = $logicalOperators[1]; // Extract individual conditions $temp = $logicalRegex->split($block[1]); $conditions = array(); foreach ($temp as $condition) { if ($conditionalRegex->match($condition)) { $left = isset($conditionalRegex->matches[1]) ? $conditionalRegex->matches[1] : null; $operator = isset($conditionalRegex->matches[2]) ? $conditionalRegex->matches[2] : null; $right = isset($conditionalRegex->matches[3]) ? $conditionalRegex->matches[3] : null; array_push($conditions, array('left' => $left, 'operator' => $operator, 'right' => $right)); } else { throw new LiquidException("Syntax Error in tag 'if' - Valid syntax: if [condition]"); } } if (count($logicalOperators)) { // If statement contains and/or $display = $this->interpretCondition($conditions[0]['left'], $conditions[0]['right'], $conditions[0]['operator'], $context); foreach ($logicalOperators as $k => $logicalOperator) { if ($logicalOperator == 'and') { $display = $display && $this->interpretCondition($conditions[$k + 1]['left'], $conditions[$k + 1]['right'], $conditions[$k + 1]['operator'], $context); } else { $display = $display || $this->interpretCondition($conditions[$k + 1]['left'], $conditions[$k + 1]['right'], $conditions[$k + 1]['operator'], $context); } } } else { // If statement is a single condition $display = $this->interpretCondition($conditions[0]['left'], $conditions[0]['right'], $conditions[0]['operator'], $context); } if ($display) { $result = $this->renderAll($block[2], $context); break; } } } $context->pop(); return $result; }
/** * Unknown tag handler * * @param string $tag * @param string $params * @param array $tokens * * @throws \Liquid\LiquidException */ public function unknownTag($tag, $params, array $tokens) { $whenSyntaxRegexp = new Regexp('/' . Liquid::get('QUOTED_FRAGMENT') . '/'); switch ($tag) { case 'when': // push the current nodelist onto the stack and prepare for a new one if ($whenSyntaxRegexp->match($params)) { $this->pushNodelist(); $this->right = $whenSyntaxRegexp->matches[0]; $this->nodelist = array(); } else { throw new LiquidException("Syntax Error in tag 'case' - Valid when condition: when [condition]"); // harry } break; case 'else': // push the last nodelist onto the stack and prepare to recieve the else nodes $this->pushNodelist(); $this->right = null; $this->elseNodelist =& $this->nodelist; $this->nodelist = array(); break; default: parent::unknownTag($tag, $params, $tokens); } }
/** * Extract variables from a string of markup * * @param string $markup * * @return array; */ private function variablesFromString($markup) { $regexp = new Regexp('/\\s*(' . Liquid::get('QUOTED_FRAGMENT') . ')\\s*/'); $parts = explode(',', $markup); $result = array(); foreach ($parts as $part) { $regexp->match($part); if (!empty($regexp->matches[1])) { $result[] = $regexp->matches[1]; } } return $result; }
/** * Parses the tokens * * @param array $tokens * * @throws \Liquid\LiquidException */ public function parse(array &$tokens) { if ($this->fileSystem === null) { throw new LiquidException("No file system"); } // read the source of the template and create a new sub document $source = $this->fileSystem->readTemplateFile($this->templateName); // tokens in this new document $maintokens = Template::tokenize($source); $eRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '\\s*extends (.*)?' . Liquid::get('TAG_END') . '$/'); foreach ($maintokens as $maintoken) { if ($eRegexp->match($maintoken)) { $m = $eRegexp->matches[1]; break; } } if (isset($m)) { $rest = array_merge($maintokens, $tokens); } else { $childtokens = $this->findBlocks($tokens); $blockstartRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '\\s*block (\\w+)\\s*(.*)?' . Liquid::get('TAG_END') . '$/'); $blockendRegexp = new Regexp('/^' . Liquid::get('TAG_START') . '\\s*endblock\\s*?' . Liquid::get('TAG_END') . '$/'); $name = null; $rest = array(); $aufzeichnen = false; for ($i = 0; $i < count($maintokens); $i++) { if ($blockstartRegexp->match($maintokens[$i])) { $name = $blockstartRegexp->matches[1]; if (isset($childtokens[$name])) { $aufzeichnen = true; array_push($rest, $maintokens[$i]); foreach ($childtokens[$name] as $item) { array_push($rest, $item); } } } if (!$aufzeichnen) { array_push($rest, $maintokens[$i]); } if ($blockendRegexp->match($maintokens[$i]) && $aufzeichnen === true) { $aufzeichnen = false; array_push($rest, $maintokens[$i]); } } } $this->hash = md5($source); $cache = Template::getCache(); if (isset($cache)) { if (($this->document = $cache->read($this->hash)) != false && $this->document->checkIncludes() != true) { } else { $this->document = new Document($rest, $this->fileSystem); $cache->write($this->hash, $this->document); } } else { $this->document = new Document($rest, $this->fileSystem); } }