Page Templates define the "look" or graphic design of your website. ExSite gives you a lot of power and flexibility in constructing your own templates.
A template is a model page, which defines how the content of real pages should be laid out, decorated (enhanced with colors and graphics), and typographically styled.
A template is very similar to a real page, except that it does not appear in any site maps. Instead, a template serves as a framework that page-specific content is inserted into. However, templates can be previewed and managed exactly like regular pages, using the Website Editor.
Every real page points to a template that it will use as its framework. Reformatting a page is as simple as pointing the page to a new template. In the Website Editor you do this by selecting Template > Change Template from the page view menu. You can also change all pages in a site to use a new template by selecting Template > Change for All Pages from the site view menu.
When ExSite has to draw a page, it has to start from some basic block of HTML. To do this, it looks for a content item named "page", which contains the base HTML framework into which all secondary content is inserted. Typically the "page" content item is defined by the template. (In principle, any web page can define its own "page" content item, and this is sometimes useful to override the templated layout for a particular page only, while still using all of the template's image files.)
The "page" item contains the base HTML for the page, with various content-management tags that tell ExSite how to find auxiliary content, such as style sheets, images, scripts, and body content. ExSite begins by parsing the content of the "page" item, finding each secondary content item that is referenced within it.
Each secondary content item has a name, and ExSite searches for content under that name, in the following locations:
As soon as a match is found, ExSite substitutes that content item in place of the content management tag. If no match is found, ExSite substitutes nothing in its place.
Since other content items can also contain content management tags, this process can continue to several levels depth, until ExSite is satisfied that all content references have been satisfied.
ExSite uses a special set of tags embedded in the HTML to tell itself to insert new content at those positions before sending it out for viewing/publishing. There are five types of special content management tags that ExSite recognizes:
These are descibed in more detail below.
Expert-level ExSite users may wish to code these tags directly into their HTML, but this is not necessary. The ExSite HTML editor has friendly tools for automatically inserting the appropriate tags in the correct format.
Content-URL tags of the form [[xyz]] can be used anywhere you have a SRC= attribute in your HTML, especially IMG tags:
<img src=[[logo]] height=50 width=50 border=0 align=left>
This type of substitution also works for linked stylesheets, and externals scripts (note the quoting, which is optional but recommeded in most cases):
<link rel="stylesheet" type="text/css" href="[[stylesheet]]"> <script type='text/javascript' src='[[my_script]]'>It can also be used inside javascript, as in this example of a rollover-image function call that uses image "home0" for the normal image, and "home1" for the rollover image:
<a href="index.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('home','','[[home1]]',1)"> <img src="[[home0]]" width="36" height="15" border="0"> </a>For images, it is often convenient to give the content item the same name as the original file. For example, this raw HTML:<img src="ourlogo.jpg" height="50" width="50" border="0" align="left">can be templated with this:
<img src="[[ourlogo.jpg]]" height="50" width="50" border="0" align="left">This allows you to very quickly run through a regular HTML file and convert all SRC= attributes by simply adding the square brackets. Designers who are accustomed to working directly with filenames may also find it more readable. If the original image name includes a path, the path should be removed from the content name to leave just the file name.
HTML substitutions
CMS tags of the form <!--content(xyz)--> can be placed anywhere in your HTML file. This tag is always replaced with HTML. If the content being substituted is already in HTML format, then it is simply swapped into place.
Any HTML content that is substituted into a page may contain other substitution tags embedded in it. The Content Management System will continue trying to expand these new tags until it cannot proceed any further. This process can continue to any depth.
WARNING: It is possible to accidentally code self-referential content loops -- for example, when your page body contains a tag like <!--content(body)-->. ExSite may not be able to generate your page in these cases.
Creating Templates
Creating a Template from an Existing Web Page
Make a copy of a representative page, including images.
This is easily done using your browser's "save as complete webpage" function. This will save your webpage as an HTML file, and save all the auxiliary files, such as stylesheets and graphics, in a subfolder.
Create the template in ExSite
Go to your website in ExSite's Website Manager (the page that shows all your web pages as icons), and from the menu, select Template → Import Template. Provide some basic info about your template, including a publication directory name (for example "Green_Template"). Choose "static" publishing, unless you know what you're doing (more info). You will also be asked to upload the copy of the webpage (the HTML file you saved in the previous step).
Upload Auxiliary Files
ExSite will scan your template, looking for extra files that it needs. It will list all of the files it finds, and ask you to upload each of them. Browse for each file until ExSite knows where they all are, and then proceed to the next step.
ExSite may not find every file that it needs. It is good at spotting files that are directly referenced in the HTML (eg. <IMG SRC="filename.jpg">), but usually misses files that are referenced in stylesheets (eg. background-image:url(filename.jpg)). Missing files can always be imported later.
Fine-Tune Your Template
At this point, your template is created, and is technically useable. However in practice, there is some manual fine-tuning that will be necessary. In particular, it will probably be necessary to edit the template's page object (in simple text mode), in order to:
- remove any non-template text/HTML from the sample page you imported, and replace it with appropriate CMS tags. For example, the main body of page text should probably be replaced with a CMS tag like this:
<!--content(body)-->- repeat the above for any other sections of content that should be managed separately from the body, such as sidebars, footers, etc.
- edit any meta-data tags to remove page-specific meta-data such as titles, and replace it with special CMS tags to substitute the appropriate meta-data at a later time. More information is here.
- template your menus. In the simple case, you can have hard-coded menus, in which case you should template your page links (more information here). Otherwise, you will use a menu plug-in, such as SimpleMenu, which can dynamically build context-sensitive menus for you (more information here).
- double-check that all external files are being correctly referenced. Sometimes ExSite can miss files, especially if they are hard to spot inside CSS or Javascript. If some files have been overlooked in these places, they will have to be tagged by hand. More information is here
Creating a Template from Scratch
This procedure is more involved than a simple import, but it gives you plenty of control over the details.
Make a copy of a representative page, including images.
This is easily done using your browser's "save as complete webpage" function. This will save your webpage as an HTML file, and save all the auxiliary files, such as stylesheets and graphics, in a subfolder.
Create the template in ExSite
Go to your website in ExSite (the page that shows all your web pages as icons), and from the menu, select Website → New Template. Provide some basic info about your website, including a publication directory name (for example "Green_Template").
You may be prompted to select a parent template. Ignore this step (select nothing) if you are working with a brand new template.
Open your new template
Go back to the website view (use the path box beside the typewriter icon), and select the icon for your new template. (Templates have an icon showing drafting tools.) It will open up, but be empty of content.
Create the "page" object
The first thing to do is create the framework for the entire page. From the menu, select Page → New Content Item. The name of this content item must be "page". The category should be "design", and the allowed mime-types should be "HTML". (Different choices are possible, but not normal in this case.) Press the "Next" button.
Using the file browse field, select the representative page (typically an HTML file) that you saved in step 1. Press the "Next" button when you are done.
Lastly, you will need to include a short comment explaining this update. Enter "import" or something like that. Press the "FINISH" button. You will be taken back to the template view, where you will see the "page" object you just created.
Update your "page" object
You imported a regular page, but now you must convert it to a template by modifying the HTML to use ExSite content management tags, instead of regular HTML tags. From the page menu, select Update &rarr update page.
ExSite will render the page in its WYSIWYG editor. There may be lots of holes, because we haven't loaded the images yet, but ignore that for now. We need to work directly with the HTML tags, so change the update method to "Edit using a simple text editor". This will change the WYSIWYG editor to one that shows the raw HTML.
Modify all external content URLs
External content URLs are tags that point to images, stylesheets, scripts, and other items that are stored in separate files. For example:
An external stylesheet:
<link href="solutions_files/exware.css" rel="stylesheet" type="text/css">An image:
<img src="solutions_files/ex-logo.gif" width="42" height="42" alt="">A javascript argument referring to an image file:
onmouseover="MM_swapImage('solutions','','images/solutions_alt.gif',1)"Replace all external file names with a simple name enclosed in double-square brackets. The simple name can be any unique name that you will use to reference that file, but it's often easiest just to re-use the original file name. Do not include any directories or other URL data that was included in the original URL. For example, the above 3 tags could be converted to this:
<link href="[[exware.css]]" rel="stylesheet" type="text/css"> <img src="[[ex-logo.gif]]" width="42" height="42" alt=""> onmouseover="MM_swapImage('solutions','','[[solutions_alt.gif]]',1)"This new notation tells ExSite that you want those files to be managed by the content management system.
Make a note of each file that you reference this way, as they will have to be imported into the content management system later (step 11).
Modify internal links
An internal link is a link to a page in the same website. For example:
<a href="index.html">Home</a>You can replace all internal links with file names enclosed in double-braces, for example:
<a href="{{index.html}}">Home</a>This notation allows the content manager to make the correct link to the file, regardless of whether the page is published to an HTML file, is not published yet (and only exists in the database), is never published (due to security or dynamic content requirements), or changes its status at some time in the future. It also allows webmasters to navigate through the site with various content management features enabled on each page.
You do not have to change your internal links to use this notation, but if you do not, then the links will not work until the pages are published, nor if the pages are ever switched to dynamic rendering or members-only access.
External links (to other sites) should not be changed.
Define your main content areas
Identify the main body of your page, and replace it all with a single tag:
<!--content(body)-->This tells the content management system to substitute the body into that position. It also keeps the body separate from the template itself.
If your page has a complex structure, with more than one content area that can be edited, you can repeat this step for each such area. Give each new area its own name (eg. "sidebar", "footnote", ...).
If you have sections of content that you want to appear on every page, then leave them in place as part of the template.
Edit your meta-data
Meta-data is additional information hidden inside the page, such as titles, descriptions, and so on.
Titles look like this:
<title>Solutions in action</title>Titles can be templated like this:
<title><!--$title--></title>Descriptions look like this:
<meta name="description" content="description of this webpage">Descriptions can be templated like this:
<meta name="description" content="<!--$description-->">Similarly, you can substitute meta-data anywhere into your page, using the <!--$meta--> tags. meta can be one of:
- title
- description
- keywords
- filename
- label [the menu label used for this page]
- mtime [last modification time of the meta-data, timestamp format]
- page_id [a numeric identifier for the page]
- site_title
- site_description
Save your updated page object
After making your changes, click "Next" and then enter a comment such as "added templating tags", for auditing purposes.
You can always return to updating the page object to refine, fix, or add new templating instructions. To do this, repeat steps 5-9.
Import your external files
For each external content file templated in step 6, you must import the file into the content management system. The easiest way to do this if you have multiple files, is to use the Page > Bulk import menu function from the page view. This allows you to upload up to 10 files at a time. Use the selector at the top to determine whether the content is "editorial" or "design" content. (For templates, "design" is usually the correct choice.) All bulk uploaded files will be named and referenced by their original file name.
If you want more detailed control over the naming and configuration of particular content items, then you can upload them individually using the Page > New Content Item menu option. This allows you to customize the naming and access control details of each content item:
- from the template screen (where you see the page icon), select from the menu Page → new content item.
- give each content item a name that is the same as the filename (or whatever name you specified in step 6).
- most imported content files in templates are "design" content, unless you want regular site editors to be able to modify these files.
- optionally, specify the allowed content types for this content item (eg. image). Leave this blank to allow any content.
- Upload the external file on the next screen. Upload the files from wherever you saved them in step 1.
- Include a brief comment (eg. "import") after each update, or accept the default comment.
After you have imported your external files, try previewing your template. From the page menu, select View → preview. Your template should display like a normal web page, except with no core content. If you see that some images or other items are missing or misformatted, you can return to any of the above steps to correct those problems.
An example of converting a regular page to a template is given at the end of this document.
Using Your New Template
When you create a new page in the Website Editor, you will be prompted to select the template to base the new page on. Select your new template on this screen.
In the Website Editor page view for the page, select Template > Change Template. Select your new template for this page here. Republish the page to make the change public.
In the Website Editor website view for the page, select Template > Change for All Pages. Select your new template for this page here. Republish the page to make the change public.
In the Website Editor website view, select Website > Configure Site. Select the default template for this website near the bottom of this form.
Experts only: when creating new pages, the Website Editor allows you to customize the layout for that page only. This is done by unchecking the "Skip Customize Layout step" box on the template selection screen. This has the effect of copying the template's page object into the new page, with the option to edit it. This effectively lets you customize or tweak the design/layout for this page only. If you want to have an altered layout that is re-useable, you need to create a derived template that can be shared. If the default layout of the template is acceptable, leave this box checked.
Although templates are models of pages, and not real pages, it is a good idea to publish them anyway. That is because templates typically incorporate numerous auxiliary files such as images, scripts, and stylesheets, and it can be a serious performance drag to fetch these files out of the content management system's database on every view. It is much better to publish them out to regular files, which not only means they are fetched faster by the webserver, but they work better with most web caching systems that will recognize them as simple cacheable files.
Publish a template in the same way you publish regular pages, ie. by selecting the publish template option from the template menu, or by publishing the entire site. Template files are published into the htdocs area of the website, in a folder named _Templates/[template_name]/.
The HTML for the template will also be published, if the template is set to publish statically. More information on this feature is given under Precompiled Templates.
This section includes more detailed information on templating, to help you template more effectively, and use more advanced templating features.
The vast majority of pages consist of the overall page (which incorporates the site design), which contains a body area that holds the primary content. The page is sometimes called a "wrapper" since it wraps around the body. ![]() |
While the body is often just a block of simple HTML, the wrapper typically contains other distinct content items, such as logos, banners, menus, and so on: ![]() |
Some content items do not result in visual "objects" on the page. Examples include stylesheets and scripts that are included in your page: ![]() |
Some pages do not have a simple wrapper+body structure. Such pages may contain multiple areas that can all contain their own unique content. A simple example is multi-column layout where auxiliary content is included in a sidebar area: ![]() |
Many page elements are obviously distinct content objects. Images, for instance, are stored in separate files, so it makes perfect sense to treat them as separate content elements. Stylesheets and scripts are often kept in separate files as well.
Many content elements are not so clearly separated, however. The body is the most obvious example, since it is normally written right into the same HTML file that holds the design framework of the page. You will need to identify exactly where the body begins and ends, in order make it "swappable". Other swappable page elements will have to be handled in the same way, at your discretion. Stylesheets and Javascript are often written right into the page itself, rather than being stored in separate files. It is a matter of personal judgement whether you want to leave these as an integral part of the page element, or if you want to extract them so that they can be managed separately (which allows them to be shared with other templates, or managed/updated by other groups of people).
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.)
For example, a typical page structure begins with an overall framework and layout in the page object, with most of the page-specific content placed into a body object. Because the page object determines basic layout, it is usually flagged as a design object. The body typically provides the readable content for the webpage, and is flagged as editorial. In addition, there may be other auxiliary images and files:
This shows that you have four separate content items to manage:
* but not necessarily. For instance, if you want the logo to be customizable on each page, it would make sense to give editors some control over it. If the logo is a fixed image that should stay the same everywhere, then it is probably design content.
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).
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:
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 dervied 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.
Content overloading is the technique of redefining a content object to over-ride the definition that would otherwise be provided by a template. As described above, 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).
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.
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:
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.
A standard page is a page that references a body content item. This is a common template format, so ExSite includes some additional features for body management:
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.
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.
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>
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:
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 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. More information is given in the Web Application Developers' Guide.
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:
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.
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.
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:
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 othe without ever needing to interact directly at a software level.
Here is an example of creating a template from a real web page. The example web page includes many embedded images, a stylesheet, and inlined Javascript, so it is a fairly representative example of a modern web design. The sections that were altered in the templating process are color-coded, so match up the colored sections to see how various elements of the page were templated.
Example Page | Template |
---|---|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>Exware Solutions in Action</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <link href="exware_files/exware.css" rel="stylesheet" type="text/css"> <script language="JavaScript" type="text/JavaScript"> <!-- function MM_swapImgRestore() { //v3.0 var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc; } function MM_preloadImages() { //v3.0 var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array(); var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++) if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}} } function MM_findObj(n, d) { //v4.01 var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) { d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);} if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n]; for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document); if(!x && d.getElementById) x=d.getElementById(n); return x; } function MM_swapImage() { //v3.0 var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3) if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];} } //--> </script> <script language="JavaScript" type="text/JavaScript"> <!-- function MM_reloadPage(init) { //reloads the window if Nav4 resized if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) { document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; onresize=MM_reloadPage; }} else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload(); } MM_reloadPage(true); //--> </script></head> <body leftmargin="0" topmargin="3" marginwidth="0" marginheight="0" onload="MM_preloadImages('images/home_alt.gif','images/prodserv_alt.gif', 'images/solutions_alt.gif','images/news_alt.gif','images/partners_alt.gif','images/careers_alt.gif', 'images/about_alt.gif','images/contact_alt.gif')"> <!-- Begin NavBar Slices --> <table width="660" border="0" cellpadding="0" cellspacing="0" align="center"> <tbody><tr> <td colspan="4" align="left" valign="top"> <img src="exware_files/topbluebar.gif" width="218" height="42" alt=""></td> <td colspan="3" align="left" valign="top"> <img src="exware_files/exwarelogo.gif" width="170" height="42" alt=""></td> <td colspan="2" align="left" valign="top"> <img src="exware_files/ex-logo.gif" width="42" height="42" alt=""></td> <td colspan="4" align="left" valign="top"> <img src="exware_files/topgoldbar.gif" width="230" height="42" alt=""></td> </tr> <tr> <td colspan="13" align="left" valign="top"> <img src="exware_files/whitespace.gif" width="660" height="10" alt=""></td> </tr> <tr> <td align="left" valign="top"> <img src="exware_files/leftgold.gif" alt="" width="18" height="15" border="0"></td> <td align="left" valign="top"> <a href="http://www.exware.com/index.html" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('home','','images/home_alt.gif',1)"> <img src="exware_files/home.gif" alt="Home" name="home" width="36" height="15" border="0"></a></td> <td align="left" valign="top"> <a href="http://www.exware.com/prod&serv.html" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('prodserv','','images/prodserv_alt.gif',1)"> <img src="exware_files/prodserv.gif" alt="Products & Services" name="prodserv" width="130" height="15" border="0"></a></td> <td colspan="2" align="left" valign="top"> <a href="http://www.exware.com/solutions.html" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('solutions','','images/solutions_alt.gif',1)"> <img src="exware_files/solutions_alt.gif" alt="Solutions in Action" name="solutions" width="122" height="15" border="0"></a></td> <td align="left" valign="top"> <a href="http://www.exware.com/news.html" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('news','','images/news_alt.gif',1)"> <img src="exware_files/news.gif" alt="News" name="news" width="45" height="15" border="0"></a></td> <td colspan="2" align="left" valign="top"> <a href="http://www.exware.com/partners.html" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('partners','','images/partners_alt.gif',1)"> <img src="exware_files/partners.gif" alt="Partners" name="partners" width="67" height="15" border="0"></a></td> <td colspan="2" align="left" valign="top"> <a href="http://www.exware.com/careers.html" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('careers','','images/careers_alt.gif',1)"> <img src="exware_files/careers.gif" alt="Careers" name="careers" width="61" height="15" border="0"></a></td> <td align="left" valign="top"> <a href="http://www.exware.com/about.html" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('aboutus','','images/about_alt.gif',1)"> <img src="exware_files/about.gif" alt="About us" name="aboutus" width="93" height="15" border="0"></a></td> <td align="left" valign="top"> <a href="http://www.exware.com/contact.html" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('contact','','images/contact_alt.gif',1)"> <img src="exware_files/contact.gif" alt="Contact Us" name="contact" width="71" height="15" border="0"></a></td> <td align="left" valign="top"> <img src="exware_files/rightgold.gif" width="17" height="15" alt=""></td> </tr> <tr> <td> <img src="exware_files/spacer.gif" width="18" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="36" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="130" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="34" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="88" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="45" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="37" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="30" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="12" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="49" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="93" height="1" alt=""></td> <td> <img src="exware_files/spacer.gif" width="71" height="10" alt=""></td> <td> <img src="exware_files/spacer.gif" width="17" height="10" alt=""></td> </tr> </tbody></table> <!-- End NavBar Slices --> <table WIDTH=660 BORDER=0 CELLPADDING=0 CELLSPACING=0 align="center"> <tr><td> <p class="header">Association Management</p> <p class="exware">A turnkey web solution for Associations and Non-Profits that incorporates the latest web productivity tools: content management, email & list management, event management, calendar & scheduling tools, member management, and much more! <br><br> </p><p class="exware"> This solution allows you to: </p><ul class="exware"> <li>attract & manage members </li> <li>streamline internal & external communications</li> <li>manage, promote & schedule events</li> <li>maintain & update their website (without having to know HTML!)</li> </ul> </div><p class="exware"> <p class="exware">Need more information? <br> Contact us today at <strong>604-684-9440</strong> or <a href="mailto:info@exware.com"><em>info@exware.com</em></a>.</p> <p class="exware"><a href="#top">top</a></p> <p class="exware"></p> </td> </tr> </tbody></table> </body></html> |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title><!--$title--></title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <link href=[[exware.css]] rel="stylesheet" type="text/css"> <!--content(rollover-script)--> </head> <body leftmargin="0" topmargin="3" marginwidth="0" marginheight="0" onLoad="MM_preloadImages('[[home_alt.gif]]','[[prodserv_alt.gif]]','[[solutions_alt.gif]]', '[[news_alt.gif]]','[[partners_alt.gif]]','[[careers_alt.gif]]','[[about_alt.gif]]','[[contact_alt.gif]]')"> <!-- Begin NavBar Slices --> <table WIDTH=660 BORDER=0 CELLPADDING=0 CELLSPACING=0 align="center"> <tr> <td COLSPAN=4 ALIGN=left VALIGN=top> <img SRC="[[topbluebar.gif]]" ALT="" WIDTH=218 HEIGHT=42 border="0"></td> <td COLSPAN=3 ALIGN=left VALIGN=top> <img SRC="[[exwarelogo.gif]]" ALT="" WIDTH=170 HEIGHT=42 border="0"></td> <td COLSPAN=2 ALIGN=left VALIGN=top> <img SRC="[[ex-logo.gif]]" ALT="" WIDTH=42 HEIGHT=42 border="0"></td> <td COLSPAN=4 ALIGN=left VALIGN=top> <img SRC="[[topgoldbar.gif]]" ALT="grid graphic" WIDTH=230 HEIGHT=42 border="0"></td> </tr> <tr> <td COLSPAN=13 ALIGN=left VALIGN=top> <img SRC="[[whitespace.gif]]" WIDTH=660 HEIGHT=10 ALT=""></td> </tr> <tr> <td ALIGN=left VALIGN=top> <img SRC="[[leftgold.gif]]" ALT="" WIDTH=18 HEIGHT=15 border="0"></td> <td ALIGN=left VALIGN=top> <a href="index.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('home','','[[home_alt.gif]]',1)"> <img src="[[home.gif]]" alt="Home" name="home" width="36" height="15" border="0"></a></td> <td ALIGN=left VALIGN=top> <a href="prod_serv.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('prodserv','','[[prodserv_alt.gif]]',1)"> <img src="[[prodserv.gif]]" alt="Products & Services" name="prodserv" width="130" height="15" border="0"></a></td> <td COLSPAN=2 ALIGN=left VALIGN=top> <a href="solutions.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('solutions','','[[solutions_alt.gif]]',1)"> <img src="[[solutions.gif]]" alt="Solutions in Action" name="solutions" width="122" height="15" border="0"></a></td> <td ALIGN=left VALIGN=top> <a href="news.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('news','','[[news_alt.gif]]',1)"> <img src="[[news.gif]]" alt="News" name="news" width="45" height="15" border="0"></a></td> <td COLSPAN=2 ALIGN=left VALIGN=top> <a href="partners.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('partners','','[[partners_alt.gif]]',1)"> <img src="[[partners.gif]]" alt="Partners" name="partners" width="67" height="15" border="0"></a></td> <td COLSPAN=2 ALIGN=left VALIGN=top> <a href="careers.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('careers','','[[careers_alt.gif]]',1)"> <img src="[[careers.gif]]" alt="Careers" name="careers" width="61" height="15" border="0"></a></td> <td ALIGN=left VALIGN=top> <a href="about.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('aboutus','','[[about_alt.gif]]',1)"> <img src="[[about.gif]]" alt="About us" name="aboutus" width="93" height="15" border="0"></a></td> <td ALIGN=left VALIGN=top> <a href="contact.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('contact','','[[contact_alt.gif]]',1)"> <img src="[[contact.gif]]" alt="Contact Us" name="contact" width="71" height="15" border="0"></a></td> <td ALIGN=left VALIGN=top> <img SRC="[[rightgold.gif]]" WIDTH=17 HEIGHT=15 ALT=""></td> </tr> <tr> <td> <img SRC="[[spacer.gif]]" WIDTH=18 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=36 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=130 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=34 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=88 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=45 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=37 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=30 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=12 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=49 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=93 HEIGHT=1 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=71 HEIGHT=10 ALT=""></td> <td> <img SRC="[[spacer.gif]]" WIDTH=17 HEIGHT=10 ALT=""></td> </tr> </table> <!-- End NavBar Slices --> <table WIDTH=660 BORDER=0 CELLPADDING=0 CELLSPACING=0 align="center"> <tr><td> <!--content(body)--> </td></tr> </table> </body> </html> |