L8on has asked for the wisdom of the Perl Monks concerning the following question:

Hello there, Is there any way to have global includes in cgi's? In php, I can enter include include/myincfile.php and it load it so I can have global functions (e.g. site_header(), site_footer(), etc ) and variables and it will load it as part of the page. I'm redesigning a website on someone else's server that doesn't provide a database so I have to use text files and I'd like to have global variables and subs pointing to files and directories. Without having to hard code directory locations into my cgi's. Any suggestions would be greatly appreciated. Thanx in advance, Layton

Replies are listed 'Best First'.
(jeffa) Re: Global includes in cgi's
by jeffa (Bishop) on Jun 09, 2001 at 19:52 UTC
    You can always use require to include another script, but in Perl, it's best to use a module for global functions:
    # Common.pm package Common; use strict; sub foo { # do stuff } sub bar { # do other stuff } 1; # have to return a non-zero value at end!
    The to use it:
    # client.pl use strict; use lib('/path/to/modules/'); use Common; Common::foo(); Common::bar();

    Jeff

    R-R-R--R-R-R--R-R-R--R-R-R--R-R-R--
    L-L--L-L--L-L--L-L--L-L--L-L--L-L--
    
Re: Global includes in cgi's
by VSarkiss (Monsignor) on Jun 09, 2001 at 20:36 UTC
    If you need to bring in code when your program first starts, then the best overall way is the use function, as jeffa pointed out above.

    Be aware, however, that use requires a bareword argument; if you try something like this, it won't work:

    my @files = qw(here there anywhere); foreach my $f (@files) { use $f; }
    If all you need is to read in a file and execute it to change some variables, you can use "do". This will search for the file named in its argument in your @INC directories, read it, parse it, and execute it. Look at perldoc -f do for details and an excellent example, but here's a quickie. This allows you to change the contents of variables in a running Perl program by modifying another file (which is what I assume you want to do if you can't read them in from a database):
    use vars qw($big_directory $lil_directory); # not 'my' do 'config_stuff.pl' or warn("Problem with config_stuff.pl"); Then, in <code>config_stuff.pl
    :
    $big_directory = '/some/where'; $lil_directory = '/some/place/else';
    In other words, you can change the values of the variables by editing config_stuff.pl and executing the "do" again.

    HTH

Re: Global includes in cgi's
by andreychek (Parson) on Jun 09, 2001 at 22:46 UTC
    The mod_perl guide has an excellent tutorial on writting configuration files.

    Although it's referring to mod_perl, I don't see any reason why it wouldn't also work under ordinary CGI.

    In short, the mod_perl guide offers this code:
    # Configuration File Example package My::Config; use strict; use vars qw(%c); %c = ( dir => { cgi => "/home/httpd/perl", docs => "/home/httpd/docs", img => "/home/httpd/docs/images", }, url => { cgi => "/perl", docs => "/", img => "/images", }, color => { hint => "#777777", warn => "#990066", normal => "#000000", }, ); # Main CGI application example use strict; use My::Config (); print "Content-type: text/plain\r\n\r\n"; print "My url docs root: $My::Config::c{url}{docs}\n";
    Again, that code is verbatim out of the mod_perl guide, and I included a link to it above. While you could directly use this code, I highly recommend reading the entire section in the guide regarding configuration files so you can decide if this is the best method for you or not. It contains a lot of good information, and is very well written.

    If you don't like the idea of using actual Perl code in your config file, there are modules at CPAN that allow you to write config files in other formats. Check out Config::IniFiles, XML::Simple, and Config::General.

    Good luck!
    -Eric
Re: Global includes in cgi's
by HamNRye (Monk) on Jun 09, 2001 at 23:39 UTC

    If you're doing it with CGI, you might want to consider either SSI includes or Iframes. I tend to output my pages from a format, so I'll just leave those examples.

    For SSI:

    <!--#include virtual=@<<<<<<<<<<<<<<<<--> $header

    With Iframes:

    <iframe src="@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" $body width="300" height="300" marginwidth="5" marginheight="5" scrolling="no" hspace="10" frameborder="0"></iframe>

    Yeah, I know it's not the most elegant backend solution, but it works well. I use this for headers and navigation and it works well. Note that in the MS world, you will have to name the file .stm, .asp, or .shtml for it to get parsed properly. (With SSI includes)

    My system works like this:

    • A configuration script is kept for the site that corresponds the area (by FS folder) to a template.
    • An Include brings in the header and footer from a .tem file in SSI format.
    • Iframes are used for static pages with dynamic content.

    An example of how I use Iframes are for our departmental section fronts. The normal section front is static, and information is brought into an Iframe. This means that people can update event information without needing to go in to these other HTML files.

    I've explained this poorly. If this sounds like something you'd like to try, e-mail me and I'll be happy to type it in English..... :)