Support > Documentation > Templating & Design > Advanced Templating Concepts

Advanced Templating Concepts

Analyzing Page Structure

Your page structure consists of numerous different elements that can be managed separately. Some are obviously separate, such as images and stylesheets, while others are all mashed together, such as the different blocks of HTML on the page. You should spend some time thinking about how to separate the different regions out so they can be managed independently of each other.

In ExSite terms the page object is the HTML framework inside which all other content is inserted. The page object contains the top-level HTML that we use to begin building the actual viewable web page. It is sometimes called a "wrapper" because it wraps all the other content in some framework HTML that lays everything out. It might be some layout tables, or some DIVs that are positioned with CSS, or something else.

In addition to inserting the external files such as images into the page using IMG tags or similar references, you can also insert external HTML into the page object. External HTML is stored in content objects with their own names, such as body, header, footer, sidebar, logo, etc. By dividing up your HTML into these different chunks, you can simplify management of your pages, by restricting editors to only those HTML elements that are of direct interest to them, and sharing other commonly-used elements across multiple pages.

Standard and Irregular Pages

Most pages have a body object, which is the primary chunk of content that fills the page. Although every web page needs a page object (or else we don't know where to begin), not every page needs a body object. However, body objects are very common--pages that have a body content item are called "standard pages". This is a common template format, so ExSite includes some additional features for standard pages:

  • a body is automatically created for you when you make a new page
  • you can create libraries of predefined bodies that can be used to quickly configure new pages
  • you can easily swap any of these predefined bodies in place of the existing body
  • some simplified content management web applications assume the presence of a body, in order to provide you with an easier interface

ExSite does not require that every page have and use a body. A page without a body is irregular, but it is still manageable using all the normal website editor tools. It must define its own contents, as the designer sees fit. As long as the template can find and use all of the special content objects on the page, the page will render perfectly well. However, it will not benefit from any of the special body-specific functions that are available in the system.

Separation of Content and Design

It is good practice to separate the design and editorial content on your site. In the simple case, this is done by isolating design content in templates, and leaving the editorial content in the real pages. This simple model is not always sufficient, however. Templates may include snippets that regular editors should have access to, and particular pages may have specialized graphics or banners that only the designers should be able to change.

ExSite allows you to specify whether each content object in the system is editorial or design. Furthermore, every user can be flagged as a designer and/or editor. These settings determine whether the user is permitted to update that content. (Note that each user type can create a content object of the other type, but will not be able to update it unless they also have the other user type's permissions.)

Polymorphism

When substituting content using the HTML substitution tag (<!--content(name)-->), if the content being substituted is NOT in HTML format, then it is automatically converted into HTML format by ExSite. For instance, although it would be normal for your body to be HTML, you could in principle upload a JPEG image as your body, instead. In this case, ExSite would take the <!--content(body)--> tag, and replace it with the equivalent of:

<img src=[[body]]>

which would inline the image into the body area of the page.

This means that ExSite content is polymorphic. That is, you can arbitrarily change the type of content in the course of your updates, and ExSite automatically adapts and does its best to display something useful. Even if the content is not browser-renderable (such as a PDF or MS-Word document), ExSite will display something to allow you to download it and view it with some other tool.

If you know that a content element will always be an external object like an image, then the URL-substitution method may be more practical, since it you can encode the explicit image tag and attributes into the wrapper. If a content item could be of any type (eg. a blurb or title, which might be plain HTML or an image, depending on the designer's whim), then the <!--content(xyz)--> format is more flexible.

In cases where the content object is an image, ExSite allows you to define special attributes to include in the IMG tag. This allows you to update not just the image data, but also the image attributes (which you cannot do using URL-substitution, which only substitutes a pointer to the data).

Template Inheritance

Templates can be derived from other templates. That simply means that the template itself has a template (and so on...). All templates that are related in this way will be searched for content.

This allows you to create a new template that shares all of the content of its parent template, but makes relatively minor additions or changes such as:

  • different color scheme
  • alternate logo
  • modified layout

Only the differing content needs to be included in the derived template, since anything not explicitly defined will be searched for and found in the parent template.

Once you have a template defined, you can easily derive new templates from them. When creating your new template in the Website Editor, you will be given the option to choose a template for it. If you choose one, your new template will inherit from the one you chose.

All of the content of the base template is inherited by and available to your new template. There is no need to re-import this content. You only need to import new content items unknown to the base template.

Your derived template can also overload (see below) other definitions in the original template (such as by replacing logos with alternate images). The versions defined in your derived template will take precedence over the originals, when you use the derived template.

Derived templates can be nested to any depth, so you can derive new templates from your derived templates, and so on.

Overloading Content Elements

Content overloading is the technique of redefining a content object to over-ride the definition that would otherwise be provided by a template. Content objects are found by conducting a search through the page, its templates and inherited templates, and libraries. With content overloading, you have a content object that would normally be found at one point in this search, but you overload it by providing a content object with the same name that will be found at an earlier point in the search. The latter content object will be used instead of the original.

This trick is typically used with inherited templates, to modify isolated aspects of their parent designs. For example, if you have a single design that has several color themes, you could isolate the colors into a content object containing the color stylesheet. The base template would define a default set of colors in this stylesheet. Then, you derive new templates that inherit from this base template, and the new templates define their own version of the color stylesheet, overloading the default color scheme.

Sometimes you just want to change the layout of the page, but most/all of the auxiliary graphics files will remain unchanged. In this case you are overloading the page object, and defining an alternative HTML framework for the template. This operation is common enough that the templating tools in the Website Editor give you the option to copy the original page object to the derived template, from where you can edit it further. From the Website Editor's Template Wizard, when you choose the template to use as your base, you have an option at the bottom of the screen to "Skip Customize Layout step". Uncheck this to copy the "page" content from the parent template into an overloaded version in your new template.

Note that overloading may not work with design elements in Precompiled Templates (see below).

Dummy content items

In your template, you may define areas of content (such as a body), which are to be filled in by a specific page, not the template itself. Nevertheless, you may want to view the template with some "dummy" body in place, to give you a better idea of what a real page would look like. Otherwise, the browser may scrunch the whole template up until it is hard to tell how a real page would be formatted.

To make a dummy body (or any other content item), simply create a body content item inside your template, just as you did for the other template files. Set it to be "editorial" content of type "HTML". When prompted to upload a new version, you can optionally reset the update method to "Edit using WYSIWYG HTML editor" to type in and format the content directly.

With your dummy body in place, template previews will give you a better idea of what a full page will look like. Specific pages will provide their own bodies, which will override the version in your template.

A similar procedure can be used to provide dummy (or default) logos, banner ads, and so on.

Base Templates

Sometimes your system will have numerous templates that don't really share much in the way of common graphic design, but they do share some other basic code that is generally useful to all templates. Examples might include:

  • generic style sheets, or multipurpose CSS class definitions
  • multipurpose javascripts for handling generic functions such as rollovers and browser sniffing
  • dummy bodies (so-called "lorem ipsum..." texts) for previewing templates
  • generic placeholder graphics (eg. "Your logo goes here!")

These types of content can be placed in a "base template" that is available for any other template in the system to inherit from to get access to them. Since base templates are just used as sources of content for other templates, and not as a real template in an of themselves, they may not have a "page" object than can be used to construct a page with. In that case, if you choose the base template as the template for an actual page, you may only see a blank page as output.

Compound Content Objects

Often you have HTML "snippets" that have a standard format, but changing content (such as headings, sidebars, framed boxes, etc.). You would like to be able to template the format of these snippets, but supply different contents for them in each case. Then to change the appearance of every one on the site, you simply have to change the one template, rather than each instance of the object.

In simple cases this can be done using CSS, but CSS is insufficient in cases where the snippet has a compound structure (ie. it contains multiple distinct content elements that are pieced together in a structured way).

The easiest way to illustrate this is by way of example. Say we want to make regular use of a visual box to highlight some content. Each box has (1) a title, (2) contents, and (3) a format to put the title and contents together. For example:

♥ title ♥
contents

CSS will not do this, since the "style" in this case includes a bunch of HTML to draw the table around the title and contents. ExSite will do this, however, using a compound content object. A compound content object is placed using the usual HTML substitution tag, except that you provide a list of items, instead of just one content item:

<!--content(fancybox,"title","contents")-->

Quoted items are literal text strings, whereas unquoted items are the names of other content objects. The first item in the list is the one that is actually substituted into the page at the position of this tag; the remaining items are substituted into the first item. This example is telling ExSite to substitute the fancybox content item into the page, after substituting the text "title" and "contents" into it, producing the example shown above.

In place of literal text strings, we could specify other content objects, which would be looked up and expanded before insertion into the compound object:

<!--content(fancybox,"The Bard Says",bard-quote)-->
♥ The Bard Says ♥
"Cowards die many times before their deaths; the valiant never taste of death but once."

The fancybox content item is the one that is actually substituted into the page, so it must have appropriate tags to accept the remaining items in the compound content object. Since these extra objects are variable, they cannot be specified explicitly. Rather, they are referred to by number. The first one (after fancybox itself, that is) is placed in fancybox using <!--content(1)-->. The next is placed using <!--content(2)-->, and so on.

Although the compound object fancybox may occur multiple times on one page, or scattered all throughout a site, it is coded only once in the content management system, and only needs to be changed in that once spot to reformat all instances of itself on the website.

Example

The above fancybox examples were made using this definition of fancybox:

<table cellspacing="0" cellpadding="4" style="border: 2px outset #999999;" width="200">
<tr><th bgcolor="#9999AA">♥ <!--content(1)--> ♥</th></tr>
<tr><td bgcolor="#CCCCDD" style="border:2px inset #CCCCDD; font-size:small;">
<!--content(2)-->
</td></tr>
</table>

Precompiled Templates

The process of building a page can be fairly involved if the template incorporates numerous subsidiary content objects, such as images, backgrounds, stylesheets, and scripts, that have to be looked up and integrated into the page. It is inefficient to repeat this process on every page view, since the templated parts of the page do not normally change. To make this process more efficient, we can "precompile" the templated aspects of the page so that we don't have to rebuild the templated elements every time.

Precompiling a template essentially involves finding all the content objects in the template that are unlikely to change on each page view (namely, the "design" elements), look those up and perform the appropriate substitutions into the page. The partially-expanded template is then published to a simple web page (index.html in the template folder). The following tags are left unexpanded, and remain in the web page as HTML comments:

  • editorial elements (such as the body)
  • dynamic content elements (such as context-sensitive menus)

When a real page view occurs, the page starts from the published precompiled template, rather than from the raw "page" object that would be pulled from the database.

To cause a given template to be precompiled in this way, set the template's "Static or dynamic" setting to static. It can then be published just like a regular page, and will automatically get published when you publish the whole site.

If you leave a template to render dynamically, it will build from scratch on every page view. This can be advantageous in some circumstances. For instance, it allows you to overload design content elements on any given page. (If you want to be able to overload certain content elements on any given page, but want the performance benefit of precompiled templates, then you can set those content elements to "editorial" to keep them from being precompiled.)

If a derived template inherits from a precompiled template, the derived template will not use the precompiled template as a starting point. Derived templates always start from scratch, allowing you to overload any element of the design. Of course you can precompile your derived template as with any other template.

Dynamic Content Substitutions

Dynamic content is substituted into a page using a tag with the following format:

<!--&Module(module-parameters)-->

where Module is the name of the dynamic content module (or "web application") and module-parameters is a bunch of text that is passed to the module to request something specific from that module. The formatting and meaning of module-parameters varies from module to module, so little can be said about it here, except that in many cases it is optional and can be left out to get the module's default behaviour:

<!--&Module()-->

Some modules are configured to accept input not only from the module-parameters, but also from regular web input sources (eg. forms, cookies, or URLs), so the content they produce can vary widely, even if you are technically still on the same page. What's more, many modules link back to themselves with different inputs, to give a very rich set of interactions to the user. ExSite automatically links back to the dynamic version of a page (using page.cgi) in this case, even when the default page view has been published to an html file.

Indirect Dynamic Content Substitutions

Normally dynamic content is substituted into the page as it is being constructed, and the final result is then dispatched (usually either to the viewer, or to the publishing program). If the destination is a publishing program, then the final substituted output will be saved to a static file, in which case it is no longer truly dynamic. There are some cases in which you would like to publish to a static file, but have certain page elements remain truly dynamic (ie. they automatically update even if the page hasn't been republished). This is particularly important when you need truly dynamic content on your index.html page, which has to be displayed in its static form. PHP (or ASP) is normally used to solve this problem, but ExSite includes a solution to inline truly dynamic content into a regular flat HTML file. This is useful when:

  • you want to publish the basic page to a static file, but keep some element of it dynamically rendered.
  • the page uses a complex template or a lot of dynamic plug-ins, which are computationally costly to rebuild on the fly, when only a small page element needs to be truly dynamic.
  • you want PHP-like behaviour on a non-PHP site.
  • you want a simple .html URL, but more sophisticated CGI- or PHP-like functionality.

In these cases, you can use an indirect dynamic content substitution. This looks exactly like a regular dynamic content tag, except there is a double ampersand:

<!--&&Module(module-parameters)-->

What ExSite does in this case, is leave a blank space for your dynamic content in the page, and then use JavaScript to make a second request for the dynamic content to fill this space. (Mnemonic: the double ampersand implies a double HTTP request: one for the base page, and a second one for the dynamic content.)

Note that indirect substitutions may fail if the viewer has JavaScript disabled (although a warning will be printed). They will likely also fail for web crawlers and search engines, who will miss out on the dynamic element of the page. However, the remainder of the page will display fine in these cases.

Page rendering times may be slower because there are two separate HTTP requests. You can work around this by fixing the size of the DIV or other HTML element that the content is being dropped into. Then the main page will render quickly, and the dynamic content will be dropped into place when it arrives.

Double-Indirect Dynamic Content Substitutions

When you use indirect dynamic substitutions, recursive links generated by the module back to itself will still redraw the entire page. If you'd like the links to refresh only the module content, using the same indirect fetching mechanism, then use the double-indirect dynamic content substitution method:

<!--&&&Module(module-parameters)-->

This generally gives the impression of a smoother redraw, and sometimes faster response in general.

Menus

ExSite uses the dynamic content substitution method to build automatic sites menus. Any website can create its own menu driver that follows its own logic for how to construct the menus on a particular page, but ExSite comes with the SimpleMenu driver which provides a general-purpose menuing system that will suffice for many sites. To add a context-sensitive menu to any page, use one of the following tags:

This will produce a full site map, showing all pages and their relationships to each other:

<!--&SimpleMenu(sitemap)-->

This will produce a menu of site links on a single line, separated by a vertical bar. In the first case, only top-level site links are shown (which should be the same on all pages), while in the second case, only children of the current page are shown (which will be context-sensitive):

<!--&SimpleMenu(horizontal)-->
<!--&SimpleMenu(horizontal,child)-->

This produces a path menu (or "cookie crumb" menu) showing where you are in the website. This is context-sensitive, of course. The menu is formatted on a single line, with the links separated by the ">" character:

<!--&SimpleMenu(path)-->

These will produce a menu of site links, one above the other. The vertical menu is context-sensitive, and will explode submenus on pages where it is appropriate:

<!--&SimpleMenu()-->
<!--&SimpleMenu(vertical)-->

By default a simple linebreak (<br>) is used to separate the links, but if the following content objects are defined, they will be used to format the menu instead:

SimpleMenuTop
this will be placed at the beginning of the menu, before all links
SimpleMenuMid
this will be placed between each menu link
SimpleMenuBot
this will be placed at the end of the menu, after all links
These can be used to give the menu some fancy-formatting, eg. a table, or graphical spacers.

Recursive Substitutions

As mentioned above, regular HTML substitutions can in turn bring in new substitution tags, and so on. Dynamic substitutions can do the same thing, as the menuing example above shows -- the <!--&SimpleMenu()--> substitution leads to a <!--content(SimpleMenuTop)--> substitution, which in turn may lead to more HTML or URL substitutions if the menu formatting involves images.

The designer has to take care to avoid infinite recursion loops, as these will result in no page being displayed (not to mention a temporary freeze-up of your server as it tries to do an infinite amount of work!).

Dynamic substitutions can also play this game, and substitute other dynamic content objects into the page. This is a simple way for web applications to call each other, allowing different web applications to interoperate with each other without ever needing to interact directly at a software level.

Topics

google (5 items)
RSS (3 items)
SEO (3 items)
plug-in modules (28 items)
IT (9 items)
best practices (5 items)
visual tutorial (29 items)
security (3 items)
data handling (7 items)
fundamentals (3 items)
graphic design (19 items)
web protocols (9 items)
programming (48 items)
html formatting (7 items)
POD (32 items)
events (8 items)