Skip to content

Instantly share code, notes, and snippets.

@baribadamshin
Last active January 28, 2017 00:53
Show Gist options
  • Save baribadamshin/3135239fe8551c79ec814ad60c5d8a55 to your computer and use it in GitHub Desktop.
Save baribadamshin/3135239fe8551c79ec814ad60c5d8a55 to your computer and use it in GitHub Desktop.
Директива @bem для шаблонизатора Blade в Laravel
<?php
namespace App\Providers;
use Blade;
use Illuminate\Support\ServiceProvider;
class BladeServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
/**
* В шаблонах появится возможность использовать директиву @bem
* Примеры:
* ------------------------------------------------------------------------------------------------
* Директива Аналог
* ------------------------------------------------------------------------------------------------
* @bem('header') @include('desktop.blocks.header.header')
* @bem('header_mod') @include('desktop.blocks.header._mod.header_mod')
* @bem('header_mod_val') @include('desktop.blocks.header._mod.header_mod_val')
* @bem('header__elem') @include('desktop.blocks.header.__elem.header__elem')
* @bem('header__elem_mod_val') @include('desktop.blocks.header.__elem._mod.header__elem_mod_val')
*
* @bem('widgets.header') @include('desktop.widgets.header.header')
* @bem('touch.header') @include('touch.blocks.header.header')
* @bem('common.widgets.header') @include('common.widgets.header.header')
*
* Конечно же будут работать и конструкции вида
* @bem('block', ['param' => 'value'])
* @bem('block', ['param' => $value])
* @bem('block', ['param' => date('Y')])
*/
Blade::directive('bem', function ($rawExpression) {
$rawExpression = preg_replace('/\s/', '', $rawExpression);
/**
* $level - уровень переопределения: common, desktop, touch
* $type - blocks, widgets
* $bem - любой блок, элемент, модификатор и вот это все
* $params - параметры передаваемые в шаблон
*/
$expressionPattern = '/^\(.(?P<level>desktop|touch|common)?\.?(?P<type>blocks|widgets)?\.?(?P<bem>[\w-]+)(.,(?P<params>.+)\))?/i';
preg_match($expressionPattern, $rawExpression, $matches);
if (!$matches) return;
$matches['level'] = $matches['level'] ?: 'desktop';
$matches['type'] = $matches['type'] ?: 'blocks';
$matches['params'] = isset($matches['params']) ? $matches['params'] : '[]';
/**
* my-block__elem_mod_val
* Если хочется вот такого результата
* [
* 'block' => 'my-block',
* 'elem' => 'elem',
* 'mod' => 'mod',
* 'val' => 'val'
* ]
*
* используем регулярное выражение:
* /^(?P<block>[^_]+)(__(?P<elem>[^_]+))?(_(?P<mod>[^_]+)(_(?P<val>[^_]+))?)?$/i
*
* --------------------
* my-block__elem_mod_val
* Сейчас результат следующий (так проще собрать путь до файла):
* [
* 'block' => 'my-block',
* 'elem' => '__elem',
* 'mod' => '_mod',
* 'val' => '_val'
* ]
*/
$blockPattern = '/^(?P<block>[^_]+)(?P<elem>__[^_]+)?(?<mod>_[^_]+)?/i';
preg_match($blockPattern, $matches['bem'], $blockMatches);
$blockMatches['elem'] = isset($blockMatches['elem']) ? $blockMatches['elem'] : null;
$blockMatches['mod'] = isset($blockMatches['mod']) ? $blockMatches['mod'] : null;
$expression = implode('.', array_filter([
$matches['level'],
$matches['type'],
$blockMatches['block'],
$blockMatches['elem'],
$blockMatches['mod'],
$matches['bem']
]));
return "<?php echo \$__env->make('$expression', {$matches['params']}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
});
}
/**
* Register any application services.
*
* @return void
*/
public function register() {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment