in reply to Re: Multiple Pages with CGI
in thread Multiple Pages with CGI

Is there a way for a basic href url to call a fuction within perl that will write a new page like I want it to do? Is there a way to have a user select a page from a list, then change to that page?

URL's don't call functions, they just establish the host from which the request will be made and perhaps the parameters of the request itself (if you're using, say, "/cgi-bin/mycgi.cgi?p=5"). After that, it's all up to you to ensure that the right thing happens, and more importantly, that no wrong thing happens. Yes, there is a way to get from the information available to the correct solution -- all dynamically generated web content you've ever seen, and every application you've ever launched on your own computer has done exactly that, after all.

Maybe it's not sinking in just yet, but you've been given several viable options to think about. Maybe you're a bit too new to programming to have the mental habits and breadth of information that will easily guide you through to a solution? If that's the case, you're going to have to expend some brain sweat to get there. Don't worry, it won't hurt. At least not too much. It will be worth the effort, even if your first go at it fails miserably.

Please forgive me if I'm assuming wrongly about your experience level in what follows. It's difficult to gauge another's knowledge and skill without a good bit of discussion, and I'm just doing the best I can to help you along with what little I know right now. Some suggestions to get you on track:

Sit down with a pencil and paper and write out what you expect your application to do, case by case and step by step. Don't even think of tapping the keyboard until you've got the whole darn thing reduced to scribble. You want at least a very good outline to start with: in this case it will do this, in this other case it will do this other thing, et cetera. Then fill in between each "in this case" and its corresponding "it will do this" with the logical steps that define what "do this" means and how it will be accomplished. By the time you're done, a possibly doable solution will probably suggest itself to you. If not, think on it some more, expend that brain sweat. Then take just one case and code it up. Make it work, at least mostly. Then work a second case into the code and provide the logic that will allow the thing to decide which response is appropriate. By that point you've got a skeleton of some hopefully reasonable logic that at least mostly works. And at that point you can set that bit of code aside and start over with your now hopefully more refined idea of what should happen. Always always always write one to throw away.

Above all else, have fun with it. Every application solves a problem ranging from "I want the string 'Hello World' to appear on my display" to "I want to solve all of the world's problems with a computer". How to get from the basic idea to the implementation of a fully working solution is a puzzle, hopefully an intriguing puzzle that will simultaneously exercise and entertain your mind.

You've been given several viable options to get you started. So get started!

Replies are listed 'Best First'.
Re^3: Multiple Pages with CGI
by f00li5h (Chaplain) on Mar 26, 2007 at 02:18 UTC

    Some of the perl web-application frameworks do use a mapping from apache handlers to perl subs... or with some other sort of callback magic. I think maypole does that, CGI::Application also does.

    If you want a request to call a sub, you just need a dispatch table keyed by page name, or id

    #use strict unless untested_code; use Template; use CGI qw/header/; print header; # hash of subs that return 2 element list of page title and page conte +nt. my %title_and_content_for = ( # about_us => \&MyModule::get_about_us_html, '/quick_hack' => sub { return ( 'this is a quick, nasty hack', 'some junk to go in the page' ) }, # ... ); my %template_variables = ( # the default is to complain, this will be replaced below title => 'Oh noes!', content => q[ I couldn't find the page you asked for ], # add other stuff to keys in %template_variables ); my $html_layout = q{ <html> <head><title>[% title %]</title></head> <body> [% content %] </body> </html> }; # call the sub for this page, if there is one. # assign the results of the sub to the keys "title" and "content" @template_variables{title,content} = $title_and_content_for{ $ENV{ PATH_INFO } }->() if defined $title_and_content_for{ $ENV{ PATH_INFO } }; # and feed the whole lot to Template toolkit my $TT = Template->new() or die $TT->error(); $TT->process(\$html_layout,\%template_variables) or die $TT->error();

    Now we view http://mysite.com/cgi-bin/sub-madness.cgi/quick_hack and if all goes according to plan (and my untested-make-it-up-on-the-spottery is as good as I think it is) you'll get a nice little html page that reads "some junk to go in the page".

    I've cheated a little, and stuffed most of the HTML generation into places you can't see, the subs on one hand, and Template::Toolkit on the other

    Other interesting this to do:

    • Perhaps want to have some kind of http/404 headers too?
    • Generating a navigation bar from the keys of the hash could be a fun exercise ...
    • Passing in a CGI instance to the subs could make for user-activated stuff, allowing foo.com/sub-madness.cgi/about_us?action=contact&from_email=f00li5h@example.com&question=....
    • It may also be good to add a default page, for when no page is requested... but you're getting mighty close to the page dispatching that your web server should be doing tat that point.

    Update

    • use Template; use CGI; print header all added post creation
    @_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print;
      Maybe I was being a mite too pedantic? A URL is just a string. If a function/method is called, it's done by the application that handles the request and generates the response, not the URL.

      Yep, I was being too darn pedantic. 'Scuse me.

        gloryhack, you are being a pedant, but it's a good point, the uri itself won't call anything...

        The uri tells the browser to ask the webserver to run the handles that run the script which runs perl which runs my code, which runs the subs...

        But let's leave out some of those parts, and say the uri does run the subs... <phb>That's all implementation anyway</phb>

        @_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print;