简体   繁体   中英

How to call a service in my twig template to create a form with Symfony 2

I'm working on a menu and I want to make it the best way as possible. The menu in question will always appear in my site, therefore, I made a twig template for that menu and each page extends it.

The thing is that, with what I have right now, my controller must pass the form to my template each time it use that template, therefore it means that all my controllers will need to repeat the code that creates the form and pass it to the form. I don't want that!

I tought about it and I tought I could create a services that would be called by my twig template and that services would pass the form in question and my template will juste show it. If could do that, it would mean that my code would be written once in a service and called once in the template, witch would be perfect.

But, the big question... Can I actually do that? And if it is possible how do I register my services to be callable in my twig, how do I call it in my twig and finally, since it's a form, could I use the handleRequest() function on the form in my service and make the page change when someone submit that form?

Here is the code I have right now:

Twig:

{% extends  "::base.html.twig"%}

{# Feuilles de style de la page #}
{% block stylesheets %}

    <link href="{{ asset("bundles/admin/css/main.css") }}" type="text/css" rel="stylesheet" />

{% endblock %}

{# Contenu de la balise Body #}
{% block contenu_body %}

    <header>
        <a href="{{ path("deconnexion") }}">
            <img src="{{ asset("bundles/admin/images/deconnexion.png") }}" alt="Déconnexion" />
        </a>
    </header>
    <main>
        <nav>
            {{ form_start(formulaire) }}
                {{ form_widget(formulaire.Ajouter) }}
                {{ form_widget(formulaire.projet) }}
                {{ form_row(formulaire.modifier) }}
                {{ form_row(formulaire.supprimer) }}
            {{ form_end(formulaire) }}
        </nav>
        <section>

        </section>
    </main>

{% endblock %}

controller:

<?php

namespace AdminBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AdminBundle\Form\ModifierSupprimerProjet;

class AdminController extends Controller
{
  public function indexAction(Request $request)
  {
    //Gets the list of my projects
    $listeProjets=$this->container->get('portfolio')->chercherListeProjets();      

    //Form to select to modify, delete or add a project
    $formulaire=$this->createForm(new ModifierSupprimerProjet(), null, array('choix' => $listeProjets, ));


    $formulaire->handleRequest($request);

    //If valid
    if($formulaire->isValid())
    {

      if($formulaire->get('Ajouter')->isClicked())
      {
        echo 'add';
      }


      if($formulaire["projet"]->getData()!=='')
      {

        if($formulaire->get('modifier')->isClicked())
        {
          echo $formulaire["projet"]->getData();
        }

        else if($formulaire->get('supprimer')->isClicked())
        {
          echo $formulaire["projet"]->getData();
        }
      }
    }

    return $this->render('AdminBundle::admin.html.twig', array(
                                                                'formulaire'=>$formulaire->createView()
                                                              ));
  }

  public function testAction()
  {
    return $this->render('AdminBundle::admin.html.twig', array());
  }
}

You should start by making sure that you really have to use a form to do the manipulations that you are trying to do. Maybe using a link to a page with the form would suffice.

But this doesn't not answer your question so here goes: Since the form will be used on every page it should be placed in your main template, in this case the base.html.twig . In fact, the content in the <main> and <header> tags should be moved to your base template. Then, you should add an action in your controller which handles the form or just rename the indexAction giving it a name more related to what you are trying to accomplish. After, you will move the code from the form in another template without any of you block tags.

menu.html.twig

{{ form_start(formulaire) }}
    {{ form_widget(formulaire.Ajouter) }}
    {{ form_widget(formulaire.projet) }}
    {{ form_row(formulaire.modifier) }}
    {{ form_row(formulaire.supprimer) }}
{{ form_end(formulaire) }}

controller

use Symfony\Component\HttpFoundation\Request;

class AdminController extends Controller
    ...

    public function menuAction() {
        $request = Request::createFromGlobals();

        // code that was in the indexAction

        return $this->render('AdminBundle::menu.html.twig', array(
            'formulaire'=>$formulaire->createView()
        ));
    }
}

In your base you will render the action.

base.html.twig

{{ render(controller('AdminBundle:Admin:menu')) }}

You can also find more documentation on this page: http://symfony.com/doc/current/book/templating.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM