Monday, May 23, 2016

Customize color codes for visual elements using a Twig Extension

Situation:

In a ticketing system, next to each ticket title I need to display a status, each status with a certain CSS style. I will be using Bootstrap  labels for displaying a certain color for each status.

I would want to avoid to have the entire logic (in Twig)  in each view where I display these statuses,  like this:


<?php

{% if ticket.status == 'start' %}
    <span class="label label-default">{{ ticket.status|trans }}</span>
{% elseif ticket.status == 'working' %}
    <span class="label label-primary">{{ ticket.status|trans }}</span> 
 
...
 
{% endif %}


Solution:

Twig Extension "The main motivation for writing an extension is to move often used code into a reusable class"

Implementation:

Start by creating a directory TwigExtension, and inside create a PHP file with a class. This class will extend \Twig_Extension.

I will create a filter which will return a certain CSS class depending on the status string, the name of the filter is "statusLabel" . I believe the code below is self explanatory.


<?php

namespace MyBundle\TwigExtensions;

/**
 * This extension handles how are displayed the statuses.
 * The status is displayed using Boostrap labels, for each status there is a certain CSS label class
 *    <span class="label label-info">Info Label</span>
 * 
 * @author Cristian Pana
 */
class StatusLabelExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('statusLabel', array($this, 'statusLabel')),
        );
    }

    public function statusLabel($status)
    {

        switch($status){
            case 'created':
                $label = 'label label-default';
                break;
            case 'start_working':
                $label = 'label label-info';
                break;
            case 'waiting_feedback':
                $label = 'label label-primary';
                break;
            case 'closed':
                $label = 'label label-success';
                break;
            default:
                $label = 'label label-danger';    
        }

        return $label;
    }

    public function getName()
    {
        return 'statusLabel_extension';
    }
}


This extension will be registered as a service tagged with 'twig.extension' in your service.yml file:


    status.label.twig_extension:
        class: MyBundle\TwigExtensions\StatusLabelExtension
        public: false
        tags:
            - { name: twig.extension }

Now I can use the newly created Twig filter in my views:


  <span class="{{ ticket.status|statusLabel }}">{{ ticket.status|trans }}</span>


No comments:

Post a Comment