Blade's path syntax is a little odd - it uses dots instead of slashes, and always requires you to start your paths from the views root. This Blade extension allows you to pass paths with slashes, and correctly resolves parent paths via the traditional ../ syntax. Lastly, the quoting of paths is optional.
// usage - in any view:
@inc('path/to/child')
@inc('../path/to/parent')
@inc(quotes/are/optional)
// installation - place this code in a service provider
Blade::extend(function($view, $compiler)
{
// (?<!\w)(\s*)@inc(\s*\(.*\))
$pattern $compiler->createMatcher('inc');
// get paths
$viewPath = $compiler->getPath();
$viewFolder = dirname($viewPath) . '/';
$root = \Config::get('view.paths')[0] . '/';
// replace all matches
return preg_replace_callback($pattern, function($matches) use($root, $viewPath, $viewFolder)
{
// get all parameters
list($match, $whitespace, $param) = $matches;
// get the relative path parameter
$param = preg_replace('%[\\(\\)\'""]%', '', $param);
// resolve the absolute path
$path = $viewFolder . $param . '.blade.php';
$path = realpath($path);
// check it exists
if( ! $path )
{
throw new \ErrorException("Relative @include '$param' not found in template '$viewPath'");
}
// if we still have a real, absolute path, convert it to dot syntax, so Blade can compile it
$expression = str_replace($root, '', $path);
$expression = str_replace('.blade.php', '', $expression);
$expression = str_replace('/', '.', $expression);
// return the new php to the view
return "$whitespace<?php echo \$__env->make('$expression', array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
}, $view);
});