Perl Application Server Developer's Guide | ||
---|---|---|
<<< Previous | Page Objects | Next >>> |
The first step in writing a page object is to register it in the Pas configuration file, pas.conf. Edit your pas.conf file and add an entry at the bottom for your new page object:
pas.pages.custom.HtmlTest=HtmlTest |
Make sure you have set up a directory for your page objects and added it to the list of library paths in the pas.conf file.
pas.lib.custom=/path/to/your/lib |
Keep in mind that changes to the Pas configuration file will not take effect untill the next time Apache is restarted. The configuration file is only loaded at startup time and is never re-loaded.
The path structure under your library directory should exactly match the package namespace for your objects. Following with the above example, a package Custom::TestPage would correspond to the file /path/to/your/lib/Custom/TestPage.pm. For our example, we are going to use the package HtmlTest.
Create your page object, declaring Org::Bgw::Pas::Page as your parent and override execute to produce your content.
package HtmlTest; use strict; use warnings; our @ISA = qw(Org::Bgw::Pas::Page); use Org::Bgw::Pas::SessionPage; sub execute { my($self) = @_; $self->response->print(q{ <HTML> <HEAD><TITLE>This is a test</TITLE></HEAD> <BODY> <H1>Test Page</H1> <P> Hello World! </P> </BODY> </HTML> }); return 1; } 1; |
If the page object is registered correctly according to the example, when you access http://localhost/pas/HtmlTest with your browser, you should see the HTML emitted by the execute method. If it is not registered correctly, the request handler will return DECLINED to Apache, and apache will probably return a 404 error messasge. To trobuleshoot what went wrong, you should consult the Pas log file, and Apache's error log file.
If your page object contained syntatical errors, or other compile time issues, an exception will be thrown and you will see a 'Pas: Internal Server Error' page with the stack trace and other error information about the environment at the time of the request. The stack trace should point to the issue that lead to the error.
During the request process Pas sees that the uri /pas/HtmlTest is registered to be handled by the objectg HtmlTest. The request handler then creates an instance of the HtmlTest Page object, invokes its request_init, invokes execute, and then invokes request_cleanup.
Once these methods have been called on your page object, the request handler then inspects the response object. If a redirect was requested, the handler returns the HTTP redirect response. If a forward was set, the request is forwarded on to the Page object or PSP specified in the forward. If neither of these conditions was true, then the contents of the response object is returned to the client.
Any cookies that were set in the response will be returned as part of the HTTP header. If your page object is derived from Org::Bgw::Pas::SessionPage, then the session id cookie will be set during the call to request_init in the session page.
You would override request_init to perform actions to set things up before execute is invoked. Org::Bgw::Pas::SessionPage utilizes request_init to initialize the session id cookie and initialize the session object itself. It either creates a new session, or loads a pre-existing session from persistient storage.
The return value of request_init is used to determine if the execute method is ever invoked on your page object. The implication of this are that you can create Page objects that specify a pre-condition for their execute method to be called. The canonical example of this is a LoggedInPage, where the LoggedInPage acts as a parent to all of the pages in your site in which you wish to require that the user is logged in before they can access the page.
package Project::LoggedInPage; use strict; use warnings; our @ISA = qw(Org::Bgw::Pas::SessionPage); use Org::Bgw::Pas::SessionPage; sub request_init { my($self) = @_; $self->SUPER::request_init; unless( $self->userProfile->isLoggedIn ) { $self->response->set_redirect('/pas/login/Login'); return undef; } return 1; } 1; |
In this example, LoggedInPage checks a user profile to see if the user is already logged in. If they are not, it sets an HTTP redirect to a login page and returns false. If the uesr is logged in, request_init returns a true value, and the request handler will then invoke the execute method.
It is a core technique in our Pas based applications for Page objects to not create presentation (HTML), but instead to perform application logic, and then forward the request on to a PSP that is responsible for presenting the information.
package Project::Catalog::Product; use strict; use warnings; our @ISA = qw(Org::Bgw::Pas::SessionPage); use Org::Bgw::Pas::SessionPage; sub execute { my($self) = @_; my $sku = $self->query->param('sku'); my $product = $self->loadProductBySku( $sku ); $self->query->param('catalog.product.item',$product); return $self->forward_request('product.psp'); } 1; |
product.psp might look like:
<% my $product = $self->query->param('catalog.product.item'); %> <HTML> <TITLE>Product: <%= $product->name %></TITLE> <BODY> <H1>Product: <%= $product->name %></H1> Height: <%= $product->height %><BR> Width: <%= $product->width %><BR> Depth: <%= $product->depth %><BR> <BR> <IMG SRC="/images/catalog/products/<% $product->sku %>.png" ALT="<%= $product->name %>"> </BODY> </HTML> |
This technique allows the product.psp PSP page to be re-used from other page objects within the application. All one of those page objects needs to do is place a product object into the query and then forward the request on to product.psp for display.
<<< Previous | Home | Next >>> |
Page Objects | Up | Another Example |