如果不存在移动版本,我需要一种简单的方法来回退默认模板。
使用一些正则表达式,我会识别移动平台,并希望使用以下模式渲染模板:
<template_name>.mobile.html.twig
但是如果这个模板不存在,我希望它能自动回退:
<template_name>.html.twig
始终存在。
我试过这篇文章的几乎所有答案: Symfony 2 load different template depending on user agent properties 但没有成功。不幸的是,没有引用版本号。
目前我正在尝试复制和修改默认的树枝加载器。
顺便说一下,......我想要实现的目标是通过添加同名模板并添加.mobile为移动设备部署不同的模板。
更新
http://www.99bugs.com/handling-mobile-template-switching-in-symfony2/ 这个也是一个很好的方法。当你没有在控制器中使用渲染函数(或注释)指定模板但只返回数组时,它会修改请求对象的格式属性,这会影响自动模板猜测。
结果模板名称:
view/<controller>/<action>.<request format>.<engine>
因此,您可以根据设备检测将请求格式从html切换到mobile.html。 这样做的缺点是每个模板都需要一个mobile.html挂件(如果不需要,可以包含非移动版本)。
更新
除了使用自定义模板提供程序外,还有hook into the kernel.view event的可能性。
答案 0 :(得分:2)
你可以创建一个服务来处理它,然后像你做模板服务那样使用它。
创建一个注入模板和请求服务的服务..
服务(YAML)
acme.templating:
class: Acme\AcmeBundle\Templating\TemplatingProvider
scope: request
arguments:
- @templating
- @request // I assume you use request in your platform decision logic,
// otherwise you don't needs this or the scope part
- 'html'
类
class TemplatingProvider
{
private $fallback;
private $platform;
... __construct($templating, $request, $fallback) etc
private function setPlatform() ... Your platform decision logic
private function getPlatform()
{
if (null === $this->platform) {
$this->setPlatform();
}
return $this->platform;
}
private function getTemplateName($name, $platform)
{
if ($platform === 'html') {
return $name;
}
$template = explode('.', $name);
$template = array_merge(
array_slice($template, 0, -2),
array($platform),
array_slice($template, -2)
);
return implode('.', $template);
}
public function renderResponse($name, array $parameters = array())
{
$newname = $this->getTemplateName($name, $this->getPlatform());
if ($this->templating->exists($newname)) {
return $this->templating->render($newname);
}
return $this->templating->renderResponse($this->getTemplateName(
$name, $this->fallback));
}
然后你可以调用你的模板服务而不是现在的服务..
return $this->container->get('acme.templating')
->renderResponse('<template_name>.html.twig', array());
答案 1 :(得分:1)
你不能检查模板是否存在吗?
if ( $this->get('templating')->exists('<templatename>.html.twig') ) {
// return this->render(yourtemplate)
} else {
// return your default template
}
或:
您可以创建一个通用方法,在根控制器中插入,如:
public function renderMobile($templateName, $params)
{
$templateShortName = explode('.html.twig', $templateName)[0];
$mobileName = $templateShortName.'.mobile.html.twig';
if ( $this->get('templating')->exists($mobileName) ) {
return $this->renderView($mobileName, $params);
} else {
return $this->renderView($templateName, $params)
}
}
你可以这样做:
return $this->renderMobile('yourtemplate', [yourparams]);
答案 2 :(得分:0)
您可以通过利用Symfony2 http://symfony.com/doc/current/cookbook/bundles/inheritance.html中的包继承属性轻松完成此操作
然后当您渲染模板时,只需调用AcmeDemoMobileBundle :: - 如果模板存在,它将被渲染,否则您将整齐地回退到桌面版本。没有额外的代码,听众或任何不明显的要求。
当然,这样做的缺点是您可以将模板移出各个捆绑包。
答案 3 :(得分:0)
您描述的后备行为并不容易实现(我们发现了困难的方法......)。好消息是我们想要您提出的相同设置,并最终使用LiipThemeBundle来达到此目的。它允许您基于例如设备具有不同的“主题”。它会为你做后备部分。
例如:
渲染模板:
@BundleName/Resources/template.html.twig
将按顺序渲染和回退:
app/Resources/themes/phone/BundleName/template.html.twig
app/Resources/BundleName/views/template.html.twig
src/BundleName/Resources/themes/phone/template.html.twig
src/BundleName/Resources/views/template.html.twig
编辑:因此,通过这种方法,您可以拥有默认模板,这些模板始终是最终的后备模式,并为您需要的移动设备提供特殊模板。