phptwitter-bootstrapbadgeshields.io

How to create shields-like badges with bootstrap?


You probably know shield badges (from shields.io).

They are dynamically created svg images of two types:

1. Value Badges

<img src="https://img.shields.io/badge/value-5555ff">

2. Key-Value Badges

<img src="https://img.shields.io/badge/key-value-5555ff">


They are great, however, there are two problems with them:

Let's say I am already using bootstrap in my project (self-hosted to minimize dependencies). How can I create those two types of badges dynamically with bootstrap?

(I also use PHP, so a badge($name, $value, $color) function would be amazing)


Solution

  • The very basic OOP approach would look like:

    <?php
    
    class Badge
    {
    
        // colors
        const COLOR_RED = '#f00';
        const COLOR_YELLOW = '#ff0';
        const COLOR_BLUE = '#55f';
    
        // badges
        const BADGE_PRIMARY = 'bg-primary';
        const BADGE_SECONDARY = 'bg-secondary';
        const BADGE_SUCCESS = 'bg-success';
        // etc
    
        // icons
        const ICON_FOO = 'icon-foo';
        const ICON_BAR = 'icon-bar';
        const ICON_BAZ = 'icon-baz';
    
    
        private $valueColour = Badge::COLOR_BLUE;
        private $badge = Badge::BADGE_SECONDARY;
    
        private $key = null;
        private $value = [];
    
    
        public function reset()
        {
            $this->valueColour = Badge::COLOR_BLUE;
            $this->badge = Badge::BADGE_SECONDARY;
            $this->key = null;
            $this->value = null;
    
            return $this;
        }
    
        public function setKey(string $key)
        {
            $this->key = $key;
            return $this;
        }
    
    
        public function addValue(string $value, $optionalIcon = null)
        {
            $icon = (!is_null($optionalIcon)) ? "<span class='some-icon-library {$optionalIcon}'></span> " : '';
            $this->value[] = $icon . $value;
            return $this;
        }
    
    
        public function setValueColour($colour)
        {
            $this->valueColour = $colour;
            return $this;
        }
    
        public function build()
        {
            if (is_null($this->value)) {
                echo 'Error: no value';
                return false;
            } else {
                if (!is_array($this->value)) {
                    echo 'A value should be an array';
                    return false;
                }
            }
            $value = implode(' | ', $this->value);
            if (is_null($this->key) || trim($this->key) == '') {
                echo "<span class='badge text-white p-0'><span class='py-1 px-2 rounded' style='background: {$this->valueColour};'> {$value}</span></span>";
            } else {
                echo "<span class='badge text-white p-0'>
                            <span class='{$this->badge} py-1 px-2 rounded-left'>{$this->key}</span>
                            <span class='py-1 px-2 rounded-right' style='background:{$this->valueColour};'>{$value}</span>
                          </span>";
            }
            return true;
        }
    }
    

    So you can use it in your code by:

    $badge = new Badge();
    
    
    // default
    $badge
        ->setKey('Basic Key')
        ->addValue('Basic value')
        ->build();
    
    // incorrect
    $badge
        ->reset()
        ->setValueColour(Badge::COLOR_RED)
        ->build();
    
    // w/out key
    $badge
        ->reset()
        ->addValue('Without key')
        ->setValueColour(Badge::COLOR_RED)
        ->build();
    
    // some sample
    $badge
        ->reset()
        ->setKey('Some Key')
        ->addValue('Some value')
        ->setValueColour(Badge::COLOR_RED)
        ->build();
    
    // value(s) with some icons
    $badge
        ->reset()
        ->setKey('Another key')
        ->addValue('Yet another value', Badge::ICON_FOO)
        ->addValue('Even more', Badge::ICON_BAR)
        ->addValue('Last but not least')
        ->setValueColour(Badge::COLOR_YELLOW)
        ->build();
    

    Note 0: Of course it's rather POC than an exact solution, so you need to polish it by yourself ;)

    Note 1: As newest Bootstrap doesn't use any icon set by default, icons are dummy so you need to fix it to use with your chosen icon set or just by custom CSS styling.

    Note 2: We do not use any setter for value as we want to make usage of array, therefore use addValue() to get pipe-separated values.