On Wed, 12 Jun 2002 11:15:01 -0400, Jesse Erlbaum [EMAIL PROTECTED] spoke
gently:
Hi Sebastian --
Now, my index.cgi would look like this:
#!/usr/bin/perl
use CGI qw(:standard);
my $q = new CGI;
my $modules = {
sales = 'Sales',
invent = 'Inventory',
},
};
# Set a default
$q-param('mod' = 'main')
unless $q-param('mod');
# Dynamically pull in the right section's module
require ComponentManager/$modules-{$q-param('mod')}{load}.pm;
# And fire it off
my $app =
ComponentManager::$modules-{$q-param('mod')}{load}-new($q);
$app-run();
It looks like you're well on your way to building quite the Rube Goldberg
machine! If I understand what you're trying to do, if you want to run your
Sales app, you would make a request like this:
http://my.site/index.cgi?mod=sales
...For Inventory, you would do this:
http://my.site/index.cgi?mod=invent
Tell me -- what is the advantage of doing that instead of doing:
http://my.site/sales.cgi
http://my.site/invent.cgi
The latter would have two advantages. First, this is how CGI::Application
(or a sub-class thereof) wants to work. Second, your instance script
(sales.cgi or invent.cgi -- instead of index.cgi) becomes MUCH more
simple:
#!/usr/bin/perl -w
use Sales;
my $app = Sales;
$app-run();
The primary loss is the single point of access. I could live with that,
and simple is Good(tm), but when I see a dozen nearly identical CGI
scripts in a directory I don't think simple, I think Hmmm, _one_
would be better.
What could be more simple than that? What does this system NOT do that your
system does?
I would seriously consider taking about twelve paces BACK and re-evaluating
your architecture. CGI::Application is intended to make your code EASY --
not turn it into a interconnected snarl of undocumented dependencies. In
general, if your instance script looks more complicated than what I've
written above, you're probably doing something wrong.
Architecturally, my example above is actually quite simple, and could
easily work in a single pm file, using base run-modes like 'SALES_LIST'
or 'INVENT_SAVEITEM'...etc. I only implemented the dynamic loading to
ease administration, personally I hate working in files longer that a
few thousand lines, and this project will easily outgrow that in total.
On another note, I would however like to pass html to run() at the
base-class level, and have it place it in the output appropriately.
There is currently no way to do that gracefully, because the http
headers are built into the run method.
Why on earth would you want to put *ANY* HTML in your code? And assuming
you have a good reason, why would you pass it through run()?
I guess I was not clear. I'm not putting html in my code. The desired
result is that I want to print a common header, without specifying it
each time in each run-mode sub. I think the easiest way would be to
allow cgiapp_prerun() to optionally return html, _just like any other
runmode does_. C::A-run() could print it just before it prints the
runmode sub's output, thereby providing a hook for for printing common
content each time.
Don't try to override the run() method. Don't do it! It is not intended to
be used this way. It may change in future version. Heck, I might change it
out of spite! :-)
:)
Another possibility might be to, within the run() sub, simply
store the
return value of cgiapp_prerun(), to be output just before the
run-mode's
return value. That would solve the header problem, and for any common
footers we could just use teardown().
There are a lot of ways to do what you want to do without breaking the
CGI::Application architecture all over the place. For starters,
HTML::Template supports a TMPL_INCLUDE tag which will pull in external
HTML. If you don't like H:T, most other templating systems have similar
features.
And you *should* be using a templating system! If you've never used one,
STOP EVERYTHING and go read the POD for HTML::Template, right now! Don't
write another line of code before you know how to use it!
I do use HTML::Template. My CGI's usually have three HTML::Template
objects: a header, content, and footer. I realize that each of my
content templates could just TMPL_INCLUDE the header and footer
files, but I choose not to do it that way, for maintenance reasons. When
things change, it can be a big can of worms. I see no reason that my
content templates should have to know anything about the
framework/headers/footers of the site. They should be autonomous,
pluggable anywhere. Isn't that how the rest of the world does it?
I realize that, using my multiple template objects, each of my run-modes
could...
return $app-param('header')-output() .
$app-param('content')-output() .
$app-param('footer')-output();
...and I may end up doing just that. It would have the benefit, for
example,