2x faster. Who needs a Buffer instance, anyway?
This commit is contained in:
@@ -1,138 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Mustache.php.
|
|
||||||
*
|
|
||||||
* (c) 2012 Justin Hileman
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Mustache;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mustache output Buffer class.
|
|
||||||
*
|
|
||||||
* Buffer instances are used by Mustache Templates for collecting output during rendering
|
|
||||||
*/
|
|
||||||
class Buffer {
|
|
||||||
private $buffer = '';
|
|
||||||
private $indent = '';
|
|
||||||
private $charset = 'UTF-8';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mustache Buffer constructor.
|
|
||||||
*
|
|
||||||
* @param string $indent Initial indent level for all lines of this buffer (default: '')
|
|
||||||
* @param string $charset Override the character set used by `htmlspecialchars()` (default: 'UTF-8')
|
|
||||||
*/
|
|
||||||
public function __construct($indent = null, $charset = null) {
|
|
||||||
if ($indent !== null) {
|
|
||||||
$this->setIndent($indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($charset !== null) {
|
|
||||||
$this->charset = $charset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current indent level.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getIndent() {
|
|
||||||
return $this->indent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the buffer indent level.
|
|
||||||
*
|
|
||||||
* Each line output by this buffer will be prefixed by this whitespace. This is used when rendering
|
|
||||||
* partials and Lambda sections.
|
|
||||||
*
|
|
||||||
* @param string $indent
|
|
||||||
*/
|
|
||||||
public function setIndent($indent) {
|
|
||||||
$this->indent = $indent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the character set used when escaping values.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getCharset() {
|
|
||||||
return $this->charset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a newline to the Buffer.
|
|
||||||
*/
|
|
||||||
public function writeLine() {
|
|
||||||
$this->buffer .= "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Output text to the Buffer.
|
|
||||||
*
|
|
||||||
* @see \Mustache\Buffer::write
|
|
||||||
*
|
|
||||||
* @param string $text
|
|
||||||
* @param bool $escape Escape this text with `htmlspecialchars()`? (default: false)
|
|
||||||
*/
|
|
||||||
public function writeText($text, $escape = false) {
|
|
||||||
$this->write($text, true, $escape);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add output to the Buffer.
|
|
||||||
*
|
|
||||||
* @param string $text
|
|
||||||
* @param bool $indent Indent this line? (default: false)
|
|
||||||
* @param bool $escape Escape this text with `htmlspecialchars()`? (default: false)
|
|
||||||
*/
|
|
||||||
public function write($text, $indent = false, $escape = false) {
|
|
||||||
$text = (string) $text;
|
|
||||||
|
|
||||||
if ($escape) {
|
|
||||||
$text = $this->escape($text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($indent) {
|
|
||||||
$this->buffer .= $this->indent . $text;
|
|
||||||
} else {
|
|
||||||
$this->buffer .= $text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush the contents of the Buffer.
|
|
||||||
*
|
|
||||||
* Resets the buffer and returns the current contents.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function flush() {
|
|
||||||
$buffer = $this->buffer;
|
|
||||||
$this->buffer = '';
|
|
||||||
|
|
||||||
return $buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to escape text.
|
|
||||||
*
|
|
||||||
* Uses the Buffer's character set (default 'UTF-8', passed as the second argument to `__construct`).
|
|
||||||
*
|
|
||||||
* @see htmlspecialchars
|
|
||||||
*
|
|
||||||
* @param string $text
|
|
||||||
*
|
|
||||||
* @return string Escaped text
|
|
||||||
*/
|
|
||||||
private function escape($text) {
|
|
||||||
return htmlspecialchars($text, ENT_COMPAT, $this->charset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+22
-16
@@ -109,11 +109,15 @@ class Compiler {
|
|||||||
const KLASS = '<?php
|
const KLASS = '<?php
|
||||||
|
|
||||||
class %s extends \Mustache\Template {
|
class %s extends \Mustache\Template {
|
||||||
public function renderInternal(\Mustache\Context $context, $indent = \'\') {
|
public function renderInternal(\Mustache\Context $context, $indent = \'\', $escape = false) {
|
||||||
$buffer = new \Mustache\Buffer($indent, $this->mustache->getCharset());
|
$buffer = \'\';
|
||||||
%s
|
%s
|
||||||
|
|
||||||
return $buffer->flush();
|
if ($escape) {
|
||||||
|
return htmlspecialchars($buffer, ENT_COMPAT, $this->mustache->getCharset());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $buffer;
|
||||||
}
|
}
|
||||||
%s
|
%s
|
||||||
}';
|
}';
|
||||||
@@ -135,18 +139,17 @@ class Compiler {
|
|||||||
|
|
||||||
const SECTION_CALL = '
|
const SECTION_CALL = '
|
||||||
// %s section
|
// %s section
|
||||||
$this->section%s($buffer, $context, $context->%s(%s));
|
$buffer .= $this->section%s($context, $indent, $context->%s(%s));
|
||||||
';
|
';
|
||||||
|
|
||||||
const SECTION = '
|
const SECTION = '
|
||||||
private function section%s(\Mustache\Buffer $buffer, \Mustache\Context $context, $value) {
|
private function section%s(\Mustache\Context $context, $indent, $value) {
|
||||||
|
$buffer = \'\';
|
||||||
if (!is_string($value) && is_callable($value)) {
|
if (!is_string($value) && is_callable($value)) {
|
||||||
$source = %s;
|
$source = %s;
|
||||||
$buffer->write(
|
$buffer .= $this->mustache
|
||||||
$this->mustache
|
->loadLambda((string) call_user_func($value, $source)%s)
|
||||||
->loadLambda((string) call_user_func($value, $source)%s)
|
->renderInternal($context, $indent);
|
||||||
->renderInternal($context, $buffer->getIndent())
|
|
||||||
);
|
|
||||||
} elseif (!empty($value)) {
|
} elseif (!empty($value)) {
|
||||||
$values = $this->isIterable($value) ? $value : array($value);
|
$values = $this->isIterable($value) ? $value : array($value);
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
@@ -154,6 +157,8 @@ class Compiler {
|
|||||||
$context->pop();
|
$context->pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $buffer;
|
||||||
}';
|
}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -212,7 +217,7 @@ class Compiler {
|
|||||||
return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $this->walk($nodes, $level));
|
return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $this->walk($nodes, $level));
|
||||||
}
|
}
|
||||||
|
|
||||||
const PARTIAL = '$buffer->write($this->mustache->loadPartial(%s)->renderInternal($context, %s));';
|
const PARTIAL = '$buffer .= $this->mustache->loadPartial(%s)->renderInternal($context, %s);';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate Mustache Template partial call PHP source.
|
* Generate Mustache Template partial call PHP source.
|
||||||
@@ -236,10 +241,11 @@ class Compiler {
|
|||||||
if (!is_string($value) && is_callable($value)) {
|
if (!is_string($value) && is_callable($value)) {
|
||||||
$value = $this->mustache
|
$value = $this->mustache
|
||||||
->loadLambda((string) call_user_func($value))
|
->loadLambda((string) call_user_func($value))
|
||||||
->renderInternal($context, $buffer->getIndent());
|
->renderInternal($context, $indent);
|
||||||
}
|
}
|
||||||
$buffer->writeText($value, %s);
|
$buffer .= $indent . %s;
|
||||||
';
|
';
|
||||||
|
const VARIABLE_ESCAPED = 'htmlspecialchars($value, ENT_COMPAT, $this->mustache->getCharset())';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate Mustache Template variable interpolation PHP source.
|
* Generate Mustache Template variable interpolation PHP source.
|
||||||
@@ -253,13 +259,13 @@ class Compiler {
|
|||||||
private function variable($id, $escape, $level) {
|
private function variable($id, $escape, $level) {
|
||||||
$method = $this->getFindMethod($id);
|
$method = $this->getFindMethod($id);
|
||||||
$id = ($method !== 'last') ? var_export($id, true) : '';
|
$id = ($method !== 'last') ? var_export($id, true) : '';
|
||||||
$escape = $escape ? 'true' : 'false';
|
$escape = $escape ? self::VARIABLE_ESCAPED : '$value';
|
||||||
|
|
||||||
return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $escape);
|
return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $escape);
|
||||||
}
|
}
|
||||||
|
|
||||||
const LINE = '$buffer->writeLine();';
|
const LINE = '$buffer .= "\n";';
|
||||||
const TEXT = '$buffer->writeText(%s);';
|
const TEXT = '$buffer .= $indent . %s;';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate Mustache Template output Buffer call PHP source.
|
* Generate Mustache Template output Buffer call PHP source.
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ abstract class Template {
|
|||||||
*
|
*
|
||||||
* @return string Rendered template
|
* @return string Rendered template
|
||||||
*/
|
*/
|
||||||
abstract public function renderInternal(Context $context);
|
abstract public function renderInternal(Context $context, $indent = '', $escape = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests whether a value should be iterated over (e.g. in a section context).
|
* Tests whether a value should be iterated over (e.g. in a section context).
|
||||||
|
|||||||
@@ -1,99 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Mustache.php.
|
|
||||||
*
|
|
||||||
* (c) 2012 Justin Hileman
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Mustache\Test;
|
|
||||||
|
|
||||||
use Mustache\Mustache;
|
|
||||||
use Mustache\Buffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @group unit
|
|
||||||
*/
|
|
||||||
class BufferTest extends \PHPUnit_Framework_TestCase {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider getConstructorArgs
|
|
||||||
*/
|
|
||||||
public function testConstructor($indent, $charset) {
|
|
||||||
$buffer = new Buffer($indent, $charset);
|
|
||||||
$this->assertEquals($indent, $buffer->getIndent());
|
|
||||||
$this->assertEquals($charset, $buffer->getCharset());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getConstructorArgs() {
|
|
||||||
return array(
|
|
||||||
array('', 'UTF-8'),
|
|
||||||
array(' ', 'ISO-8859-1'),
|
|
||||||
array("\t\t\t", 'Shift_JIS'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testWrite() {
|
|
||||||
$buffer = new Buffer;
|
|
||||||
$this->assertEquals('', $buffer->flush());
|
|
||||||
|
|
||||||
$buffer->writeLine();
|
|
||||||
$buffer->writeLine();
|
|
||||||
$buffer->writeLine();
|
|
||||||
$this->assertEquals("\n\n\n", $buffer->flush());
|
|
||||||
$this->assertEquals('', $buffer->flush());
|
|
||||||
|
|
||||||
$buffer->write('foo');
|
|
||||||
$buffer->write('bar');
|
|
||||||
$buffer->writeLine();
|
|
||||||
$buffer->write('baz');
|
|
||||||
$this->assertEquals("foobar\nbaz", $buffer->flush());
|
|
||||||
$this->assertEquals('', $buffer->flush());
|
|
||||||
|
|
||||||
$indent = "\t\t";
|
|
||||||
$buffer->setIndent($indent);
|
|
||||||
$buffer->writeText('foo');
|
|
||||||
$buffer->writeLine();
|
|
||||||
$buffer->writeText('bar');
|
|
||||||
$this->assertEquals("\t\tfoo\n\t\tbar", $buffer->flush());
|
|
||||||
$this->assertEquals('', $buffer->flush());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider getEscapeAndIndent
|
|
||||||
*/
|
|
||||||
public function testEscapingAndIndenting($text, $escape, $indent, $whitespace, $expected) {
|
|
||||||
$buffer = new Buffer;
|
|
||||||
$buffer->setIndent($whitespace);
|
|
||||||
|
|
||||||
$buffer->write($text, $indent, $escape);
|
|
||||||
$this->assertEquals($expected, $buffer->flush());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEscapeAndIndent() {
|
|
||||||
return array(
|
|
||||||
array('> "fun & games" <', false, false, "\t", '> "fun & games" <'),
|
|
||||||
array('> "fun & games" <', true, false, "\t", '> "fun & games" <'),
|
|
||||||
array('> "fun & games" <', true, true, "\t", "\t> "fun & games" <"),
|
|
||||||
array('> "fun & games" <', false, true, "\t", "\t> \"fun & games\" <"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testChangeIndent() {
|
|
||||||
$indent = "\t\t";
|
|
||||||
$buffer = new Buffer($indent);
|
|
||||||
$this->assertEquals($indent, $buffer->getIndent());
|
|
||||||
|
|
||||||
$indent = "";
|
|
||||||
$buffer->setIndent($indent);
|
|
||||||
$this->assertEquals($indent, $buffer->getIndent());
|
|
||||||
|
|
||||||
$indent = " ";
|
|
||||||
$buffer->setIndent($indent);
|
|
||||||
$this->assertEquals($indent, $buffer->getIndent());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -35,13 +35,13 @@ class CompilerTest extends \PHPUnit_Framework_TestCase {
|
|||||||
return array(
|
return array(
|
||||||
array('', array(), 'Banana', array(
|
array('', array(), 'Banana', array(
|
||||||
"\nclass Banana extends \Mustache\Template",
|
"\nclass Banana extends \Mustache\Template",
|
||||||
'$buffer->flush();',
|
'return $buffer;',
|
||||||
)),
|
)),
|
||||||
|
|
||||||
array('', array('TEXT'), 'Monkey', array(
|
array('', array('TEXT'), 'Monkey', array(
|
||||||
"\nclass Monkey extends \Mustache\Template",
|
"\nclass Monkey extends \Mustache\Template",
|
||||||
'$buffer->writeText(\'TEXT\');',
|
'$buffer .= $indent . \'TEXT\';',
|
||||||
'$buffer->flush();',
|
'return $buffer;',
|
||||||
)),
|
)),
|
||||||
|
|
||||||
array(
|
array(
|
||||||
@@ -62,13 +62,13 @@ class CompilerTest extends \PHPUnit_Framework_TestCase {
|
|||||||
'Monkey',
|
'Monkey',
|
||||||
array(
|
array(
|
||||||
"\nclass Monkey extends \Mustache\Template",
|
"\nclass Monkey extends \Mustache\Template",
|
||||||
'$buffer->writeText(\'foo\');',
|
'$buffer .= $indent . \'foo\'',
|
||||||
'$buffer->writeLine();',
|
'$buffer .= "\n"',
|
||||||
'$value = $context->find(\'name\');',
|
'$value = $context->find(\'name\');',
|
||||||
'$buffer->writeText($value, true);',
|
'$buffer .= $indent . htmlspecialchars($value, ENT_COMPAT, $this->mustache->getCharset());',
|
||||||
'$value = $context->last();',
|
'$value = $context->last();',
|
||||||
'$buffer->writeText(\'\\\'bar\\\'\');',
|
'$buffer .= $indent . \'\\\'bar\\\'\';',
|
||||||
'$buffer->flush();',
|
'return $buffer;',
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class TemplateStub extends Template {
|
|||||||
return $this->mustache;
|
return $this->mustache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderInternal(Context $context) {
|
public function renderInternal(Context $context, $indent = '', $escape = false) {
|
||||||
return $this->rendered;
|
return $this->rendered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user