How do I include raw HTML files in Symfony2/Twig templates?

17,344

Solution 1

A quick recap on twig file extensions (taken from the documentation):

Every template name also has two extensions that specify the format and engine for that template.

AcmeBlogBundle:Blog:index.html.twig - HTML format, Twig engine
AcmeBlogBundle:Blog:index.html.php - HTML format, PHP engine
AcmeBlogBundle:Blog:index.css.twig - CSS format, Twig engine

By default, any Symfony2 template can be written in either Twig or PHP, and the last part of the extension (e.g. .twig or .php) specifies which of these two engines should be used. The first part of the extension, (e.g. .html, .css, etc) is the final format that the template will generate.

Therefore it makes sense to me that including a file as .html would be at the least ambiguous even if it didn't throw an error.

So you have 3 choices:

  1. If the files are purely javascript then include them as script tags in your page.

  2. If they are mixed HTML and JS then escape the JS with {% raw %} and include the files as foo.html.twig templates. If there are lots of scripts being included like this then most likely your designers could do with a little refactoring and move the bulk of their scripts to external files (see option 1)

  3. If you really insist you could always write a Twig extension to include raw HTML files. (EDIT: See @Haprog's answer below for more details on this option).

    {{ include_html('foo/bar.html') }}

  4. UPDATE 2015 twig has since added the source function:

{{ source('AcmeSomeBundle:Default:somefile.html.twig') }}

Kudos to @Nigel Angel in the comments below for option 4.

Solution 2

I also came upon the same problem trying to find a solution to include files (mustache templates) as raw in Twig templates so Twig doesn't try to parse them.

At first I had my mustache template files named simply sometemplate.html and wrapped in {% raw %} tags. This worked for a while, but then I started using PhpStorm IDE with the Handlebars plugin (for mustache syntax). For PhpStorm to recognize the files as mustache syntax, they need to have a unique file extension (.mustache by default), so I renamed my sometemplate.html to sometemplate.mustache but I really disliked the idea that my mustache templates needed to be wrapped with Twig tags. So I ended up doing what @rdjs said in his option 3. This is the best solution imo.

Here's the working Twig extension function I made:

function twig_include_raw(Twig_Environment $env, $template) {
    return $env->getLoader()->getSource($template);
}
$twig->addFunction('include_raw', new Twig_Function_Function('twig_include_raw', array('needs_environment' => true)));

With this in place you can easily include files as "raw" without Twig parsing them by doing:

{{ include_raw('sometemplate.mustache')|raw }}

I even made a Twig macro for simplifying including mustache templates to HTML head sections:

{% macro mustache_script(id, file) -%}
<script id="{{ id }}" type="text/x-mustache-template">
{{ include_raw(file)|raw }}
</script>
{%- endmacro %}

And after importing the file with the above macro to your Twig template ({% import "macros.twig" %} for example), you can easily import mustache template files in your Twig templates by simply doing {{ mustache_script('sometemplate_tpl', 'sometemplate.mustache') }} inside a HTML <head> section.

I hope this helps someone who's looking for a solution to the same problem.

Solution 3

I came accross this post, as I had a similar question. After an hour or so searching and trying, I found out, that as from Twig Version 1.15 the "source Function" was added.

Maybe that helps someone in the future.

Solution 4

Follow up on Kari, if you're in an extension.. you can apply it this way.

public function getFunctions() {
    return [
        'include_raw' =>  new \Twig_Function_Method($this, 'twig_include_raw', array('needs_environment'=> true, 'is_safe'=> array('all')))
    ];
}

And that'd be a $this->twig_include_raw type method. You'd include within your template as:

{{ include_raw("my/file/here.html.twig") }}

No need for " | raw".

Share:
17,344
wdh
Author by

wdh

Updated on June 09, 2022

Comments

  • wdh
    wdh almost 2 years

    I'm working on a project in Symfony2 and I have several small pieces of html that need to be included in one of my main views. According to the official Twig documentation I should be able to simply use {% include 'filename.html' %} but in Symfony unless the filename ends in ".html.twig" it throws and error saying it cannot find the file. I'd like to avoid using Twig templates for these files since they have no dynamic content and lots of double braces (they're javascript templates) and requiring the template designer to have to wrap every one of these files in {% raw %} tags seems like a really Kludgey way to do it.

  • wdh
    wdh over 12 years
    What I'm trying to do is have a way for Mustache templates to be included in the page for use by javascript. Putting them directly in the template surrounded by {% raw %} tags works but I feel its pretty disorganized and can get unwieldy when there's a lot of small template bits. Loading the template bits via ajax unnecessarily slows things down on the client end since there are more requests. Putting the templates in a twig file that has no actual twig markup in it (other than {% raw %}) bugs the OCD developer in me but it seems like the simplest option in this case. Thanks.
  • Craig
    Craig over 11 years
    This seems it will solve a problem I'm looking at, but I have no idea where the twig_include_raw function should be defined and what/when should call $twig->addFunction. Can you explain it a bit further.
  • Haprog
    Haprog about 11 years
    @Craig Sorry I haven't replied sooner. You can define the function anywhere you like. Just make sure to call $twig->addFunction() anywhere after you set up Twig with $twig = new Twig_Environment($loader); I usually have my own twigInit() function that handles setting up the Twig environment including loading the extensions I use. You might also want to read the documentation page about extending Twig at twig.sensiolabs.org/doc/advanced.html
  • Matt Kenefick
    Matt Kenefick almost 11 years
    This is great. You can bypass need for "| raw" if you add "'is_safe'=> array('all')" to the options after needs_environment.
  • Nigel Angel
    Nigel Angel almost 10 years
    What namespace do you "use" Twig_Function_Function from? Where is this code added? I'm trying in a controller. Edit: Ah, new \Twig_Function_Function
  • Nigel Angel
    Nigel Angel almost 10 years
    twig has since added the source function {{ source('AcmeSomeBundle:Default:somefile.html.twig') }}
  • Yes Barry
    Yes Barry about 9 years
    Is it possible to use phtml files instead?