Skip to content

TwigDataCollector chokes on dynamic 'string' based templates #24540

Closed
@gnat42

Description

@gnat42
Q A
Bug report? yes
Feature request? no
BC Break report? yes/no
RFC? no
Symfony version 3.4.x-dev

We have a situation where we deal with some user-editable templates. Think, templates that are merged with needed content, in this case legal documents. The user can then edit the automatically produced content and we create a pdf from that content.

Here's some of the code

public function render($data, array $params)
{
        $templateConfig = $this->getPracticeTemplateConfig();
        $fullParams = array_merge($params,['template' => $templateConfig]);
        $submittedData = $this->splitIntoPages($data);

        $processedData = [];
        foreach ($submittedData as $content) {
            $endContent = (next($submittedData) == true) ? '<div style="page-break-after: always;"></div>' : '';
            $data = sprintf("{%% extends 'NSPracticeBundle:DocumentTemplate:content.html.twig' %%} {%% block content %%}%s%s{%% endblock %%}", $content, $endContent);
            $template = $this->twig->createTemplate($data);
            $processedData[] = $template->render($fullParams);
        }

        $data = sprintf('{%% extends \'NSPracticeBundle:DocumentTemplate:%s.html.twig\' %%} {%% block body %%}%s{%% endblock %%}',
            $templateConfig->getTwigTemplate(),
            implode('', $processedData)
        );

        $template = $this->twig->createTemplate($data);
        return $template->render($fullParams);
}

This all works perfectly. The issue is that in a dev environment the TwigDataCollector dies as its unable to locate template as returned by $this->twig->createTemplate($data) since its a 'string' instead of an actual path.

It seems to me that I'm either solving my problem incorrectly or the lateCollect() function should be changed to (catching and ignoring the error):

public function lateCollect()
    {
        $this->data['profile'] = serialize($this->profile);
        $this->data['template_paths'] = array();

        $templateFinder = function (Profile $profile) use (&$templateFinder) {
            try {
                if ($profile->isTemplate() && $template = $this->twig->load($profile->getName())->getSourceContext()->getPath()) {
                    $this->data['template_paths'][$profile->getName()] = $template;
                }
                foreach ($profile as $p) {
                    $templateFinder($p);
                }
            } catch (\Twig_Error_Loader $exception) {
            }
        };
        $templateFinder($this->profile);
    }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions