Fix docs, done #2

This commit is contained in:
bzick 2013-07-04 01:28:10 +04:00
parent 4b8b56482c
commit 9600fc78d7
13 changed files with 64 additions and 31 deletions

View File

@ -1,6 +1,17 @@
CHANGELOG
=========
## 1.0.5
### Add `Fenom::AUTO_ESCAPE` support (feature #2)
### Update documentation
## 1.0.4 (2013-06-27)
### Add nested level for {extends} and {use}
### Small bug fix
### Update documentation
## 1.0.3 (2013-06-20)
### Allow any callable for modifier (instead string)

6
docs/develop.md Normal file
View File

@ -0,0 +1,6 @@
Develop
=======
If you want to discuss the enhancement of the Fenom, create an issue on Github or submit a pull request.
For questions: a.cobest@gmail.com (English, Russian languages)

View File

@ -5,6 +5,7 @@ Documentation
* [Install](./install.md)
* [Usage](./usage.md)
* [Develop](./develop.md)
* [Syntax](./syntax.md)
* [Settings](./settings.md)
* [Callbacks and filters](./callbacks.md)

View File

@ -12,6 +12,8 @@ use Fenom\Template,
/**
* Fenom Template Engine
*
* @author Ivan Shalganov <a.cobest@gmail.com>
*/
class Fenom {
const VERSION = '1.0';
@ -24,12 +26,13 @@ class Fenom {
const MODIFIER = 5;
/* Options */
const DENY_METHODS = 0x10;
const DENY_INLINE_FUNCS = 0x20;
const FORCE_INCLUDE = 0x40;
const AUTO_RELOAD = 0x80;
const FORCE_COMPILE = 0xF0;
const DENY_METHODS = 0x10;
const DENY_INLINE_FUNCS = 0x20;
const FORCE_INCLUDE = 0x40;
const AUTO_RELOAD = 0x80;
const FORCE_COMPILE = 0xF0;
const DISABLE_CACHE = 0x1F0;
const AUTO_ESCAPE = 0x200;
/* Default parsers */
const DEFAULT_CLOSE_COMPILER = 'Fenom\Compiler::stdClose';

View File

@ -15,6 +15,7 @@ use Fenom\Scope;
/**
* Compilers collection
* @package Fenom
* @author Ivan Shalganov <a.cobest@gmail.com>
*/
class Compiler {
/**

View File

@ -11,7 +11,7 @@ namespace Fenom;
/**
* Collection of modifiers
*
* @author Ivan Shalganov <a.cobest@gmail.com>
*/
class Modifier {

View File

@ -11,7 +11,7 @@ namespace Fenom;
use Fenom\ProviderInterface;
/**
* Templates provider
* Base template provider
* @author Ivan Shalganov
*/
class Provider implements ProviderInterface {
@ -110,10 +110,14 @@ class Provider implements ProviderInterface {
* @param string $tpl
* @return bool
*/
public function isTemplateExists($tpl) {
public function templateExists($tpl) {
return file_exists($this->_path."/".$tpl);
}
/**
* @param array $tpls
* @return array
*/
public function getLastModifiedBatch($tpls) {
$tpls = array_flip($tpls);
foreach($tpls as $tpl => &$time) {

View File

@ -9,12 +9,17 @@
*/
namespace Fenom;
/**
* Template provider interface
* @package Fenom
* @author Ivan Shalganov <a.cobest@gmail.com>
*/
interface ProviderInterface {
/**
* @param string $tpl
* @return bool
*/
public function isTemplateExists($tpl);
public function templateExists($tpl);
/**
* @param string $tpl
* @param int $time

View File

@ -12,6 +12,7 @@ use Fenom;
/**
* Primitive template
* @author Ivan Shalganov <a.cobest@gmail.com>
*/
class Render extends \ArrayObject {
private static $_props = array(

View File

@ -11,6 +11,8 @@ namespace Fenom;
/**
* Scope for blocks tags
*
* @author Ivan Shalganov <a.cobest@gmail.com>
*/
class Scope extends \ArrayObject {

View File

@ -14,7 +14,7 @@ use Fenom;
* Template compiler
*
* @package Fenom
* @author Ivan Shalganov <owner@bzick.net>
* @author Ivan Shalganov <a.cobest@gmail.com>
*/
class Template extends Render {
@ -391,6 +391,13 @@ class Template extends Render {
return parent::fetch($values);
}
private function _print($data) {
if($this->_options & Fenom::AUTO_ESCAPE) {
return "echo htmlspecialchars($data, ENT_COMPAT, 'UTF-8')";
} else {
return "echo $data";
}
}
/**
* Internal tags router
* @param Tokenizer $tokens
@ -412,9 +419,9 @@ class Template extends Render {
} elseif ($tokens->is('/')) {
return $this->_end($tokens);
} elseif ($tokens->is('#')) {
return "echo ".$this->parseConst($tokens).';';
return $this->_print($this->parseConst($tokens)).';';
} else {
return $code = "echo ".$this->parseExp($tokens).";";
return $code = $this->_print($this->parseExp($tokens)).";";
}
} catch (InvalidUsageException $e) {
throw new CompileException($e->getMessage()." in {$this} line {$this->_line}", 0, E_ERROR, $this->_name, $this->_line, $e);
@ -460,12 +467,12 @@ class Template extends Render {
if($tokens->is(Tokenizer::MACRO_STRING)) {
$action = $tokens->getAndNext();
} else {
return 'echo '.$this->parseExp($tokens).';'; // may be math and/or boolean expression
return $this->_print($this->parseExp($tokens)).';'; // may be math and/or boolean expression
}
if($tokens->is("(", T_NAMESPACE, T_DOUBLE_COLON)) { // just invoke function or static method
$tokens->back();
return "echo ".$this->parseExp($tokens).";";
return $this->_print($this->parseExp($tokens)).";";
} elseif($tokens->is('.')) {
$name = $tokens->skip()->get(Tokenizer::MACRO_STRING);
if($action !== "macro") {
@ -1110,4 +1117,5 @@ class Template extends Render {
class CompileException extends \ErrorException {}
class SecurityException extends CompileException {}
class InvalidUsageException extends \LogicException {}
class InvalidUsageException extends \LogicException {}
class TokenizeException extends \RuntimeException {}

View File

@ -33,6 +33,7 @@ defined('T_YIELD') || define('T_YIELD', 370);
* @property array $next the next token
*
* @package Fenom
* @author Ivan Shalganov <a.cobest@gmail.com>
*/
class Tokenizer {
const TOKEN = 0;
@ -244,13 +245,13 @@ class Tokenizer {
/**
* If the next token is a valid one, move the position of cursor one step forward. Otherwise throws an exception.
* @param array $tokens
* @throws TokenizeException
* @throws UnexpectedTokenException
* @return mixed
*/
public function _next($tokens) {
$this->next();
if(!$this->curr) {
throw new TokenizeException("Unexpected end of expression");
throw new UnexpectedTokenException($this, $tokens);
}
if($tokens) {
if($this->_valid($tokens, $this->key())) {
@ -259,12 +260,7 @@ class Tokenizer {
} else {
return;
}
if(count($tokens) == 1 && is_string($tokens[0])) {
$expect = ", expect '".$tokens[0]."'";
} else {
$expect = "";
}
throw new TokenizeException("Unexpected token '".$this->current()."'$expect");
throw new UnexpectedTokenException($this, $tokens);
}
/**
@ -560,15 +556,10 @@ class Tokenizer {
}
}
/**
* Tokenize error
*/
class TokenizeException extends \RuntimeException {}
/**
* Unexpected token
*/
class UnexpectedTokenException extends TokenizeException {
class UnexpectedTokenException extends \RuntimeException {
public function __construct(Tokenizer $tokens, $expect = null, $where = null) {
if($expect && count($expect) == 1 && is_string($expect[0])) {
$expect = ", expect '".$expect[0]."'";

View File

@ -16,8 +16,8 @@ class FSProviderTest extends \Fenom\TestCase {
}
public function testIsTemplateExists() {
$this->assertTrue($this->provider->isTemplateExists("template1.tpl"));
$this->assertFalse($this->provider->isTemplateExists("unexists.tpl"));
$this->assertTrue($this->provider->templateExists("template1.tpl"));
$this->assertFalse($this->provider->templateExists("unexists.tpl"));
}
public function testGetSource() {