9

I need to include the contents of a file (inside my resources folder) inside a Twig template.

I have tried this with no luck:

{% include 'public/directory/file.ext' %}

Isn't Twig capable of this? (I don't want to use Assetic)

David Morales
  • 17,816
  • 12
  • 77
  • 105

4 Answers4

17

New in version 1.15: The source function was added in Twig 1.15. The source function returns the content of a template without rendering it

http://twig.sensiolabs.org/doc/functions/source.html

Disparity
  • 211
  • 2
  • 5
  • 5
    This only works if you're reading a template. This does not allow to include arbitrary files. – afilina Jan 04 '18 at 19:32
3

I made a bundle just for this some time ago. It's pretty much a wrapper for file_get_contents.

The setup can be found here.

Community
  • 1
  • 1
kgilden
  • 10,336
  • 3
  • 50
  • 48
  • 1
    Making a Twig Extension is the way to go. I have implemented one based on your bundle, but if someone has no time or knowdledge for doing this, your bundle is a nice solution. Thanks. – David Morales Dec 20 '11 at 23:43
  • 2
    Just an improvement for your extension: when you call "file" from the template, you will notice that the output is escaped (if you have autoescape on), so you will be forced to add the "raw" filter. In order to avoid that, add this as the third parameter of your Twig_Function_Method call: array('is_safe' => array('html')) – David Morales Dec 21 '11 at 00:36
  • @gilden where is the composer.json in your repo? – Besnik Jul 25 '14 at 14:35
1

You can solve this problem with twig extension functions. ( http://symfony.com/doc/current/cookbook/templating/twig_extension.html )

Create a php file in your Bundle for the Twig extension

<?php

namespace AppBundle\Twig;

use Twig_Extension;
use Twig_SimpleFunction;

class AppExtension extends Twig_Extension
{
  public function getFunctions()
  {
    return array(
      new Twig_SimpleFunction('fileGetContents', array($this, 'fileGetContents') ),
    );
  }

  public function fileGetContents($file)
  {
    return file_get_contents($file);
  }

  public function getName()
  {
    return 'app_extension';
  }
}
?>

Add this code to the app/config/services.yml

app.twig_extension:
    class: AppBundle\Twig\AppExtension
    public: false
    tags:
        - { name: twig.extension }

Now you can use your custom function as any default function in your twig template

<p>{{ fileGetContents( asset("uploads/my_text_file.txt") ) }}</p>
1

Twig will complain when loading your file if it is not a valid twig template. The reason is that Twig will include the rendered file and not the content of it (found here).

You could try with a use statement but I don't think this will work either.

Moreover, the syntax you use seems incorrect. When I include (or use) another twig template, I use this syntax:

{% use "AcmeWebsiteBundle::include.html.twig" %}

And the file include.html.twig resideds in src\Acme\WebsiteBundle\Resources\views\include.html.twig. So, if your file is in src\Acme\WebsiteBundle\Resources\public\directory\include.ext, you could try

{% use "AcmeWebsiteBundle::..\public\directory\include.ext" %}

If that doesn't work, you could possibly move the file into the views folder. If this is not possible, you can possibliy put in app\Resources\views\ and use the syntax:

{% use "::include.ext" %}

If the use statement doesn't work, which I'm afraid of, you could possibly wrap your file into a twig template directly. I'm templating some simple JSON structures with twig. So, there may be a way for you to include the content of file.ext into a twig template and then render it.

If all this fail, you will have to create a Twig extension that add a new tag (something like content) that would read a file and output its content in your twig template.

{% content 'public/directory/file.ext' %} {# would put content of the file #}

Hope this will help you to include your file.

Regards,
Matt

Matt
  • 10,633
  • 3
  • 46
  • 49
  • 3
    I appreciate your answer, but your suggestions don't work. Please, if you answer, at least you should be sure that what you suggest works. – David Morales Dec 20 '11 at 21:19