Overheard from Alan Programming

“My god, I think that actually works!”


foreach my $id ( keys %$hr ) {
my $d = $hr->{$id};
if( $d->{parent_id} == 0 ) {
$hr->{$id}->{top} = $d->{pagename};
} elsif( $hr->{$d->{parent_id}}->{parent_id} == 0 ) {
$hr->{$id}->{top} = $hr->{$d->{parent_id}}->{pagename};
} elsif( $hr->{$hr->{$d->{parent_id}}->{parent_id}}->{parent_id} == 0 ) {
$hr->{$id}->{top} = $hr->{$hr->{$d->{parent_id}}->{parent_id}}->{pagename};
}
}

In case anyone is wondering, this is a (probably bad, yet working) way to set what the top level pagename of a menu item is so that I can know which main menu item to highlight for a given current page. This lets me iterate through a top level menu to print it to the screen and as I go through simply check to see if the current pagename (the url with .html and leading path stripped) has a top level entry of whatever the currently printing menu item is.

Note that there are comments above this code because in 3 days I'll have no idea what the heck this is doing 🙂

If anyone has a better way of doing this, please let me know, I do actually enjoy reducing complexity, and don't write perl code like the above for the fun of unreadable code!

Other ideas I had were:


  • create a data structure representing the menu sub-levels and then traverse that back from whatever point it's at when a page is hit, but that means having to find the page in a possibly N-levels deep nested data structure
  • doing N database calls (right now there are only 3 levels deep, that could change sometime in the far future) to see if the current page is the top level, and if not, see if it's parent is the top level, and if not another database call to see if that is the top level, that's 3 database hits more per page load, which is just ugly, and I'm pretty sure that processing in-memory is far faster for perl than database calls.

2 Comments on “Overheard from Alan Programming”

  1. For the love of larry, use a recursive function!
    Or, if you need to reduce DB hits (and do you really? it’s a simple enough call) store the toplevel field in the DB row for the lower level pages – it’s not DB-normal format, but it’s a reasonable optimisation.

  2. Storing the top level field in the DB row for lower level pages is definitely a legit design. Adding some code to re-copy down the top level field to the lower level pages if it changes is probably a lot easier than trying to write/maintain the above code. Ya it works now, but what about if you have to change it!