Изменить поведение распознавателя шаблонов Zend Framework 2 по умолчанию

Я только начал изучать Zend Framework 2. Одна вещь, которую я не могу понять, это то, как изменить поведение платформы, когда она решает, какой шаблон представления использовать, когда я не передаю его в viewmodel.

При поиске ответа я обнаружил следующее, в котором говорится, что Zend разрешает шаблоны представления, используя приведенный ниже путь:

{normalized-module-name}/{normalized-controller-name}/{normalized-action-name}

(Источник: http://zend-framework-community.634137.n4.nabble.com/Question-regarding-template-path-stack-tp4660952p4660959.html)

Теперь я хочу отредактировать или удалить сегмент имени нормализованного модуля. Все файлы просмотра остаются в моей папке module / views. Причина, по которой я хочу это изменить, заключается в том, что я использую подпространства имен в качестве имени моего модуля, в результате чего первый сегмент пространства имен используется в качестве нормализованного имени модуля (что для меня недостаточно конкретно).

Чтобы дать вам пример, модуль Foo\Bar приведет к тому, что пример будет отображен из:

/modules/Foo/Bar/view/foo/test/index.phtml,

Я хотел бы изменить это поведение по умолчанию:

/modules/Foo/Bar/view/bar/test/index.phtml

2

Решение

У меня была похожая проблема, и вот мое решение.

Инжектор шаблонов по умолчанию присоединен к менеджеру событий текущего контроллера с приоритетом -90 и разрешает имя шаблона только в том случае, если модель представления не снабжена им.
Зная это, вы можете создать свой собственный шаблонный инжектор с необходимой логикой и прикрепить его к менеджеру событий с более высоким приоритетом.

Пожалуйста, смотрите код ниже:

public function onBootstrap(EventInterface $event)
{
$eventManager = $event->getApplication()->getEventManager();

$eventManager->getSharedManager()
->attach(
'Zend\Stdlib\DispatchableInterface',
MvcEvent::EVENT_DISPATCH,
new TemplateInjector(),
-80 // you can put here any negative number higher -90
);
}

Ваш шаблонный инжектор, который разрешает пути шаблона вместо пути по умолчанию.

class TemplateInjector
{
public function __invoke(MvcEvent $event)
{
$model = $event->getResult();

if (!$model instanceof ViewModel)
{
return;
}

$controller = $event->getTarget();if ($model->getTemplate())
{
return ;
}

if (!is_object($controller))
{
return;
}

$namespace = explode('\\', ltrim(get_class($controller), '\\'));

$controllerClass = array_pop($namespace);
array_pop($namespace); //taking out the folder with controllers
array_shift($namespace); //taking out the company namespace

$moduleName = implode('/', $namespace);

$controller = substr($controllerClass, 0, strlen($controllerClass) - strlen('Controller'));
$action = $event->getRouteMatch()->getParam('action');
$model->setTemplate(strtolower($moduleName.'/'.$controller.'/'.$action));
}
}

Вот ссылка из моего блога, где я написал об этом более подробно: http://blog.igorvorobiov.com/2014/10/18/creating-a-custom-template-injector-to-deal-with-sub-namespaces-in-zend-framework-2/

3

Другие решения

Начиная с zf 2.3 вы можете использовать дополнительный параметр конфигурации view_manager['controller_map'] чтобы разрешить другое разрешение имени шаблона.

Посмотрите на этот PR для получения дополнительной информации: https://github.com/zendframework/zf2/pull/5670

'view_manager' => array(
'controller_map' => array(
'Foo\Bar' => true,
),
);

В результате контроллер FQCN, начинающийся с ‘Foo \ Bar’, будет разрешен в соответствии с этими правилами:

  1. strip \ Controller \ namespace
  2. Контроллер полосы в конце
  3. склонить CamelCase, чтобы разбить
  4. заменить разделитель пространства имен на косую черту

Например: Foo\Bar\Controller\Baz\TestController -> foo/bar/baz/test/actionname

Обновить:

Начиная с Zend-MVC v3.0, это поведение по умолчанию

4

Правильный шаблон для ViewModel внедряется в событие MVC ‘dispatch’ (определено в ViewManager) от Zend\Mvc\View\Http\InjectTemplateListener с приоритетом -90

Вам нужно будет создать собственный InjectTemplateListener и зарегистрировать его с более высоким приоритетом для того же события.

Но я бы рекомендовал устанавливать шаблон в каждом действии вручную из-за производительности — смотрите http://samminds.com/2012/11/zf2-performance-quicktipp-1-viewmodels/

0

Определение имени шаблона — это сложный процесс (для системных ресурсов), и во всех статьях о производительности ZF2 говорится, что вы должны предоставить имя шаблона вручную, чтобы повысить производительность.

так что не тратьте время на поиск способа сделать то, что вы в конечном итоге будете делать вручную: D

0

Чтобы улучшить ответ Next Developer, я пишу следующий код в TemplateInjector.php:

class TemplateInjector
{

public function __invoke(MvcEvent $event)
{
$model = $event->getResult();

if (!$model instanceof ViewModel) {
return;
}

if ($model->getTemplate()) {
return;
}

$controller = $event->getTarget();

if (!is_object($controller)) {
return;
}

$splitNamespace = preg_split('/[\\\]+/', ltrim(get_class($controller), '\\'));
$moduleName = $splitNamespace[1];
$controller = $splitNamespace[0];
$action = $event->getRouteMatch()->getParam('action');
$model->setTemplate(strtolower($moduleName . '/' . $controller . '/' . $action));
}
}

Я изменил способ построения шаблона. Использование регулярных выражений быстрее, чем использование методов массива.

0
По вопросам рекламы [email protected]