Преглед на файлове

Merge branch 'feature/partial-loader' into dev

Justin Hileman преди 14 години
родител
ревизия
e5f3a059ab
променени са 5 файла, в които са добавени 151 реда и са изтрити 1 реда
  1. 4 1
      Mustache.php
  2. 85 0
      MustacheLoader.php
  3. 60 0
      test/MustacheLoaderTest.php
  4. 1 0
      test/fixtures/bar.mustache
  5. 1 0
      test/fixtures/foo.mustache

+ 4 - 1
Mustache.php

@@ -819,7 +819,10 @@ class Mustache {
 	 * @return string
 	 */
 	protected function _getPartial($tag_name) {
-		if (is_array($this->_partials) && isset($this->_partials[$tag_name])) {
+		if (
+			(is_array($this->_partials) || $this->_partials instanceof ArrayAccess)
+			&& isset($this->_partials[$tag_name])
+		) {
 			return $this->_partials[$tag_name];
 		}
 

+ 85 - 0
MustacheLoader.php

@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * A Mustache Partial filesystem loader.
+ *
+ * @author Justin Hileman {@link http://justinhileman.com}
+ */
+class MustacheLoader implements ArrayAccess {
+
+	protected $baseDir;
+	protected $partialsCache = array();
+	protected $extension;
+
+	/**
+	 * MustacheLoader constructor.
+	 *
+	 * @access public
+	 * @param  string $baseDir   Base template directory.
+	 * @param  string $extension File extension for Mustache files (default: 'mustache')
+	 * @return void
+	 */
+	public function __construct($baseDir, $extension = 'mustache') {
+		if (!is_dir($baseDir)) {
+			throw new InvalidArgumentException('$baseDir must be a valid directory, ' . $baseDir . ' given.');
+		}
+
+		$this->baseDir   = $baseDir;
+		$this->extension = $extension;
+	}
+
+	/**
+	 * @param  string $offset Name of partial
+	 * @return boolean
+	 */
+	public function offsetExists($offset) {
+		return (isset($this->partialsCache[$offset]) || file_exists($this->pathName($offset)));
+	}
+	
+	/**
+	 * @throws InvalidArgumentException if the given partial doesn't exist
+	 * @param  string $offset Name of partial
+	 * @return string Partial template contents
+	 */
+	public function offsetGet($offset) {
+		if (!$this->offsetExists($offset)) {
+			throw new InvalidArgumentException('Partial does not exist: ' . $offset);
+		}
+
+		if (!isset($this->partialsCache[$offset])) {
+			$this->partialsCache[$offset] = file_get_contents($this->pathName($offset));
+		}
+
+		return $this->partialsCache[$offset];
+	}
+	
+	/**
+	 * MustacheLoader is an immutable filesystem loader. offsetSet throws a LogicException if called.
+	 *
+	 * @throws LogicException
+	 * @return void
+	 */
+	public function offsetSet($offset, $value) {
+		throw new LogicException('Unable to set offset: MustacheLoader is an immutable ArrayAccess object.');
+	}
+	
+	/**
+	 * MustacheLoader is an immutable filesystem loader. offsetUnset throws a LogicException if called.
+	 *
+	 * @throws LogicException
+	 * @return void
+	 */
+	public function offsetUnset($offset) {
+		throw new LogicException('Unable to unset offset: MustacheLoader is an immutable ArrayAccess object.');
+	}
+
+	/**
+	 * An internal helper for generating path names.
+	 * 
+	 * @param  string $file Partial name
+	 * @return string File path
+	 */
+	protected function pathName($file) {
+		return $this->baseDir . '/' . $file . '.' . $this->extension;
+	}
+}

+ 60 - 0
test/MustacheLoaderTest.php

@@ -0,0 +1,60 @@
+<?php
+
+require_once '../Mustache.php';
+require_once '../MustacheLoader.php';
+
+/**
+ * @group loader
+ */
+class MustacheLoaderTest extends PHPUnit_Framework_TestCase {
+
+	public function testTheActualFilesystemLoader() {
+		$loader = new MustacheLoader(dirname(__FILE__).'/fixtures');
+		$this->assertEquals(file_get_contents(dirname(__FILE__).'/fixtures/foo.mustache'), $loader['foo']);
+		$this->assertEquals(file_get_contents(dirname(__FILE__).'/fixtures/bar.mustache'), $loader['bar']);
+	}
+
+	public function testMustacheUsesFilesystemLoader() {
+		$template = '{{> foo }} {{> bar }}';
+		$data = array(
+			'truthy' => true,
+			'foo'    => 'FOO',
+			'bar'    => 'BAR',
+		);
+		$output = 'FOO BAR';
+		$m = new Mustache();
+		$partials = new MustacheLoader(dirname(__FILE__).'/fixtures');
+		$this->assertEquals($output, $m->render($template, $data, $partials));
+	}
+
+	public function testMustacheUsesDifferentLoadersToo() {
+		$template = '{{> foo }} {{> bar }}';
+		$data = array(
+			'truthy' => true,
+			'foo'    => 'FOO',
+			'bar'    => 'BAR',
+		);
+		$output = 'FOO BAR';
+		$m = new Mustache();
+		$partials = new DifferentMustacheLoader();
+		$this->assertEquals($output, $m->render($template, $data, $partials));
+	}
+}
+
+class DifferentMustacheLoader implements ArrayAccess {
+	protected $partials = array(
+		'foo' => '{{ foo }}',
+		'bar' => '{{# truthy }}{{ bar }}{{/ truthy }}',
+	);
+
+	public function offsetExists($offset) {
+		return isset($this->partials[$offset]);
+	}
+
+	public function offsetGet($offset) {
+		return $this->partials[$offset];
+	}
+
+	public function offsetSet($offset, $value) {}
+	public function offsetUnset($offset) {}
+}

+ 1 - 0
test/fixtures/bar.mustache

@@ -0,0 +1 @@
+{{# truthy }}{{ bar }}{{/ truthy }}

+ 1 - 0
test/fixtures/foo.mustache

@@ -0,0 +1 @@
+{{ foo }}