php - Symfony 2 根据用户代理属性加载不同的模板

标签 php mobile symfony twig

有可能(以及如何)

  • 确定用户是否使用移动设备
  • 在这种情况下强制 symfony 2 加载不同的模板
  • (并回退默认的 html 模板)

id 喜欢做的是,在不修改任何 Controller 的情况下加载不同的模板。

更新

这里真正的问题不是检测部分,它真的与 symfony 无关。可以在 Controller 级别完成(加载不同的模板):

public function indexAction()
{
    $format = $this->isMobile() ? 'mob' : 'html';
    return $this->render('AcmeBlogBundle:Blog:index.'.$format.'.twig');
}

但它可以在全局范围内完成吗?就像一个服务,或者在每个请求之前执行的东西,并在模板规则中进行更改。

最佳答案

好的,所以我没有完整的解决方案,但比在哪里寻找一个多一点:)

您可以在 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:         ~

然后定义提到的加载器服务:

services:
    moby.loader:
        class: Acme\AppBundle\Twig\Loader\MobyFilesystemLoader
        arguments:    ["@templating.locator", "@service_container"]

然后定义加载器服务类:

namespace Acme\AppBundle\Twig\Loader;

use Symfony\Bundle\FrameworkBundle\Templating\Loader\FilesystemLoader;
use Symfony\Component\Templating\Storage\FileStorage;


class MobyFilesystemLoader extends FilesystemLoader
{
     protected $container;

     public function __construct($templatePathPatterns, $container) 
     {
         parent::__construct($templatePathPatterns);
         $this->container = $container;
     }

     public function load(\Symfony\Component\Templating\TemplateReferenceInterface $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;
       }
 }

如您所见,这不是完整的解决方案,但我希望这至少能为您指明正确的方向。

编辑:刚刚发现有一个具有移动检测功能的包,带有自定义的 Twig 引擎,根据发送请求的设备呈现模板文件 ZenstruckMobileBundle ,虽然我从来没有用过它...... :)

关于php - Symfony 2 根据用户代理属性加载不同的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8257676/

相关文章:

javascript - 验证失败时禁用按钮

javascript - 弹出窗口在移动设备上如何响应?

php - 使用 symfony2 设置 php-sdk-gae

sql - Symfony 2 : Generate SQL from specific entity

php - Docker Compose 与 PHP、MySQL、nginx 连接问题

php - 在 MySQL 中 INSERT INTO ... ON DUPLICATE KEY UPDATE 的正确语法是什么?

php - 如何确定 CSV 文件字段是制表符分隔还是逗号分隔?

javascript - 如何使用 javascript 检测设备类型

javascript - 防止在特定屏幕尺寸的智能手机上滚动

symfony - 如何将 token 存储作为参数传递给 Symfony 3.4 中的事件监听器