Twig template cannot include php template

14,889

Solution 1

You cannot mix-and-match twig and php in a single Response (to do so would be circumventing part of the point of twig, which is to prevent designers from creating too much logic in the view).

I think the Symfony documentation should/could be clearer about this (at the moment it basically says "enable them both and do what you like").

If you embed another controller then you should be able to serve up a different Response and that Response can be php based.

Solution 2

NOTE: snippets below are totally non-tested.

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

The function date seems to create \DateTime object.

{% set now = date() %}
{% set offset = date(now.format('Y/m/01')).format(w) %} {# weekday of 1st day #}
{% set number = now.format('t') %} {# days in month #}
{% set koniec = 7 - ((offset + number) % 7) %}
{% set aktualny = now.format('n') %} {# today #}

However, if you wants to include original php file (say 'calendar.php') in twig, you have to write extension to get it work.

class CalendarExtension extends \Twig_Extension
{
    private $pathToPhp; //store that where the php file is

    public function setPhpFile($pathToPhp)
    {
        $this->pathToPhp = $pathToPhp;
    }

    public function getFunctions()
    {
        return array(
            new \Twig_SimpleFunction('calendar', array($this, 'showCalendar'))
        );
    }

    public function showCalendar([put arguments here if you need])
    {
        ob_start();
        include ($this->pathToPhp);
        return ob_get_clean();
    }
}

To make above work, you should create "tagged" service in container.

in app/config/config.yml

services:
    calendar_twig_extension:
        class: __Namespace__\CalendarExtension
        calls:
            - [setPhpFile, [__path to your calendar.php__]]
        tags:
            - [name: twig.extension]

words that double-underscored should be replaced:

  • _ _ Namespace _ _ : Namespace of CalendarExtension
  • _ _ path to your calendar.php _ _ : full path to your calendar.php. You can use parameters like %kernel.root_dir% and so on to manage your path project-relative.

With these, you finally can simply write

{{ calendar([arguments for CalendarExtension::showCalendar]) }}

Solution 3

Have you considered rendering your calendar php template by using {% render 'ApplicationBundle:Controller:action' %} and in the action rendering the php template?

You might also render your calendar php in the action that render calendar twig and pass the output of the php template as a simple twig variable.

Note: to display such a var, don't forget to do {{ var|raw }} if there is any html tag inside.

Note2: as of symfony2.2, the render parameter as changed to {% render url('route_name') %}

Share:
14,889

Related videos on Youtube

tpsa
Author by

tpsa

Updated on July 11, 2022

Comments

  • tpsa
    tpsa almost 2 years

    I encountered a problem, which for me is quite not clear and hard to understand. I have tried to make calendar widget, which is supposed to be display on every page on my site. So, I think it should be average template (no arguments, no every site). I tried to do it as twig template. I managed to render calendar, but I had a problem with acquiring date object (which is necessary to get proper arguments for rendering calendar). After a short while, I tried to make a php template, which will be included by main twig template (layout.html.twig). It does not success. I have enabled php engine in config.yml, but does not help - php template is in fact included, but as a normal file, not php file (not parsed as php script), (but php engine is working, I tried to render php template from a controller it works). I have read also it is possible to include a result from another controller in template, but for me it is not proper solution, I have not tried that (php template should fit to this problem).

    What should I do to solve this problem?

    Main config.yml

    imports:
        - { resource: parameters.ini }
        - { resource: security.yml }
    
    framework:
        #esi:             ~
        translator:      { fallback: %locale% }
        secret:          %secret%
        charset:         UTF8
        router:          { resource: "%kernel.root_dir%/config/routing.yml" }
        form:            true
        csrf_protection: true
        validation:      { enable_annotations: true }
        templating:      { engines: ['twig', 'php'] }
        session:
            default_locale: %locale%
            auto_start:     true
    
    # Twig Configuration
    twig:
        debug:            %kernel.debug%
        strict_variables: %kernel.debug%
    
    # Assetic Configuration
    assetic:
        debug:          %kernel.debug%
        use_controller: false
        # java: /usr/bin/java
        filters:
            cssrewrite: ~
            # closure:
            #     jar: %kernel.root_dir%/java/compiler.jar
            # yui_css:
            #     jar: %kernel.root_dir%/java/yuicompressor-2.4.2.jar
    
    # Doctrine Configuration
    doctrine:
        dbal:
            driver:   %database_driver%
            host:     %database_host%
            port:     %database_port%
            dbname:   %database_name%
            user:     %database_user%
            password: %database_password%
            charset:  UTF8
    
        orm:
            auto_generate_proxy_classes: %kernel.debug%
            auto_mapping: true
    
    # Swiftmailer Configuration
    #swiftmailer:
    #    transport: %mailer_transport%
    #    host:      %mailer_host%
    #    username:  %mailer_user%
    #    password:  %mailer_password%
    
    jms_security_extra:
        secure_controllers:  true
        secure_all_services: false
    
    # services:
    #    TpsaMailer:
    
    #        class: Tpsa\TestBundle\Controller\MailerController
    

    layout.html.twig

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    
    {% block stylesheets %}
    <link rel="stylesheet" type="text/css"
    href="{{ asset('bundles/tpsablog/css/main.css') }}">
    {% endblock %}
    
    {% block javascripts %}
    <!-- empty javascripts -->
    {% endblock %}
    
    <title>
    {% block title %}
    {% trans %}blog.programisty.duga{% endtrans %}
    {% endblock %}
    </title>
    
    </head>
    <body>
    <div id="all">
        <div id="top">
            {% block top %}
                <div style="float: left" class="right">
                                <img style="float: left;
                                vertical-align: middle; margin: 8px
                                8px 8px 0px" src="{{ asset('bundles/tpsablog/images/glider.png') }}">
                    <h4>{% trans %}blog.programisty.duga{% endtrans %}</h4>
                    <div style="font-size: 8px">
                        {% trans %}ciekawosc.wiedza.niewygodne{% endtrans %}
                        <!-- Ciekawość i wiedza... To, co jest niewygodne dla
                        władzy -->
                    </div>
    
                </div>
                <div style="float: right">
                    <a href="{{ path('HomePage') }}">{% trans %}strona.glowna{% endtrans %}</a>
                    <a href="{{ path('AboutPage') }}">{% trans %}o.mnie{% endtrans %}</a>
                    <a href="{{ path('TBB_mess_add') }}">{% trans %}napisz.do.mnie{% endtrans %}</a>
                    {% if is_granted('IS_AUTHENTICATED_FULLY') %}
                    {{ app.user.username }}
                    <a href="{{ path('TBB_tag_list_homepage') }}">{% trans %}tagi{% endtrans %}</a>
                    <a href="{{ path('TBB_mess_list_homepage') }}">{% trans %}wiadomosci{% endtrans %}</a>
                    <a href="{{ path('logout') }}">{% trans %}wyloguj{% endtrans %}</a>
                    {% else %}
                    <a href="{{ path('login') }}">{% trans %}zaloguj{% endtrans %}</a>
                    {% endif %}
                    <div style="text-align: center; margin: 10px 0px">
                    <a href="{{ path('TBB_rss') }}">
                    <img src="{{ asset('bundles/tpsablog/images/rss.png')
                    }}" alt="rss channel">  
                    </a>
                    <a href="http://www.facebook.com/duga.chernobyl"
                    target="_blank">
                    <img src="{{ asset('bundles/tpsablog/images/facebook.png') }}"
                    alt="facebook"> 
                    </a>
                    <a href="http://www.youtube.com/user/DugaEye"
                    target="_blank">
                    <img src="{{ asset('bundles/tpsablog/images/youtube.png') 
                    }}" alt="youtube">
                    </a>
                    </div>
                </div>
                <div style="clear:both"></div>
            {% endblock %}
        </div>
    
        <div id="frame">
            <div id="left">
            {% block content %}
                {% trans %}TODO{% endtrans %}
            {% endblock %}
            </div>
            <div id="right">
            {% block panel %}
                <div style="text-align: left">
                    <div style="text-align: center">    
                    <h4>{% trans %}profil.duga.eye{% endtrans %}</h4>
                    <img style="width: 100px" src="{{
                    asset('bundles/tpsablog/images/photo.jpg')
                    }}">
                    </div>
                    <div style="font-weight:900; margin-top: 10px">
                    <ul>
                    <li>{% trans %}wiek{% endtrans %}: 21</li>
                    <li>{% trans %}miejsce{% endtrans %}: /dev/null</li>
                    <li>{% trans %}zainteresowania{% endtrans %}: {% trans %}programowanie.hacking.filozofia{% endtrans %}</li>
                    <li>{% trans %}email{% endtrans %}: <a
                    href="mailto:duga(dot)eye(at)gmx(dot)com">Mail</a>
                    </ul>
                    </div>
                </div>
                <h3>{% trans %}reklamy{% endtrans %}</h3>
                {% include '::calendar.html.php' %}
            {% endblock %}
            </div>
        </div>
    
        <div id="footer">
            {% block footer %}
            {% trans %}footer{% endtrans %}
            {% endblock %}
        </div>
    
    
    </div>
    </body>
    </html>
    

    How to get proper parameters offset, number, koniec, aktualny from php Date object? (now it is hard coded)

    calendar.html.twig

    {% include '::calendar.html.php' %}
    
    {% set offset = 1 %}
    {% set number = 28 %}
    {% set koniec =  7 - ((offset + number) % 7) %}
    {% set aktualny = 13 %}
    <table border="0" style="text-align: center">
    <thead>
    <tr>
    <td>{% trans %}pn{% endtrans %}</td>
    <td>{% trans %}wt{% endtrans %}</td>
    <td>{% trans %}sr{% endtrans %}</td>
    <td>{% trans %}czw{% endtrans %}</td>
    <td>{% trans %}pt{% endtrans %}</td>
    <td>{% trans %}sob{% endtrans %}</td>
    <td>{% trans %}nie{% endtrans %}</td>
    </tr>
    <tbody>
    {% if offset % 7 != 0 %}
    <tr>
    {% for i in range(0,offset-1,1) %}<td><br></td>{% endfor %}
    {% endif %}
    {% for i in 1..number %}
    {% if (i+offset)%7 == 1 %}<tr>{% endif %}
    <td>
    {% if i == aktualny %}
    <span style="color: red">{{ i }}</span>
    {% else %}
    {{ i }}
    
    {% endif %} 
    
    </td>
    {% if (i+offset)%7 == 0  %}</tr>{% endif %}
    {% endfor %}
    {% if koniec  < 7 %}
    {% for i in 1..koniec %}
    <td><br></td>
    {% endfor %}
    </tr>
    {% endif %}
    </tbody>
    </table>
    

    php template which should be executed as php template by including it in twig template , but it is not parsed and executed as the one template.

    calendar.html.php

    ppp<?php echo  ('ala') ?>ooo
    

    Simply includes 'pppooo' in source, not visible being handled as html tag.

    deps file if it is needed

    [symfony]
        git=http://github.com/symfony/symfony.git
        version=v2.0.9
    
    [twig]
        git=http://github.com/fabpot/Twig.git
        version=v1.5.1
    
    [monolog]
        git=http://github.com/Seldaek/monolog.git
        version=1.0.2
    
    [doctrine-common]
        git=http://github.com/doctrine/common.git
        version=2.1.4
    
    [doctrine-dbal]
        git=http://github.com/doctrine/dbal.git
        version=2.1.5
    
    [doctrine]
        git=http://github.com/doctrine/doctrine2.git
        version=2.1.5
    
    [swiftmailer]
        git=http://github.com/swiftmailer/swiftmailer.git
        version=v4.1.5
    
    [assetic]
        git=http://github.com/kriswallsmith/assetic.git
        version=v1.0.2
    
    [twig-extensions]
        git=http://github.com/fabpot/Twig-extensions.git
    
    [metadata]
        git=http://github.com/schmittjoh/metadata.git
        version=1.0.0
    
    [SensioFrameworkExtraBundle]
        git=http://github.com/sensio/SensioFrameworkExtraBundle.git
        target=/bundles/Sensio/Bundle/FrameworkExtraBundle
        version=origin/2.0
    
    [JMSSecurityExtraBundle]
        git=http://github.com/schmittjoh/JMSSecurityExtraBundle.git
        target=/bundles/JMS/SecurityExtraBundle
        version=origin/1.0.x
    
    [SensioDistributionBundle]
        git=http://github.com/sensio/SensioDistributionBundle.git
        target=/bundles/Sensio/Bundle/DistributionBundle
        version=origin/2.0
    
    [SensioGeneratorBundle]
        git=http://github.com/sensio/SensioGeneratorBundle.git
        target=/bundles/Sensio/Bundle/GeneratorBundle
        version=origin/2.0
    
    [AsseticBundle]
        git=http://github.com/symfony/AsseticBundle.git
        target=/bundles/Symfony/Bundle/AsseticBundle
        version=v1.0.1
    
  • denkiryokuhatsuden
    denkiryokuhatsuden over 10 years
    and as of symfony 2.2.x, render parameter has changed again to {{ render(controller('ApplicationBundle:Controller:action')) }}.