Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add current files to the repository

  • Loading branch information...
commit 69ca72074ec2599f8c46d99d639857238bce2a20 1 parent 6717dd3
@edmundask authored
Showing with 12,838 additions and 0 deletions.
  1. +5 −0 .gitignore
  2. +12 −0 config/autoload.php
  3. +207 −0 config/twiggy.php
  4. +4 −0 helpers/twiggy_helper.php
  5. +261 −0 libraries/Twiggy.php
  6. +5 −0 spark.info
  7. +9 −0 vendor/Twig/AUTHORS
  8. +455 −0 vendor/Twig/CHANGELOG
  9. +31 −0 vendor/Twig/LICENSE
  10. +15 −0 vendor/Twig/README.markdown
  11. +46 −0 vendor/Twig/lib/Twig/Autoloader.php
  12. +219 −0 vendor/Twig/lib/Twig/Compiler.php
  13. +35 −0 vendor/Twig/lib/Twig/CompilerInterface.php
  14. +1,060 −0 vendor/Twig/lib/Twig/Environment.php
  15. +195 −0 vendor/Twig/lib/Twig/Error.php
  16. +20 −0 vendor/Twig/lib/Twig/Error/Loader.php
  17. +21 −0 vendor/Twig/lib/Twig/Error/Runtime.php
  18. +21 −0 vendor/Twig/lib/Twig/Error/Syntax.php
  19. +488 −0 vendor/Twig/lib/Twig/ExpressionParser.php
  20. +93 −0 vendor/Twig/lib/Twig/Extension.php
  21. +1,004 −0 vendor/Twig/lib/Twig/Extension/Core.php
  22. +64 −0 vendor/Twig/lib/Twig/Extension/Debug.php
  23. +77 −0 vendor/Twig/lib/Twig/Extension/Escaper.php
  24. +35 −0 vendor/Twig/lib/Twig/Extension/Optimizer.php
  25. +112 −0 vendor/Twig/lib/Twig/Extension/Sandbox.php
  26. +84 −0 vendor/Twig/lib/Twig/ExtensionInterface.php
  27. +69 −0 vendor/Twig/lib/Twig/Filter.php
  28. +33 −0 vendor/Twig/lib/Twig/Filter/Function.php
  29. +34 −0 vendor/Twig/lib/Twig/Filter/Method.php
  30. +37 −0 vendor/Twig/lib/Twig/Filter/Node.php
  31. +38 −0 vendor/Twig/lib/Twig/FilterInterface.php
  32. +63 −0 vendor/Twig/lib/Twig/Function.php
  33. +34 −0 vendor/Twig/lib/Twig/Function/Function.php
  34. +35 −0 vendor/Twig/lib/Twig/Function/Method.php
  35. +37 −0 vendor/Twig/lib/Twig/Function/Node.php
  36. +37 −0 vendor/Twig/lib/Twig/FunctionInterface.php
  37. +406 −0 vendor/Twig/lib/Twig/Lexer.php
  38. +29 −0 vendor/Twig/lib/Twig/LexerInterface.php
  39. +102 −0 vendor/Twig/lib/Twig/Loader/Array.php
  40. +100 −0 vendor/Twig/lib/Twig/Loader/Chain.php
  41. +152 −0 vendor/Twig/lib/Twig/Loader/Filesystem.php
  42. +59 −0 vendor/Twig/lib/Twig/Loader/String.php
  43. +45 −0 vendor/Twig/lib/Twig/LoaderInterface.php
  44. +38 −0 vendor/Twig/lib/Twig/Markup.php
  45. +227 −0 vendor/Twig/lib/Twig/Node.php
  46. +40 −0 vendor/Twig/lib/Twig/Node/AutoEscape.php
  47. +45 −0 vendor/Twig/lib/Twig/Node/Block.php
  48. +38 −0 vendor/Twig/lib/Twig/Node/BlockReference.php
  49. +20 −0 vendor/Twig/lib/Twig/Node/Body.php
  50. +39 −0 vendor/Twig/lib/Twig/Node/Do.php
  51. +21 −0 vendor/Twig/lib/Twig/Node/Expression.php
  52. +86 −0 vendor/Twig/lib/Twig/Node/Expression/Array.php
  53. +28 −0 vendor/Twig/lib/Twig/Node/Expression/AssignName.php
  54. +40 −0 vendor/Twig/lib/Twig/Node/Expression/Binary.php
  55. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Add.php
  56. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/And.php
  57. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php
  58. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php
  59. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php
  60. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Concat.php
  61. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Div.php
  62. +17 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Equal.php
  63. +29 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/FloorDiv.php
  64. +17 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Greater.php
  65. +17 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php
  66. +33 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/In.php
  67. +17 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Less.php
  68. +17 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/LessEqual.php
  69. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Mod.php
  70. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Mul.php
  71. +17 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/NotEqual.php
  72. +33 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/NotIn.php
  73. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Or.php
  74. +33 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Power.php
  75. +33 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Range.php
  76. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Binary/Sub.php
  77. +52 −0 vendor/Twig/lib/Twig/Node/Expression/BlockReference.php
  78. +31 −0 vendor/Twig/lib/Twig/Node/Expression/Conditional.php
  79. +23 −0 vendor/Twig/lib/Twig/Node/Expression/Constant.php
  80. +34 −0 vendor/Twig/lib/Twig/Node/Expression/ExtensionReference.php
  81. +61 −0 vendor/Twig/lib/Twig/Node/Expression/Filter.php
  82. +44 −0 vendor/Twig/lib/Twig/Node/Expression/Filter/Default.php
  83. +66 −0 vendor/Twig/lib/Twig/Node/Expression/Function.php
  84. +53 −0 vendor/Twig/lib/Twig/Node/Expression/GetAttr.php
  85. +37 −0 vendor/Twig/lib/Twig/Node/Expression/MethodCall.php
  86. +76 −0 vendor/Twig/lib/Twig/Node/Expression/Name.php
  87. +48 −0 vendor/Twig/lib/Twig/Node/Expression/Parent.php
  88. +22 −0 vendor/Twig/lib/Twig/Node/Expression/TempName.php
  89. +54 −0 vendor/Twig/lib/Twig/Node/Expression/Test.php
  90. +36 −0 vendor/Twig/lib/Twig/Node/Expression/Test/Constant.php
  91. +55 −0 vendor/Twig/lib/Twig/Node/Expression/Test/Defined.php
  92. +34 −0 vendor/Twig/lib/Twig/Node/Expression/Test/Divisibleby.php
  93. +33 −0 vendor/Twig/lib/Twig/Node/Expression/Test/Even.php
  94. +32 −0 vendor/Twig/lib/Twig/Node/Expression/Test/Null.php
  95. +33 −0 vendor/Twig/lib/Twig/Node/Expression/Test/Odd.php
  96. +30 −0 vendor/Twig/lib/Twig/Node/Expression/Test/Sameas.php
  97. +30 −0 vendor/Twig/lib/Twig/Node/Expression/Unary.php
  98. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Unary/Neg.php
  99. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Unary/Not.php
  100. +18 −0 vendor/Twig/lib/Twig/Node/Expression/Unary/Pos.php
  101. +37 −0 vendor/Twig/lib/Twig/Node/Flush.php
  102. +113 −0 vendor/Twig/lib/Twig/Node/For.php
  103. +56 −0 vendor/Twig/lib/Twig/Node/ForLoop.php
  104. +67 −0 vendor/Twig/lib/Twig/Node/If.php
  105. +51 −0 vendor/Twig/lib/Twig/Node/Import.php
  106. +88 −0 vendor/Twig/lib/Twig/Node/Include.php
  107. +84 −0 vendor/Twig/lib/Twig/Node/Macro.php
  108. +323 −0 vendor/Twig/lib/Twig/Node/Module.php
  109. +40 −0 vendor/Twig/lib/Twig/Node/Print.php
  110. +48 −0 vendor/Twig/lib/Twig/Node/Sandbox.php
  111. +71 −0 vendor/Twig/lib/Twig/Node/SandboxedModule.php
  112. +60 −0 vendor/Twig/lib/Twig/Node/SandboxedPrint.php
  113. +102 −0 vendor/Twig/lib/Twig/Node/Set.php
  114. +35 −0 vendor/Twig/lib/Twig/Node/SetTemp.php
  115. +41 −0 vendor/Twig/lib/Twig/Node/Spaceless.php
  116. +40 −0 vendor/Twig/lib/Twig/Node/Text.php
  117. +30 −0 vendor/Twig/lib/Twig/NodeInterface.php
  118. +20 −0 vendor/Twig/lib/Twig/NodeOutputInterface.php
  119. +89 −0 vendor/Twig/lib/Twig/NodeTraverser.php
  120. +162 −0 vendor/Twig/lib/Twig/NodeVisitor/Escaper.php
  121. +247 −0 vendor/Twig/lib/Twig/NodeVisitor/Optimizer.php
  122. +115 −0 vendor/Twig/lib/Twig/NodeVisitor/SafeAnalysis.php
  123. +93 −0 vendor/Twig/lib/Twig/NodeVisitor/Sandbox.php
  124. +48 −0 vendor/Twig/lib/Twig/NodeVisitorInterface.php
  125. +370 −0 vendor/Twig/lib/Twig/Parser.php
  126. +28 −0 vendor/Twig/lib/Twig/ParserInterface.php
  127. +20 −0 vendor/Twig/lib/Twig/Sandbox/SecurityError.php
  128. +120 −0 vendor/Twig/lib/Twig/Sandbox/SecurityPolicy.php
  129. +25 −0 vendor/Twig/lib/Twig/Sandbox/SecurityPolicyInterface.php
  130. +457 −0 vendor/Twig/lib/Twig/Template.php
  131. +47 −0 vendor/Twig/lib/Twig/TemplateInterface.php
  132. +31 −0 vendor/Twig/lib/Twig/Test/Function.php
  133. +32 −0 vendor/Twig/lib/Twig/Test/Method.php
  134. +35 −0 vendor/Twig/lib/Twig/Test/Node.php
  135. +26 −0 vendor/Twig/lib/Twig/TestInterface.php
  136. +219 −0 vendor/Twig/lib/Twig/Token.php
  137. +34 −0 vendor/Twig/lib/Twig/TokenParser.php
  138. +77 −0 vendor/Twig/lib/Twig/TokenParser/AutoEscape.php
  139. +83 −0 vendor/Twig/lib/Twig/TokenParser/Block.php
  140. +42 −0 vendor/Twig/lib/Twig/TokenParser/Do.php
  141. +54 −0 vendor/Twig/lib/Twig/TokenParser/Extends.php
  142. +61 −0 vendor/Twig/lib/Twig/TokenParser/Filter.php
  143. +42 −0 vendor/Twig/lib/Twig/TokenParser/Flush.php
  144. +89 −0 vendor/Twig/lib/Twig/TokenParser/For.php
  145. +74 −0 vendor/Twig/lib/Twig/TokenParser/From.php
  146. +93 −0 vendor/Twig/lib/Twig/TokenParser/If.php
  147. +47 −0 vendor/Twig/lib/Twig/TokenParser/Import.php
  148. +71 −0 vendor/Twig/lib/Twig/TokenParser/Include.php
  149. +69 −0 vendor/Twig/lib/Twig/TokenParser/Macro.php
  150. +55 −0 vendor/Twig/lib/Twig/TokenParser/Sandbox.php
  151. +84 −0 vendor/Twig/lib/Twig/TokenParser/Set.php
  152. +59 −0 vendor/Twig/lib/Twig/TokenParser/Spaceless.php
  153. +85 −0 vendor/Twig/lib/Twig/TokenParser/Use.php
  154. +113 −0 vendor/Twig/lib/Twig/TokenParserBroker.php
  155. +45 −0 vendor/Twig/lib/Twig/TokenParserBrokerInterface.php
  156. +42 −0 vendor/Twig/lib/Twig/TokenParserInterface.php
  157. +140 −0 vendor/Twig/lib/Twig/TokenStream.php
View
5 .gitignore
@@ -0,0 +1,5 @@
+*.log
+.DS_Store
+*.tmproj
+*.sublime-project
+*.sublime-workspace
View
12 config/autoload.php
@@ -0,0 +1,12 @@
+<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
+
+/**
+ * Twiggy - Twig template engine implementation for CodeIgniter
+ *
+ * @author Edmundas Kondrašovas <as@edmundask.lt>
+ * @license http://www.opensource.org/licenses/MIT
+ */
+
+$autoload['libraries'] = array('twiggy');
+$autoload['config'] = array('twiggy');
+$autoload['helper'] = array();
View
207 config/twiggy.php
@@ -0,0 +1,207 @@
+<?php if(!defined('BASEPATH')) exit('No direct script access allowed');
+
+/**
+ * Twiggy - Twig template engine implementation for CodeIgniter
+ *
+ * Twiggy is not just a simple implementation of Twig template engine
+ * for CodeIgniter. It supports themes, layouts, templates for regular
+ * apps and also for apps that use HMVC (module support).
+ *
+ * @package CodeIgniter
+ * @subpackage Twiggy
+ * @category Config
+ * @author Edmundas Kondrašovas <as@edmundask.lt>
+ * @license http://www.opensource.org/licenses/MIT
+ * @version 0.7.0
+ * @copyright Copyright (c) 2012 Edmundas Kondrašovas <as@edmundask.lt>
+ */
+
+/*
+|--------------------------------------------------------------------------
+| Template file extension
+|--------------------------------------------------------------------------
+|
+| This lets you define the extension for template files. It doesn't affect
+| how Twiggy deals with templates but this may help you if you want to
+| distinguish different kinds of templates. For example, for CodeIgniter
+| you may use *.html.twig template files and *.html.jst for js templates.
+|
+*/
+
+$config['twiggy']['template_file_ext'] = '.html.twig';
+
+
+/*
+|--------------------------------------------------------------------------
+| Syntax Delimiters
+|--------------------------------------------------------------------------
+|
+| If you don't like the default Twig syntax delimiters or if they collide
+| with other languages (for example, you use handlebars.js in your
+| templates), here you can change them.
+|
+| Ruby erb style:
+|
+| 'tag_comment' => array('<%#', '#%>'),
+| 'tag_block' => array('<%', '%>'),
+| 'tag_variable' => array('<%=', '%>')
+|
+| Smarty style:
+|
+| 'tag_comment' => array('{*', '*}'),
+| 'tag_block' => array('{', '}'),
+| 'tag_variable' => array('{$', '}'),
+|
+*/
+
+$config['twiggy']['delimiters'] = array
+(
+ 'tag_comment' => array('{#', '#}'),
+ 'tag_block' => array('{%', '%}'),
+ 'tag_variable' => array('{{', '}}')
+);
+
+
+/*
+|--------------------------------------------------------------------------
+| Environment Options
+|--------------------------------------------------------------------------
+|
+| These are all twig-specific options that you can set. To learn more about
+| each option, check the official documentation.
+|
+*/
+
+$config['twiggy']['environment']['cache'] = FALSE;
+$config['twiggy']['environment']['debug'] = FALSE;
+$config['twiggy']['environment']['charset'] = 'utf-8';
+$config['twiggy']['environment']['base_template_class'] = 'Twig_Template';
+$config['twiggy']['environment']['auto_reload'] = NULL;
+$config['twiggy']['environment']['strict_variables'] = FALSE;
+$config['twiggy']['environment']['autoescape'] = TRUE;
+$config['twiggy']['environment']['optimizations'] = -1;
+
+
+/*
+|--------------------------------------------------------------------------
+| Twig Cache Dir
+|--------------------------------------------------------------------------
+|
+| Path to the cache folder for compiled twig templates. It is relative to
+| CodeIgniter's base directory.
+|
+*/
+
+$config['twiggy']['twig_cache_dir'] = 'cache/twig/';
+
+/*
+|--------------------------------------------------------------------------
+| Themes Base Dir
+|--------------------------------------------------------------------------
+|
+| Directory where themes are located at. This path is relative to
+| CodeIgniter's base directory OR module's base directory. For example:
+|
+| $config['themes_base_dir'] = 'themes/';
+|
+| It will actually mean that themes should be placed at:
+|
+| {APPPATH}/themes/ and {APPPATH}/modules/{some_module}/themes/.
+|
+| NOTE: modules do not necessarily need to be in {APPPATH}/modules/ as
+| Twiggy will figure out the paths by itself. That way you can package
+| your modules with themes.
+|
+| Also, do not forget the trailing slash!
+|
+*/
+
+$config['twiggy']['themes_base_dir'] = 'themes/';
+
+
+/*
+|--------------------------------------------------------------------------
+| Include APPPATH
+|--------------------------------------------------------------------------
+|
+| This lets you include the APPPATH for the themes base directory (only for
+| the application itself, not the modules). See the example below.
+|
+| Suppose you have:
+| $config['themes_base_dir'] = 'themes/'
+| $config['include_apppath'] = TRUE
+|
+| Then the path will be {APPPATH}/themes/ but if you set this option to
+| FALSE, then you will have themes/.
+|
+| This is useful for when you want to have the themes folder outside the
+| application (APPPATH) folder.
+|
+*/
+
+$config['twiggy']['include_apppath'] = TRUE;
+
+
+/*
+|--------------------------------------------------------------------------
+| Default theme
+|--------------------------------------------------------------------------
+*/
+
+$config['twiggy']['default_theme'] = 'default';
+
+
+/*
+|--------------------------------------------------------------------------
+| Default layout
+|--------------------------------------------------------------------------
+*/
+
+$config['twiggy']['default_layout'] = 'index';
+
+
+/*
+|--------------------------------------------------------------------------
+| Default template
+|--------------------------------------------------------------------------
+*/
+
+$config['twiggy']['default_template'] = 'index';
+
+
+/*
+|--------------------------------------------------------------------------
+| Auto-reigster functions
+|--------------------------------------------------------------------------
+|
+| Here you can list all the functions that you want Twiggy to automatically
+| register them for you.
+|
+| NOTE: only registered functions can be used in Twig templates.
+|
+*/
+
+$config['twiggy']['register_functions'] = array
+(
+
+);
+
+
+/*
+|--------------------------------------------------------------------------
+| Auto-reigster filters
+|--------------------------------------------------------------------------
+|
+| Much like with functions, list filters that you want Twiggy to
+| automatically register them for you.
+|
+| NOTE: only registered filters can be used in Twig templates. Also, keep
+| in mind that a filter is nothing more than just a regular function that
+| acceps a string (value) as a parameter and outputs a modified/new string.
+|
+*/
+
+$config['twiggy']['register_filters'] = array
+(
+
+);
View
4 helpers/twiggy_helper.php
@@ -0,0 +1,4 @@
+<?php
+
+
+/* End of file twiggy_helper.php */
View
261 libraries/Twiggy.php
@@ -0,0 +1,261 @@
+<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
+
+/**
+ * Twiggy - Twig template engine implementation for CodeIgniter
+ *
+ * Twiggy is not just a simple implementation of Twig template engine
+ * for CodeIgniter. It supports themes, layouts, templates for regular
+ * apps and also for apps that use HMVC (module support).
+ *
+ * @package CodeIgniter
+ * @subpackage Twiggy
+ * @category Libraries
+ * @author Edmundas Kondrašovas <as@edmundask.lt>
+ * @license http://www.opensource.org/licenses/MIT
+ * @version 0.7.0
+ * @copyright Copyright (c) 2012 Edmundas Kondrašovas <as@edmundask.lt>
+ */
+
+if(!defined('TWIGGY_ROOT')) define('TWIGGY_ROOT', dirname(__DIR__));
+
+require_once(TWIGGY_ROOT . '/vendor/Twig/lib/Twig/Autoloader.php');
+Twig_Autoloader::register();
+
+class Twiggy
+{
+ private $CI;
+
+ private $_config = array();
+ private $_template_locations = array();
+ private $_data;
+ private $_themes_base_dir;
+ private $_theme;
+ private $_layout;
+ private $_template;
+ private $_twig;
+ private $_twig_loader;
+ private $_module;
+
+ /**
+ * Constructor
+ */
+
+ public function __construct()
+ {
+ log_message('debug', 'Twiggy: library initialized');
+
+ $this->CI =& get_instance();
+
+ $this->_config = $this->CI->config->item('twiggy');
+
+ $this->_themes_base_dir = ($this->_config['include_apppath']) ? APPPATH . $this->_config['themes_base_dir'] : $this->_config['themes_base_dir'];
+ $this->_set_template_locations($this->_config['default_theme']);
+
+ try
+ {
+ $this->_twig_loader = new Twig_Loader_Filesystem($this->_template_locations);
+ }
+ catch(Twig_Error_Loader $e)
+ {
+ log_message('error', 'Twiggy: failed to load the default theme');
+ show_error("Default theme in {$this->_themes_base_dir}{$this->_config['default_theme']} does not exist.");
+ }
+
+ $this->_twig = new Twig_Environment($this->_twig_loader, $this->_config['environment']);
+ $this->_twig->setLexer(new Twig_Lexer($this->_twig, $this->_config['delimiters']));
+
+ // Auto-register functions and filters.
+ if(count($this->_config['register_functions']) > 0)
+ {
+ foreach($this->_config['register_functions'] as $function) $this->register_function($function);
+ }
+
+ if(count($this->_config['register_filters']) > 0)
+ {
+ foreach($this->_config['register_filters'] as $filter) $this->register_filter($filter);
+ }
+ }
+
+ /**
+ * Set data
+ *
+ * @access public
+ * @param string key (variable name)
+ * @param mixed data
+ * @param boolean (optional) is this a global variable?
+ * @return object instance of this class
+ */
+
+ public function set($key, $value, $global = FALSE)
+ {
+ if($global)
+ {
+ $this->_twig->addGlobal($key, $value);
+ }
+ else
+ {
+ $this->_data[$key] = $value;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Register a function in Twig environment
+ *
+ * @access public
+ * @param string the name of an existing function
+ * @return object instance of this class
+ */
+
+ public function register_function($name)
+ {
+ $this->_twig->addFunction($name, new Twig_Function_Function($name));
+
+ return $this;
+ }
+
+ /**
+ * Register a filter in Twig environment
+ *
+ * @access public
+ * @param string the name of an existing function
+ * @return object instance of this class
+ */
+
+ public function register_filter($name)
+ {
+ $this->_twig->addFilter($name, new Twig_Filter_Function($name));
+
+ return $this;
+ }
+
+ /**
+ * Load theme
+ *
+ * @access public
+ * @param string name of theme to load
+ * @return object instance of this class
+ */
+
+ public function theme($theme)
+ {
+ if(!is_dir(realpath($this->_themes_base_dir. $theme)))
+ {
+ log_message('error', 'Twiggy: requested theme '. $theme .' has not been loaded because it does not exist.');
+ show_error("Theme does not exist in {$this->_themes_base_dir}{$theme}.");
+ }
+
+ $this->_loaded_theme = $theme;
+ $this->_set_template_locations($theme);
+
+ return $this;
+ }
+
+ /**
+ * Set layout
+ *
+ * @access public
+ * @param string name of the layout
+ * @return object instance of this class
+ */
+
+ public function layout($name)
+ {
+ $this->_layout = $name . $this->_config['template_file_ext'];
+ $this->_twig->addGlobal('_layout', '_layouts/'. $this->_layout);
+
+ return $this;
+ }
+
+ /**
+ * Set template
+ *
+ * @access public
+ * @param string name of the template file
+ * @return object instance of this class
+ */
+
+ public function template($name)
+ {
+ $this->_template = $name . $this->_config['template_file_ext'];
+
+ return $this;
+ }
+
+ /**
+ * Render and return compiled HTML
+ *
+ * @access public
+ * @return string compiled HTML
+ */
+
+ public function render()
+ {
+ $output = $this->_twig->loadTemplate($this->_template);
+
+ return $output->render($this->_data);
+ }
+
+ /**
+ * Display the compiled HTML content
+ *
+ * @access public
+ * @return void
+ */
+
+ public function display()
+ {
+ $output = $this->_twig->loadTemplate($this->_template);
+ $output->display($this->_data);
+ }
+
+ /**
+ * Set template locations
+ *
+ * @access private
+ * @param string name of theme to load
+ * @return void
+ */
+
+ private function _set_template_locations($theme)
+ {
+ // Check if HMVC is installed.
+ // NOTE: there may be a simplier way to check it but this seems good enough.
+ if(method_exists($this->CI->router, 'fetch_module'))
+ {
+ $this->_module = $this->CI->router->fetch_module();
+
+ // Only if the current page is served from a module do we need to add extra template locations.
+ if(!empty($this->_module))
+ {
+ $module_locations = Modules::$locations;
+
+ foreach($module_locations as $loc => $offset)
+ {
+ $this->_template_locations[] = $loc . $this->_module . '/' . $this->_config['themes_base_dir'] . $theme;
+ }
+ }
+ }
+
+ $this->_template_locations[] = $this->_themes_base_dir . $theme;
+
+ // Reset the paths if needed.
+ if(is_object($this->_twig_loader))
+ {
+ $this->_twig_loader->setPaths($this->_template_locations);
+ }
+ }
+
+ /**
+ * Magic method __get()
+ */
+
+ public function __get($variable)
+ {
+ if($variable == 'twig') return $this->_twig;
+
+ return (array_key_exists($variable, $this->_data)) ? $this->_data[$variable] : FALSE;
+ }
+}
+// End Class
View
5 spark.info
@@ -0,0 +1,5 @@
+
+name: twiggy
+version: 0.7.0
+compatibility: 2.1.0
+tags: ["template", "theme", "twig"]
View
9 vendor/Twig/AUTHORS
@@ -0,0 +1,9 @@
+Twig is written and maintained by the Twig Team:
+
+Lead Developer:
+
+- Fabien Potencier <fabien.potencier@symfony-project.org>
+
+Project Founder:
+
+- Armin Ronacher <armin.ronacher@active-4.com>
View
455 vendor/Twig/CHANGELOG
@@ -0,0 +1,455 @@
+* 1.6.1 (2012-02-29)
+
+ * fixed Twig C extension
+ * removed the creation of Twig_Markup instances when not needed
+ * added a way to set the default global timezone for dates
+ * fixed the slice filter on strings when the length is not specified
+ * fixed the creation of the cache directory in case of a race condition
+
+* 1.6.0 (2012-02-04)
+
+ * fixed raw blocks when used with the whitespace trim option
+ * made a speed optimization to macro calls when imported via the "from" tag
+ * fixed globals, parsers, visitors, filters, tests, and functions management in Twig_Environment when a new one or new extension is added
+ * fixed the attribute function when passing arguments
+ * added slice notation support for the [] operator (syntactic sugar for the slice operator)
+ * added a slice filter
+ * added string support for the reverse filter
+ * fixed the empty test and the length filter for Twig_Markup instances
+ * added a date function to ease date comparison
+ * fixed unary operators precedence
+ * added recursive parsing support in the parser
+ * added string and integer handling for the random function
+
+* 1.5.1 (2012-01-05)
+
+ * fixed a regression when parsing strings
+
+* 1.5.0 (2012-01-04)
+
+ * added Traversable objects support for the join filter
+
+* 1.5.0-RC2 (2011-12-30)
+
+ * added a way to set the default global date interval format
+ * fixed the date filter for DateInterval instances (setTimezone() does not exist for them)
+ * refactored Twig_Template::display() to ease its extension
+ * added a number_format filter
+
+* 1.5.0-RC1 (2011-12-26)
+
+ * removed the need to quote hash keys
+ * allowed hash keys to be any expression
+ * added a do tag
+ * added a flush tag
+ * added support for dynamically named filters and functions
+ * added a dump function to help debugging templates
+ * added a nl2br filter
+ * added a random function
+ * added a way to change the default format for the date filter
+ * fixed the lexer when an operator ending with a letter ends a line
+ * added string interpolation support
+ * enhanced exceptions for unknown filters, functions, tests, and tags
+
+* 1.4.0 (2011-12-07)
+
+ * fixed lexer when using big numbers (> PHP_INT_MAX)
+ * added missing preserveKeys argument to the reverse filter
+ * fixed macros containing filter tag calls
+
+* 1.4.0-RC2 (2011-11-27)
+
+ * removed usage of Reflection in Twig_Template::getAttribute()
+ * added a C extension that can optionally replace Twig_Template::getAttribute()
+ * added negative timestamp support to the date filter
+
+* 1.4.0-RC1 (2011-11-20)
+
+ * optimized variable access when using PHP 5.4
+ * changed the precedence of the .. operator to be more consistent with languages that implements such a feature like Ruby
+ * added an Exception to Twig_Loader_Array::isFresh() method when the template does not exist to be consistent with other loaders
+ * added Twig_Function_Node to allow more complex functions to have their own Node class
+ * added Twig_Filter_Node to allow more complex filters to have their own Node class
+ * added Twig_Test_Node to allow more complex tests to have their own Node class
+ * added a better error message when a template is empty but contain a BOM
+ * fixed "in" operator for empty strings
+ * fixed the "defined" test and the "default" filter (now works with more than one call (foo.bar.foo) and for both values of the strict_variables option)
+ * changed the way extensions are loaded (addFilter/addFunction/addGlobal/addTest/addNodeVisitor/addTokenParser/addExtension can now be called in any order)
+ * added Twig_Environment::display()
+ * made the escape filter smarter when the encoding is not supported by PHP
+ * added a convert_encoding filter
+ * moved all node manipulations outside the compile() Node method
+ * made several speed optimizations
+
+* 1.3.0 (2011-10-08)
+
+no changes
+
+* 1.3.0-RC1 (2011-10-04)
+
+ * added an optimization for the parent() function
+ * added cache reloading when auto_reload is true and an extension has been modified
+ * added the possibility to force the escaping of a string already marked as safe (instance of Twig_Markup)
+ * allowed empty templates to be used as traits
+ * added traits support for the "parent" function
+
+* 1.2.0 (2011-09-13)
+
+no changes
+
+* 1.2.0-RC1 (2011-09-10)
+
+ * enhanced the exception when a tag remains unclosed
+ * added support for empty Countable objects for the "empty" test
+ * fixed algorithm that determines if a template using inheritance is valid (no output between block definitions)
+ * added better support for encoding problems when escaping a string (available as of PHP 5.4)
+ * added a way to ignore a missing template when using the "include" tag ({% include "foo" ignore missing %})
+ * added support for an array of templates to the "include" and "extends" tags ({% include ['foo', 'bar'] %})
+ * added support for bitwise operators in expressions
+ * added the "attribute" function to allow getting dynamic attributes on variables
+ * added Twig_Loader_Chain
+ * added Twig_Loader_Array::setTemplate()
+ * added an optimization for the set tag when used to capture a large chunk of static text
+ * changed name regex to match PHP one "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" (works for blocks, tags, functions, filters, and macros)
+ * removed the possibility to use the "extends" tag from a block
+ * added "if" modifier support to "for" loops
+
+* 1.1.2 (2011-07-30)
+
+ * fixed json_encode filter on PHP 5.2
+ * fixed regression introduced in 1.1.1 ({{ block(foo|lower) }})
+ * fixed inheritance when using conditional parents
+ * fixed compilation of templates when the body of a child template is not empty
+ * fixed output when a macro throws an exception
+ * fixed a parsing problem when a large chunk of text is enclosed in a comment tag
+ * added PHPDoc for all Token parsers and Core extension functions
+
+* 1.1.1 (2011-07-17)
+
+ * added a performance optimization in the Optimizer (also helps to lower the number of nested level calls)
+ * made some performance improvement for some edge cases
+
+* 1.1.0 (2011-06-28)
+
+ * fixed json_encode filter
+
+* 1.1.0-RC3 (2011-06-24)
+
+ * fixed method case-sensitivity when using the sandbox mode
+ * added timezone support for the date filter
+ * fixed possible security problems with NUL bytes
+
+* 1.1.0-RC2 (2011-06-16)
+
+ * added an exception when the template passed to "use" is not a string
+ * made 'a.b is defined' not throw an exception if a is not defined (in strict mode)
+ * added {% line \d+ %} directive
+
+* 1.1.0-RC1 (2011-05-28)
+
+Flush your cache after upgrading.
+
+ * fixed date filter when using a timestamp
+ * fixed the defined test for some cases
+ * fixed a parsing problem when a large chunk of text is enclosed in a raw tag
+ * added support for horizontal reuse of template blocks (see docs for more information)
+ * added whitespace control modifier to all tags (see docs for more information)
+ * added null as an alias for none (the null test is also an alias for the none test now)
+ * made TRUE, FALSE, NONE equivalent to their lowercase counterparts
+ * wrapped all compilation and runtime exceptions with Twig_Error_Runtime and added logic to guess the template name and line
+ * moved display() method to Twig_Template (generated templates should now use doDisplay() instead)
+
+* 1.0.0 (2011-03-27)
+
+ * fixed output when using mbstring
+ * fixed duplicate call of methods when using the sandbox
+ * made the charset configurable for the escape filter
+
+* 1.0.0-RC2 (2011-02-21)
+
+ * changed the way {% set %} works when capturing (the content is now marked as safe)
+ * added support for macro name in the endmacro tag
+ * make Twig_Error compatible with PHP 5.3.0 >
+ * fixed an infinite loop on some Windows configurations
+ * fixed the "length" filter for numbers
+ * fixed Template::getAttribute() as properties in PHP are case sensitive
+ * removed coupling between Twig_Node and Twig_Template
+ * fixed the ternary operator precedence rule
+
+* 1.0.0-RC1 (2011-01-09)
+
+Backward incompatibilities:
+
+ * the "items" filter, which has been deprecated for quite a long time now, has been removed
+ * the "range" filter has been converted to a function: 0|range(10) -> range(0, 10)
+ * the "constant" filter has been converted to a function: {{ some_date|date('DATE_W3C'|constant) }} -> {{ some_date|date(constant('DATE_W3C')) }}
+ * the "cycle" filter has been converted to a function: {{ ['odd', 'even']|cycle(i) }} -> {{ cycle(['odd', 'even'], i) }}
+ * the "for" tag does not support "joined by" anymore
+ * the "autoescape" first argument is now "true"/"false" (instead of "on"/"off")
+ * the "parent" tag has been replaced by a "parent" function ({{ parent() }} instead of {% parent %})
+ * the "display" tag has been replaced by a "block" function ({{ block('title') }} instead of {% display title %})
+ * removed the grammar and simple token parser (moved to the Twig Extensions repository)
+
+Changes:
+
+ * added "needs_context" option for filters and functions (the context is then passed as a first argument)
+ * added global variables support
+ * made macros return their value instead of echoing directly (fixes calling a macro in sandbox mode)
+ * added the "from" tag to import macros as functions
+ * added support for functions (a function is just syntactic sugar for a getAttribute() call)
+ * made macros callable when sandbox mode is enabled
+ * added an exception when a macro uses a reserved name
+ * the "default" filter now uses the "empty" test instead of just checking for null
+ * added the "empty" test
+
+* 0.9.10 (2010-12-16)
+
+Backward incompatibilities:
+
+ * The Escaper extension is enabled by default, which means that all displayed
+ variables are now automatically escaped. You can revert to the previous
+ behavior by removing the extension via $env->removeExtension('escaper')
+ or just set the 'autoescape' option to 'false'.
+ * removed the "without loop" attribute for the "for" tag (not needed anymore
+ as the Optimizer take care of that for most cases)
+ * arrays and hashes have now a different syntax
+ * arrays keep the same syntax with square brackets: [1, 2]
+ * hashes now use curly braces (["a": "b"] should now be written as {"a": "b"})
+ * support for "arrays with keys" and "hashes without keys" is not supported anymore ([1, "foo": "bar"] or {"foo": "bar", 1})
+ * the i18n extension is now part of the Twig Extensions repository
+
+Changes:
+
+ * added the merge filter
+ * removed 'is_escaper' option for filters (a left over from the previous version) -- you must use 'is_safe' now instead
+ * fixed usage of operators as method names (like is, in, and not)
+ * changed the order of execution for node visitors
+ * fixed default() filter behavior when used with strict_variables set to on
+ * fixed filesystem loader compatibility with PHAR files
+ * enhanced error messages when an unexpected token is parsed in an expression
+ * fixed filename not being added to syntax error messages
+ * added the autoescape option to enable/disable autoescaping
+ * removed the newline after a comment (mimicks PHP behavior)
+ * added a syntax error exception when parent block is used on a template that does not extend another one
+ * made the Escaper extension enabled by default
+ * fixed sandbox extension when used with auto output escaping
+ * fixed escaper when wrapping a Twig_Node_Print (the original class must be preserved)
+ * added an Optimizer extension (enabled by default; optimizes "for" loops and "raw" filters)
+ * added priority to node visitors
+
+* 0.9.9 (2010-11-28)
+
+Backward incompatibilities:
+ * the self special variable has been renamed to _self
+ * the odd and even filters are now tests:
+ {{ foo|odd }} must now be written {{ foo is odd }}
+ * the "safe" filter has been renamed to "raw"
+ * in Node classes,
+ sub-nodes are now accessed via getNode() (instead of property access)
+ attributes via getAttribute() (instead of array access)
+ * the urlencode filter had been renamed to url_encode
+ * the include tag now merges the passed variables with the current context by default
+ (the old behavior is still possible by adding the "only" keyword)
+ * moved Exceptions to Twig_Error_* (Twig_SyntaxError/Twig_RuntimeError are now Twig_Error_Syntax/Twig_Error_Runtime)
+ * removed support for {{ 1 < i < 3 }} (use {{ i > 1 and i < 3 }} instead)
+ * the "in" filter has been removed ({{ a|in(b) }} should now be written {{ a in b }})
+
+Changes:
+ * added file and line to Twig_Error_Runtime exceptions thrown from Twig_Template
+ * changed trans tag to accept any variable for the plural count
+ * fixed sandbox mode (__toString() method check was not enforced if called implicitly from complex statements)
+ * added the ** (power) operator
+ * changed the algorithm used for parsing expressions
+ * added the spaceless tag
+ * removed trim_blocks option
+ * added support for is*() methods for attributes (foo.bar now looks for foo->getBar() or foo->isBar())
+ * changed all exceptions to extend Twig_Error
+ * fixed unary expressions ({{ not(1 or 0) }})
+ * fixed child templates (with an extend tag) that uses one or more imports
+ * added support for {{ 1 not in [2, 3] }} (more readable than the current {{ not (1 in [2, 3]) }})
+ * escaping has been rewritten
+ * the implementation of template inheritance has been rewritten
+ (blocks can now be called individually and still work with inheritance)
+ * fixed error handling for if tag when a syntax error occurs within a subparse process
+ * added a way to implement custom logic for resolving token parsers given a tag name
+ * fixed js escaper to be stricter (now uses a whilelist-based js escaper)
+ * added the following filers: "constant", "trans", "replace", "json_encode"
+ * added a "constant" test
+ * fixed objects with __toString() not being autoescaped
+ * fixed subscript expressions when calling __call() (methods now keep the case)
+ * added "test" feature (accessible via the "is" operator)
+ * removed the debug tag (should be done in an extension)
+ * fixed trans tag when no vars are used in plural form
+ * fixed race condition when writing template cache
+ * added the special _charset variable to reference the current charset
+ * added the special _context variable to reference the current context
+ * renamed self to _self (to avoid conflict)
+ * fixed Twig_Template::getAttribute() for protected properties
+
+* 0.9.8 (2010-06-28)
+
+Backward incompatibilities:
+ * the trans tag plural count is now attached to the plural tag:
+ old: `{% trans count %}...{% plural %}...{% endtrans %}`
+ new: `{% trans %}...{% plural count %}...{% endtrans %}`
+
+ * added a way to translate strings coming from a variable ({% trans var %})
+ * fixed trans tag when used with the Escaper extension
+ * fixed default cache umask
+ * removed Twig_Template instances from the debug tag output
+ * fixed objects with __isset() defined
+ * fixed set tag when used with a capture
+ * fixed type hinting for Twig_Environment::addFilter() method
+
+* 0.9.7 (2010-06-12)
+
+Backward incompatibilities:
+ * changed 'as' to '=' for the set tag ({% set title as "Title" %} must now be {% set title = "Title" %})
+ * removed the sandboxed attribute of the include tag (use the new sandbox tag instead)
+ * refactored the Node system (if you have custom nodes, you will have to update them to use the new API)
+
+ * added self as a special variable that refers to the current template (useful for importing macros from the current template)
+ * added Twig_Template instance support to the include tag
+ * added support for dynamic and conditional inheritance ({% extends some_var %} and {% extends standalone ? "minimum" : "base" %})
+ * added a grammar sub-framework to ease the creation of custom tags
+ * fixed the for tag for large arrays (some loop variables are now only available for arrays and objects that implement the Countable interface)
+ * removed the Twig_Resource::resolveMissingFilter() method
+ * fixed the filter tag which did not apply filtering to included files
+ * added a bunch of unit tests
+ * added a bunch of phpdoc
+ * added a sandbox tag in the sandbox extension
+ * changed the date filter to support any date format supported by DateTime
+ * added strict_variable setting to throw an exception when an invalid variable is used in a template (disabled by default)
+ * added the lexer, parser, and compiler as arguments to the Twig_Environment constructor
+ * changed the cache option to only accepts an explicit path to a cache directory or false
+ * added a way to add token parsers, filters, and visitors without creating an extension
+ * added three interfaces: Twig_NodeInterface, Twig_TokenParserInterface, and Twig_FilterInterface
+ * changed the generated code to match the new coding standards
+ * fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }})
+ * added an exception when a child template has a non-empty body (as it is always ignored when rendering)
+
+* 0.9.6 (2010-05-12)
+
+ * fixed variables defined outside a loop and for which the value changes in a for loop
+ * fixed the test suite for PHP 5.2 and older versions of PHPUnit
+ * added support for __call() in expression resolution
+ * fixed node visiting for macros (macros are now visited by visitors as any other node)
+ * fixed nested block definitions with a parent call (rarely useful but nonetheless supported now)
+ * added the cycle filter
+ * fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII
+ * added a long-syntax for the set tag ({% set foo %}...{% endset %})
+ * unit tests are now powered by PHPUnit
+ * added support for gettext via the `i18n` extension
+ * fixed twig_capitalize_string_filter() and fixed twig_length_filter() when used with UTF-8 values
+ * added a more useful exception if an if tag is not closed properly
+ * added support for escaping strategy in the autoescape tag
+ * fixed lexer when a template has a big chunk of text between/in a block
+
+* 0.9.5 (2010-01-20)
+
+As for any new release, don't forget to remove all cached templates after
+upgrading.
+
+If you have defined custom filters, you MUST upgrade them for this release. To
+upgrade, replace "array" with "new Twig_Filter_Function", and replace the
+environment constant by the "needs_environment" option:
+
+ // before
+ 'even' => array('twig_is_even_filter', false),
+ 'escape' => array('twig_escape_filter', true),
+
+ // after
+ 'even' => new Twig_Filter_Function('twig_is_even_filter'),
+ 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)),
+
+If you have created NodeTransformer classes, you will need to upgrade them to
+the new interface (please note that the interface is not yet considered
+stable).
+
+ * fixed list nodes that did not extend the Twig_NodeListInterface
+ * added the "without loop" option to the for tag (it disables the generation of the loop variable)
+ * refactored node transformers to node visitors
+ * fixed automatic-escaping for blocks
+ * added a way to specify variables to pass to an included template
+ * changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules)
+ * improved the filter system to allow object methods to be used as filters
+ * changed the Array and String loaders to actually make use of the cache mechanism
+ * included the default filter function definitions in the extension class files directly (Core, Escaper)
+ * added the // operator (like the floor() PHP function)
+ * added the .. operator (as a syntactic sugar for the range filter when the step is 1)
+ * added the in operator (as a syntactic sugar for the in filter)
+ * added the following filters in the Core extension: in, range
+ * added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes)
+ * enhanced some error messages to provide better feedback in case of parsing errors
+
+* 0.9.4 (2009-12-02)
+
+If you have custom loaders, you MUST upgrade them for this release: The
+Twig_Loader base class has been removed, and the Twig_LoaderInterface has also
+been changed (see the source code for more information or the documentation).
+
+ * added support for DateTime instances for the date filter
+ * fixed loop.last when the array only has one item
+ * made it possible to insert newlines in tag and variable blocks
+ * fixed a bug when a literal '\n' were present in a template text
+ * fixed bug when the filename of a template contains */
+ * refactored loaders
+
+* 0.9.3 (2009-11-11)
+
+This release is NOT backward compatible with the previous releases.
+
+ The loaders do not take the cache and autoReload arguments anymore. Instead,
+ the Twig_Environment class has two new options: cache and auto_reload.
+ Upgrading your code means changing this kind of code:
+
+ $loader = new Twig_Loader_Filesystem('/path/to/templates', '/path/to/compilation_cache', true);
+ $twig = new Twig_Environment($loader);
+
+ to something like this:
+
+ $loader = new Twig_Loader_Filesystem('/path/to/templates');
+ $twig = new Twig_Environment($loader, array(
+ 'cache' => '/path/to/compilation_cache',
+ 'auto_reload' => true,
+ ));
+
+ * deprecated the "items" filter as it is not needed anymore
+ * made cache and auto_reload options of Twig_Environment instead of arguments of Twig_Loader
+ * optimized template loading speed
+ * removed output when an error occurs in a template and render() is used
+ * made major speed improvements for loops (up to 300% on even the smallest loops)
+ * added properties as part of the sandbox mode
+ * added public properties support (obj.item can now be the item property on the obj object)
+ * extended set tag to support expression as value ({% set foo as 'foo' ~ 'bar' %} )
+ * fixed bug when \ was used in HTML
+
+* 0.9.2 (2009-10-29)
+
+ * made some speed optimizations
+ * changed the cache extension to .php
+ * added a js escaping strategy
+ * added support for short block tag
+ * changed the filter tag to allow chained filters
+ * made lexer more flexible as you can now change the default delimiters
+ * added set tag
+ * changed default directory permission when cache dir does not exist (more secure)
+ * added macro support
+ * changed filters first optional argument to be a Twig_Environment instance instead of a Twig_Template instance
+ * made Twig_Autoloader::autoload() a static method
+ * avoid writing template file if an error occurs
+ * added $ escaping when outputting raw strings
+ * enhanced some error messages to ease debugging
+ * fixed empty cache files when the template contains an error
+
+* 0.9.1 (2009-10-14)
+
+ * fixed a bug in PHP 5.2.6
+ * fixed numbers with one than one decimal
+ * added support for method calls with arguments ({{ foo.bar('a', 43) }})
+ * made small speed optimizations
+ * made minor tweaks to allow better extensibility and flexibility
+
+* 0.9.0 (2009-10-12)
+
+ * Initial release
View
31 vendor/Twig/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2009 by the Twig Team, see AUTHORS for more details.
+
+Some rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ * The names of the contributors may not be used to endorse or
+ promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
View
15 vendor/Twig/README.markdown
@@ -0,0 +1,15 @@
+Twig, the flexible, fast, and secure template language for PHP
+==============================================================
+
+Twig is a template language for PHP, released under the new BSD license (code
+and documentation).
+
+Twig uses a syntax similar to the Django and Jinja template languages which
+inspired the Twig runtime environment.
+
+More Information
+----------------
+
+Read the [documentation][1] for more information.
+
+[1]: http://twig.sensiolabs.org/documentation
View
46 vendor/Twig/lib/Twig/Autoloader.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Autoloads Twig classes.
+ *
+ * @package twig
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Autoloader
+{
+ /**
+ * Registers Twig_Autoloader as an SPL autoloader.
+ */
+ static public function register()
+ {
+ ini_set('unserialize_callback_func', 'spl_autoload_call');
+ spl_autoload_register(array(new self, 'autoload'));
+ }
+
+ /**
+ * Handles autoloading of classes.
+ *
+ * @param string $class A class name.
+ *
+ * @return boolean Returns true if the class has been loaded
+ */
+ static public function autoload($class)
+ {
+ if (0 !== strpos($class, 'Twig')) {
+ return;
+ }
+
+ if (is_file($file = dirname(__FILE__).'/../'.str_replace(array('_', "\0"), array('/', ''), $class).'.php')) {
+ require $file;
+ }
+ }
+}
View
219 vendor/Twig/lib/Twig/Compiler.php
@@ -0,0 +1,219 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ * (c) 2009 Armin Ronacher
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Compiles a node to PHP code.
+ *
+ * @package twig
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Compiler implements Twig_CompilerInterface
+{
+ protected $lastLine;
+ protected $source;
+ protected $indentation;
+ protected $env;
+
+ /**
+ * Constructor.
+ *
+ * @param Twig_Environment $env The twig environment instance
+ */
+ public function __construct(Twig_Environment $env)
+ {
+ $this->env = $env;
+ }
+
+ /**
+ * Returns the environment instance related to this compiler.
+ *
+ * @return Twig_Environment The environment instance
+ */
+ public function getEnvironment()
+ {
+ return $this->env;
+ }
+
+ /**
+ * Gets the current PHP code after compilation.
+ *
+ * @return string The PHP code
+ */
+ public function getSource()
+ {
+ return $this->source;
+ }
+
+ /**
+ * Compiles a node.
+ *
+ * @param Twig_NodeInterface $node The node to compile
+ * @param integer $indentation The current indentation
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function compile(Twig_NodeInterface $node, $indentation = 0)
+ {
+ $this->lastLine = null;
+ $this->source = '';
+ $this->indentation = $indentation;
+
+ $node->compile($this);
+
+ return $this;
+ }
+
+ public function subcompile(Twig_NodeInterface $node, $raw = true)
+ {
+ if (false === $raw) {
+ $this->addIndentation();
+ }
+
+ $node->compile($this);
+
+ return $this;
+ }
+
+ /**
+ * Adds a raw string to the compiled code.
+ *
+ * @param string $string The string
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function raw($string)
+ {
+ $this->source .= $string;
+
+ return $this;
+ }
+
+ /**
+ * Writes a string to the compiled code by adding indentation.
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function write()
+ {
+ $strings = func_get_args();
+ foreach ($strings as $string) {
+ $this->addIndentation();
+ $this->source .= $string;
+ }
+
+ return $this;
+ }
+
+ public function addIndentation()
+ {
+ $this->source .= str_repeat(' ', $this->indentation * 4);
+
+ return $this;
+ }
+
+ /**
+ * Adds a quoted string to the compiled code.
+ *
+ * @param string $value The string
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function string($value)
+ {
+ $this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\"));
+
+ return $this;
+ }
+
+ /**
+ * Returns a PHP representation of a given value.
+ *
+ * @param mixed $value The value to convert
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function repr($value)
+ {
+ if (is_int($value) || is_float($value)) {
+ $this->raw($value);
+ } elseif (null === $value) {
+ $this->raw('null');
+ } elseif (is_bool($value)) {
+ $this->raw($value ? 'true' : 'false');
+ } elseif (is_array($value)) {
+ $this->raw('array(');
+ $i = 0;
+ foreach ($value as $key => $value) {
+ if ($i++) {
+ $this->raw(', ');
+ }
+ $this->repr($key);
+ $this->raw(' => ');
+ $this->repr($value);
+ }
+ $this->raw(')');
+ } else {
+ $this->string($value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Adds debugging information.
+ *
+ * @param Twig_NodeInterface $node The related twig node
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function addDebugInfo(Twig_NodeInterface $node)
+ {
+ if ($node->getLine() != $this->lastLine) {
+ $this->lastLine = $node->getLine();
+ $this->write("// line {$node->getLine()}\n");
+ }
+
+ return $this;
+ }
+
+ /**
+ * Indents the generated code.
+ *
+ * @param integer $step The number of indentation to add
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function indent($step = 1)
+ {
+ $this->indentation += $step;
+
+ return $this;
+ }
+
+ /**
+ * Outdents the generated code.
+ *
+ * @param integer $step The number of indentation to remove
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function outdent($step = 1)
+ {
+ $this->indentation -= $step;
+
+ if ($this->indentation < 0) {
+ throw new Twig_Error('Unable to call outdent() as the indentation would become negative');
+ }
+
+ return $this;
+ }
+}
View
35 vendor/Twig/lib/Twig/CompilerInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface implemented by compiler classes.
+ *
+ * @package twig
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface Twig_CompilerInterface
+{
+ /**
+ * Compiles a node.
+ *
+ * @param Twig_NodeInterface $node The node to compile
+ *
+ * @return Twig_CompilerInterface The current compiler instance
+ */
+ function compile(Twig_NodeInterface $node);
+
+ /**
+ * Gets the current PHP code after compilation.
+ *
+ * @return string The PHP code
+ */
+ function getSource();
+}
View
1,060 vendor/Twig/lib/Twig/Environment.php
@@ -0,0 +1,1060 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Stores the Twig configuration.
+ *
+ * @package twig
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Environment
+{
+ const VERSION = '1.7.0-DEV';
+
+ protected $charset;
+ protected $loader;
+ protected $debug;
+ protected $autoReload;
+ protected $cache;
+ protected $lexer;
+ protected $parser;
+ protected $compiler;
+ protected $baseTemplateClass;
+ protected $extensions;
+ protected $parsers;
+ protected $visitors;
+ protected $filters;
+ protected $tests;
+ protected $functions;
+ protected $globals;
+ protected $runtimeInitialized;
+ protected $loadedTemplates;
+ protected $strictVariables;
+ protected $unaryOperators;
+ protected $binaryOperators;
+ protected $templateClassPrefix = '__TwigTemplate_';
+ protected $functionCallbacks;
+ protected $filterCallbacks;
+ protected $staging;
+
+ /**
+ * Constructor.
+ *
+ * Available options:
+ *
+ * * debug: When set to `true`, the generated templates have a __toString()
+ * method that you can use to display the generated nodes (default to
+ * false).
+ *
+ * * charset: The charset used by the templates (default to utf-8).
+ *
+ * * base_template_class: The base template class to use for generated
+ * templates (default to Twig_Template).
+ *
+ * * cache: An absolute path where to store the compiled templates, or
+ * false to disable compilation cache (default)
+ *
+ * * auto_reload: Whether to reload the template is the original source changed.
+ * If you don't provide the auto_reload option, it will be
+ * determined automatically base on the debug value.
+ *
+ * * strict_variables: Whether to ignore invalid variables in templates
+ * (default to false).
+ *
+ * * autoescape: Whether to enable auto-escaping (default to true);
+ *
+ * * optimizations: A flag that indicates which optimizations to apply
+ * (default to -1 which means that all optimizations are enabled;
+ * set it to 0 to disable)
+ *
+ * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance
+ * @param array $options An array of options
+ */
+ public function __construct(Twig_LoaderInterface $loader = null, $options = array())
+ {
+ if (null !== $loader) {
+ $this->setLoader($loader);
+ }
+
+ $options = array_merge(array(
+ 'debug' => false,
+ 'charset' => 'UTF-8',
+ 'base_template_class' => 'Twig_Template',
+ 'strict_variables' => false,
+ 'autoescape' => true,
+ 'cache' => false,
+ 'auto_reload' => null,
+ 'optimizations' => -1,
+ ), $options);
+
+ $this->debug = (bool) $options['debug'];
+ $this->charset = $options['charset'];
+ $this->baseTemplateClass = $options['base_template_class'];
+ $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
+ $this->extensions = array(
+ 'core' => new Twig_Extension_Core(),
+ 'escaper' => new Twig_Extension_Escaper((bool) $options['autoescape']),
+ 'optimizer' => new Twig_Extension_Optimizer($options['optimizations']),
+ );
+ $this->strictVariables = (bool) $options['strict_variables'];
+ $this->runtimeInitialized = false;
+ $this->setCache($options['cache']);
+ $this->functionCallbacks = array();
+ $this->filterCallbacks = array();
+ }
+
+ /**
+ * Gets the base template class for compiled templates.
+ *
+ * @return string The base template class name
+ */
+ public function getBaseTemplateClass()
+ {
+ return $this->baseTemplateClass;
+ }
+
+ /**
+ * Sets the base template class for compiled templates.
+ *
+ * @param string $class The base template class name
+ */
+ public function setBaseTemplateClass($class)
+ {
+ $this->baseTemplateClass = $class;
+ }
+
+ /**
+ * Enables debugging mode.
+ */
+ public function enableDebug()
+ {
+ $this->debug = true;
+ }
+
+ /**
+ * Disables debugging mode.
+ */
+ public function disableDebug()
+ {
+ $this->debug = false;
+ }
+
+ /**
+ * Checks if debug mode is enabled.
+ *
+ * @return Boolean true if debug mode is enabled, false otherwise
+ */
+ public function isDebug()
+ {
+ return $this->debug;
+ }
+
+ /**
+ * Enables the auto_reload option.
+ */
+ public function enableAutoReload()
+ {
+ $this->autoReload = true;
+ }
+
+ /**
+ * Disables the auto_reload option.
+ */
+ public function disableAutoReload()
+ {
+ $this->autoReload = false;
+ }
+
+ /**
+ * Checks if the auto_reload option is enabled.
+ *
+ * @return Boolean true if auto_reload is enabled, false otherwise
+ */
+ public function isAutoReload()
+ {
+ return $this->autoReload;
+ }
+
+ /**
+ * Enables the strict_variables option.
+ */
+ public function enableStrictVariables()
+ {
+ $this->strictVariables = true;
+ }
+
+ /**
+ * Disables the strict_variables option.
+ */
+ public function disableStrictVariables()
+ {
+ $this->strictVariables = false;
+ }
+
+ /**
+ * Checks if the strict_variables option is enabled.
+ *
+ * @return Boolean true if strict_variables is enabled, false otherwise
+ */
+ public function isStrictVariables()
+ {
+ return $this->strictVariables;
+ }
+
+ /**
+ * Gets the cache directory or false if cache is disabled.
+ *
+ * @return string|false
+ */
+ public function getCache()
+ {
+ return $this->cache;
+ }
+
+ /**
+ * Sets the cache directory or false if cache is disabled.
+ *
+ * @param string|false $cache The absolute path to the compiled templates,
+ * or false to disable cache
+ */
+ public function setCache($cache)
+ {
+ $this->cache = $cache ? $cache : false;
+ }
+
+ /**
+ * Gets the cache filename for a given template.
+ *
+ * @param string $name The template name
+ *
+ * @return string The cache file name
+ */
+ public function getCacheFilename($name)
+ {
+ if (false === $this->cache) {
+ return false;
+ }
+
+ $class = substr($this->getTemplateClass($name), strlen($this->templateClassPrefix));
+
+ return $this->getCache().'/'.substr($class, 0, 2).'/'.substr($class, 2, 2).'/'.substr($class, 4).'.php';
+ }
+
+ /**
+ * Gets the template class associated with the given string.
+ *
+ * @param string $name The name for which to calculate the template class name
+ *
+ * @return string The template class name
+ */
+ public function getTemplateClass($name)
+ {
+ return $this->templateClassPrefix.md5($this->loader->getCacheKey($name));
+ }
+
+ /**
+ * Gets the template class prefix.
+ *
+ * @return string The template class prefix
+ */
+ public function getTemplateClassPrefix()
+ {
+ return $this->templateClassPrefix;
+ }
+
+ /**
+ * Renders a template.
+ *
+ * @param string $name The template name
+ * @param array $context An array of parameters to pass to the template
+ *
+ * @return string The rendered template
+ */
+ public function render($name, array $context = array())
+ {
+ return $this->loadTemplate($name)->render($context);
+ }
+
+ /**
+ * Displays a template.
+ *
+ * @param string $name The template name
+ * @param array $context An array of parameters to pass to the template
+ */
+ public function display($name, array $context = array())
+ {
+ $this->loadTemplate($name)->display($context);
+ }
+
+ /**
+ * Loads a template by name.
+ *
+ * @param string $name The template name
+ *
+ * @return Twig_TemplateInterface A template instance representing the given template name
+ */
+ public function loadTemplate($name)
+ {
+ $cls = $this->getTemplateClass($name);
+
+ if (isset($this->loadedTemplates[$cls])) {
+ return $this->loadedTemplates[$cls];
+ }
+
+ if (!class_exists($cls, false)) {
+ if (false === $cache = $this->getCacheFilename($name)) {
+ eval('?>'.$this->compileSource($this->loader->getSource($name), $name));
+ } else {
+ if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) {
+ $this->writeCacheFile($cache, $this->compileSource($this->loader->getSource($name), $name));
+ }
+
+ require_once $cache;
+ }
+ }
+
+ if (!$this->runtimeInitialized) {
+ $this->initRuntime();
+ }
+
+ return $this->loadedTemplates[$cls] = new $cls($this);
+ }
+
+ /**
+ * Returns true if the template is still fresh.
+ *
+ * Besides checking the loader for freshness information,
+ * this method also checks if the enabled extensions have
+ * not changed.
+ *
+ * @param string $name The template name
+ * @param timestamp $time The last modification time of the cached template
+ *
+ * @return Boolean true if the template is fresh, false otherwise
+ */
+ public function isTemplateFresh($name, $time)
+ {
+ foreach ($this->extensions as $extension) {
+ $r = new ReflectionObject($extension);
+ if (filemtime($r->getFileName()) > $time) {
+ return false;
+ }
+ }
+
+ return $this->loader->isFresh($name, $time);
+ }
+
+ public function resolveTemplate($names)
+ {
+ if (!is_array($names)) {
+ $names = array($names);
+ }
+
+ foreach ($names as $name) {
+ if ($name instanceof Twig_Template) {
+ return $name;
+ }
+
+ try {
+ return $this->loadTemplate($name);
+ } catch (Twig_Error_Loader $e) {
+ }
+ }
+
+ if (1 === count($names)) {
+ throw $e;
+ }
+
+ throw new Twig_Error_Loader(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
+ }
+
+ /**
+ * Clears the internal template cache.
+ */
+ public function clearTemplateCache()
+ {
+ $this->loadedTemplates = array();
+ }
+
+ /**
+ * Clears the template cache files on the filesystem.
+ */
+ public function clearCacheFiles()
+ {
+ if (false === $this->cache) {
+ return;
+ }
+
+ foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->cache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
+ if ($file->isFile()) {
+ @unlink($file->getPathname());
+ }
+ }
+ }
+
+ /**
+ * Gets the Lexer instance.
+ *
+ * @return Twig_LexerInterface A Twig_LexerInterface instance
+ */
+ public function getLexer()
+ {
+ if (null === $this->lexer) {
+ $this->lexer = new Twig_Lexer($this);
+ }
+
+ return $this->lexer;
+ }
+
+ /**
+ * Sets the Lexer instance.
+ *
+ * @param Twig_LexerInterface A Twig_LexerInterface instance
+ */
+ public function setLexer(Twig_LexerInterface $lexer)
+ {
+ $this->lexer = $lexer;
+ }
+
+ /**
+ * Tokenizes a source code.
+ *
+ * @param string $source The template source code
+ * @param string $name The template name
+ *
+ * @return Twig_TokenStream A Twig_TokenStream instance
+ */
+ public function tokenize($source, $name = null)
+ {
+ return $this->getLexer()->tokenize($source, $name);
+ }
+
+ /**
+ * Gets the Parser instance.
+ *
+ * @return Twig_ParserInterface A Twig_ParserInterface instance
+ */
+ public function getParser()
+ {
+ if (null === $this->parser) {
+ $this->parser = new Twig_Parser($this);
+ }
+
+ return $this->parser;
+ }
+
+ /**
+ * Sets the Parser instance.
+ *
+ * @param Twig_ParserInterface A Twig_ParserInterface instance
+ */
+ public function setParser(Twig_ParserInterface $parser)
+ {
+ $this->parser = $parser;
+ }
+
+ /**
+ * Parses a token stream.
+ *
+ * @param Twig_TokenStream $tokens A Twig_TokenStream instance
+ *
+ * @return Twig_Node_Module A Node tree
+ */
+ public function parse(Twig_TokenStream $tokens)
+ {
+ return $this->getParser()->parse($tokens);
+ }
+
+ /**
+ * Gets the Compiler instance.
+ *
+ * @return Twig_CompilerInterface A Twig_CompilerInterface instance
+ */
+ public function getCompiler()
+ {
+ if (null === $this->compiler) {
+ $this->compiler = new Twig_Compiler($this);
+ }
+
+ return $this->compiler;
+ }
+
+ /**
+ * Sets the Compiler instance.
+ *
+ * @param Twig_CompilerInterface $compiler A Twig_CompilerInterface instance
+ */
+ public function setCompiler(Twig_CompilerInterface $compiler)
+ {
+ $this->compiler = $compiler;
+ }
+
+ /**
+ * Compiles a Node.
+ *
+ * @param Twig_NodeInterface $node A Twig_NodeInterface instance
+ *
+ * @return string The compiled PHP source code
+ */
+ public function compile(Twig_NodeInterface $node)
+ {
+ return $this->getCompiler()->compile($node)->getSource();
+ }
+
+ /**
+ * Compiles a template source code.
+ *
+ * @param string $source The template source code
+ * @param string $name The template name
+ *
+ * @return string The compiled PHP source code
+ */
+ public function compileSource($source, $name = null)
+ {
+ try {
+ return $this->compile($this->parse($this->tokenize($source, $name)));
+ } catch (Twig_Error $e) {
+ $e->setTemplateFile($name);
+ throw $e;
+ } catch (Exception $e) {
+ throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e);
+ }
+ }
+
+ /**
+ * Sets the Loader instance.
+ *
+ * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance
+ */
+ public function setLoader(Twig_LoaderInterface $loader)
+ {
+ $this->loader = $loader;
+ }
+
+ /**
+ * Gets the Loader instance.
+ *
+ * @return Twig_LoaderInterface A Twig_LoaderInterface instance
+ */
+ public function getLoader()
+ {
+ return $this->loader;
+ }
+
+ /**
+ * Sets the default template charset.
+ *
+ * @param string $charset The default charset
+ */
+ public function setCharset($charset)
+ {
+ $this->charset = $charset;
+ }
+
+ /**
+ * Gets the default template charset.
+ *
+ * @return string The default charset
+ */
+ public function getCharset()
+ {
+ return $this->charset;
+ }
+
+ /**
+ * Initializes the runtime environment.
+ */
+ public function initRuntime()
+ {
+ $this->runtimeInitialized = true;
+
+ foreach ($this->getExtensions() as $extension) {
+ $extension->initRuntime($this);
+ }
+ }
+
+ /**
+ * Returns true if the given extension is registered.
+ *
+ * @param string $name The extension name
+ *
+ * @return Boolean Whether the extension is registered or not
+ */
+ public function hasExtension($name)
+ {
+ return isset($this->extensions[$name]);
+ }
+
+ /**
+ * Gets an extension by name.
+ *
+ * @param string $name The extension name
+ *
+ * @return Twig_ExtensionInterface A Twig_ExtensionInterface instance
+ */
+ public function getExtension($name)
+ {
+ if (!isset($this->extensions[$name])) {
+ throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $name));
+ }
+
+ return $this->extensions[$name];
+ }
+
+ /**
+ * Registers an extension.
+ *
+ * @param Twig_ExtensionInterface $extension A Twig_ExtensionInterface instance
+ */
+ public function addExtension(Twig_ExtensionInterface $extension)
+ {
+ $this->extensions[$extension->getName()] = $extension;
+ $this->parsers = null;
+ $this->visitors = null;
+ $this->filters = null;
+ $this->tests = null;
+ $this->functions = null;
+ $this->globals = null;
+ }
+
+ /**
+ * Removes an extension by name.
+ *
+ * @param string $name The extension name
+ */
+ public function removeExtension($name)
+ {
+ unset($this->extensions[$name]);
+ $this->parsers = null;
+ $this->visitors = null;
+ $this->filters = null;
+ $this->tests = null;
+ $this->functions = null;
+ $this->globals = null;
+ }
+
+ /**
+ * Registers an array of extensions.
+ *
+ * @param array $extensions An array of extensions
+ */
+ public function setExtensions(array $extensions)
+ {
+ foreach ($extensions as $extension) {
+ $this->addExtension($extension);
+ }
+ }
+
+ /**
+ * Returns all registered extensions.
+ *
+ * @return array An array of extensions
+ */
+ public function getExtensions()
+ {
+ return $this->extensions;
+ }
+
+ /**
+ * Registers a Token Parser.
+ *
+ * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance
+ */
+ public function addTokenParser(Twig_TokenParserInterface $parser)
+ {
+ $this->staging['token_parsers'][] = $parser;
+ $this->parsers = null;
+ }
+
+ /**
+ * Gets the registered Token Parsers.
+ *
+ * @return Twig_TokenParserBrokerInterface A broker containing token parsers
+ */
+ public function getTokenParsers()
+ {
+ if (null === $this->parsers) {
+ $this->parsers = new Twig_TokenParserBroker();
+
+ if (isset($this->staging['token_parsers'])) {
+ foreach ($this->staging['token_parsers'] as $parser) {
+ $this->parsers->addTokenParser($parser);
+ }
+ }
+
+ foreach ($this->getExtensions() as $extension) {
+ $parsers = $extension->getTokenParsers();
+ foreach($parsers as $parser) {
+ if ($parser instanceof Twig_TokenParserInterface) {
+ $this->parsers->addTokenParser($parser);
+ } elseif ($parser instanceof Twig_TokenParserBrokerInterface) {
+ $this->parsers->addTokenParserBroker($parser);
+ } else {
+ throw new Twig_Error_Runtime('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances');
+ }
+ }
+ }
+ }
+
+ return $this->parsers;
+ }
+
+ /**
+ * Gets registered tags.
+ *
+ * Be warned that this method cannot return tags defined by Twig_TokenParserBrokerInterface classes.
+ *
+ * @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances
+ */
+ public function getTags()
+ {
+ $tags = array();
+ foreach ($this->getTokenParsers()->getParsers() as $parser) {
+ if ($parser instanceof Twig_TokenParserInterface) {
+ $tags[$parser->getTag()] = $parser;
+ }
+ }
+
+ return $tags;
+ }
+
+ /**
+ * Registers a Node Visitor.
+ *
+ * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance
+ */
+ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
+ {
+ $this->staging['visitors'][] = $visitor;
+ $this->visitors = null;
+ }
+
+ /**
+ * Gets the registered Node Visitors.
+ *
+ * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
+ */
+ public function getNodeVisitors()
+ {
+ if (null === $this->visitors) {
+ $this->visitors = isset($this->staging['visitors']) ? $this->staging['visitors'] : array();
+ foreach ($this->getExtensions() as $extension) {
+ $this->visitors = array_merge($this->visitors, $extension->getNodeVisitors());
+ }
+ }
+
+ return $this->visitors;
+ }
+
+ /**
+ * Registers a Filter.
+ *
+ * @param string $name The filter name
+ * @param Twig_FilterInterface $filter A Twig_FilterInterface instance
+ */
+ public function addFilter($name, Twig_FilterInterface $filter)
+ {
+ $this->staging['filters'][$name] = $filter;
+ $this->filters = null;
+ }
+
+ /**
+ * Get a filter by name.
+ *
+ * Subclasses may override this method and load filters differently;
+ * so no list of filters is available.
+ *
+ * @param string $name The filter name
+ *
+ * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exists
+ */
+ public function getFilter($name)
+ {
+ if (null === $this->filters) {
+ $this->getFilters();
+ }
+
+ if (isset($this->filters[$name])) {
+ return $this->filters[$name];
+ }
+
+ foreach ($this->filters as $pattern => $filter) {
+ $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);
+
+ if ($count) {
+ if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
+ array_shift($matches);
+ $filter->setArguments($matches);
+
+ return $filter;
+ }
+ }
+ }
+
+ foreach ($this->filterCallbacks as $callback) {
+ if (false !== $filter = call_user_func($callback, $name)) {
+ return $filter;
+ }
+ }
+
+ return false;
+ }
+
+ public function registerUndefinedFilterCallback($callable)
+ {
+ $this->filterCallbacks[] = $callable;
+ }
+
+ /**
+ * Gets the registered Filters.
+ *
+ * Be warned that this method cannot return filters defined with registerUndefinedFunctionCallback.
+ *
+ * @return Twig_FilterInterface[] An array of Twig_FilterInterface instances
+ *
+ * @see registerUndefinedFilterCallback
+ */
+ public function getFilters()
+ {
+ if (null === $this->filters) {
+ $this->filters = isset($this->staging['filters']) ? $this->staging['filters'] : array();
+ foreach ($this->getExtensions() as $extension) {
+ $this->filters = array_merge($this->filters, $extension->getFilters());
+ }
+ }
+
+ return $this->filters;
+ }
+
+ /**
+ * Registers a Test.
+ *
+ * @param string $name The test name
+ * @param Twig_TestInterface $test A Twig_TestInterface instance
+ */
+ public function addTest($name, Twig_TestInterface $test)
+ {
+ $this->staging['tests'][$name] = $test;
+ $this->tests = null;
+ }
+
+ /**
+ * Gets the registered Tests.
+ *
+ * @return Twig_TestInterface[] An array of Twig_TestInterface instances
+ */
+ public function getTests()
+ {
+ if (null === $this->tests) {
+ $this->tests = isset($this->staging['tests']) ? $this->staging['tests'] : array();
+ foreach ($this->getExtensions() as $extension) {
+ $this->tests = array_merge($this->tests, $extension->getTests());
+ }
+ }
+
+ return $this->tests;
+ }
+
+ /**
+ * Registers a Function.
+ *
+ * @param string $name The function name
+ * @param Twig_FunctionInterface $function A Twig_FunctionInterface instance
+ */
+ public function addFunction($name, Twig_FunctionInterface $function)
+ {
+ $this->staging['functions'][$name] = $function;
+ $this->functions = null;
+ }
+
+ /**
+ * Get a function by name.
+ *
+ * Subclasses may override this method and load functions differently;
+ * so no list of functions is available.
+ *
+ * @param string $name function name
+ *
+ * @return Twig_Function|false A Twig_Function instance or false if the function does not exists
+ */
+ public function getFunction($name)
+ {
+ if (null === $this->functions) {
+ $this->getFunctions();
+ }
+
+ if (isset($this->functions[$name])) {
+ return $this->functions[$name];
+ }
+
+ foreach ($this->functions as $pattern => $function) {
+ $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), <