bench-o bench-o - 2 months ago 25
Twig Question

Symfony2 Twig extension: Creating form

I wanted to have a contact-form-block that i can reuse on different pages and templates. So i decided to write a Twig extension. The problem is that i cant access the createFormBuilder() function. The second problem will be then that i cant access the request object for validation. My current code looks like this:

<?php

namespace Name\NameBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class ContactExtension extends \Twig_Extension
{
function getName() {
return 'contact_extension';
}

function getFunctions() {
return array(
'contactform' => new \Twig_Function_Method($this, 'contactform'),
);
}

function contactform() {
$form = $this->createFormBuilder()
->add('Name', 'text')
->add('Message', 'textarea')
->add('Send', 'submit')
->getForm();

return $this->render('NameBundle:forms:contactform.html.twig', array(
'form' => $form->createView(),
}
}


But i get error "Call to undefined method createFormBuilder()"...

Also i will get error if i change the function to
function contactform(Request $request) { ... }


What do i need to add to use this function an object? Or maybe the twig extension is the completely wrong approach?

Answer Source

createFormBuilder() is a Controller helper that allows you to access the form.factory service within your controllers through the container (code below)

namespace Symfony\Bundle\FrameworkBundle\Controller;
// ...
class Controller extends ContainerAware
{
    // ...
    public function createFormBuilder($data = null, array $options = array())
    {
        return $this->container->get('form.factory')->createBuilder('form', $data, $options);
    }

You're not in a "Controller context" here, so if you want to use the form.factory service within your extension you've to inject it.

BUT,

I'll not advice your to manage your contactForm this way (using a Twig Extension function). Why don't you just create a contactAction within the appropriate controller. You can then render your form in your templates using the twig render helper,

{{ render(controller('YourBundle:YourController:contactAction')) }}