How to get formatted HTML generated by Symfony

2019-06-14 09:31发布

I'm using Symfony2 to generate forms, or actually Twig, which uses Symfony's functions, so the view looks like this:

{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}

This generates HTML code without any newlines or indentation. This is unreadable when I look into HTML source code.

Is there any way to force Symfony/Twig to format the generated HTML?

标签: symfony twig
2条回答
我想做一个坏孩纸
2楼-- · 2019-06-14 10:07

This link explains form customization in twig beautifully. There are numerous ways of applying css styling to form elements. For example, if you have a form with a field name you can add a css class to it this way:

{# render a widget, but add a "foo" class to it #}
{{ form_widget(form.name, {'attr': {'class': 'foo'}}) }}

or to the label:

{{ form_label(form.name, 'Your Name', {'label_attr': {'class': 'foo'}}) }}

Then you can use the css classes to render form elements as per your design. Hope you get the idea. The docs and link provided in the answer are both useful in this regard.

查看更多
▲ chillily
3楼-- · 2019-06-14 10:16

Update: the below "solution" made me a headache precisely this line:

$html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');

It converts all non-ascii characters to entities, which is not very smart. Javascript's confirm and alert functions don't convert it back to UTF-8, they display strings as they are.


Thanks everybody, but I think I wasn't clear enough:) I didn't mean formatting by css or generally changing how the rendered page looks like, but rather changing HTML source code.

Anyway, with these two articles I finally managed to do what I wanted:

How do you format DOM structures in PHP?

http://php-and-symfony.matthiasnoback.nl/2011/10/symfony2-create-a-response-filter-and-set-extra-response-headers/

Step 1.

So, first the response listener, in (for example) AppBundle/EventListener/ResponseListener.php:

namespace AppBundle\EventListener;

use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;

class ResponseListener {

    private $container;

    public function __construct(Container $container) {
        $this->container = $container;
    }

    function tidyHtml($html)
    {
        $dom = new \DOMDocument();

        if (libxml_use_internal_errors(true) === true)
        {
            libxml_clear_errors();
        }

        $html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');
        $html = preg_replace(array('~\R~u', '~>[[:space:]]++<~m'), array("\n", '><'), $html);

        if ((empty($html) !== true) && ($dom->loadHTML($html) === true))
        {
            $dom->formatOutput = true;

            if (($html = $dom->saveXML($dom->documentElement, LIBXML_NOEMPTYTAG)) !== false)
            {
                $regex = array
                (
                    '~' . preg_quote('<![CDATA[', '~') . '~' => '',
                    '~' . preg_quote(']]>', '~') . '~' => '',
                    '~></(?:area|base(?:font)?|br|col|command|embed|frame|hr|img|input|keygen|link|meta|param|source|track|wbr)>~' => ' />',
                );

                return '<!DOCTYPE html>' . "\n" . preg_replace(array_keys($regex), $regex, $html);
            }
        }

        return false;
    }   


    public function onKernelResponse(FilterResponseEvent $event) {
        $request = $event->getRequest();
        //only when format == html and environment == dev
        if ($request->getRequestFormat() == 'html' && $this->container->get('kernel')->getEnvironment() == 'dev') {
            $event->getResponse()->setContent($this->tidyHtml($event->getResponse()->getContent()));
        }

    }

}

Step 2.

In services.yml:

response_listener:
    class: AppBundle\EventListener\ResponseListener
    arguments: ['@service_container']
    tags:
        - { name: kernel.event_listener, event: kernel.response, method : onKernelResponse }
查看更多
登录 后发表回答