From 35e53b8cef8447c305188447b93dc5e922922fdd Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Thu, 22 Mar 2012 11:48:07 -0500 Subject: [PATCH] Reintegrating Blade with Laravel using View engine event. --- application/config/application.php | 1 + application/start.php | 13 ++ laravel/blade.php | 187 +++++++++++++++++++++++++++++ laravel/core.php | 1 + laravel/laravel.php | 1 + laravel/view.php | 13 +- storage/views/.gitignore | 0 7 files changed, 213 insertions(+), 3 deletions(-) create mode 100644 laravel/blade.php create mode 100644 storage/views/.gitignore diff --git a/application/config/application.php b/application/config/application.php index 4c1a769f0c5..c5f5a3ba72b 100644 --- a/application/config/application.php +++ b/application/config/application.php @@ -119,6 +119,7 @@ 'Auth' => 'Laravel\\Auth', 'Asset' => 'Laravel\\Asset', 'Autoloader' => 'Laravel\\Autoloader', + 'Blade' => 'Laravel\\Blade', 'Bundle' => 'Laravel\\Bundle', 'Cache' => 'Laravel\\Cache', 'Config' => 'Laravel\\Config', diff --git a/application/start.php b/application/start.php index 8420ac568bc..518448a3756 100644 --- a/application/start.php +++ b/application/start.php @@ -112,6 +112,19 @@ return Lang::file($bundle, $language, $file); }); +/* +|-------------------------------------------------------------------------- +| Enable The Blade View Engine +|-------------------------------------------------------------------------- +| +| The Blade view engine provides a clean, beautiful templating language +| for your application, including syntax for echoing data and all of +| the typical PHP control structures. We'll simply enable it here. +| +*/ + +Blade::sharpen(); + /* |-------------------------------------------------------------------------- | Set The Default Timezone diff --git a/laravel/blade.php b/laravel/blade.php new file mode 100644 index 00000000000..015af686d2f --- /dev/null +++ b/laravel/blade.php @@ -0,0 +1,187 @@ +path, BLADE_EXT)) + { + return false; + } + + $compiled = path('storage').'views/'.md5($view->path); + + // If the view doesn't exist or has been modified since the last time it + // was compiled, we will recompile the view into pure PHP from it's + // Blade representation, writing it to cached storage. + if ( ! file_exists($compiled) or (filemtime($view->path) > filemtime($compiled))) + { + file_put_contents($compiled, Blade::compile($view->path)); + } + + $view->path = $compiled; + + // Once the view has been compiled, we can simply set the path to the + // compiled view on the view instance and call the typical "get" + // method on the view to evaluate the compiled PHP view. + return $view->get(); + }); + } + + /** + * Compiles the specified file containing Blade pseudo-code into valid PHP. + * + * @param string $path + * @return string + */ + public static function compile($path) + { + return static::compile_string(file_get_contents($path)); + } + + /** + * Compiles the given string containing Blade pseudo-code into valid PHP. + * + * @param string $value + * @return string + */ + public static function compile_string($value) + { + foreach (static::$compilers as $compiler) + { + $method = "compile_{$compiler}"; + + $value = static::$method($value); + } + + return $value; + } + + /** + * Rewrites Blade echo statements into PHP echo statements. + * + * @param string $value + * @return string + */ + protected static function compile_echos($value) + { + return preg_replace('/\{\{(.+?)\}\}/', '', $value); + } + + /** + * Rewrites Blade structure openings into PHP structure openings. + * + * @param string $value + * @return string + */ + protected static function compile_structure_openings($value) + { + $pattern = '/(\s*)@(if|elseif|foreach|for|while)(\s*\(.*\))/'; + + return preg_replace($pattern, '$1', $value); + } + + /** + * Rewrites Blade structure closings into PHP structure closings. + * + * @param string $value + * @return string + */ + protected static function compile_structure_closings($value) + { + $pattern = '/(\s*)@(endif|endforeach|endfor|endwhile)(\s*)/'; + + return preg_replace($pattern, '$1$3', $value); + } + + /** + * Rewrites Blade else statements into PHP else statements. + * + * @param string $value + * @return string + */ + protected static function compile_else($value) + { + return preg_replace('/(\s*)@(else)(\s*)/', '$1$3', $value); + } + + /** + * Rewrites Blade @yield statements into Section statements. + * + * The Blade @yield statement is a shortcut to the Section::yield method. + * + * @param string $value + * @return string + */ + protected static function compile_yields($value) + { + $pattern = static::matcher('yield'); + + return preg_replace($pattern, '$1', $value); + } + + /** + * Rewrites Blade @section statements into Section statements. + * + * The Blade @section statement is a shortcut to the Section::start method. + * + * @param string $value + * @return string + */ + protected static function compile_section_start($value) + { + $pattern = static::matcher('section'); + + return preg_replace($pattern, '$1', $value); + } + + /** + * Rewrites Blade @endsection statements into Section statements. + * + * The Blade @endsection statement is a shortcut to the Section::stop method. + * + * @param string $value + * @return string + */ + protected static function compile_section_end($value) + { + return preg_replace('/@endsection/', '', $value); + } + + /** + * Get the regular expression for a generic Blade function. + * + * @param string $function + * @return string + */ + protected static function matcher($function) + { + return '/(\s*)@'.$function.'(\s*\(.*\))/'; + } + +} \ No newline at end of file diff --git a/laravel/core.php b/laravel/core.php index 2f830d1eb98..48ad7ecb3ef 100644 --- a/laravel/core.php +++ b/laravel/core.php @@ -13,6 +13,7 @@ define('EXT', '.php'); define('CRLF', "\r\n"); +define('BLADE_EXT', '.blade.php'); define('DEFAULT_BUNDLE', 'application'); define('MB_STRING', (int) function_exists('mb_get_info')); diff --git a/laravel/laravel.php b/laravel/laravel.php index 97e4e7509f4..3a90fe0d64e 100644 --- a/laravel/laravel.php +++ b/laravel/laravel.php @@ -11,6 +11,7 @@ | may be used by the developer. | */ + require 'core.php'; /* diff --git a/laravel/view.php b/laravel/view.php index 4eddb64a9f1..52cac63e3ab 100644 --- a/laravel/view.php +++ b/laravel/view.php @@ -117,9 +117,9 @@ protected function path($view) $view = str_replace('.', '/', $view); - // We delegate the determination of view paths to the view loader - // event so that the developer is free to override and manage - // the loading views in any way they see fit. + // We delegate the determination of view paths to the view loader event + // so that the developer is free to override and manage the loading + // of views in any way they see fit for their application. $path = Event::first(static::loader, array($bundle, $view)); if ( ! is_null($path)) @@ -141,10 +141,17 @@ public static function file($bundle, $view) { $root = Bundle::path($bundle).'views/'; + // Views may have either the default PHP fiel extension of the "Blade" + // extension, so we will need to check for both in the view path + // and return the first one we find for the given view. if (file_exists($path = $root.$view.EXT)) { return $path; } + elseif (file_exists($path = $root.$view.BLADE_EXT)) + { + return $path; + } } /** diff --git a/storage/views/.gitignore b/storage/views/.gitignore new file mode 100644 index 00000000000..e69de29bb2d