Apache2-ASP

 view release on metacpan or  search on metacpan

lib/Apache2/ASP/Manual/BestPractices.pod  view on Meta::CPAN

  </html>

Example "nested" MasterPage: C</masters/child.asp>

  <%@ MasterPage %>
  <%@ Page UseMasterPage="/masters/main.asp">
  
  <asp:Content PlaceHolderID="ph_content">
    <div class="left_column">
      <!-- menu goes here -->
    </div>
    <div class="right_column">
      <!-- individual page content goes here -->
      <asp:ContentPlaceHolder id="ph_page_content" runat="server"></asp:ContentPlaceHolder>
    </div>
  </asp:Content>

And a page that uses C</masters/child.asp> as a MasterPage would look like this:

  <%@ Page UseMasterPage="/masters/child.asp" %>
  
  <asp:Content id="title" PlaceHolderID="ph_title" runat="server">The Title</asp:Content>
  
  <asp:Content id="copy" PlaceHolderID="ph_page_content" runat="server">
    Hello World!
  </asp:Content>

The resulting HTML printed to the browser would look like this:

  <html>
    <head>
      <title>The Title</title>
    </head>
    <body>
      <div class="content">
        <div class="left_column">
          <!-- menu goes here -->
        </div>
        <div class="right_column">
          <!-- individual page content goes here -->
          Hello World!
        </div>
      </div>
    </body>
  </html>

=head2 Advantages of MasterPages

Not only do you get inheritance for your web pages, they actually execute faster.
Why?  Because includes require extra overhead of setting up "mock" requests
in which the included ASP scripts are executed.  MasterPages do not require this
extra work.

=head1 HANDLERS

Generally speaking, all forms should submit to handlers, rather than other ASP
scripts.  This results in a predictable MVC setup.

Of course, Apache2::ASP doesn't B<force> you to do this.  You can do whatever you want.

However, if you upload a file, you must upload it to a subclass of L<Apache2::ASP::UploadHandler>.
Generally you would inherit from L<Apache2::ASP::MediaManager> though, if you plan on
doing much with uploaded files.

=head2 Namespaces

Because of the way namespaces work in Perl, web servers with multiple VirtualHosts
should keep all handlers in their own namespaces.

For example:

B<Site 1>:

  /handlers/site1.user.login
  /handlers/site1.user.logout
  /handlers/site1.user.register

B<Site 2>:

  /handlers/site2.user.login
  /handlers/site2.user.logout
  /handlers/site2.user.register

If you were to simply use C</handlers/user.login>, that one handler would be
invoked for any website's C</handlers/user.login> URI.  Unless this is what you
want, avoid the namespace clashes by going with the naming convention described
above.

=head2 Path-to-Class Mapping

Apache2::ASP converts URI's matching C</handlers/*> to their corresponding Perl
class names.

Examples:

=over 4

=item * C</handlers/site1.user.login>

C<site1::user::login>

=item * C</handlers/site1.user.logout>

C<site1::user::logout>

=back

=head1 FILE UPLOADS

Just inherit from L<Apache2::ASP::MediaManager> unless you need more control.

See the documentation for L<Apache2::ASP::MediaManager> for more information.

=head1 VALIDATION

Apache2::ASP supports - but does not provide - server-side validation.  In fact,
it is recommended that all validation is performed on the server, in one way or
another.

AJAX may be your preferred means of doing form validations and such, which Apache2::ASP
fully supports.  Apache2::ASP simply does not B<require> the use of AJAX or any other
idiom.

lib/Apache2/ASP/Manual/BestPractices.pod  view on Meta::CPAN

  
  use strict;
  use warnings 'all';
  use Test::More 'no_plan';
  use base 'Apache2::ASP::Test::Base';
  
  # Create our base test object:
  my $s = __PACKAGE__->SUPER::new();
  
  # Make a request:
  my $res = $s->ua->get("/index.asp");
  
  # $res is a normal HTTP::Response object:
  ok( $res->is_success => "Got /index.asp" );
  like $res->content, qr/Hello, World/, "Contents look right";
  is( $res->header('content-type') => 'text/html' );

Run your tests with:

  prove t

All of your tests will be run.

=head1 CODE COVERAGE

Along with unit testing, code coverage is another great reason to use Apache2::ASP.

Just by using the L<Devel::Cover> utility C<cover> you can get code coverage
for not only your website's libraries, but also its handlers and ASP scripts.

=head1 PROFILING

Profiling an Apache2::ASP web application fits right in with your unit tests and
code coverage.

L<Devel::NYTProf> is an excellent profiler tool for Perl and works very well with
Apache2::ASP web applications.

=head1 ERROR HANDLING

Errors are handled by subclasses of L<Apache2::ASP::ErrorHandler>.

The default ErrorHandler prints a stacktrace to the browser and sends a copy
to the email address specified in your config file.

=head2 Configuration

Open your C</conf/apache2-asp-config.xml> file and look for the following:

  <errors>
    <error_handler>...</error_handler>
    <mail_errors_to>...</mail_errors_to>
    <mail_errors_from>...</mail_errors_from>
    <smtp_server>...</smtp_server>
  </errors>

Make changes as necessary.

=head1 FILE UPLOADS

Almost any time you need to process a file upload, your best bet is to subclass
L<Apache2::ASP::MediaManager>.

See L<Apache2::ASP::MediaManager> for details.

If you really need to do something special, either subclass L<Apache2::ASP::UploadHandler>
or write your own C<mod_perl> handler and submit to it.

=head1 SECURITY

=head2 Restricting Access

Apache2::ASP simplifies this by providing the RequestFilter interface (L<Apache2::ASP::RequestFilter>).

B<Example>:

Suppose you want all requests to C</members/*> to require authentication.

Adjust your C</conf/apache2-asp-config.xml> like this:

  <configuration>
    ...
    <web>
      ...
      <request_filters>
        <filter>
          <uri_match>/members/.*</uri_match>
          <class>My::MembersOnlyFilter</class>
        </filter>
      </request_filters>
    </web>
    ...
  </configuration>

Somewhere in your C<@INC> (like, say, C</lib>) add C<My/MembersOnlyFilter.pm> 
with the following code:

  package My::MembersOnlyFilter;
  
  use strict;
  use warnings 'all';
  use base 'Apache2::ASP::RequestFilter';
  use vars __PACKAGE__->VARS;
  
  #======================================================
  sub run
  {
    my ($s, $context) = @_;
    
    unless( $Session->{logged_in} )
    {
      # User is *not* logged in:
      return $Response->Redirect("/login.asp");
    }# end unless()
    
    # User is logged in:
    return $Response->Declined;
  }# end run()
  
  1;# return true:



( run in 0.752 second using v1.01-cache-2.11-cpan-b16cb0d3907 )