8

There are plenty of answers to this question for Java (How to convert byte size into human readable format in java?, and Format file size as MB, GB etc) and even for Groovy/Grails, not to mention PHP, but is there a built-in or convenient way to do this in FreeMarker?

For clarity, I'm after the generic SI method in common parlance, rather than Binary powers of 2. E.g.

      1 ➤ 1B
    123 ➤ 123B
   1000 ➤ 1KB
   1728 ➤ 1.7KB
7077888 ➤ 7.1MB

And so on.

Given that FreeMarker doesn't appear to have a logarithm function, is there a way to do this in pure FreeMarker, or is my only option to create a Template Method with Java.

Community
  • 1
  • 1
Horatio Alderaan
  • 3,264
  • 2
  • 24
  • 30

2 Answers2

5

In case anyone is interested, I had a crack at coding up something myself using string manipulation. I wouldn't recommend doing something like this if you can avoid it, but if you're stuck, it might help:

<#--
 # Format Number of Bytes in SI Units
 # -->
<#function si num>
  <#assign order     = num?round?c?length />
  <#assign thousands = ((order - 1) / 3)?floor />
  <#if (thousands < 0)><#assign thousands = 0 /></#if>
  <#assign siMap = [ {"factor": 1, "unit": ""}, {"factor": 1000, "unit": "K"}, {"factor": 1000000, "unit": "M"}, {"factor": 1000000000, "unit":"G"}, {"factor": 1000000000000, "unit": "T"} ]/>
  <#assign siStr = (num / (siMap[thousands].factor))?string("0.#") + siMap[thousands].unit />
  <#return siStr />
</#function>
Horatio Alderaan
  • 3,264
  • 2
  • 24
  • 30
  • (Unrelated, but you don't need `()`-s after `#if` in FreeMarker. They do nothing.) – ddekany Dec 17 '13 at 01:03
  • @ddekany You are right. Unless, of course, you are doing a "greater than" comparison. For example `<#if (num > 3)>` [as described in the Freemarker docs](http://freemarker.org/docs/ref_directive_if.html#ref.directive.if). Personally, I like to keep the brackets in there so I don't forget them when I do write a greater-than comparison. – Horatio Alderaan Dec 17 '13 at 01:17
0

No, there's no such functionality built in. BTW, that should be just a number_format pattern, but DecimalFormat doesn't have pattern that does this, so FreeMarker doesn't have it either.

ddekany
  • 29,656
  • 4
  • 57
  • 64