2013-06-04 3 views
5

Nota: Quello che sto facendo qui è embedding controllers < --- vedere che link per una simile (ufficiale) esempio.Symfony2 - Twig rendere controller e tornare risposta gamma

voglio chiamare un controller da un modello ramoscello, e hanno quel controller restituire un array che posso utilizzare in tutto il resto del mio modello.

posso farlo con variabili individuali:

Ramoscello

{% set testVar = render(controller('AppBundle:Test:index')) %} 

controller

class TestController extends Controller 
{ 
    public function testAction() 
    { 
     return new Response('OH HAI'); 
    } 
} 

Tuttavia, il seguente genera un'eccezione: ("The Response content must be a string or object implementing __toString(), "array" given.")con lo stesso ramoscello file.

public function testAction() 
{ 
    return new Response(array('test' => 1, 'foo' => 'bar')); 
} 

Questo genera l'eccezione sopra. Come posso ottenere ciò che cerco senza creare un modello extra fittizio e inutile per il controller per il rendering?

+2

Quello che stai cercando di fare è la rottura del pattern MVP (stai provando a mettere la logica in view layer). Il mio consiglio è ripensare alla tua soluzione. Forse se dici di più quello che vuoi ottenere, posso dire di più. Saluti! – Cyprian

+0

Grazie per la risposta @Cyprian, mi sono sbagliato a farlo, quindi forse c'è un altro modo. La mia vista è suddivisa in 3 modelli di ramoscello che estendono un modello di layout: ** header **, ** sidebar ** e ** content **. La * barra laterale * richiede dati dinamici per ogni caricamento della pagina (alcune statistiche live, ad esempio). Ho bisogno che la barra laterale contenga questi dati, qualunque cosa sia nel modello * content *. – Jimbo

+0

Il mio obiettivo era quello di codificare la barra laterale, recuperando i propri dati da un controller separato, e quindi tutto ciò che codice in futuro sono solo le pagine di contenuto e non ho bisogno di duplicare alcun codice per ottenere le statistiche per la barra laterale. – Jimbo

risposta

5

Il modo standard per ottenere quello che vuoi sembra qualcosa del genere.

Supponiamo che tu abbia la tua azione regolare. Per esempio.

class TestController extends Controller 
{ 
    public function testAction() 
    { 
     return $this->render('AppBundle:Test:index.html.twig'); 
    } 
} 

E il modello:

<html> 
    <body> 
     {% block sidebar %} 
      {{ controller('AppBundle:Test:sidebar') }} 
     {% endblock %} 
     {% block content %} 
      Hello world 
     {% endblock %}      
    </body> 
</html> 

Dopodiché è necessario creare qualche azione per la barra laterale. Nota che in questo modo eviti di inserire qualsiasi logica nel tuo livello di vista.

class BaseController extends Controller 
{ 
    public function sidebarAction() 
    { 
     $status = $this->get('some.status.logic')->retrieveStatus(); 

     return $this->render('AppBundle:Base:sidebar.html.twig', array(
      'status' => $status, 
     )); 
    } 
} 

E la tua Base/sidebar.html.twig:

<div class="sidebar"> 
    {{ status.showStatusInfo() }} 
</div> 

E questo è tutto. Non stai violando MVP in questo modo, perché non hai ancora alcuna logica nel tuo livello di vista (la logica per la barra laterale è in BaseController).

+0

Penso di essere preoccupato per troppi livelli di astrazione, ma questo sembra essere il miglior modo di agire. Saluti! – Jimbo