1

I'm trying to make a dynamic twig template to print lists of Entities with different number of fields. The whole point is that I can't print all the columns of $lligues.

My controller looks like this:

    /**
    * @Route("/llistarlliga",name="llistar_lliga")
    */
    public function llistarLliga(){
        $repository = $this->getDoctrine()->getRepository('AppBundle:Lliga');

        $camps = array('Nom','Nº equips','Accions');
        $lligues = $repository->findAll();
        return $this->render('templates/list.html.twig', array('camps' => $camps, 'lligues' => $lligues,
                                                                'title' => 'Llistat de lligues'));
    }

Twig template:

{# app/Resources/views/forms/lista.html.twig #}
{% extends "templates/home.html.twig" %}
{% block title %}
    {{title}}
{% endblock %}
{% block body %}  
    <table>
        <thead>
            {% for i in 0..camps|length-1 %}
                <th>{{camps[i]}}</th>
            {% endfor %}
        </thead>
        <tbody>
            {% for lliga in lligues %}
                <tr>
                    <td>{{lliga.nom}}</td>
                    <td>{{lliga.numequips}}</td>
                    <td>
                        <a href="{{ path('borrar_lliga', {'nom' : lliga.nom}) }}"><img src="{{ asset('images/bin.png') }}" /></a>
                        <a href="{{ path('modificar_lliga', {'nom' : lliga.nom}) }}"><img src="{{ asset('images/edit.png') }}" /></a>
                    </td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
{% endblock %}

So, I would like to change the second loop (for lliga in lligues) to make it dynamic, so if it has more fields or less, it prints them too.

Thanks to everyone!

hasumedic
  • 2,139
  • 12
  • 17
xinp4chi
  • 73
  • 11
  • What do you mean by "if it has more fields or less"? How can an entity of have less fields than another entity of the same class? – Terenoth Mar 09 '16 at 09:21
  • I mean, i want that twig to display all my entities. So my lliga entity, has 2 fields, my Equip entity has 8 fields, my Jugador entity has 10 fields. I just want to use one unique template. Did I explain my self now? I'm sorry. – xinp4chi Mar 09 '16 at 09:35
  • Have you tried `{% for equip in lligues.equips %}`and then `{{equip.nom}}`? Twig can traverse your entities, the only thing you'll need to take into account is to fetch join all those entities if you don't want to end up having N+1 problems everywhere. – hasumedic Mar 09 '16 at 09:40
  • Ok I understand now. Unfortunately, I have no idea how to achieve this. – Terenoth Mar 09 '16 at 09:40
  • @hasumedic Thats not the point, I want to simply have a dynamic template that can cover all my entities. I can't understand how that would work in my case, but thanks for helping! – xinp4chi Mar 09 '16 at 09:46
  • see http://stackoverflow.com/questions/11841515/twig-iterate-over-object-properties and http://stackoverflow.com/questions/11780073/symfony2-twig-display-all-fields-and-keys – Rvanlaak Mar 09 '16 at 11:04
  • @Rvanlaak thanks, i'll take a look! – xinp4chi Mar 09 '16 at 18:54

1 Answers1

3

You can create a twig filter cast_to_array.

First you need to create the custom filter. Something like this:

namespace AppBundle\Twig;


class ArrayExtension extends \Twig_Extension
{
    /**
     * @inheritDoc
     */
    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('cast_to_array', array($this, 'castToArray'))
        );
    }

    public function castToArray($stdClassObject) {
        $response = array();
        foreach ($stdClassObject as $key => $value) {
            $response[] = array($key, $value);
        }
        return $response;
    }


    /**
     * Returns the name of the extension.
     *
     * @return string The extension name
     */
    public function getName()
    {
        return 'array_extension';
    }
}

And add it to your app\config\services.yml:

services:
app.twig_extension:
    class: AppBundle\Twig\ArrayExtension
    public: false
    tags:
        - { name: twig.extension }

Finally, you case use your custom filter in your Twig templates:

{# app/Resources/views/forms/lista.html.twig #}
{% extends "templates/home.html.twig" %}
{% block title %}
    {{title}}
{% endblock %}
{% block body %}  
    <table>
        <thead>
            {% for i in 0..camps|length-1 %}
                <th>{{camps[i]}}</th>
            {% endfor %}
        </thead>
        <tbody>
            {% for lliga in lligues %}
                <tr>

                    {% for key, value in lliga|cast_to_array %}
                        <td>{{ value }}</td>
                    {% endfor %}

                    <td>
                        <a href="{{ path('borrar_lliga', {'nom' : lliga.nom }) }}"><img src="{{ asset('images/bin.png') }}" /></a>
                        <a href="{{ path('modificar_lliga', {'nom' : lliga.nom }) }}"><img src="{{ asset('images/edit.png') }}" /></a>
                    </td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
{% endblock %}

I believe this could do the trick.

ohvitorino
  • 186
  • 1
  • 15
  • I can't try it right now. Tomorrow morning ill try it and post how did it go! Thank you very much! – xinp4chi Mar 09 '16 at 18:53
  • It says Unknown "cast_to_array" filter... Any idea? – xinp4chi Mar 10 '16 at 11:38
  • My bad, I assumed that filter already existed by default. But in fact I have it in my code base as a custom filter. The custom filter is based on [http://stackoverflow.com/a/11908528/968986](http://stackoverflow.com/a/11908528/968986). I'll edit the my answer to reflect the filter creation. – ohvitorino Mar 10 '16 at 12:17
  • Actually, dont worry! Honestly, I'll make different templates for each entity, it will be faster, because I have to finish this project for school by tomorrow! Thank you very much! – xinp4chi Mar 10 '16 at 12:25
  • Well, I already added it :) Other users can use it in the future, if it fits their case. – ohvitorino Mar 10 '16 at 12:38
  • In any case, ill give it a try when im done. I really apreciate ur help. Thanks a lot! – xinp4chi Mar 10 '16 at 12:50
  • No problem :) Good luck! – ohvitorino Mar 10 '16 at 12:52