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 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) ## 1.0.3 (2013-06-20)
### Allow any callable for modifier (instead string) ### 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) * [Install](./install.md)
* [Usage](./usage.md) * [Usage](./usage.md)
* [Develop](./develop.md)
* [Syntax](./syntax.md) * [Syntax](./syntax.md)
* [Settings](./settings.md) * [Settings](./settings.md)
* [Callbacks and filters](./callbacks.md) * [Callbacks and filters](./callbacks.md)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,7 +14,7 @@ use Fenom;
* Template compiler * Template compiler
* *
* @package Fenom * @package Fenom
* @author Ivan Shalganov <owner@bzick.net> * @author Ivan Shalganov <a.cobest@gmail.com>
*/ */
class Template extends Render { class Template extends Render {
@ -391,6 +391,13 @@ class Template extends Render {
return parent::fetch($values); 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 * Internal tags router
* @param Tokenizer $tokens * @param Tokenizer $tokens
@ -412,9 +419,9 @@ class Template extends Render {
} elseif ($tokens->is('/')) { } elseif ($tokens->is('/')) {
return $this->_end($tokens); return $this->_end($tokens);
} elseif ($tokens->is('#')) { } elseif ($tokens->is('#')) {
return "echo ".$this->parseConst($tokens).';'; return $this->_print($this->parseConst($tokens)).';';
} else { } else {
return $code = "echo ".$this->parseExp($tokens).";"; return $code = $this->_print($this->parseExp($tokens)).";";
} }
} catch (InvalidUsageException $e) { } catch (InvalidUsageException $e) {
throw new CompileException($e->getMessage()." in {$this} line {$this->_line}", 0, E_ERROR, $this->_name, $this->_line, $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)) { if($tokens->is(Tokenizer::MACRO_STRING)) {
$action = $tokens->getAndNext(); $action = $tokens->getAndNext();
} else { } 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 if($tokens->is("(", T_NAMESPACE, T_DOUBLE_COLON)) { // just invoke function or static method
$tokens->back(); $tokens->back();
return "echo ".$this->parseExp($tokens).";"; return $this->_print($this->parseExp($tokens)).";";
} elseif($tokens->is('.')) { } elseif($tokens->is('.')) {
$name = $tokens->skip()->get(Tokenizer::MACRO_STRING); $name = $tokens->skip()->get(Tokenizer::MACRO_STRING);
if($action !== "macro") { if($action !== "macro") {
@ -1110,4 +1117,5 @@ class Template extends Render {
class CompileException extends \ErrorException {} class CompileException extends \ErrorException {}
class SecurityException extends CompileException {} 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 * @property array $next the next token
* *
* @package Fenom * @package Fenom
* @author Ivan Shalganov <a.cobest@gmail.com>
*/ */
class Tokenizer { class Tokenizer {
const TOKEN = 0; 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. * If the next token is a valid one, move the position of cursor one step forward. Otherwise throws an exception.
* @param array $tokens * @param array $tokens
* @throws TokenizeException * @throws UnexpectedTokenException
* @return mixed * @return mixed
*/ */
public function _next($tokens) { public function _next($tokens) {
$this->next(); $this->next();
if(!$this->curr) { if(!$this->curr) {
throw new TokenizeException("Unexpected end of expression"); throw new UnexpectedTokenException($this, $tokens);
} }
if($tokens) { if($tokens) {
if($this->_valid($tokens, $this->key())) { if($this->_valid($tokens, $this->key())) {
@ -259,12 +260,7 @@ class Tokenizer {
} else { } else {
return; return;
} }
if(count($tokens) == 1 && is_string($tokens[0])) { throw new UnexpectedTokenException($this, $tokens);
$expect = ", expect '".$tokens[0]."'";
} else {
$expect = "";
}
throw new TokenizeException("Unexpected token '".$this->current()."'$expect");
} }
/** /**
@ -560,15 +556,10 @@ class Tokenizer {
} }
} }
/**
* Tokenize error
*/
class TokenizeException extends \RuntimeException {}
/** /**
* Unexpected token * Unexpected token
*/ */
class UnexpectedTokenException extends TokenizeException { class UnexpectedTokenException extends \RuntimeException {
public function __construct(Tokenizer $tokens, $expect = null, $where = null) { public function __construct(Tokenizer $tokens, $expect = null, $where = null) {
if($expect && count($expect) == 1 && is_string($expect[0])) { if($expect && count($expect) == 1 && is_string($expect[0])) {
$expect = ", expect '".$expect[0]."'"; $expect = ", expect '".$expect[0]."'";

View File

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