There are three ways that you can affect the appearance or output of a
Big Medium widget:
- Change preference settings under the "Settings" menu. Many widgets
offer configuration options that affect their appearance in pages.
- Add custom CSS styles to modify the appearance of the widget's output.
You can do this by adding CSS style entries to the theme style sheet
("Layout>Edit Theme Style Sheet" in the control panel menu) or style editor
("Styles" in the control panel menu).
- Customize the actual HTML markup of the widget.
This tutorial addresses the third option, allowing you to create your own
custom widget markup for any Big Medium widget. This tutorial requires
basic to intermediate knowledge of HTML and FTP access to the server
where Big Medium is installed.
Location of Widget Templates
Big Medium 2.0 uses template files to define the generated markup for each
widget. These files are located in the moxiedata directory on your server,
in this directory:
moxiedata/templates/site_templates/HTML
Widget template files start with wi_ then the name of the widget, then
.tmpl (e.g., wi_htmlhead.tmpl, wi_headline.tmpl, etc).
You can override these templates by adding your own custom templates into
the moxiedata/templates_custom directory -- specifically here:
moxiedata/templates_custom/site_templates/HTML
It's recommended to add custom templates to this templates_custom directory
instead of editing the original templates in the templates directory.
Changes that you make to the originals could get clobbered when you update
to a new version, but files in the templates_custom directory will remain
untouched by updates. This provides an easy way to hack and customize
Big Medium without having to go back and redo the changes every time you
update your Big Medium installation.
Example: Customizing the <%related%> Widget
Say that you want to change the <%related%> widget to display in a dropdown
menu instead of an unordered list. Here's how you would do it.
In a text editor, open the default template file for <%related%>:
moxiedata/templates/site_templates/HTML/wi_related.tmpl
The contents look like this:
<!-- start <%related%> -->
<div class="bmc_related">
<TMPL_IF NAME=HEADING><h3><TMPL_VAR NAME=HEADING></h3></TMPL_IF>
<ul><TMPL_LOOP NAME=LINKS>
<li><a href="<TMPL_VAR NAME=URL>"<TMPL_IF NAME=NEW_WINDOW>
onclick="BM.newWin(this);return false;" target="newsite"
</TMPL_IF>><TMPL_VAR NAME=TITLE></a></li>
</TMPL_LOOP></ul>
</div>
<!-- end <%related%> -->
You can see that it's a mix of HTML tags and some upper-case tags that
start with TMPL_. The latter are template tags, and we'll get to those
later. For now, it's enough to know that these are placeholders for
content and template commands. The output of this widget normally looks
like this:
<!-- start <%related%> -->
<div class="bmc_related">
<h3>Related Links</h3>
<ul>
<li><a href="http://www.example.com/">Example link 1</a></li>
<li><a href="http://www.example2.com/">Example link 2</a></li>
<li><a href="http://www.example3.com/">Example link 3</a></li>
</ul>
</div>
<!-- end <%related%> -->
...and let's say that we want to change it to look like this, a form
with a single <select> element that jumps to a new page when a "Go"
button is clicked:
<!-- start <%related%> -->
<div class="bmc_related">
<form action="" onsubmit="var list=this.RelatedSelect;
var href=list.options[list.selectedIndex].value;
if (href) document.location.href=href;
return false;">
<select id="RelatedSelect" name="RelatedSelect">
<option value="">
Related Links
</option>
<option value="http://www.example.com/">
Example link 1
</option>
<option value="http://www.example2.com/">
Example link 2
</option>
<option value="http://www.example3.com/">
Example link 3
</option>
</select>
<input type="submit" value="Go" />
</form>
</div>
<!-- end <%related%> -->
What we really want to do here is wrap a <form> and <select>
tag around the link options in the same way that the original templates
wrapped a <ul> around the link list items. In the big picture,
the template looks like this:
<!-- start <%related%> -->
<div class="bmc_related">
<form action="" onsubmit="var list=this.RelatedSelect;
var href=list.options[list.selectedIndex].value;
if (href) document.location.href=href;
return false;">
<select id="RelatedSelect" name="RelatedSelect">
OPTIONS GO HERE
</select>
<input type="submit" value="Go" />
</form>
</div>
<!-- end <%related%> -->
Where we've put "OPTIONS GO HERE" is where we want the template to do
its magic, inserting the links (as well as the "Related Links" header
if one is specified) into the select menu. Looking at the original
template, we see that this is how it's done to create the list items:
<ul><TMPL_LOOP NAME=LINKS>
<li><a href="<TMPL_VAR NAME=URL>"<TMPL_IF NAME=NEW_WINDOW>
onclick="BM.newWin(this);return false;" target="newsite"
</TMPL_IF>><TMPL_VAR NAME=TITLE></a></li>
</TMPL_LOOP></ul>
...and it's not much of a leap to see how we might change this to generate
<option> tags instead of <li> tags:
<TMPL_LOOP NAME=LINKS>
<option value="<TMPL_VAR NAME=URL>">
<TMPL_VAR NAME=TITLE>
</option>
</TMPL_LOOP>
And then we can just add the "Related Links" header above this loop like
so:
<TMPL_IF NAME=HEADING>
<option value=""><TMPL_VAR NAME=HEADING></option>
</TMPL_IF>
<TMPL_LOOP NAME=LINKS>
<option value="<TMPL_VAR NAME=URL>">
<TMPL_VAR NAME=TITLE>
</option>
</TMPL_LOOP>
Plugging this into our big-picture template, we get this final result:
<!-- start <%related%> -->
<div class="bmc_related">
<form action="" onsubmit="var list=this.RelatedSelect;
var href=list.options[list.selectedIndex].value;
if (href) document.location.href=href;
return false;">
<select id="RelatedSelect" name="RelatedSelect">
<TMPL_IF NAME=HEADING>
<option value=""><TMPL_VAR NAME=HEADING></option>
</TMPL_IF>
<TMPL_LOOP NAME=LINKS>
<option value="<TMPL_VAR NAME=URL>">
<TMPL_VAR NAME=TITLE>
</option>
</TMPL_LOOP>
</select>
<input type="submit" value="Go" />
</form>
</div>
<!-- end <%related%> -->
All that remains is to upload our custom template to the server. As
described above, we'll put it into the templates_custom directory,
instead of replacing the original template. If this is your first
template customization, then you probably need to create the HTML
directory at this location:
moxiedata/templates_custom/site_templates/HTML
...and then place the custom template file here:
moxiedata/templates_custom/site_templates/HTML/wi_related.tmpl
And that's it, you're done! When you rebuild pages at the site,
you'll find that the <%related%> widget is now generating a dropdown
menu of related links instead of displaying an ordered list.
Template Syntax
As you no doubt noticed in the example above, template files consist of a
mix of HTML tags and template tags. Template tags are typically uppercase
and always start with TMPL_. These templates follow the syntax of the
HTML::Template Perl module. For all the gorey details, you can check out
the HTML::Template documentation at CPAN, but here
is an explanation of the most common tags:
<TMPL_VAR NAME=FOOBAR>
This is a placeholder for a content variable. The name attribute indicates
which variable the tag represents. In our <%related%> example, the
"HEADING" variable represented the "Related Links" header, the "URL"
variable represented the URL of each link, and the "TITLE" variable
represented the text of each link.
<TMPL_IF NAME=FOOBAR> ... </TMPL_IF>
If the variable named by the name attribute is a true value, then the
HTML between the tags will be generated. If not, it will be omitted.
In our <%related%> example, the "HEADING" variable is included in the
display only if it exists. (The HTML preferences for this widget allows
you to clear the heading, so we only include it if it's not empty).
<TMPL_LOOP NAME=FOOBAR> ... </TMPL_LOOP>
Some templates are provided with one or more named lists of data. The
TMPL_LOOP tag steps through each of the items in the list named in the
name attribute. In our <%related%> example, this is how we displayed each
of the links in the list, displaying the "URL" and "TITLE" variable
for each item in the loop.