| 1 |
<?php |
| 2 |
|
| 3 |
/* |
| 4 |
* This file is part of Mustache.php. |
| 5 |
* |
| 6 |
* (c) 2010-2014 Justin Hileman |
| 7 |
* |
| 8 |
* For the full copyright and license information, please view the LICENSE |
| 9 |
* file that was distributed with this source code. |
| 10 |
*/ |
| 11 |
|
| 12 |
/** |
| 13 |
* A Mustache Template loader for inline templates. |
| 14 |
* |
| 15 |
* With the InlineLoader, templates can be defined at the end of any PHP source |
| 16 |
* file: |
| 17 |
* |
| 18 |
* $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__); |
| 19 |
* $hello = $loader->load('hello'); |
| 20 |
* $goodbye = $loader->load('goodbye'); |
| 21 |
* |
| 22 |
* __halt_compiler(); |
| 23 |
* |
| 24 |
* @@ hello |
| 25 |
* Hello, {{ planet }}! |
| 26 |
* |
| 27 |
* @@ goodbye |
| 28 |
* Goodbye, cruel {{ planet }} |
| 29 |
* |
| 30 |
* Templates are deliniated by lines containing only `@@ name`. |
| 31 |
* |
| 32 |
* The InlineLoader is well-suited to micro-frameworks such as Silex: |
| 33 |
* |
| 34 |
* $app->register(new MustacheServiceProvider, array( |
| 35 |
* 'mustache.loader' => new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__) |
| 36 |
* )); |
| 37 |
* |
| 38 |
* $app->get('/{name}', function ($name) use ($app) { |
| 39 |
* return $app['mustache']->render('hello', compact('name')); |
| 40 |
* }) |
| 41 |
* ->value('name', 'world'); |
| 42 |
* |
| 43 |
* // ... |
| 44 |
* |
| 45 |
* __halt_compiler(); |
| 46 |
* |
| 47 |
* @@ hello |
| 48 |
* Hello, {{ name }}! |
| 49 |
* |
| 50 |
*/ |
| 51 |
class Mustache_Loader_InlineLoader implements Mustache_Loader |
| 52 |
{ |
| 53 |
protected $fileName; |
| 54 |
protected $offset; |
| 55 |
protected $templates; |
| 56 |
|
| 57 |
/** |
| 58 |
* The InlineLoader requires a filename and offset to process templates. |
| 59 |
* The magic constants `__FILE__` and `__COMPILER_HALT_OFFSET__` are usually |
| 60 |
* perfectly suited to the job: |
| 61 |
* |
| 62 |
* $loader = new Mustache_Loader_InlineLoader(__FILE__, __COMPILER_HALT_OFFSET__); |
| 63 |
* |
| 64 |
* Note that this only works if the loader is instantiated inside the same |
| 65 |
* file as the inline templates. If the templates are located in another |
| 66 |
* file, it would be necessary to manually specify the filename and offset. |
| 67 |
* |
| 68 |
* @param string $fileName The file to parse for inline templates |
| 69 |
* @param int $offset A string offset for the start of the templates. |
| 70 |
* This usually coincides with the `__halt_compiler` |
| 71 |
* call, and the `__COMPILER_HALT_OFFSET__`. |
| 72 |
*/ |
| 73 |
public function __construct($fileName, $offset) |
| 74 |
{ |
| 75 |
if (!is_file($fileName)) { |
| 76 |
throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid filename.'); |
| 77 |
} |
| 78 |
|
| 79 |
if (!is_int($offset) || $offset < 0) { |
| 80 |
throw new Mustache_Exception_InvalidArgumentException('InlineLoader expects a valid file offset.'); |
| 81 |
} |
| 82 |
|
| 83 |
$this->fileName = $fileName; |
| 84 |
$this->offset = $offset; |
| 85 |
} |
| 86 |
|
| 87 |
/** |
| 88 |
* Load a Template by name. |
| 89 |
* |
| 90 |
* @throws Mustache_Exception_UnknownTemplateException If a template file is not found. |
| 91 |
* |
| 92 |
* @param string $name |
| 93 |
* |
| 94 |
* @return string Mustache Template source |
| 95 |
*/ |
| 96 |
public function load($name) |
| 97 |
{ |
| 98 |
$this->loadTemplates(); |
| 99 |
|
| 100 |
if (!array_key_exists($name, $this->templates)) { |
| 101 |
throw new Mustache_Exception_UnknownTemplateException($name); |
| 102 |
} |
| 103 |
|
| 104 |
return $this->templates[$name]; |
| 105 |
} |
| 106 |
|
| 107 |
/** |
| 108 |
* Parse and load templates from the end of a source file. |
| 109 |
*/ |
| 110 |
protected function loadTemplates() |
| 111 |
{ |
| 112 |
if ($this->templates === null) { |
| 113 |
$this->templates = array(); |
| 114 |
$data = file_get_contents($this->fileName, false, null, $this->offset); |
| 115 |
foreach (preg_split("/^@@(?= [\w\d\.]+$)/m", $data, -1) as $chunk) { |
| 116 |
if (trim($chunk)) { |
| 117 |
list($name, $content) = explode("\n", $chunk, 2); |
| 118 |
$this->templates[trim($name)] = trim($content); |
| 119 |
} |
| 120 |
} |
| 121 |
} |
| 122 |
} |
| 123 |
} |
| 124 |
|