|
@@ -0,0 +1,344 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
|
|
+
|
|
|
+namespace eYaf;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * Layout class used for render layouts and views.
|
|
|
+ *
|
|
|
+ * Layout class allows to use of a base layout skeleton and render views inside
|
|
|
+ * this layout template.
|
|
|
+ * The concept is to not render and display the view template directly but storing it
|
|
|
+ * in {@link $content} property. Then will render the skeleton layout and
|
|
|
+ * pass the {@link $content} property to it.
|
|
|
+ * <code>
|
|
|
+ * application/views/layouts/front.phtml
|
|
|
+ *
|
|
|
+ * <html>
|
|
|
+ * <head>
|
|
|
+ * <title><?php echo $title ?></title>
|
|
|
+ * </head>
|
|
|
+ * <body>
|
|
|
+ * <?= $_content_ // This is where your view from each action
|
|
|
+ * will be displayed ?>
|
|
|
+ * </body>
|
|
|
+ * </html>
|
|
|
+ * </code>
|
|
|
+ *
|
|
|
+ * If no layout is defined then returns the renderd action view template.
|
|
|
+ *
|
|
|
+ * Also allows to set variable to views and access them from the base
|
|
|
+ * skeleton layout. In above layout $title variable is set to title tag.
|
|
|
+ * Then in a view template we can set the value for $title variable.
|
|
|
+ * <code>
|
|
|
+ * application/views/index/index.phtml
|
|
|
+ *
|
|
|
+ * <?php $this->title = "Index Action" ?>
|
|
|
+ * <h1>Index Action</h1>
|
|
|
+ * </code>
|
|
|
+ *
|
|
|
+ * @author Andreas Kollaros <[email protected]>
|
|
|
+ *
|
|
|
+ */
|
|
|
+class Layout implements \Yaf\View_Interface
|
|
|
+{
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The template engine to render views and layout templates.
|
|
|
+ *
|
|
|
+ * Default engine is Yaf\View\Simple
|
|
|
+ *
|
|
|
+ * @var Yaf\View\Simple
|
|
|
+ */
|
|
|
+ public $engine;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Options to be passed to template engine.
|
|
|
+ *
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ protected $options=array();
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ */
|
|
|
+ protected $layout_path;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The name of layout file without extension.
|
|
|
+ *
|
|
|
+ * @var string
|
|
|
+ */
|
|
|
+ protected $layout = 'layout';
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Handles the rendered action view data.
|
|
|
+ *
|
|
|
+ * @var string
|
|
|
+ */
|
|
|
+ protected $content;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Array with assigned template variables.
|
|
|
+ *
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ protected $tpl_vars = array();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Template directory.
|
|
|
+ *
|
|
|
+ * @var string
|
|
|
+ */
|
|
|
+ protected $tpl_dir;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Constructor
|
|
|
+ *
|
|
|
+ * @param array $options key/value pair of options to be assigned to
|
|
|
+ * template engine.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function __construct($path, $options=array())
|
|
|
+ {
|
|
|
+ $this->layout_path = $path;
|
|
|
+ $this->options = $options;
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Return the instance of a template engine.
|
|
|
+ *
|
|
|
+ * @return Yaf\View\Simple
|
|
|
+ */
|
|
|
+ protected function engine()
|
|
|
+ {
|
|
|
+ $this->engine = $this->engine ?: new \Yaf\View\Simple(
|
|
|
+ $this->tpl_dir,
|
|
|
+ $this->options
|
|
|
+ );
|
|
|
+
|
|
|
+ return $this->engine;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Create engine instance and set the path of views and layout templates.
|
|
|
+ *
|
|
|
+ * Layout path is set by default to layout directory inside views path.
|
|
|
+ *
|
|
|
+ * @param string $path The directory to set as the path.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function setScriptPath($path)
|
|
|
+ {
|
|
|
+ if (is_readable($path)) {
|
|
|
+ $this->tpl_dir = $path;
|
|
|
+ $this->engine()->setScriptPath($path);
|
|
|
+
|
|
|
+ // Overwirte layouts path by setting it where views path is.
|
|
|
+ // This will force layout in modules to be placed in
|
|
|
+ // modules/views/layouts directory
|
|
|
+ $this->layout_path = $path . "/layouts";
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ throw new \Exception("Invalid path: {$path}");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Getter method for views path.
|
|
|
+ *
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ public function getScriptPath()
|
|
|
+ {
|
|
|
+ return $this->engine()->getScriptPath();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Setter for Layout::layout variable
|
|
|
+ *
|
|
|
+ * @param string $name the name of layout file without extension.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function setLayout($name)
|
|
|
+ {
|
|
|
+ $this->layout = $name;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Getter for Layout::layout variable
|
|
|
+ *
|
|
|
+ * @return string the name of layout file without extension
|
|
|
+ */
|
|
|
+ public function getLayout()
|
|
|
+ {
|
|
|
+ return $this->layout;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public function setLayoutPath($path)
|
|
|
+ {
|
|
|
+ $this->layout_path = $path;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get full layout path with filename and extension.
|
|
|
+ *
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ public function getLayoutPath()
|
|
|
+ {
|
|
|
+ $config = \Yaf\Application::app()->getConfig()->get('application');
|
|
|
+ return $this->layout_path . "/" . $this->layout . ".{$config->view->ext}";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Assign a variable to the template
|
|
|
+ *
|
|
|
+ * @param string $name The variable name.
|
|
|
+ * @param mixed $value The variable value.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function __set($name, $value)
|
|
|
+ {
|
|
|
+ $this->assign($name, $value);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Allows testing with empty() and isset() to work
|
|
|
+ *
|
|
|
+ * @param string $name
|
|
|
+ *
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ public function __isset($name)
|
|
|
+ {
|
|
|
+ return (null !== $this->engine()->$name);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Allows unset() on object properties to work
|
|
|
+ *
|
|
|
+ * @param string $name
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function __unset($name)
|
|
|
+ {
|
|
|
+ $this->engine()->clear($name);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Assign variables to the template
|
|
|
+ *
|
|
|
+ * Allows setting a specific key to the specified value, OR passing
|
|
|
+ * an array of key => value pairs to set en masse.
|
|
|
+ *
|
|
|
+ * @see __set()
|
|
|
+ *
|
|
|
+ * @param string|array $name The assignment strategy to use (key or
|
|
|
+ * array of key => value pairs)
|
|
|
+ * @param mixed $value (Optional) If assigning a named variable,
|
|
|
+ * use this as the value.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function assign($name, $value = null)
|
|
|
+ {
|
|
|
+
|
|
|
+ $this->tpl_vars[$name] = $value;
|
|
|
+
|
|
|
+ $this->engine()->assign($name, $value);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Assign variables by reference to the template
|
|
|
+ *
|
|
|
+ */
|
|
|
+ public function assignRef($name, &$value)
|
|
|
+ {
|
|
|
+ $this->tpl_vars[$name] = $value;
|
|
|
+
|
|
|
+ $this->engine()->assignRef($name, $value);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Clear all assigned variables
|
|
|
+ *
|
|
|
+ * Clears all variables assigned to Yaf\View either via
|
|
|
+ * {@link assign()} or property overloading
|
|
|
+ * ({@link __get()}/{@link __set()}).
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function clearVars() {
|
|
|
+ $this->tpl_vars = array();
|
|
|
+ $this->engine()->clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Processes a view and returns the output.
|
|
|
+ *
|
|
|
+ * This method called once from controller to render the given view.
|
|
|
+ * So render the view at $this->content property and then render the
|
|
|
+ * layout template.
|
|
|
+ *
|
|
|
+ * @param string $tpl The template to process.
|
|
|
+ * @param array $tpl_vars Additional variables to be assigned to template.
|
|
|
+ *
|
|
|
+ * @return string The view or layout template output.
|
|
|
+ */
|
|
|
+ public function render($tpl, $tpl_vars=array()) {
|
|
|
+
|
|
|
+ $tpl_vars = array_merge($this->tpl_vars, $tpl_vars);
|
|
|
+
|
|
|
+ $this->content = $this->engine()->render($tpl, $tpl_vars);
|
|
|
+
|
|
|
+ // if no layout is defined,
|
|
|
+ // return the rendered view template
|
|
|
+ if (null == $this->layout) {
|
|
|
+
|
|
|
+ return $this->content;
|
|
|
+ }
|
|
|
+
|
|
|
+ // If we assign some variables into view template, then maybe we need
|
|
|
+ // them to layout view.
|
|
|
+ // Hack??
|
|
|
+ // Get template vars from view via Reflection class and assign them to
|
|
|
+ // layout view
|
|
|
+ $ref = new \ReflectionClass($this->engine());
|
|
|
+ $prop = $ref->getProperty('_tpl_vars');
|
|
|
+ $prop->setAccessible(true);
|
|
|
+ $view_vars = $prop->getValue($this->engine());
|
|
|
+
|
|
|
+ $tpl_vars = array_merge($tpl_vars, $view_vars);
|
|
|
+ $tpl_vars['_content_'] = $this->content;
|
|
|
+
|
|
|
+ return $this->engine()->render(
|
|
|
+ $this->getLayoutPath(),
|
|
|
+ $tpl_vars
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Directly display the constens of a view / layout template.
|
|
|
+ *
|
|
|
+ * @param string $tpl The template to process.
|
|
|
+ * @param array $tpl_vars Additional variables to be assigned to template.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function display($tpl, $tpl_vars=array()) {
|
|
|
+ echo $this->render($tpl, $tpl_vars);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|