首页 > 解决方案 > Symfony 3.4 Uncaught Symfony\Component\Form\Exception\LogicException:渲染独立表单时未找到块“form_start”

问题描述

这是上一个问题的延续。 Symfony3 CreateFormFactory 的 ->getForm() 方法在哪里

我克服了这个障碍,现在系统无法找到模板目录。我仍在关注 Symfony 指南。https://symfony.com/doc/3.4/components/form.html#rendering-the-form

参考指南的第 23 行看起来需要将真实目录传递给 twig。请参阅下图以供参考。

Symfony Twig Bridge 目录位置

我知道它看起来很多余,但它只是试图告诉 Twig 模板所在的位置。这返回了一个错误。

  Uncaught Twig\Error\LoaderError: The "C:\oerm_dev\www\dev\future5_2\vendor\symfony\twig-bridge../../templates/billing" directory does not exist ("C:\oerm_dev\www\dev\future5_2\vendor\symfony\twig-bridge../../templates/billing"). in C:\oerm_dev\www\dev\future5_2\vendor\twig\twig\src\Loader\FilesystemLoader.php:106

正如您在左侧看到的模板目录所在的位置。似乎 Twig 想要查看自己的文件夹,而不是给出文件夹位置。我尝试了几种不同的变体。

    $loader = new FilesystemLoader(['../../templates/billing',
        $vendorTwigBridgeDirectory.'requeueCharge.html.twig']);

这也会产生错误。

  Uncaught Twig\Error\LoaderError: The "C:\oerm_dev\www\dev\future5_2\vendor\symfony\twig-bridge\requeueCharge.html.twig" directory does not exist

其中错误信息为真,该位置不存在。但是我仍然不知道如何将树枝重定向到视图所在的文件夹?

更新

我只是继续创建文件夹并将 layout.html.twig 文件移动到该位置。现在错误信息是

 Uncaught Symfony\Component\Form\Exception\LogicException: No block "form_start" found while rendering the form. 
 Template.php(380): Twig\Template->displayWithErrorHandling(Array, Arr in C:\oerm_dev\www\dev\future5_2\templates\billing\requeueCharge.html.twig on line 8

该文件中的第 8 行内容如下:

    {% extends 'layout.html.twig' %}
    {% block title %}{% endblock %}
    {% block body %}

        <div class="container">
        <h3></h3>

        {{ form_start(reportForm) }}
            {{ form_widget(reportForm) }}
            <button type="submit" class="btn btn-primary">Search</button>
        {{ form_end(reportForm) }}       

问题不在于模板/计费,而是代码需要指向组件 twig-bridge 附带的内置模板。在示例中,文件夹 Resource/views/Forms 是一个必须使用的真实目录。

标签: phpsymfonytwig

解决方案


我发现我需要更仔细地阅读并调查呈现的每一行代码。所以,这是一个自我评价。这就是解谜的方法。

我最终得到了这个:

    use Symfony\Bridge\Twig\Extension\FormExtension;
    use Symfony\Bridge\Twig\Extension\TranslationExtension;
    use Symfony\Bridge\Twig\Form\TwigRendererEngine;
    use Symfony\Component\Form\FormRenderer;
    use Symfony\Component\Form\Forms;
    use Symfony\Component\Form\Extension\Csrf\CsrfExtension;
    use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationExtension;
    use Symfony\Component\HttpFoundation\Session\Session;
    use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage;
    use Symfony\Component\Security\Csrf\CsrfTokenManager;
    use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
    use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage;
    use Symfony\Component\Translation\Loader\XliffFileLoader;
    use Symfony\Component\Translation\Translator;
    use Twig\Environment;
    use Twig\Extension\DebugExtension;
    use Twig\HeaderExtension;
    use Twig\Loader\FilesystemLoader;
    use Twig\RuntimeLoader\FactoryRuntimeLoader;

class RequeueChargesController extends Controller
{
public function requeueCharge()
{
    $defaultFormTheme = 'form_div_layout.html.twig';
    $vendorDirectory = dirname(__DIR__, 2).'\vendor';

    $translator = new Translator('en');
    $translator->addLoader('xlf', new XliffFileLoader());

    //$form->handleRequest();
    $session = new Session(new PhpBridgeSessionStorage());
    $csrfGenerator = new UriSafeTokenGenerator();
    $csrfStorage = new SessionTokenStorage($session);
    $csrfManager = new CsrfTokenManager($csrfGenerator, $csrfStorage);

    $appVariableReflection = new \ReflectionClass('\Symfony\Bridge\Twig\AppVariable');
    $vendorTwigBridgeDirectory = dirname($appVariableReflection->getFileName());

    $loader = new FilesystemLoader(['../../templates/billing/',
        $vendorTwigBridgeDirectory.'/Resources/views/Form']);

    $twig = new Environment($loader, [
        'debug' => true,
    ]);
    $twig->addExtension(new HeaderExtension());
    $twig->addExtension(new DebugExtension());
    $twig->addExtension(new TranslationExtension($translator));

    $formEngine = new TwigRendererEngine([$defaultFormTheme], $twig);
    $twig->addRuntimeLoader(new FactoryRuntimeLoader([
        FormRenderer::class => function () use ($formEngine, $csrfManager) {
        return new FormRenderer($formEngine, $csrfManager);
        }
    ]));

    $twig->addExtension(new FormExtension());

    $formFactory = Forms::createFormFactoryBuilder()
        ->addExtension(new HttpFoundationExtension())
        ->addExtension(new CsrfExtension($csrfManager))
        ->getFormFactory();

    $form = $formFactory->createBuilder(TaskType::class)
        ->getForm();

    return $twig->render('requeueCharge.html.twig', [
        'payments' => 'Charge',
        'reportForm' => $form->createView()

    ]);
}
}

https://symfony.com/doc/3.4/components/form.html#rendering-the-form中给出的示例代码几乎不需要改动即可工作。

您可以将该示例与我必须执行的操作进行比较,以使其在 OpenEMR 代码库中运行。如果您有任何问题,请尝试我。


推荐阅读