Using Parameters & Expressions to make a Breadcrumb Trail within a Template Driven site

How many times have you wanted to have a visible trail through the folder architecture of your web site for easy navigation to a previous area (much like the Macromedia site and others)? It is an easily understood and instantaneous 'roadmap' of where you are in the current site, and how to get back the way you came in, and is a particularly effective tool in a complex network of files and navigation links.

There are many ways to implement this nice little feature but doing so in a template controlled environment can prove challenging.

What types of solutions are available?

There are several types of solutions available for your use: some are server-side, some use javascript routines to calculate the current position, and others are hand made on each and every page (YIKES!).

While we recommend that you use a javascript routine or a server-side solution, we were asked by a template enthusiast (Chuck Parish) how to troubleshoot some issues that he was having with templates, parameters, mouse-over events to change the browser status bar and the breadcrumb trail.  Our solution, although nowhere near what Chuck had originally asked is a fine solution that works well for him and may for others.

We've thought long and hard how we could write this as a tutorial and have come to the conclusion that it would be better for us to provide a downloadable sample site for you to peruse so that we can discuss what we have done rather than provide a 15 page tutorial.  With that said, please follow these directions...

  1. Download Breadcrumbs.zip
  2. Open your file management software (Windows Explorer or Mac Finder) and create a new folder somewhere on your local hard drive. The download is a zip containing files and folders. So, when you extract these files, make sure you do so ensuring that you retain folder structure. Extract the download into the new folder you created above in step 2.
  3. Start Dreamweaver MX and create a new site definition (using the Site > New Site... menu item).  Set the local root path to the folder named Breadcrumbs, that is in the folder that you created in step 2. Name this site whatever you want!
  4. Open the template named: woohoo.dwt; ugh.dwt and drat.fwt located in the Templates folder. This is the template that we created the trail navigation block in.  The preferred method of viewing this file is using Standard View (NOT Layout View) with Code & Design View (Split-screen) so that you can see what is going on in code view.
  5. Open the child page named: folder1/folder2/page2.html. This is a child page based off of the template named woohoo.dwt to show the functionality and control of the crumb trail using template parameters and expressions.
  6. Leave all the files open so that you can easily switch between them as we run through the description below of what was done and why.

What was done and why...

The objective of this exercise (as explained to us by Chuck) was to provide a template solution for a breadcrumb trail system using DMX's expressions and parameters.  The breadcrumb trail was to show the path by which the user arrived on any given page in the tree structure, to have these path items hyper linked, and when moused over, to change the status bar message of the browser instead of showing a url.  The current page was not to be linked but a next and previous page navigation method was also desired. The template parameter was to be easily controlled through the Modify > Template Properties... dialog. Sounds simple, right?

Attempt 1 (100% Failed!):

Make a unique parameter in the template that would contain the whole string for the breadcrumb trail. Then, on each child page, modify the parameter value using the Modify > Template Properties... dialog to show a new string or bread crumb trail for each page in the site.

Sample code for attempt 1
(Using ugh.dwt & ugh-Index.html):

<!-- TemplateParam
     name="trailsegment"
     type="text"
     value="<a href=&quot;page1.html&quot; onMouseOver=&quot;window.status=&#39;Return to Page 1 of How to find God.&#39;;return true&quot; onMouseOut=&quot;window.status=&#39;&#39;;return true&quot;>Page 2</a><span class=&quot;navcrumbstitle&quot;>&gt; </span>"
-->

The issues found: This methodology was abandoned due to the fact that the string was complex in nature as related to double and single quotations.  Although a workaround could be provided, the Modify > Template Properties... menu item and DMX's UI would not read or manage the current parameters value. In other words, it was an impending train wreck from a maintenance point of view!  This in turn caused an issue where if you changed the parameter value in code view, the change would not propagate on the child page(s) until the Modify > Template Properties... was opened and closed to force the Template engine to run and update the parameter value used on the page from that set manually in the head. (eek)

The second attempt (75% Passed! 25% Failed!):

Separate the modifiable content of the string into unique parameters.

Sample code for attempt 2
(Using drat.dwt & drat-Index.html) :

Head Region:

<!-- TemplateParam name="Displayroot" type="boolean" value="true" -->
<!-- TemplateParam name="Nameroot" type="text" value="Home" -->
<!-- TemplateParam name="URLroot" type="text" value="index.html" -->
<!-- TemplateParam name="Statusroot" type="text" value="Return to our Home Page" -->
<!-- TemplateParam name="Displaylvl1" type="boolean" value="true" -->
<!-- TemplateParam name="Namelvl1" type="text" value="Folder Level 1" -->
<!-- TemplateParam name="URLlvl1" type="text" value="folder1/index.html" -->
<!-- TemplateParam name="Statuslvl1" type="text" value="Go to Folder 1 [root]" -->
<!-- TemplateParam name="Displaylvl2" type="boolean" value="true" -->
<!-- TemplateParam name="Namelvl2" type="text" value="Folder Level 2" -->
<!-- TemplateParam name="URLlvl2" type="text" value="folder2/index.html" -->
<!-- TemplateParam name="Statuslvl2" type="text" value="Go to Folder 2 [root]" -->
<!-- TemplateParam name="Displaylvl3" type="boolean" value="true" -->
<!-- TemplateParam name="Namelvl3" type="text" value="Folder Level 3" -->
<!-- TemplateParam name="URLlvl3" type="text" value="folder3/index.html" -->
<!-- TemplateParam name="Statuslvl3" type="text" value="Go to Folder 3 [root]" -->
<!-- TemplateParam name="Displayprev" type="boolean" value="true" -->
<!-- TemplateParam name="Nameprev" type="text" value="Previous Page" -->
<!-- TemplateParam name="URLprev" type="text" value="page2.html" -->
<!-- TemplateParam name="Statusprev" type="text" value="Back to Page 2" -->
<!-- TemplateParam name="Displaynext" type="boolean" value="true" -->
<!-- TemplateParam name="Namenext" type="text" value="Next Page" -->
<!-- TemplateParam name="URLnext" type="text" value="page4.html" -->
<!-- TemplateParam name="Statusnext" type="text" value="Forward to Page 4" -->
<!-- TemplateParam name="Namecurr" type="text" value="Page 3" -->

Body Region:

<span class="trail">You are here: <!-- TemplateBeginIf cond="Displayroot" --><a href="@@(URLroot)@@" onMouseOver="window.status='@@(Statusroot)@@';return true;" onMouseOut="window.status='';return true;">@@(Nameroot)@@</a><!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="Displaylvl1" --> > <a href="@@(URLlvl1)@@" onMouseOver="window.status='@@(Statuslvl1)@@';return true;" onMouseOut="window.status='';return true;">@@(Namelvl1)@@</a><!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="Displaylvl2" --> > <a href="@@(URLlvl2)@@" onMouseOver="window.status='@@(Statuslvl2)@@';return true;" onMouseOut="window.status='';return true;">@@(Namelvl2)@@</a><!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="Displaylvl3" --> > <a href="@@(URLlvl3)@@" onMouseOver="window.status='@@(Statuslvl3)@@';return true;" onMouseOut="window.status='';return true;">@@(Namelvl3)@@</a><!-- TemplateEndIf -->
> @@(Namecurr)@@
<!-- TemplateBeginIf cond="Displayprev" --> : <a href="@@(URLprev)@@" onMouseOver="window.status='@@(Statusprev)@@';return true;" onMouseOut="window.status='';return true;">@@(Nameprev)@@</a><!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="Displaynext" --> : <a href="@@(URLnext)@@" onMouseOver="window.status='@@(Statusnext)@@';return true;" onMouseOut="window.status='';return true;">@@(Namenext)@@</a><!-- TemplateEndIf --></span>

The issues found: This methodology was almost there, but we were missing the ability to customize the separator markers for the trail as well as the next/previous selections. We were also forced to show those separators which doesn't give us much flexibility, but will do in a pinch.

The final attempt (100% Passed!):

Now, we want the ability to customize a unique trail separator, next/prev separator, and trail message.  We also want the ability to programmatically only display the separator(s) if the previous segment of the trail is displayed thereby preventing display of multiple separators.

Sample code for the final attempt
(Using the remainder of the files including woohoo.dwt) :

Head Region:

<!-- TemplateParam name="Displayintro" type="boolean" value="true" -->
<!-- TemplateParam name="Nameintro" type="text" value="You are here: " -->
<!-- TemplateParam name="BCTrailMarker" type="text" value="&amp;raquo;" -->
<!-- TemplateParam name="PrevNextMarker" type="text" value="&amp;laquo;" -->
<!-- TemplateParam name="Displayroot" type="boolean" value="true" -->
<!-- TemplateParam name="Nameroot" type="text" value="Home" -->
<!-- TemplateParam name="URLroot" type="URL" value="index.html" -->
<!-- TemplateParam name="Statusroot" type="text" value="Return to our Home Page" -->
<!-- TemplateParam name="Displaylvl1" type="boolean" value="true" -->
<!-- TemplateParam name="Namelvl1" type="text" value="Folder Level 1" -->
<!-- TemplateParam name="URLlvl1" type="URL" value="folder1/index.html" -->
<!-- TemplateParam name="Statuslvl1" type="text" value="Go to Folder 1 [root]" -->
<!-- TemplateParam name="Displaylvl2" type="boolean" value="true" -->
<!-- TemplateParam name="Namelvl2" type="text" value="Folder Level 2" -->
<!-- TemplateParam name="URLlvl2" type="URL" value="folder2/index.html" -->
<!-- TemplateParam name="Statuslvl2" type="text" value="Go to Folder 2 [root]" -->
<!-- TemplateParam name="Displaylvl3" type="boolean" value="true" -->
<!-- TemplateParam name="Namelvl3" type="text" value="Folder Level 3" -->
<!-- TemplateParam name="URLlvl3" type="URL" value="folder3/index.html" -->
<!-- TemplateParam name="Statuslvl3" type="text" value="Go to Folder 3 [root]" -->
<!-- TemplateParam name="Displayprev" type="boolean" value="true" -->
<!-- TemplateParam name="Nameprev" type="text" value="Previous Page" -->
<!-- TemplateParam name="URLprev" type="URL" value="page2.html" -->
<!-- TemplateParam name="Statusprev" type="text" value="Back to Page 2" -->
<!-- TemplateParam name="Displaynext" type="boolean" value="true" -->
<!-- TemplateParam name="Namenext" type="text" value="Next Page" -->
<!-- TemplateParam name="URLnext" type="URL" value="page4.html" -->
<!-- TemplateParam name="Statusnext" type="text" value="Forward to Page 4" -->
<!-- TemplateParam name="Namecurr" type="text" value="Page 3" -->

Body Region:

<span class="trail"><!-- TemplateBeginIf cond="(Displayintro==true)" --> @@(Nameintro)@@ <!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="Displayroot" --><a href="@@(URLroot)@@" onMouseOver="window.status='@@(Statusroot)@@';return true;" onMouseOut="window.status='';return true;">@@(Nameroot)@@</a><!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="(Displayroot==true)" --> @@(BCTrailMarker)@@ <!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="Displaylvl1" --> <a href="@@(URLlvl1)@@" onMouseOver="window.status='@@(Statuslvl1)@@';return true;" onMouseOut="window.status='';return true;">@@(Namelvl1)@@</a><!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="(Displaylvl1==true)" --> @@(BCTrailMarker)@@ <!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="Displaylvl2" --> <a href="@@(URLlvl2)@@" onMouseOver="window.status='@@(Statuslvl2)@@';return true;" onMouseOut="window.status='';return true;">@@(Namelvl2)@@</a><!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="(Displaylvl2==true)" --> @@(BCTrailMarker)@@ <!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="Displaylvl3" --> <a href="@@(URLlvl3)@@" onMouseOver="window.status='@@(Statuslvl3)@@';return true;" onMouseOut="window.status='';return true;">@@(Namelvl3)@@</a><!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="(Displaylvl3==true)" --> @@(BCTrailMarker)@@ <!-- TemplateEndIf -->
@@(Namecurr)@@
<!-- TemplateBeginIf cond="(Displayprev==true)" --> @@(PrevNextMarker)@@ <!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="Displayprev" --> <a href="@@(URLprev)@@" onMouseOver="window.status='@@(Statusprev)@@';return true;" onMouseOut="window.status='';return true;">@@(Nameprev)@@</a><!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="(Displaynext==true)" --> @@(PrevNextMarker)@@ <!-- TemplateEndIf -->
<!-- TemplateBeginIf cond="Displaynext" --> <a href="@@(URLnext)@@" onMouseOver="window.status='@@(Statusnext)@@';return true;" onMouseOut="window.status='';return true;">@@(Namenext)@@</a><!-- TemplateEndIf --></span>

The Parameters Explained:

Parameter Name — Type —  Function List

Name

Type

Function

Displayintro

B

Set visibility of the custom Trail message (T/F)

Nameintro

T

Customizable Trail message

BCTrailMarker

T

Customizable Trail separator

PrevNextMarker

T

Customizable Current/Previous/Next separator

Displayroot

B

Set visibility of the root level (T/F)

Nameroot

T

Customizable root text

URLroot

U

Customizable root url (from current position)

Statusroot

T

Customizable Status bar message

Displaylvl1 (through 3)

B

Set visibility of sub-levels 1 through 3 (T/F)

Namelvl1 (through 3)

T

Customizable sub-levels 1 through 3 text

URLlvl1 (through 3)

U

Customizable sub-levels 1 through 3 url (from current position)

Statuslvl1 (through 3)

T

Customizable Status bar message

Displayprev (next)

B

Set visibility of previous/next link (T/F)

Nameprev (next)

T

Customizable previous/next text

URLprev (next)

U

Customizable previous/next url (from current position)

Statusprev (next)

T

Customizable Status bar message

Namecurr

T

Customizable Current location Text

Table Legend

T — Text

B — Boolean (true/false)

U — URL

All of these items are customizable on the child page built from this template using the Modify > Template Properties... menu item, which allows you total control of your breadcrumb trail on each and every page.

How does it work?

Without the parameters and expressions, our line would look like this (we only look at a single segment of the entire trail here) in the template:
<a href="index.html" onMouseOver="window.status='Return to our Home Page';return true;" onMouseOut="window.status='';return true;">Home</a>
and we would have to put this into an editable region to do any customization to it. As it turns out, the child page (when viewed through the browser) looks identical to this, but our trail is actually in a non-editable area, allowing consistency throughout the site for position and style (you could add a parameter for the style too, but there is no way for the style sheet selections to be available from the Modify Template Properties dialog so we have opted to not have it as a parameter and let the template control it, where we can see and use the style selector with ease).

The Pitfalls:

Because this is a home-grown breadcrumb trail method, you will have to customize each of these parameters after you initially save the child page.  Once customized though, moving the files to other locations in your site's architecture will be maintained because we used the URL parameter type for the URL* parameters.  Cool huh!?!

In addition, because of the interplay among these parameters, and the effect of that on the final resulting code in the child page, it would be possible to get things a little wonky by an uncoordinated adjustment of these parameters! Just make sure you know what you are modifying and why!

Modifications you can make:

There are several enhancements that you can make to this trail exercise, some of which have caveats if you apply them to a site already containing the crumb trail as outlined.

  1. Change the template Name* parameter values to something descriptive so that when the Modify > Template Properties... dialog is run, there is content in the parameters that is discernable to the template user.
  2. As an alternative to Modification #1, add a new optional region containing a layer that houses the instructions for the crumb trail parameters. (This method is preferred, for some, over modification 1 above.)
    WARNING: If you add this after the fact in an existing site, be sure to set the parameter for the optional region to false prior to updating the site.  If you do not, then this layer will be visible on every existing page based on the template.  Ugly at best and requires manual modification of each instance page using the Modify > Template Properties... dialog. Once the site is updated, feel free to modify the template parameter to be true so that any new pages created from the template display the instructions layer.
  3. Add the Namecurr expression to the template's title tag so that you don't have to remember to update the title of the document as it will be based on the value of the Namecurr parameter.
  4. Add or remove folder levels as required.  If adding folder levels, be sure to keep the same naming scheme for the template parameters in the head section and the regions in the body section where the crumb trail resides. Don't forget to modify the expressions that display the trail separator so that they are relevant to the appropriate folder.
    WARNING: If you add folder levels after the fact in an existing site, be sure to set the parameter for the new folder level(s) to false prior to updating the site.  If you do not, then these newly added folder levels will be visible on every existing page based on the template.  This will require manual modification of each instance page using the Modify > Template Properties... dialog. Once the site is updated, feel free to modify the template parameter to be true (displayed) so that any new pages created from the template display the full possible crumb trail path.

Downloads:

Please download Breadcrumbs.zip to see what we've done.