设置在DB上定义的模板

时间:2014-01-16 11:26:21

标签: php symfony twig

我有一个带有后端和前端的项目。 在后端我想添加一个选项来更改模板 该样式在base.html.twig上定义:

<link href="{{ asset('css/themes/default.css') }}" rel="stylesheet" type="text/css" id="style_color"/>

我的问题是如何在加载此文件时更改样式。 模板选项将存储在数据库中。

编辑: 在我这样做的那一刻:我在默认控制器上创建了一个动作,返回一个新的Response,其中包含在DB上定义的模板,然后是base.html.twig。

{{ render(controller("AdminPageBundle:Default:getTemplateAdmin")) }}

它是这样的,但我认为这不是最好的方法

1 个答案:

答案 0 :(得分:3)

我希望我理解这个问题。我假设您正在寻找一种方法来“绑定”正确的样式表,具体取决于数据库中的设置,后者已经解决了

Twig提供了一种类似于继承的OOP,您可以利用它来实现这一功能。

以下是三个步骤的解决方案:

第一步:编写“主题感知”动作。在控制器中

...

public function adminAction(){
    //get the settings information, this is hardcoded for the sake of esample
    //you may as well fetch this from the DB
    $themeSettings = array('style'=>'blue');

    //render the template and inject the variable
    return $this->render('AdminPageBundle:Default:template.html.twig',
        array('theme'=>$themeSettings));

}

步骤2:使用默认主题创建基本模板(故障安全) //我们称之为base.html.twig

<!DOCTYPE html>
<html>
<head>
...
{% block stylesheets %}
<link href="{{ asset('css/themes/default.css') }}" rel="stylesheet" type="text/css"/>
{% endblock %}
....
</head>
...

步骤3:覆盖主题感知模板中的“样式表”块 //template.html.twig:

{# make it a child of base.html.twig #}
{% extends '::base.html.twig' %}

{# override the stylesheets block #}
{% block stylesheets %}
{# include what you already have in the parent template (link to default.css) #}
{{ parent }}
{# add your own theme from the database (using the 'theme' variable from the controller #}
<link href="{{ asset('css/themes/'~ theme.style ~ '.css') }}" rel="stylesheet" type="text/css"/>
{% endblock %}

使用此示例,渲染“template.html.twig”会将样式表加载到“/css/themes/blue.css”。

您也可以直接在基本模板中实现这一点,而不依赖于继承,但我假设某些模板是主题感知的,而有些则不是。 Inheritence可以灵活地在您需要的地方实现此功能。

当然,还有其他几种方法可以解决这个问题。处理主题的Writing a custom twig extension对于可靠的长期解决方案来说是正确的,特别是如果主题不仅仅是加载样式表。您还可以编写一个事件处理程序(用于kernel.view事件)来修改模板或在渲染之前注入主题设置。 This answer显示了一个示例。