CGI::Application::Plugin::PageLookup::Loop - Manage list structures in a website
Version 1.8
This module manages the instantiation of list style template parameters across a website; for example TMPL_LOOP in HTML::Template, though one must use HTML::Template::Pluggable for it to work. For example a menu is typically implemented in HTML as <ul>....</ul>. Using this module the menu can be instantiated from the database and the same data used to instantiate a human-readable sitemap page. On the other hand the staff page will have list data that is only required on that page. This module depends on CGI::Application::Plugin::PageLookup.
In the template you might define a menu as follows (with some CSS and javascript to make it look nice):
<ul> <TMPL_LOOP NAME="loop.menu"> <li> <a href="<TMPL_VAR NAME="lang">/<TMPL_VAR NAME="this.href1">"><TMPL_VAR NAME="this.atitle1"></a> <TMPL_IF NAME="submenu1"> <ul> <TMPL_LOOP NAME="submenu1"> <li> <a href="<TMPL_VAR NAME="lang">/<TMPL_VAR NAME="href2">"><TMPL_VAR NAME="atitle2"></a> <TMPL_IF NAME="submenu2"> <ul> <TMPL_LOOP NAME="submenu2"> <li> <a href="<TMPL_VAR NAME="lang">/<TMPL_VAR NAME="href3">"><TMPL_VAR NAME="atitle3"></a> </li> </TMPL_LOOP> </ul> </TMPL_IF> </li> </TMPL_LOOP> </ul> </TMPL_IF> </li> </TMPL_LOOP> </ul>
and the intention is that this should be the same on all English pages, the same on all Vietnamese pages etc etc. The use of "this." below the top levels is dictated by HTML::Template::Plugin::Dot which also optionally allows renaming of this implicit variable. You must register the "loop" parameter as a CGI::Application::Plugin::PageLookup::Loop object as follows:
use CGI::Application; use CGI::Application::Plugin::PageLookup qw(:all); use CGI::Application::Plugin::PageLookup::Loop; use HTML::Template::Pluggable; use HTML::Template::Plugin::Dot; sub cgiapp_init { my $self = shift; # pagelookup depends CGI::Application::DBH; $self->dbh_config(......); # whatever arguments are appropriate $self->html_tmpl_class('HTML::Template::Pluggable'); $self->pagelookup_config( # load smart dot-notation objects objects => { # Register the 'values' parameter loop => 'CGI::Application::Plugin::PageLookup::Loop', }, # Processing of the 'lang' parameter inside a loop requires global_vars = 1 inside the template infrastructure template_params => {global_vars => 1} ); } ...
The astute reader will notice that the above will only work if you set the 'global_vars' to true. After that all that remains is to populate the cgiapp_loops table with the appropriate values. To fill the above menu you might run the following SQL:
INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'menu', '', 0, 'href1', '') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'menu', '', 0, 'atitle1', 'Home page') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'menu', '', 1, 'href1', 'aboutus') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'menu', '', 1, 'atitle1', 'About us') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'menu', '', 2, 'href1', 'products') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'menu', '', 2, 'atitle1', 'Our products') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'menu', '', 3, 'href1', 'contactus') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'menu', '', 3, 'atitle1', 'Contact us') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'menu', '', 4, 'href1', 'sitemap') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'menu', '', 4, 'atitle1', 'Sitemap')
Now suppose that you need to describe the products in more detail. Then you might add the following rows:
INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu1', '2', 0, 'href2', 'wodgets') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu1', '2', 0, 'atitle2', 'Finest wodgets') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu1', '2', 1, 'href2', 'bladgers') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu1', '2', 1, 'atitle2', 'Delectable bladgers') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu1', '2', 2, 'href2', 'spodges') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu1', '2', 2, 'atitle2', 'Exquisite spodges')
Now suppose that the bladger market is hot, and we need to further subdivide our menu. Then you might add the following rows:
INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu2', '2,1', 0, 'href3', 'bladgers/runcible') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu2', '2,1', 0, 'atitle3', 'Runcible bladgers') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu2', '2,1', 1, 'href3', 'bladgers/collapsible') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu2', '2,1', 1, 'atitle3', 'Collapsible bladgers') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu2', '2,1', 2, 'href3', 'bladgers/goldplated') INSERT INTO cgiapp_loops (lang, loopName, lineage, rank, param, value) VALUES ('en', 'submenu2', '2,1', 2, 'atitle3', 'Gold plated bladgers')
This module depends on only one extra table: cgiapp_loops. The lang and internalId columns join against the cgiapp_table. However the internalId column can null, making the parameter available to all pages in the same language. The key is formed by all of the columns except for the value.
Field Type Null Key Default Extra ------------ ------------------------------------------------------------------- ---- ---- ------- ----- lang varchar(2) NO UNI NULL internalId unsigned numeric(10,0) YES UNI NULL loopName varchar(20) NO UNI NULL lineage varchar(255) NO UNI rank unsigned numeric(2,0) NO UNI 0 param varchar(20) NO UNI NULL value text NO NULL
The loopName is the parameter name of the TMPL_LOOP structure. The rank indicates which iteration of the loop this row is instantiating. The lineage is a comma separated list of ranks so that we know what part of a nested loop structure this row instantiates. For a top-level parameter this will always be the empty string.
A constructor following the requirements set out in CGI::Application::Plugin::PageLookup.
We need to autoload methods so that the template writer can use loops without needing to know where the loops will be used. Thus 'can' must return a true value in all cases to avoid breaking HTML::Template::Plugin::Dot. Also 'can' is supposed to either return undef or a CODE ref. This seems the cleanest way of meeting all requirements.
We need to autoload methods so that the template writer can use loops without needing to know where the variables will be used.
A private function that does what is says.
We have to define DESTROY, because an autoloaded version would be bad.
Nicholas Bamber, <nicholas at periapt.co.uk>
<nicholas at periapt.co.uk>
Please report any bugs or feature requests to bug-cgi-application-plugin-pagelookup at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CGI-Application-Plugin-PageLookup. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
bug-cgi-application-plugin-pagelookup at rt.cpan.org
AUTOLOAD is quite a fraught subject. There is probably no perfect solution. See http://www.perlmonks.org/?node_id=342804 for a sample of the issues.
You can find documentation for this module with the perldoc command.
perldoc CGI::Application::Plugin::PageLookup::Loop
You can also look for information at:
RT: CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=CGI-Application-Plugin-PageLookup
AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/CGI-Application-Plugin-PageLookup
CPAN Ratings
http://cpanratings.perl.org/d/CGI-Application-Plugin-PageLookup
Search CPAN
http://search.cpan.org/dist/CGI-Application-Plugin-PageLookup/
Copyright 2009 Nicholas Bamber.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
To install CGI::Application::Plugin::PageLookup, copy and paste the appropriate command in to your terminal.
cpanm
cpanm CGI::Application::Plugin::PageLookup
CPAN shell
perl -MCPAN -e shell install CGI::Application::Plugin::PageLookup
For more information on module installation, please visit the detailed CPAN module installation guide.