问题描述
是否有可能(以及如何)
Is it possible (and how) to
- 确定用户是否使用移动设备
- 在这种情况下强制 symfony 2 加载不同的模板
- (并回退默认的 html 模板)
id 喜欢做的是,在不修改任何控制器的情况下加载不同的模板.
What id like to do is, to load different templates without modifying any controller.
更新
这里的真正问题不是检测部分,它实际上与 symfony 无关.可以在控制器级别完成(加载不同的模板):
It wasn't the detection part the real issue here, it's really nothing to do with symfony. It can be done (load different template) on a controller level:
public function indexAction()
{
$format = $this->isMobile() ? 'mob' : 'html';
return $this->render('AcmeBlogBundle:Blog:index.'.$format.'.twig');
}
但是它可以在全球范围内完成吗?就像一个服务,或者在每个请求之前执行的东西,并在模板规则中进行更改.
But can it be done globally? Like a service, or something that execute before every request, and make changes in the templating rules.
推荐答案
好的,所以我没有一个完整的解决方案,但比在哪里寻找一个多一点:)
Ok, so I don't have a full solution but a little more than where to look for one :)
您可以在 app/config/config.yml 中为模板项指定加载器(服务)
You can specify loaders (services) for templating item in app/config/config.yml
framework:
esi: { enabled: true }
#translator: { fallback: %locale% }
secret: %secret%
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: %kernel.debug%
form: true
csrf_protection: true
validation: { enable_annotations: true }
templating:
engines:
- twig
loaders: [moby.loader]
default_locale: %locale%
trust_proxy_headers: false
session: ~
然后定义提到的加载器服务:
Then define the mentioned loader service:
services:
moby.loader:
class: AcmeAppBundleTwigLoaderMobyFilesystemLoader
arguments: ["@templating.locator", "@service_container"]
然后定义你的加载器服务类:
After that define your loader service class:
namespace AcmeAppBundleTwigLoader;
use SymfonyBundleFrameworkBundleTemplatingLoaderFilesystemLoader;
use SymfonyComponentTemplatingStorageFileStorage;
class MobyFilesystemLoader extends FilesystemLoader
{
protected $container;
public function __construct($templatePathPatterns, $container)
{
parent::__construct($templatePathPatterns);
$this->container = $container;
}
public function load(SymfonyComponentTemplatingTemplateReferenceInterface $template)
{
// Here you can filter what you actually want to change from html
// to mob format
// ->get('controller') returns the name of a controller
// ->get('name') returns the name of the template
if($template->get('bundle') == 'AcmeAppBundle')
{
$request = $this->container->get('request');
$format = $this->isMobile($request) ? 'mob' : 'html';
$template->set('format', $format);
}
try {
$file = $this->locator->locate($template);
} catch (InvalidArgumentException $e) {
return false;
}
return new FileStorage($file);
}
/**
* Implement your check to see if request is made from mobile platform
*/
private function isMobile($request)
{
return true;
}
}
正如您所看到的,这不是完整的解决方案,但我希望这至少可以为您指明正确的方向.
As you can see this isn't the full solution, but I hope that this, at least, points you to the right direction.
刚刚发现有一个具有移动检测功能的捆绑包,带有自定义树枝引擎,可根据发送请求的设备呈现模板文件ZenstruckMobileBundle,虽然我从来没有用过它... :)
Just found out that there is a bundle with mobile detection capabilities, with custom twig engine that renders template file depending on a device that sent requestZenstruckMobileBundle, although I never used it so... :)
这篇关于Symfony 2 根据用户代理属性加载不同的模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!