HTML::Lister - Multidimensional Structure to HTML List Converter


  use HTML::Lister;
  my $lister = new HTML::Lister;
  print "Content-type: text/html\n\n";
  print $lister->List($arrayref);
  print $lister->oList(@array);
  print $lister->hashList(%hash);
  print $lister->List($hashref);


HTML::Lister is a small HTML utility that addresses a built-in function that has left unaddressed -- it handles multidimensional objects, calling itself recursively to create an HTML list entity from the contents.

Honestly, I hacked this thing together quickly out of need, but it's becomes somehting I use on a regular basis, debugging CGI scripts live through a browser and so on.

Put then again, that's where Perl itself came from!


new() (constructor method)

This is just the typical constructor method. It currently takes no arguments and provides no options.


List() is the primary method of Lister. It takes any array, arrayref, hashref, or scalar value (though the latter is admittedly pointless) and makes an unordered list (UL entity) out of what it gets.

If it receives a hashref, it calls hashList on the dereferences hashref, making an unordered list with no LI entities, but with a definition list inside it. This has the potentially annoying side effect of indenting any lone hashref it's handed, but it will still work and doesn't matter for debugging purposes, which is Lister's main utilisation. If you want to avoid this, hand it off to hashList() instead.

An array or arrayref handed to List will create a proper bulleted unordered list. A scalar or scalarref handed off to List() will return a list of one item.

If List() encounters a reference in any of its argument list, it will dereference it and call the appropriate method on that item if it dereferences to an array or hash. If it's a hashref, it will call hashList. If it's an array, it will call itself. That's also why just handing it a hashref works, but handing it a real hash won't -- the keys and values end up as @_ as an array.

Oh, yeah -- a plain list or listref works nicely, too. (It's an array -- @_ -- by the time the method sees it anyway, which is also why handing it a hash won't work).


The oList() method works just like the List() method, except that the lists it creates are HTML OL entities -- that is, ordered lists. That means they're numbered (or lettered, or whatever, depending on their nestedness).

It should be noted somewhere (and here seems like a good place) that if you call oList, and oList finds a hashref, and that hash contains an arrayref, the object will in fact remember where it came from and call oList again, not List. In other words, if you start with numbered lists, you will get numbered lists all the way in. If you start with bulleted lists, you will get bulleted lists all the way in. This is to be considered cool.


The hashList() method takes a hash or hashref as an argument. You can use it in a utility fashion, if you want, and hand it an array or list, too, and it may give you what you expect. Handing it an arrayref or listref almost definitely will *not* do what you want. hashList creates an HTML definition list (DL entity). The keys become DT entities and the values become DD entities. In the case of handing it an array or list, the even-indexed items become DTs and the odd-indexed items become DDs.

As with the other two methods, hashList() recognises when it encounters a reference, dereferences it, and calls the appropriate method on it. If it is called explicitly, sub-lists will be UL entities (bulleted lists).

Do not hand hashList a blessed hashref... it won't work. Dereference it first (i.e. hashList(%$cgi) or hand it off through List, which will do the job for you. Honestly, I'm still scratching my head on this one. I'm sure there's a perfectly rational explanation, and I think I have come up with it on a number of occassions, but I never remember when the Sudafed and NyQuil wear off.

notes on all methods

None of these methods are intended for use with other kinds of references. They won't break it, but you will simply get GLOB(0x80f1098) or CODE(0x80fd9d8) or whatever. It can't see past that point. Nevertheless, this is a far cry better than the listing functions built into right now (no offense to that wonderful module that I use all the time or it's writers or maintainers -- you can't do everything).

CSS support and additional tag parametres

I'll admit this is badly kludged in. You can access the variables $HTML::Lister::aryparams and $HTML::Lister::hashparams directly to set up additional paramatres for the HTML code created. Whatever is in these variables will appear in the entity's tag, right after the *l -- thus you will want to start anything you put here with a space.

For instance, to set a CSS class on your definition lists, you might do this: $HTML::Lister::hashparams = ' class="purdy"' and your HTML entity will look like this: <dl class="purdy">

These default to '', so the list entities default to being a plain tag ('<ul>,<dl>,<ol>')


It would be nice if I could get some help building a non-OO version of this, too. However, I'm not sure how that would work since some parts, like remembering what called it, is implicitly OO in approach. This way it could be wrapped into and thus be much more widely used.

I should also give some thought to a better approach to setting up tag parametres, and supporting the sub-entity parametres as well (the DT, DD, and LI items).

I'd love it if someone would help me find an easy way to get at the actual stuff of other types of references, like displaying the first 160 characters of code in a PRE tag for a coderef, or some easy way to list all the associated entities of a glob ref.

Figure out that blasted blessed hashList issue. And remember the answer later.

Figure out why all the Denny'ses are closing down.

Figure out how to properly pluralise an inherently possessive proper noun.


Dodger (Sean Cannon)

Contact me if you want to help or patch anything on the TO DO list.


Umm, call it the Artistic Licence. I hate the legal crap part. Dammit, Jim, I'm a programmer, not a lwayer.

This module is implicitly and explicitly distributed under the Perl Artistic Licence. All rights reserved, all rites reversed.


perl(1), CGI(3)