3. Changing the site structure

Since only the administrator will be able to make changes, there is no need to let visitors see those options. Splitting out the menu to its own subsite will be our first task.

3.1. Using a subsite

A site in RIFE can be built from smaller subsites. Using subsites is a good way to make a site modular and it also makes it easier to reuse parts of a site in other applications. In this example, we'll put the administration part in its own subsite, and we'll also show another advantage of doing so when we add the authentication mechanism.

To achieve this, we simply move the elements to its own site file, sites/admin.xml, and add a subsite tag in the main site file, pointing to the subsite:

Example 8.3. The main site definition file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE site SYSTEM "/dtd/site.dtd">
 
<site>

  <arrival destid="DISPLAY"/>

  <element id="DISPLAY" file="display.xml" url="/display">
    <flowlink srcexit="admin" destid="ADMIN"/>
  </element>

  <!-- Add a subsite --> 
  <subsite id="ADMIN" file="admin.xml" urlprefix="/admin"/>
 
</site>

Now locations starting with /admin will be handled by the administration subsite. After moving over the add, install and remove elements, the new site file looks like the following:

Example 8.4. The admin site definition file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE site SYSTEM "/dtd/site.dtd">
 
<site>
 
  <globalexit name="menu" destid="MENU"/>
 
  <arrival destid="MENU"/>
 
  <element id="MENU" file="admin/menu.xml" url="/menu">
    <flowlink srcexit="install" destid="INSTALL"/>
    <flowlink srcexit="add" destid="ADD"/>
    <flowlink srcexit="remove" destid="REMOVE"/>
    <flowlink srcexit="back_to_display" destid=".DISPLAY"/>
  </element>
  
  <element id="INSTALL" file="admin/install.xml" url="/install"/>
  <element id="ADD" file="admin/add.xml" url="/add"/>
  <element id="REMOVE" file="admin/remove.xml" url="/remove"/>
                                                                                        
</site>

When referring back to the main site from the subsite, we set the destination to .DISPLAY. The dot is used as a separator, so the destination points to an element in the main site. Without the leading dot, links are relative, and refer to elements in the current subsite.

The dot seperates in a very similar way as the slash when you seperate directory names on your filesystem. For example, you could have written .ADMIN.REMOVE instead of REMOVE to refer to the removal element. Doing this however makes your site definition unflexible so it's generally discouraged.

Following the directory analogy, it's also possible to reference elements that are defined higher up the subsite hierarchy without using the leading dot. You're probably very familiar with the double-dot, .., which allows you to go to the parent directory. In RIFE, you can use the circumflex character: ^. Thus instead of writing .DISPLAY you could have used ^DISPLAY notation. Depending on your design this might again make your site structure more flexible and easier to cut up in seperated modules. Note that for file paths you have to seperate the double dot with slashes too. In RIFE element paths you just use the circumflex without dot seperators since they're completely redundant.

3.2. The authentication element

Now it's time to handle the actual authentication. The element for doing that is very simple to write. All we need to do is to extend a built-in element in RIFE, rife/authenticated/memory.xml:

Example 8.5. The authentication element

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE element SYSTEM "/dtd/element.dtd">
  
<element extends="rife/authenticated/memory.xml">
  <property name="template_name">auth.form</property>
  <property name="role">admin</property>
   
  <submission name="credentials">
    <param name="login"/>
    <param name="password"/>
  </submission>
   
  <childtrigger name="authid"/>
</element>

The built-in element handles all the authentication logic, including processing and displaying the login template from Example 8.6, “The authentication template”. There are two properties, one for specifying which template file to use and one for the role. In this simple application, we only use one role, but it can be a very powerful tool when there is a need for fine-grained access control to different parts of a site.

The submission parameters of the element are defined as usual, but the childtrigger tag is something new. We'll describe its purpose in a moment, but first we need to add a form for the login submission.

3.3. The login form

We need a template with a form for filling in the user name and password. There should be no surprises here, just a regular form with a submission named credentials as specified in Example 8.5, “The authentication element”.

Example 8.6. The authentication template

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
                      "http://www.w3.org/TR/html4/strict.dtd">

<html>
<head><title>Admin</title></head>
<body>
  <table cellpadding="5" cellspacing="0">
    <tr valign="top" nowrap="1">
      <td width="100%">
        <h3>Please provide a login and password</h3>
        <!--I 'auth.error_area'/-->
 
        <form name="credentials" action="[!V 'SUBMISSION:FORM:credentials'/]"
              method="post">
        <!--V 'SUBMISSION:PARAMS:credentials'/-->
        login<br/>
        <input name="login" value="[!V 'PARAM:login'][!/V]" type="text"
               size="18" maxlength="10" /><br/>
        password<br/>
        <input name="password" type="password" size="18" maxlength="10" /><br/>
        <input type="submit" value="Login" /><br/>
        </form>
      </td>
    </tr>
  </table>
</body>
</html>>