phpsymfonytwigfosuserbundle

Symfony2 FOSUserBundle Overriding Forms


I am trying to change the template for the registration form in my application so that I can add some other HTML to it. Here is the /My/UserBundle/Resources/views/Registration/register.html.twig file:

{% extends "MyUserBundle::layout.html.twig" %}

{% block fos_user_content %}
<section class="register site-content">
    <header>
        <h1>{{ 'layout.register'|trans({}, 'FOSUserBundle') }}</h1>
    </header>
    <div class="block">
        {% include "FOSUserBundle:Registration:register_content.html.twig" %}
    </div>
</section>
{% endblock fos_user_content %}

And I have successfully overridden the layout.html.twig:

{% extends 'MyMainBundle::layout.html.twig' %}

{% block title %}{{ site_name }}{% endblock %}

{% block content %}
    {% for key, message in app.session.getFlashes() %}
    <div class="{{ key }}">
        {{ message|trans({}, 'FOSUserBundle') }}
    </div>
    {% endfor %}
    {% block fos_user_content %}{% endblock %}
{% endblock %}

as well as form.html.twig:

{% extends 'FOSUserBundle::form.html.twig' %}

{% block field_row %}
    <li class="form_row">
        {{ form_label(form) }}
        {{ form_errors(form) }}
        {{ form_widget(form) }}
    </li>
{% endblock field_row %}

{% block form_widget %}
    <ul {{ block('container_attributes') }}>
        {{ block('field_rows') }}
        {{ form_rest(form) }}
    </ul>
{% endblock form_widget %}

config parts:

# FOS User Configuration
fos_user:
    db_driver: orm
    firewall_name: main
    user_class: My\UserBundle\Entity\User
    from_email:
      address: %admin_email%
      sender_name: %site_name%
    template:
      engine: twig
      theme: MyUserBundle::form.html.twig

I have cleared my cache.

Whenever I go to

http://localhost/register/

apache just hangs until it times out.

The best I can figure out, is the PHP maximum execution message says it crashes on a twig template in the cache on line 16. That line is function doGetParent(...) The file is:

<?php

/* FOSUserBundle::form.html.twig */
class __TwigTemplate_9cf68a2af1db50466c556a735bcdeba0 extends Twig_Template
{
    public function __construct(Twig_Environment $env)
    {
        parent::__construct($env);

        $this->blocks = array(
            'field_row' => array($this, 'block_field_row'),
            'form_widget' => array($this, 'block_form_widget'),
        );
    }

    protected function doGetParent(array $context)
    {
        return "FOSUserBundle::form.html.twig";
    }

    protected function doDisplay(array $context, array $blocks = array())
    {
        $this->getParent($context)->display($context, array_merge($this->blocks, $blocks));
    }

    // line 3
    public function block_field_row($context, array $blocks = array())
    {
        // line 4
        echo "    <li class=\"form_row\">
        ";
        // line 5
        echo $this->env->getExtension('form')->renderLabel($this->getContext($context, "form"));
        echo "
        ";
        // line 6
        echo $this->env->getExtension('form')->renderErrors($this->getContext($context, "form"));
        echo "
        ";
        // line 7
        echo $this->env->getExtension('form')->renderWidget($this->getContext($context, "form"));
        echo "
    </li>
";
    }

    // line 11
    public function block_form_widget($context, array $blocks = array())
    {
        // line 12
        echo "    <ul ";
        $this->displayBlock("container_attributes", $context, $blocks);
        echo ">
        ";
        // line 13
        $this->displayBlock("field_rows", $context, $blocks);
        echo "
        ";
        // line 14
        echo $this->env->getExtension('form')->renderRest($this->getContext($context, "form"));
        echo "
    </ul>
";
    }

    public function getTemplateName()
    {
        return "FOSUserBundle::form.html.twig";
    }

    public function isTraitable()
    {
        return false;
    }
}

It has also timed out on \vendor\twig\lib\Twig\Template.php on line 65 Which is public function getParent(array $context)

So clearly there is some problem with getParent but I don't know what that means or how to fix it.


Solution

  • According to the FOSUserBundle documentation:

    The easiest way to override a bundle's template is to simply place a new one in your app/Resources folder. To override the layout template located at Resources/views/layout.html.twig in the FOSUserBundle directory, you would place you new layout template at app/Resources/FOSUserBundle/views/layout.html.twig.

    As you can see the pattern for overriding templates in this way is to create a folder with the name of the bundle class in the app/Resources directory. Then add your new template to this folder, preserving the directory structure from the original bundle.

    In my project I override FOSUserBundle's layout as they said and it's work like a charm.

    So doing it at the same way you will need to create app/Resources/FOSUserBundle/views/Registration/register.html.twig. (or the form you want to override)

    EDIT

    Ok, I just realize that you've chosen to extend the FOSUserBundle. In that case instead of app/Resources/ you need to do it inside your bundle. But you don't need to put

    {% extends 'FOSUserBundle::form.html.twig' %}
    

    The FOSUserBundle will detect that you are overriding the bundle and will be extended automatically.

    And you also need to tell your bundle that FOSUserBundle is its parent.

    class YourBundle extends Bundle
    {
        public function getParent()
        {
            return 'FOSUserBundle';
        }
    }