0

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?

konrad_firm
  • 859
  • 1
  • 11
  • 28
  • 2
    Look at it in firebug or similar developer tool. – malcolm Jan 28 '16 at 15:10
  • 1
    Did you see recipe from [cookbook](http://symfony.com/doc/current/cookbook/form/form_customization.html)? – cn007b Jan 28 '16 at 15:47
  • @malcom, thanks, yes, I know that, but you do know that Firebug/Chrome shows corrected source code, so if e.g. there is a closing tag missing, you will not notice this using the above tools. But +1 anyway :) – konrad_firm Jan 29 '16 at 08:42
  • @Vladimir Kovpak - thanks, that's OK, although I rather hoped for a general solution, not only for forms. See my own answer. But +1 anyway:) – konrad_firm Jan 29 '16 at 08:43

2 Answers2

1

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.

mansoor.khan
  • 2,309
  • 26
  • 39
  • Thanks, +1 for a nice article (to read for later), but I didn't mean styling or how the page looks rendered, but rather how HTML source code looks like, I think I wasn't clear enough. – konrad_firm Jan 29 '16 at 08:39
  • Even for the markup, if you render labels, input fields separately in your code with say
    tags, you'll get a clean, readable markup.
    – mansoor.khan Jan 29 '16 at 08:50
0

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 }
Community
  • 1
  • 1
konrad_firm
  • 859
  • 1
  • 11
  • 28