pileofrogs has asked for the wisdom of the Perl Monks concerning the following question:

Hail, ye Monks!

I'm new to Catalyst and writing my first app. I'm querying my os for user disk quotas and then displaying them. I'm trying to figure out the appropriate place to put logic to convert the quota data from kilobytes to more friendly values. Here's what I'm talking about:

Sucky

LimitUsed
20000546

Better

LimitUsedUsed Percent
20 MB546 Kb03%

I get a hash from my model which contains block_curr,block_hard etc... in kilobytes, courtesy of Quota. I want to display in megabytes or gigabyes as appropriate and also show the percentage of used space. I do this now inside the controller, but that seems wrong to me. I feel like I should handle that inside my view, but I don't know how. I'm using Template Toolkit as my view, so I could do what I want with Template Toolkit plugins...

So! My question is, where is the right place in a Catalyst app to put this kind of view specific logic and how do I put it there? If there are any good articles discussing this, please point the way.

Thanks!
--Pileofrogs

Replies are listed 'Best First'.
Re: Catalyst & Pretty Data
by bellaire (Hermit) on Mar 06, 2009 at 01:30 UTC
    It is a subjective decision, but I agree with you that converting data values which are stored as kilobytes into a different human-readable format is something that should be in the view. In particular, you might decide to give users the option as to how they want that number displayed (straight kilobytes or human-readable), in which case it's definitely a view concern.

    As to how to go about that, I would go with a template filter. You'd set up a function which accepts the number as input and returns the "pretty" formatted string. Then you set the option in your template configuration to call that function as a filter. Say you named your function pretty_size, then you'd do something like this:
    $template = Template->new({ FILTERS => { 'pretty_size' => \&pretty_size, }, });
    Update: Under Catalyst, that'd probably be somewhere in your view module, for example in TT.pm, e.g.:
    __PACKAGE__->config({ #...existing config... FILTERS => { 'pretty_size' => \&pretty_size, }, });
    And then, use | pretty size in your template directive to change the kilobytes value to your formatted string, for example if the data is in the template variable kilobytes:
    <td>[% kilobytes | pretty_size %]</td>
Re: Catalyst & Pretty Data
by Tanktalus (Canon) on Mar 06, 2009 at 00:43 UTC

    More abstractly, this is a MVC question. Do I put this in my Model, View, or Controller? I think you are saying that the Model (data store) would be the wrong place to start playing with the data, since you've omitted that option. I'm not sure there is a right, or wrong, answer to your question - but I'm not eliminating the Model from the possibilities. Theoretically, if you have a model for this page that is a wrapper around Quota, I don't see it being any worse to say $m->get_limit() vs $m->get_limit_hr() (human-readable). After all, it's your model that would know what the units are that it's returning (is it in bytes, KB, MB, GB, TB? Or is it returning in bits, trits, or some other unit?). I could easily argue that the Model owns the information, and the Controller should merely be asking for the data in the format it needs to pass on to the View.

    Of course, I could argue similarly in favour of Controller and View as the owners of the transformation, but which one would be the strongest argument would depend on the rest of your site, and what types of flexibility are important, as well as any other infrastructure you may have (e.g., translations).

Re: Catalyst & Pretty Data
by CountZero (Bishop) on Mar 06, 2009 at 06:01 UTC
    Did you look at Number::Format yet? It has been implemented as a plugin / filter for Template Toolkit: Template::Plugin::Number::Format

    From the docs:

    Template::Plugin::Number::Format makes the number-munging grooviness of Number::Format available to your templates. It is used like a plugin, but installs filters into the current context.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James