Open Source Content Management Framework

Styling MidCOM Error Pages

  1. Authentication related elements
    1. Login Form using the 'form' Authentication Frontend (midcom_services_auth_frontend_form)
    2. Login Page (midcom_services_auth_login_page)
    3. Access Denied Page (midcom_services_auth_access_denied)
  2. Styling of the other MidCOM Error pages
    1. 4xx Standard Error pages (midcom_error_4xx)
    2. 500 Internal Server Errors

For quite some time, all error pages generated by MidCOM where unstyled simple error pages (Bergie called them "industrial" ;-)). During the Development of MidCOM 2.6 I reworked the code of these parts to finally allow the site developers to add their own error pages.

The examples outlined here require MidCOM CVS as of 2005-07-28 (which will be available as 2.5.1 in the near future) and at least Midgard 1.7.0. It is assumed that you know how to handle Midgard Style- and Page-Elements, and how they interact.

In all cases, the basic idea is to have a simple page in the Distribution itself and allow the site developer to add either style or page elements that can override the defaults.

Since Midgard Style Elements evaluate in the scope of the callee, each element will list a number of variables that can be accessed directly without having to global them in as it is required with MidCOM Style-Engine driven pages.

Since the Style Engine does not distinguish between page and style elements during execution, you can add the replacement elements where you like. Be aware though, that it is strongly encouraged to add the element in the Style, not the Page. The required style element names are given in the headings of the various sections.

Authentication related elements

The authentication pages are divided in three elements:

Login Form using the 'form' Authentication Frontend (midcom_services_auth_frontend_form)

This is the simplest part of it, it will add the actual login form to the generated pages. It is decopuled from the rest, because a) its behavoir is depended on the authentication frontend used and b) it needs to be reusable in the other two elements.

This tutorial assumes that you use the default 'form' frontend.

Currently, only the "form" authentication frontend is avaialbe, which renders a simple form that can be styled using CSS. Lets look at the default source first:

<form name="midcom_services_auth_frontend_form" action="" 
    method="POST" id="midcom_services_auth_frontend_form">
    <label for="username">
    <?php echo $_MIDCOM->i18n->get_string('username', 'midcom'); ?>:
        <input name="username" id="username" />
    </label>
    <label for="password">
        <?php echo $_MIDCOM->i18n->get_string('password', 'midcom'); ?>: 
        <input name="password" id="password" type="password" />
    </label>
    <input type="submit" name="midcom_services_auth_frontend_form_submit" 
        id="midcom_services_auth_frontend_form_submit" value="<?php
        echo $_MIDCOM->i18n->get_string('login', 'midcom'); ?>" />
</form>

As you can see, you shouldn't have much trouble customizing this form by just generating appropriate CSS rules that are included in the actual error pages generated. If you need to replace this element nevertheless, ensure that the name of the various form elements are not changed in any way.

Login Page (midcom_services_auth_login_page)

The login page is shown if there is no authenticated user and either the systemwide login page is called, or some component calls $_MIDCOM->auth->require_valid_user().

It is similar to the regular error pages with a slightly different formatting not crying out "ERROR" as loud. These pages still add an HTTP 403 Forbidden Header to prevent search engines or any cache to interfere with the page.

The exact HTTP responses delivered by these pages may change in the course of the development of MidCOM 2.6, you might want to keep an eye on this tutorial in this respect therefore.

Again, lets look at the source of the default page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title><?php echo $title; ?></title>
<style type="text/css">
    body { color: #000000; background-color: #FFFFFF; }
    address { font-size: smaller; }
    a:link { color: #0000CC; }

    #login_warning { color: red; }
    p.login_message { }

    form label { margin-left: none; padding-left: none; display: block; }
    form label input { margin: 0.5ex 0 0 0; display: block; }
</form>
</style>
</head>

<body>
<h1><?php echo $title; ?></h1>

<p class='login_message'><?php 
    echo $_MIDCOM->i18n->get_string('login message - please enter credencials', 
    'midcom');?></p>

<?php echo $login_warning; ?>

<?php $_MIDCOM->auth->show_login_form(); ?>

<address>
    <a href="/"><?php echo $_SERVER['SERVER_NAME']; ?></a><br />
    <?php echo date('r'); ?><br />
    <?php echo $_SERVER['SERVER_SOFTWARE']; ?>
</address>
</body>
</html>

The important thing here is the fact that you are delivering a full HTML page at this point. It is rendered by the method midcom_services_auth::show_login_page(), which makes the following variables available:

  • $title: A localized page title generated by looking up the string 'login' in the main MidCOM L10n Database.
  • $login_warning: This string is populated with a localized warning in case that the (last) login failed. It is automatically enclosed in a
    paragraph with the CSS ID login_warning assigned to it. If there was no problem, the string is empty.

To add the actual login form, call $_MIDCOM->auth->show_login_form(), as shown in the example above. While it is theoretically possible to add the login form manually, this is strongly discouraged, as it breaks the modularity of the MidCOM authentication core.

Access Denied Page (midcom_services_auth_access_denied)

This page is shown on all failed permission checks other then $_MIDCOM->auth->require_valid_user() (see above for that one). It delivers a HTTP 403 Forbidden page which also includes the possibility to log in to the system using different credencials.

This is the default page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title><?php echo $title; ?></title>
<style type="text/css">
    body { color: #000000; background-color: #FFFFFF; }
    a:link { color: #0000CC; }
    address { font-size: smaller; }

    #login_warning { color: red; }

    form label { margin-left: none; padding-left: none; display: block; }
    form label input { margin: 0.5ex 0 0 0; display: block; }
</form>
</style>
</head>

<body>
<h1><?php echo $title; ?></h1>

<p><?php echo $message; ?></p>

<h2><?php echo $_MIDCOM->i18n->get_string('login', 'midcom');?>:</h2>

<?php echo $login_warning; ?>

<?php $this->_auth_frontend->show_authentication_form(); ?>

<p><strong>Error 403</strong></p>
<address>
    <a href="/"><?php echo $_SERVER['SERVER_NAME']; ?></a><br />
    <?php echo date('r'); ?><br />
    <?php echo $_SERVER['SERVER_SOFTWARE']; ?>
</address>
</body>
</html>

As you can see, this is quite similar to the Login page, with the main difference that it is more error-like. Therefore, all of the annotations from the login form and its usage do also count for the Acccess Denied element, with the single addition of another variable:

  • $message: includes the reason why the access to the page failed. It is localized (at least when coming from the MidCOM ACL core) and outlines the nature of the failed privilege check.

Styling of the other MidCOM Error pages

These pages are generated by calls to $_MIDCOM->generate_error(). They indicate critical errors which prevent a page from being processed completly.

4xx Standard Error pages (midcom_error_4xx)

Currently, the framework knows these error conditions in the 4xx cateogory:

  • 404 Not Found: This is the case happening most often, indicating that an element requested by the user could not be found.
  • 401 Unauthorized: This is a legacy error code, that is not in wide use right now. I have not yet decided what to do with it.
  • 403 Forbidden: Normally, 403 errors are now handled by the ACL framework (see above). In the unlikly case however, that the ACL service has not yet started up, the core must deliver the corresponding error message.

All of the errors mentioned above are delivered using the style element with their appropriate error code appended. So not found will call midcom_error_404.

The basic error page looks like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title><?echo $title; ?></title>
<style type="text/css">
    body { color: #000000; background-color: #FFFFFF; }
    a:link { color: #0000CC; }
    p, address {margin-left: 3em;}
    address {font-size: smaller;}
</style>
</head>

<body>
<h1><?echo $title; ?></h1>

<p>
<?echo $message; ?>
</p>

<h2>Error <?echo $code; ?></h2>
<address>
    <a href="/"><?php echo $_SERVER['SERVER_NAME']; ?></a><br />
    <?php echo date('r'); ?><br />
    <?php echo $_SERVER['SERVER_SOFTWARE']; ?>
</address>
</body>
</html>

Again, we have a few variables available at your disposal:

  • $title: contains the currently not localized clear-text name of the error as it is defined in the HTTP specs.
  • $message: This is the error message that should be shown to the user. It depends on the calling component whether this string is localized or not.
  • $code: contains the integer response code sent to the browser.
  • $header: contains the full HTTP/1.0 response code which has been sent to the browser already. You should normally not need this variable.

500 Internal Server Errors

This type of error page is not styleable by the site developer, as it is thrown in many places where critical errors occur. Since you can use regular MidCOM functions during rendering a customized error page, the possibility of an error throwing an error is perfectly possible, which is why the HTTP 500 error remains hardcoded (and simple).

Designed by Nemein, hosted by Kafit