fbpx

The fine art of integrating Twitter Bootstrap with Symfony Forms

While there are several bundles that would make integrating Twitter Bootstrap into Symfony as easy as including a new bundle with Composer, I like to learn how things work behind the scenes. In this article I will attempt to show you how this is done when you want to use Twitter Bootstrap’s form styles with your Symfony forms. I am assuming you are familiar with Symfony’s Form components and Twitter Bootstrap in general.

Twig’s form_row block is responsible for rendering the label, the input and any errors the form may have, but where does the template that defines this block come from? To answer that question we need to look deep into Symfony’s source:

vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig

Every part of the form renders from blocks defined somewhere inside this file. Since the form_row is responsible for the layout, lets search for the form_row block inside this file.

{% block form_row %}
{% spaceless %}
    <div>
        {{ form_label(form) }}
        {{ form_errors(form) }}
        {{ form_widget(form) }}
    </div>
{% endspaceless %}
{% endblock form_row %}

We found it! But wait, any decent developer out there should know by now that we don’t want to overwrite this default file that’s part of Symfony’s core. If you do that, when you upgrade Symfony all your changes will be gone. Instead, let’s make a new file in the app/Resources/views directory and override the default look to work with Twitter Bootstrap.

{% block form_row %}
{% spaceless %}
    <div class="control-group">
        {{ form_label(form) }}
        <div class="controls">
            {{ form_widget(form) }}
            {{ form_errors(form) }}
        </div>
    </div>
{% endspaceless %}
{% endblock form_row %}

This is the minimum configuration you need to get your Symfony forms working with Twitter Bootstrap. In order for Symfony to know we want to override the look of the forms, we need to tell it to use our new forms file. Open up the config.yml file and add the pointer to your new forms layout.

# Twig Configuration
twig:
    form:
        resources:
            - "::forms.html.twig"

We are now in control of how the form will be rendered. If you browse to your form and inspect an element you will see that it now uses our new layout. If you submit your form blank, you will noticed that the errors are still pretty ugly. Let’s fix that.

Since we don’t know where the errors are coming from, let’s search the original layout file (form_div_layout.html.twig) for the word form_errors and see if we find anything.

{% block form_errors %}
{% spaceless %}
    {% if errors|length > 0 %}
    <ul>
        {% for error in errors %}
            <li>{{
                error.messagePluralization is null
                    ? error.messageTemplate|trans(error.messageParameters, 'validators')
                    : error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators')
            }}</li>
        {% endfor %}
    </ul>
    {% endif %}
{% endspaceless %}
{% endblock form_errors %}

Copy the block to our new file and let’s modify it to play well with Twitter Bootstrap:

{% block form_errors %}
{% spaceless %}
    {% if errors|length > 0 %}
    <span class="help-inline">
        {% for error in errors %}
            {{
                error.messagePluralization is null
                    ? error.messageTemplate|trans(error.messageParameters, 'validators')
                    : error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators')
            }}
        {% endfor %}
    </span>
    {% endif %}
{% endspaceless %}
{% endblock form_errors %}

As you can see we got rid of those ugly unordered lists and replaced them with Twitter Bootstrap’s help-inline span. Things are starting to look much better, but wouldn’t it be nice if we could highlight the fields when something goes wrong? You guessed it, Twitter Bootstrap provides just this.

Let’s go back to our first block, the form_row block. And let’s add the error class to the controls-group:

{% block form_row %}
{% spaceless %}
    <div class="control-group error">
        {{ form_label(form) }}
        <div class="controls">
            {{ form_widget(form) }}
            {{ form_errors(form) }}
        </div>
    </div>
{% endspaceless %}
{% endblock form_row %}

Ok, that’s almost what we want… but shouldn’t we highlight only the fields that actually have errors on them? Symfony makes this easy. In this block we have access to the errors variable. In fact there are a few other variables that we have access to as well, that are beyond the scope of this article. To only add the error class when we need it all we have to do is test for such:

{% block form_row %}
{% spaceless %}
    <div class="control-group {{ errors|length > 0 ? 'error' : '' }}">
        {{ form_label(form) }}
        <div class="controls">
            {{ form_widget(form) }}
            {{ form_errors(form) }}
        </div>
    </div>
{% endspaceless %}
{% endblock form_row %}

With this our forms are looking much better. As you can see modifying our forms is as easy as creating a file to selectively override the default block code found in form_div_layout.html.twig. I invite you to continue to play with this file and see what other customization you can do. For now, we have the basis for a Twitter Bootstrap form in place and with a little more work we could be 100% bootstrapped!

What it means to deliver Quality, Part 1: Metrics from Abstraction

What is Quality?
On the surface, Quality can be an abstract concept. Like Love: everyone wants it, plans for it, goes to great lengths for it, and even once achieved it is difficult to maintain. On one hand, folklore surrounds figures such as Steve Jobs in their legendary quest for industrial design and quality, and on the other hand, everyone claims to deliver it. It can also be like Beauty, in that it is “in the eye of the beholder”. It is certainly perceptual and expectation based.
How does one differentiate “good” quality, “industry standard” quality, “high” quality, “exceptional” quality etc.? As software professionals, we are often asked to defend our quality, isn’t it time we had a clear answer? Quality is a journey: you have to know where you want to go, how to get there, and most importantly how much you are willing to give to get there. Taking these similes one step further – abstract concepts make for difficult comparisons. Can you say which of your children you love more? No, but you can certainly compare their non-abstract aspects. E.g. You can say which one is a faster runner. If you can measure it, you can compare it. So let’s learn our measurements first so we know first where we want to be.

What is a high quality software application?
Bringing this back to software applications, aspects of quality can be compared such as:
1. Numbers of bugs /kLoC (1000 lines of code) can be measured and compared. E.g. Infoworld reports that industry standard applications see 5-20 bugs/kLoc in production. Its probably a multiple of that in the QA phase of the SDLC. Regardless, at least we have a test whereby we can call an application “industry standard”. You can further break this down to be more rigorous to capture certain aspects of code quality e.g security specific bugs.
2. Performance: you can get industry standard data such as the Gomez lists per industry e.g. the top mobile retail sites average between 4 and 8 seconds in response time. This gives us some absolute standards to begin the discussion.
3. Usability: Surprisingly, measurements can even be made in this perception-centered area. The SUS scale helps us put numbers around usability. An industry average score is 68.
4. Similarly, user experience or look and feel can also be measured via questionnaire format using the SUPR-Q measure.
5. Uptime: if you are running a hosted application, uptime metrics should be monitored and compared to the industry. The published averages are just that: average. Do you need to be average or better in your specific field? E.g. if you are launching a new service in a competitive environment you probably need usability and performance better than average to build that critical user base compared to an employee-focused app for internal purposes, the client may not want to spend as much for something that the users are required to use anyway. Not that they need to be forced to endure poor quality but the standards may be less stringent.

So if you had to justify your work to a tough client or come in strong at a presentation you can go in armed with statistics. Such metrics are essential for internal as well as external benchmarks. Internally, it gives your team a target of what is expected and once you have baselined your current quality you can incentivize continued improvement/maintenance of quality. Externally, it makes a strong statement once you have arrived at a hard fought level of quality that your ascent was intentional and likely eliminates low-end competitors. At Informulate, for example, at client presentations we refer to one of our projects where we delivered an application of ~500 kLoc with less than 350 bugs (0.75 bugs/kLoc or 10X the industry average).

After Metrics, what?
Now that we know where we need to be vis-à-vis the industry, how do we get there and what tradeoffs do we need to make in the process? Check back for the next installment on Managing For Quality

We love making an impact!

To request a call, fill out the form below and an Informulate team member will reach out to discuss your project needs.

We are ready to help you succeed!

To request a call, fill out the form below and an Informulate team member will reach out to discuss your project needs.

Business Intelligence

To learn more about our Business Intelligence solutions, fill out the form below and an Informulate team member will reach out to discuss your project needs.

Code Review

To learn more about our Code Review, fill out the form below and an Informulate team member will reach out to discuss your project needs.

Process Audit

To learn more about our Process Audit, fill out the form below and an Informulate team member will reach out to discuss your project needs.

AI Workflow Review

To learn more about our AI workflow Review, fill out the form below and an Informulate team member will reach out to discuss your project needs.

Digital Transformation

To learn more about our Digital Transformation solutions, fill out the form below and an Informulate team member will reach out to discuss your project needs.

Product Development

To learn more about our Product Development solutions, fill out the form below and an Informulate team member will reach out to discuss your project needs.

Team Enrichment

To learn more about our Team Enrichment solutions, fill out the form below and an Informulate team member will reach out to discuss your project needs.

Process Automation

To learn more about our Process Automation solutions, fill out the form below and an Informulate team member will reach out to discuss your project needs.

We love building things!

To request a call, fill out the form below and an Informulate team member will reach out to discuss your project needs.

AI Consulting

To learn more about our AI Consulting solutions, fill out the form below and an Informulate team member will reach out to discuss your project needs.

We love making an impact!

To request a call, fill out the form below and an Informulate team member will reach out to discuss your project needs.

We love making an impact!

To request a call, fill out the form below and an Informulate team member will reach out to discuss your project needs.

We love making an impact!

To request a call, fill out the form below and an Informulate team member will reach out to discuss your project needs.

Digital Transformation

To learn more about our Digital Transformation solutions, fill out the form below and an Informulate team member will reach out to discuss your project needs.

We love making an impact!

To request a call, fill out the form below and an Informulate team member will reach out to discuss your project needs.

Submit Your Resume

To apply for this position, fill out the form below and attach your resume in PDF format. A member of our HR team will review your submission and reply accordingly.