RE: [cgiapp] Subclassing form, futher thoughts

2002-06-12 Thread Jesse Erlbaum

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();


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.


 So far, the above seems like it will be a good solution.
 
 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()?


 One thought that comes to mind is to have run() accept two 
 scalars, the
 values being strings that it prepends and appends, 
 respectively, to the
 runmode's output. Don't know how great an idea that is.

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!


TTYL,

-Jesse-


-
Web Archive:  http://www.mail-archive.com/cgiapp@lists.vm.com/
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Re: [cgiapp] Subclassing form, futher thoughts

2002-06-12 Thread Seb

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,