
PHP includes with Cascade Server
Published on by Josh Hughes | Posts by This Author
The University of Missouri makes heavy use of Hannon Hill’s Cascade Server, a XSLT-based content management system. This is a fairly advanced tutorial that assumes some basic familiarity with that product.
Now, one of the things that sets Cascade apart from other content management systems is it doesn’t build live pages on the fly. Changes to files and templates must be published out before they will be live on the server. The downside to this is that even a fairly minor edit, like changing contact information in the footer, may require your entire site to be republished. For a large site, this might take a significant amount of time.
Fortunately, there is a solution. We can move our boilerplate content to separate files, and instead configure Cascade to use PHP includes on the live site. I’d like to share my method for setting this up, using a site footer as an example.
Include File Template
The first step is to create a template for files we’ll be including with PHP:
<include><system-region name="DEFAULT"/></include>
These files will just contain the content we attach to the DEFAULT region. The <include> is only there because valid XML requires a root node. We’ll be stripping it out later on.
Configuration Set
Next, we’ll create an “Include File” configuration set with the following options:
- Template should be the template we just created
- XSLT Format should not be set
- Configuration can be published must be checked
- Output File Extension should be .php
- Type of Data should be XML
- Include XML Declaration in Published Files must be unchecked
- The
DEFAULTregion does not need a Block or Format set.
Include Files
Next, in Cascade, create an includes directory in your web root (it’s possible to store the include files elsewhere, but note that it requires a minor edit to the _include file described below).
Then, create a new page that uses the “Include File” configuration set we created earlier, and name it footer.
Block and Format
Next, we need to setup our Block and Format. We will use the same Block and Format in two places:
- For the
DEFAULTregion of our include file. - For the region of our standard pages where we want to use the include. (Probably
FOOTERfor this example).
The Block will consist of the HTML for the footer, wrapped in a <system-xml> tag (again, since valid XML requires a root node). The Text Block option is good for this purpose.
<system-xml><p>Copyright © 2012 — Curators of the <a href="http://www.umsystem.edu">University of Missouri</a>. All rights reserved. <a href="http://missouri.edu/dmca/">DMCA</a> and <a href="http://missouri.edu/copyright.php">other copyright information</a>. An <a href="http://missouri.edu/eeo-aa.php">equal opportunity/affirmative action</a> institution.</p></system-xml>
The Format will look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="/_internal/stylesheets/_include"/>
<xsl:output indent="yes" method="xml"/>
<xsl:template match="/">
<xsl:call-template name="output-content">
<xsl:with-param name="filename">footer</xsl:with-param>
<xsl:with-param name="content">
<xsl:copy-of select="system-xml/node()"/>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
In this file, an XSL template is called, named output-content, that has two parameters: the filename, footer, and the actual content of the include, which is, in this case, selects everything in the Block in-between the <system-xml> tag.
It’s worth noting, that the block doesn’t necessarily have to be static HTML. A XML block can be used, and all you have to do is make sure that the result of your XSL transformation is placed in-between the <xsl:with-param name="content"> tag of the output-content template.
_include
Now, output-content is defined by the _include stylesheet we’ve brought in via xsl:import. Here’s the definition for that file. Note that, you may need to update the xsl:import statement to accurately reflect where you’re storing the _include stylesheet.
This file determines contextually whether or not to bring in one of the include files with PHP, or to simply output the content.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml"/>
<xsl:template name="output-content">
<xsl:param name="filename"/>
<xsl:param name="content"/>
[system-view:internal]
<xsl:copy-of select="$content"/>
[/system-view:internal]
[system-view:external]
<xsl:processing-instruction name="php">
# Location of includes directory
# (set to just off the server root - change it if you're storing the includes elsewhere)
$includeDirectory = $_SERVER["DOCUMENT_ROOT"] . '/' . 'includes/';
# Filename parameter from XSL template
$fileName = trim('<xsl:value-of select="$filename"/>');
# Full path of the include file
$includePath = $includeDirectory . $fileName . '.php';
# Just output the content if
# 1. The file that's executing this code *is* the include file
# 2. or the $isInclude flag has been set to true (see the else block)
if (($_SERVER["SCRIPT_FILENAME"] == $includePath) or ((isset($isInclude)) and ($isInclude === true)))
{
</xsl:processing-instruction>
<xsl:copy-of select="$content"/>
<xsl:processing-instruction name="php">
}
# Otherwise, bring in the contents of the include file
else
{
if (file_exists($includePath))
{
# Setting $isInclude to true forces the include file to output its content when it's brought in
$isInclude = true;
# Capture the content of the include
ob_start();
include $includePath;
$content = ob_get_contents();
ob_end_clean();
# Strip the "include" root tag and print the contents
preg_match_all('/<include>(.*)<\/include>/s', $content, $matches);
print_r($matches[1][0]);
# Reset the $isInclude flag
$isInclude = false;
}
}
</xsl:processing-instruction>
[/system-view:external]
</xsl:template>
</xsl:stylesheet>
That’s it! Now to make changes to the footer, all you have to do is edit the footer block we defined above, and then publish out /includes/footer.
For convenience, here’s a ZIP file containing all of the files discussed in this post:

