Readable file sizes with the Twig templating system
Or, just create the twig extension:
ByteConversionTwigExtension.php
<?php
// src/AppBundle/Twig/Extension
namespace AppBundle\Twig\Extension;
class ByteConversionTwigExtension extends \Twig_Extension
{
/**
* Gets filters
*
* @return array
*/
public function getFilters()
{
return array(
new \Twig_SimpleFilter('format_bytes', array($this, 'formatBytes')),
);
}
public function getName()
{
return 'format_bytes';
}
function formatBytes($bytes, $precision = 2)
{
$units = array('B', 'KiB', 'MiB', 'GiB', 'TiB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
// Uncomment one of the following alternatives
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
}
services.yml
parameters:
app.byte_conversion_twig_extension.twig.extension.class: AppBundle\Twig\Extension\ByteConversionTwigExtension
services:
app.byte_conversion.twig.extension:
class: %app.byte_conversion_twig_extension.twig.extension.class%
tags:
- { name: twig.extension }
Twig template:
{{ variable | format_bytes }}
There are a couple of ways you can go about accomplishing that:
1) get a Twig extension that will handle it for you. One like this one: https://github.com/BrazilianFriendsOfSymfony/BFOSTwigExtensionsBundle
Once enabled you would just do:
{{ maxBytes|bfos_format_bytes }}
And this will give you what you want.
2) You can create a macro that will do this if you dont want to add an entire extension. That would look something like this:
{% macro bytesToSize(bytes) %}
{% spaceless %}
{% set kilobyte = 1024 %}
{% set megabyte = kilobyte * 1024 %}
{% set gigabyte = megabyte * 1024 %}
{% set terabyte = gigabyte * 1024 %}
{% if bytes < kilobyte %}
{{ bytes ~ ' B' }}
{% elseif bytes < megabyte %}
{{ (bytes / kilobyte)|number_format(2, '.') ~ ' KiB' }}
{% elseif bytes < gigabyte %}
{{ (bytes / megabyte)|number_format(2, '.') ~ ' MiB' }}
{% elseif bytes < terabyte %}
{{ (bytes / gigabyte)|number_format(2, '.') ~ ' GiB' }}
{% else %}
{{ (bytes / terabyte)|number_format(2, '.') ~ ' TiB' }}
{% endif %}
{% endspaceless %}
{% endmacro %}
You can read more about where to put and how to use the macros here: http://twig.sensiolabs.org/doc/tags/macro.html
A twig extension for human readable code using symfony 4 coding format and Jeffrey Sambells formatting function:
src/Twig/AppExtension.php
<?php
namespace App\Twig;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class AppExtension extends AbstractExtension
{
/**
* @var ContainerInterface
*/
protected $container;
/**
* Constructor
*
* @param ContainerInterface $container
*/
public function __construct(
ContainerInterface $container
)
{
$this->container = $container;
}
public function getFilters()
{
return array(
new TwigFilter('formatBytes', array($this, 'formatBytes')),
);
}
/**
* @param $bytes
* @param int $precision
* @return string
*/
public function formatBytes($bytes, $precision = 2)
{
$size = ['B','kB','MB','GB','TB','PB','EB','ZB','YB'];
$factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$precision}f", $bytes / pow(1024, $factor)) . @$size[$factor];
}
}
services.yaml:
App\Twig\AppExtension:
arguments:
- '@service_container'
tags:
- { name: twig.extension}
usage in template:
{{ bytes| formatBytes }}
{{ bytes| formatBytes(0) }}