如何在symfony2中从数据库中呈现Twig模板

时间:2021-09-03 07:02:04

I'm working on application written in symfony2 and I want to send email after some action/event... the problem is, that users can definig something like "email templates" which stores in db like simple string, for example: "This is some email from {{ user }}" and I need to render body for email from that template... In symfony documentation from this link: http://symfony.com/doc/2.0/cookbook/email.html#sending-emails the methos for render is $this->renderView and it expects reference to file as "bundle:controller:file.html.twig", but my template is database as simple string... How can I render it?

我正在研究用symfony2编写的应用程序,我希望在一些动作/事件之后发送电子邮件...问题是,用户可以定义类似“电子邮件模板”的东西,它像db一样存储在db中,例如:“这个是来自{{user}}的一些电子邮件,我需要从该模板呈现电子邮件的正文...在此链接的symfony文档中:http://symfony.com/doc/2.0/cookbook/email.html#sending -emails用于渲染的方法是$ this-> renderView,它希望引用文件为“bundle:controller:file.html.twig”,但我的模板是数据库作为简单的字符串...我该如何渲染它?

10 个解决方案

#1


22  

Twig_Loader_String is deprecated and was always designed for internal use anyway. The usage of this loader is strongly discouraged.

Twig_Loader_String已弃用,无论如何总是设计用于内部使用。强烈建议不要使用此加载程序。

From the API doc:

从API文档:

This loader should NEVER be used. It only exists for Twig internal purposes. When using this loader with a cache mechanism, you should know that a new cache key is generated each time a template content "changes" (the cache key being the source code of the template). If you don't want to see your cache grows out of control, you need to take care of clearing the old cache file by yourself.

永远不要使用这个装载机。它仅存在于Twig内部用途。当使用带有缓存机制的加载器时,您应该知道每次模板内容“更改”(缓存键是模板的源代码)时都会生成新的缓存键。如果您不希望看到缓存失去控制,则需要自己清理旧的缓存文件。

Also check out this issue: https://github.com/symfony/symfony/issues/10865

另请查看此问题:https://github.com/symfony/symfony/issues/10865


The best way I know to load a template from a String source are:

我知道从String源加载模板的最佳方法是:

From a controller:

$template = $this->get('twig')->createTemplate('Hello {{ name }}');
$template->render(array('name'=>'World'));

as described here: http://twig.sensiolabs.org/doc/recipes.html#loading-a-template-from-a-string

如下所述:http://twig.sensiolabs.org/doc/recipes.html#loading-a-template-from-a-string

From a twig template:

{{ include(template_from_string("Hello {{ name }}", {'name' : 'Peter'})) }}

as described here: http://twig.sensiolabs.org/doc/functions/template_from_string.html

如下所述:http://twig.sensiolabs.org/doc/functions/template_from_string.html

Note, that the 'template_from_string' - function is not available by default and needs to be loaded. In symfony you would do this by adding a new service:

请注意,'template_from_string' - 函数默认情况下不可用,需要加载。在symfony中,您可以通过添加新服务来完成此操作:

# services.yml
services:
    appbundle.twig.extension.string:
        class: Twig_Extension_StringLoader
        tags:
            - { name: 'twig.extension' }

#2


17  

This should work. Replace "Hello {{ name }}" with your template text, and fill the array that is passed into the render function with any variables that you need.

这应该工作。将“Hello {{name}}”替换为模板文本,并使用您需要的任何变量填充传递给render函数的数组。

$env = new \Twig_Environment(new \Twig_Loader_String());
echo $env->render(
  "Hello {{ name }}",
  array("name" => "World")
);

#3


10  

Clone the native twig service and replace the filesystem loader with the native twig string loader:

克隆本机twig服务并使用本机twig字符串加载器替换文件系统加载器:

<service id="my.twigstring" class="%twig.class%">
    <argument type="service" id="my.twigstring.loader" />
    <argument>%twig.options%</argument>
</service>        
<service id="my.twigstring.loader" class="Twig_Loader_String"></service>

Usage example from within a controller:

控制器内的用法示例:

$this->get('my.twigstring')->render('Hello {{ name }}', array('name' => 'Fabien'));

#4


8  

The Twigengine doesn't support rendering strings. But there is a bundle available wich adds this behavior called TwigstringBundle.

Twigengine不支持渲染字符串。但是有一个捆绑可用,它添加了一个名为TwigstringBundle的行为。

It adds the $this->get('twigstring') service wich you can use to render your strings.

它添加了$ this-> get('twigstring')服务,您可以使用它来呈现您的字符串。

#5


6  

The best way to do it is to use template_from_string twig function.

最好的方法是使用template_from_string twig函数。

{{ include(template_from_string("Hello {{ name }}")) }}
{{ include(template_from_string(page.template)) }}

See documentation of template_from_string

请参阅template_from_string的文档

See why it is not a good idea to use Twig_Loader_Chain or Twig_Loader_String for that purpose on this github issue by stof.

看看为什么在stof这个github问题上为此目的使用Twig_Loader_Chain或Twig_Loader_String不是一个好主意。

#6


1  

With Symfony 2.2 you can use the Twig_Chain_Loader
How to register another (custom) Twig loader in Symfony2 environment?

使用Symfony 2.2,你可以使用Twig_Chain_Loader如何在Symfony2环境中注册另一个(自定义)Twig加载器?

#7


0  

FYI, This feature was suggested to be added in the core of Twig as of 1.11.0, but will be needed to be activated by the developper.

仅供参考,从1.11.0开始,建议将此功能添加到Twig的核心,但需要由开发人员激活。

#8


0  

You can find a good example here : http://twig.sensiolabs.org/doc/recipes.html#using-a-database-to-store-templates

你可以在这里找到一个很好的例子:http://twig.sensiolabs.org/doc/recipes.html#using-a-database-to-store-templates

#9


0  

I recently had to implement a CMS used by multiple parties where each party could completely customize their templates. To achieve this I implemented a custom Twig Loader.

我最近不得不实施多方使用的CMS,每个方都可以完全自定义他们的模板。为此,我实现了一个自定义的Twig Loader。

The most difficult part was coming up with a naming convention for the templates guaranteed not to overlap with any existing templates, for example <organisation_slug>!AppBundle:template.html.twig. In case the template was not customised, the template AppBundle:template.html.twig would have to be loaded as fallback template.

最困难的部分是提出模板的命名约定,保证不与任何现有模板重叠,例如 !AppBundle:template.html.twig。如果模板未自定义,则必须将模板AppBundle:template.html.twig作为后备模板加载。

However, this is not possible with the Chain Loader (AFAIK) because there the template name cannot be modified. Therefore I had to inject the default loader (i.e. the loader chain) into my loader and use it to load the fallback template.

但是,链式加载器(AFAIK)无法实现这一点,因为无法修改模板名称。因此,我必须将默认加载器(即加载器链)注入我的加载器并使用它来加载回退模板。

Another solution would be to pass the request stack or the session to the template loader, making it possible to automatically detect the organisation, but this is difficult because the security component depends on the templating subsystem, causing circular dependency issues.

另一种解决方案是将请求堆栈或会话传递给模板加载器,从而可以自动检测组织,但这很困难,因为安全组件依赖于模板子系统,导致循环依赖性问题。

#10


-7  

  $message = \Swift_Message::newInstance()
        ->setSubject('Hello Email')
        ->setFrom('send@example.com')
        ->setTo('recipient@example.com')
        ->setBody('hai its a sample mail')
    ;
    $this->get('mailer')->send($message);

#1


22  

Twig_Loader_String is deprecated and was always designed for internal use anyway. The usage of this loader is strongly discouraged.

Twig_Loader_String已弃用,无论如何总是设计用于内部使用。强烈建议不要使用此加载程序。

From the API doc:

从API文档:

This loader should NEVER be used. It only exists for Twig internal purposes. When using this loader with a cache mechanism, you should know that a new cache key is generated each time a template content "changes" (the cache key being the source code of the template). If you don't want to see your cache grows out of control, you need to take care of clearing the old cache file by yourself.

永远不要使用这个装载机。它仅存在于Twig内部用途。当使用带有缓存机制的加载器时,您应该知道每次模板内容“更改”(缓存键是模板的源代码)时都会生成新的缓存键。如果您不希望看到缓存失去控制,则需要自己清理旧的缓存文件。

Also check out this issue: https://github.com/symfony/symfony/issues/10865

另请查看此问题:https://github.com/symfony/symfony/issues/10865


The best way I know to load a template from a String source are:

我知道从String源加载模板的最佳方法是:

From a controller:

$template = $this->get('twig')->createTemplate('Hello {{ name }}');
$template->render(array('name'=>'World'));

as described here: http://twig.sensiolabs.org/doc/recipes.html#loading-a-template-from-a-string

如下所述:http://twig.sensiolabs.org/doc/recipes.html#loading-a-template-from-a-string

From a twig template:

{{ include(template_from_string("Hello {{ name }}", {'name' : 'Peter'})) }}

as described here: http://twig.sensiolabs.org/doc/functions/template_from_string.html

如下所述:http://twig.sensiolabs.org/doc/functions/template_from_string.html

Note, that the 'template_from_string' - function is not available by default and needs to be loaded. In symfony you would do this by adding a new service:

请注意,'template_from_string' - 函数默认情况下不可用,需要加载。在symfony中,您可以通过添加新服务来完成此操作:

# services.yml
services:
    appbundle.twig.extension.string:
        class: Twig_Extension_StringLoader
        tags:
            - { name: 'twig.extension' }

#2


17  

This should work. Replace "Hello {{ name }}" with your template text, and fill the array that is passed into the render function with any variables that you need.

这应该工作。将“Hello {{name}}”替换为模板文本,并使用您需要的任何变量填充传递给render函数的数组。

$env = new \Twig_Environment(new \Twig_Loader_String());
echo $env->render(
  "Hello {{ name }}",
  array("name" => "World")
);

#3


10  

Clone the native twig service and replace the filesystem loader with the native twig string loader:

克隆本机twig服务并使用本机twig字符串加载器替换文件系统加载器:

<service id="my.twigstring" class="%twig.class%">
    <argument type="service" id="my.twigstring.loader" />
    <argument>%twig.options%</argument>
</service>        
<service id="my.twigstring.loader" class="Twig_Loader_String"></service>

Usage example from within a controller:

控制器内的用法示例:

$this->get('my.twigstring')->render('Hello {{ name }}', array('name' => 'Fabien'));

#4


8  

The Twigengine doesn't support rendering strings. But there is a bundle available wich adds this behavior called TwigstringBundle.

Twigengine不支持渲染字符串。但是有一个捆绑可用,它添加了一个名为TwigstringBundle的行为。

It adds the $this->get('twigstring') service wich you can use to render your strings.

它添加了$ this-> get('twigstring')服务,您可以使用它来呈现您的字符串。

#5


6  

The best way to do it is to use template_from_string twig function.

最好的方法是使用template_from_string twig函数。

{{ include(template_from_string("Hello {{ name }}")) }}
{{ include(template_from_string(page.template)) }}

See documentation of template_from_string

请参阅template_from_string的文档

See why it is not a good idea to use Twig_Loader_Chain or Twig_Loader_String for that purpose on this github issue by stof.

看看为什么在stof这个github问题上为此目的使用Twig_Loader_Chain或Twig_Loader_String不是一个好主意。

#6


1  

With Symfony 2.2 you can use the Twig_Chain_Loader
How to register another (custom) Twig loader in Symfony2 environment?

使用Symfony 2.2,你可以使用Twig_Chain_Loader如何在Symfony2环境中注册另一个(自定义)Twig加载器?

#7


0  

FYI, This feature was suggested to be added in the core of Twig as of 1.11.0, but will be needed to be activated by the developper.

仅供参考,从1.11.0开始,建议将此功能添加到Twig的核心,但需要由开发人员激活。

#8


0  

You can find a good example here : http://twig.sensiolabs.org/doc/recipes.html#using-a-database-to-store-templates

你可以在这里找到一个很好的例子:http://twig.sensiolabs.org/doc/recipes.html#using-a-database-to-store-templates

#9


0  

I recently had to implement a CMS used by multiple parties where each party could completely customize their templates. To achieve this I implemented a custom Twig Loader.

我最近不得不实施多方使用的CMS,每个方都可以完全自定义他们的模板。为此,我实现了一个自定义的Twig Loader。

The most difficult part was coming up with a naming convention for the templates guaranteed not to overlap with any existing templates, for example <organisation_slug>!AppBundle:template.html.twig. In case the template was not customised, the template AppBundle:template.html.twig would have to be loaded as fallback template.

最困难的部分是提出模板的命名约定,保证不与任何现有模板重叠,例如 !AppBundle:template.html.twig。如果模板未自定义,则必须将模板AppBundle:template.html.twig作为后备模板加载。

However, this is not possible with the Chain Loader (AFAIK) because there the template name cannot be modified. Therefore I had to inject the default loader (i.e. the loader chain) into my loader and use it to load the fallback template.

但是,链式加载器(AFAIK)无法实现这一点,因为无法修改模板名称。因此,我必须将默认加载器(即加载器链)注入我的加载器并使用它来加载回退模板。

Another solution would be to pass the request stack or the session to the template loader, making it possible to automatically detect the organisation, but this is difficult because the security component depends on the templating subsystem, causing circular dependency issues.

另一种解决方案是将请求堆栈或会话传递给模板加载器,从而可以自动检测组织,但这很困难,因为安全组件依赖于模板子系统,导致循环依赖性问题。

#10


-7  

  $message = \Swift_Message::newInstance()
        ->setSubject('Hello Email')
        ->setFrom('send@example.com')
        ->setTo('recipient@example.com')
        ->setBody('hai its a sample mail')
    ;
    $this->get('mailer')->send($message);