Best practices? Organizing CGI code and modules?

R

robb

Hi,

I've taken over management of a website that has absolute chaos in the
organization of the CGI directory (/cgi-bin). There are ~600 files and
directories here, no user-built modules, and perl files
indiscriminately named .pl, .cgi, etc.

Instituting revision control has been a big help. :)

But specifically to perl, is there a consensus about where to put which
files, and how they should be named? I personally like to develop with
packages and modules, and this is a new thing in this environment. I
so far have these kinds of files that I'm developing:

Test Scripts
Application-Specific Modules
Application-Independent Modules
Application CGI scripts, referenced directly from a web client

Currently, here's what I'm doing, but I don't believe this is optimal:

/cgi-bin
App. CGI scripts, named *.cgi.
App-independent modules named *.pm

/cgi-bin/CamelCaseAppName
App-specific modules, named *.pm
App-specific test scripts, named *.pm

I'm definitely interested in removing things from cgi-bin that don't
need to be there. And, I want to increase maintainability. I also
want to enable automated running of all my tests.

Thanks for any input,
Robb
 
U

Uri Guttman

ro> Test Scripts

those are executables so should be in some bin/ dir. they don't need to
be in any cgi areas (unless they are cgi driven). in fact i wouldn't put
any development source in the actual cgi dirs. copy tested scripts into
cgi dirs using an install process.

ro> Application CGI scripts, referenced directly from a web client

in many cases those can be reduced to minimal or even reused scripts
that call out to modules that do all the work. this is a very good way
to do this because the modules will have a clean perl API which can be
called from standalone test scripts. the cgi scripts become trival
wrappers which grab the cgi params (using CGI.pm or mod_perl), mung the
data into the form the modules want (hash trees, etc.) and call out
to the proper modules. the results are processed into html output
(possibly using a templater) and that can be also done in external
modules. then the cgi is even simpler and it can almost be made into a
common script that can do many operations based on its name (check $0 as
a primary dispatch arg) or a command type param.

with these modules you can develop them anywhere you want. use lib can
help you find and load them from the proper installed dirs (or you can
install them in perl's default lib dirs). you can put the test script
development near the modules that they test which is good too.

ro> I'm definitely interested in removing things from cgi-bin that don't
ro> need to be there. And, I want to increase maintainability. I also
ro> want to enable automated running of all my tests.

what needs to be in cgi-bin is a minimal set of cgi scripts which just
call out to modules that do the real work. this makes your cgi very
clean and easy to manage. consider cgi as just an interface to your
modules and design your code accordingly. interfaces should be isolated
from back end work so you can more easily have multiple interfaces
(think cgi and test scripts as using two different interfaces).

uri
 
T

Ted Zlatanov

Currently, here's what I'm doing, but I don't believe this is optimal:

/cgi-bin
App. CGI scripts, named *.cgi.
App-independent modules named *.pm

/cgi-bin/CamelCaseAppName
App-specific modules, named *.pm
App-specific test scripts, named *.pm

I like to "use lib '/usr/local/PROJECT'" for things in cgi-bin, then
put all modules, templates, etc. under /usr/local/PROJECT.
'/usr/local' is a matter of preference, but it really helps to base
the code somewhere outside of the webserver's grubby indexing hands.

Ted
 
J

John Bokma

Hi,

I've taken over management of a website that has absolute chaos in the
organization of the CGI directory (/cgi-bin). There are ~600 files and
directories here, no user-built modules, and perl files
indiscriminately named .pl, .cgi, etc.

Instituting revision control has been a big help. :)

But specifically to perl, is there a consensus about where to put which
files,

First, regarding the cgi-bin directory, this should be *outside* your
document root (see: http://johnbokma.com/windows/apache-virtual-hosts-
xp.html)

Next all files that are not cgi scripts *shouldn't* be in this directory.
One configuration mistake, and they are available on the Internet.
and how they should be named? I personally like to develop with
packages and modules, and this is a new thing in this environment. I
so far have these kinds of files that I'm developing:

Test Scripts

Shouldn't be online.
Application-Specific Modules
Application-Independent Modules
Application CGI scripts, referenced directly from a web client

only ones that should be inside cgi-bin online.
Currently, here's what I'm doing, but I don't believe this is optimal:

/cgi-bin
App. CGI scripts, named *.cgi.
App-independent modules named *.pm

Would put the latter in a directory that is outside document root *and*
outside cgi-bin. Readable by your scripts.
/cgi-bin/CamelCaseAppName
App-specific modules, named *.pm

See above
App-specific test scripts, named *.pm

pm stands for Perl module.
 
P

Peter J. Holzer

I've taken over management of a website that has absolute chaos in the
organization of the CGI directory (/cgi-bin). There are ~600 files and
directories here, no user-built modules, and perl files
indiscriminately named .pl, .cgi, etc.

This hasn't got anything to do with perl, but ...
I always hated the cgi-bin directory, as it makes a rather irrelevant
distinction between static and dynamic content. If I have two
applications app1 (which consists of foo.cgi, bar.html and baz.jpg) and
app2 (which consists of waldo.cgi, fubar.html and fred.png) I find it a
lot clearer to organize them as

/
app1/
foo.cgi
bar.html
baz.jpg
app2/
waldo.cgi
fubar.html
fred.png

than

/
docs/
bar.html
fubar.html
cgi-bin/
foo.cgi
waldo.cgi
images/
baz.jpg
fred.png

If you use MultiViews with Apache, you can even hide the distinction
completely by omitting the extension in the URL: So if the user accesses
/app1/foo, /app1/foo.cgi will be invoked, and if he accesses /app1/bar,
/app1/bar.html will be invoked. If I later decide that bar needs to
generated dynamically, I can simply add a /app1/bar.cgi and remove the
/app1/bar.html. The user will still access the same URL, but now a CGI
script will be invoked.

As for the organisation of the code, I agree with Uri: Put as much as
possible into modules which can be installed anywhere where perl can
find them and make the CGI scripts only thin wrappers.

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,832
Latest member
GlennSmall

Latest Threads

Top