APY / APYDataGridBundle

Symfony Datagrid Bundle
MIT License
492 stars 344 forks source link

export fails when using custom twigs #1072

Closed FredDut closed 1 year ago

FredDut commented 2 years ago

Hello, If I use twigs for customizing a cell in the grid and and the grid globaly, the export fails with "Block "grid_titles" doesn't exist in grid template "ee"." An example based on https://github.com/npotier/apydatagrid-demo author/book in config/packages/twig.yaml:

    paths:
        '%kernel.project_dir%/vendor/apy/datagrid-bundle/Resources/views': apy

templates/grid.html.twig:

{% extends '@apy/blocks.html.twig' %}
{# ------------------------------------------------------ grid ------------------------------------------------------ #}
{% block grid %}
<div class="grid">
{% if grid.totalCount > 0 or grid.isFiltered or grid.noDataMessage is same as (false) %}
    <form id="{{ grid.hash }}" action="{{ grid.routeUrl }}" method="post">
        <div class="grid_header">
        {% if grid.massActions|length > 0 %}
            {{ grid_actions(grid) }}
        {% endif %}
        </div>
        <div class="grid_body">
        <table class="table table-sm table-striped table-bordered">
        <thead>
        {% if grid.isTitleSectionVisible %}
            {{ grid_titles(grid) }}
        {% endif %}
        {% if grid.isFilterSectionVisible %}
            {{ grid_filters(grid) }}
        {% endif %}
        </thead>
        <tbody>
        {{ grid_rows(grid) }}
        </tbody>
        </table>
        </div>
        <div class="grid_footer">
        {% if grid.isPagerSectionVisible %}
            {{ grid_pager(grid) }}
        {% endif %}
        {% if grid.exports|length > 0 %}
            {{ grid_exports(grid) }}
        {% endif %}
        {% if grid.tweaks|length > 0 %}
            {{ grid_tweaks(grid) }}
        {% endif %}
        </div>
        {% if withjs %}
            {{ grid_scripts(grid) }}
        {% endif %}
    </form>
{% else %}
    {{ grid_no_data(grid) }}
{% endif %}
</div>
{% endblock grid %}

templates/author/index.html.twig

{% extends 'base.html.twig' %}

{% block title %}Author index{% endblock %}

{% block body %}
    <h1>Author index</h1>
{{ grid(grid, "author/grid_template.html.twig") }}
    <a href="{{ path('author_new') }}">Create new</a>
{% endblock %}

templates/author/grid_template.html.twig `{% extends 'grid.html.twig' %}

{% block grid_column_id_cell %} here {{ value }} {% endblock %}`

AuthorController ` /**

Nota: same error if grid.html.twig doesn't extend blocks.html.twig

FredDut commented 2 years ago

I forgot to say: apy/datagrid-bundle 4.0.2 symfony 5.4.7 php 7.2.24

mhor commented 2 years ago

HI, @FredDut it's seems to be a bug introduced here.

It's not TemplateWrapper class that should be use but `Twig\Templateclass

FredDut commented 2 years ago

Hi @mhor , rolling back to Twig\Template is not enough. I've to change

public function setTemplate($template)
    {
        if (is_string($template)) {
            if (substr($template, 0, 8) === '__SELF__') {
                $this->templates = $this->getTemplatesFromString(substr($template, 8));
                $this->templates[] = $this->twig->loadTemplate(static::DEFAULT_TEMPLATE);
            } else {
                $this->templates = $this->getTemplatesFromString($template);
            }
        } elseif ($this->templates === null) {
            $this->templates[] = $this->twig->loadTemplate(static::DEFAULT_TEMPLATE);
        } else {
            throw new \Exception('Unable to load template');
        }

        return $this;
    }

in

public function setTemplate($template)
    {
        if (is_string($template)) {
            if (substr($template, 0, 8) === '__SELF__') {
                $this->templates = $this->getTemplatesFromString(substr($template, 8));
                $this->templates[] = $this->twig->loadTemplate(static::DEFAULT_TEMPLATE);
            } else {
                $this->templates = $this->getTemplatesFromString($template);
                $this->templates[] = $this->twig->loadTemplate(static::DEFAULT_TEMPLATE);
            }
        } elseif ($this->templates === null) {
            $this->templates[] = $this->twig->loadTemplate(static::DEFAULT_TEMPLATE);
        } else {
            throw new \Exception('Unable to load template');
        }

        return $this;
    }

or this

public function setTemplate($template)
    {
        if (is_string($template)) {
            if (substr($template, 0, 8) === '__SELF__') {
                $this->templates = $this->getTemplatesFromString(substr($template, 8));
            } else {
                $this->templates = $this->getTemplatesFromString($template);
            }
            $this->templates[] = $this->twig->loadTemplate(static::DEFAULT_TEMPLATE);
        } elseif ($this->templates === null) {
            $this->templates[] = $this->twig->loadTemplate(static::DEFAULT_TEMPLATE);
        } else {
            throw new \Exception('Unable to load template');
        }

        return $this;
    }

but I don't really know what I'm doing I don't know why the DEFAULT_TEMPLATE is not loaded by getTemplatesFromString and why it was working before.

npotier commented 1 year ago

Hello @FredDut thank you for reporting this bug.

I've updated the demo repo here https://github.com/npotier/apydatagrid-demo to reproduce this case.

With the latest version of APYDatagridBundle, I don't reproduce this bug.

Could you try and confirm it please ?

Thank you 😄

FredDut commented 1 year ago

Hello, I don't reproduce it anymore, neither do I. It's fixed. Thanks