Best Practices

Slowly, we are working on improving object-oriented design and code/display separation.

Template design:

  • Keep program logic in the program, but move any display logic to the template. Some useful smarty template functions and modifiers include: escape, html_options, html_select_date. Some sf-active specific plugins include: sf_link, media_icon, and a version of html_select_date that optionally doesn't select a date by default.

Configuration variables:

  • Cache variables to disk whenever possible, rather than relying on a live database lookup. Two new methods (of the Cache class) have been created to assist this: cache_var and get_cached_var. To use get_cached_var:
      where before you would write
      include(SF_CACHE_PATH .'/');
      $this->tkeys['blah_options'] = $blah_options;
      you can now write $this->tkeys['blah_options'] = $this->get_cached_var('blah_options') instead.

Designing Forms


  • Make it easy to identify the most important information and have good defaults for everything else. One way to do this is to separate the content entry (i.e., feature text + title) from the metadata entry (template, display date, etc), or even putting the metatadata entry at the side or bottom of the form.
  • If there is a limit on the length that a field can be, include the limit in the form entry widget so text isn't later cut off unexpectedly.
  • Avoid "mystery" links. Instead of including text that says "click on the feature name to edit it", put a clearly labeled edit link next to the feature name. If you have to explain it, it's not clear enough.
  • Simplify entry. If the computer can figure it out automatically (e.g., order number) there's no reason to force the user to input it for you.
  • Give descriptive error messages.


Lots of things appear in lists: articles in the article edit page, features, feature photos, categories, style sheets and templates, etc. They should all look the same for the user so that the user can apply knowledge from one part of the site to another.

  • Use headings on every table, describing what each column is. The header rows should be surrounded by the
  • Use alternating colors on alternating rows (this is easy with Smarty and the Cycle Modifier To make it more consistent, let's use a style definition instead of hardcoding the color in the template.
  • Spacing or borders between rows (we should pick one and be consistent -- borders + colors might be too much, so I'm leaning towards spacing)
  • Put actions in their own links (e.g, edit, make feature, etc) in the same row as the title + other information.


  • ID (if needed -- can be left out in many cases)
  • Name
  • Author (if needed)
  • Description
  • Other fields
  • Order (we should find a javascript reordering widget to hide this further)
  • Actions

I think actions should always go at the end, but it could also work to have them directly below the resource's name. We should decide on this and stick with one approach.

Admin Page Header Markup

the markup for every admin page should be as follows:

  • a container div, marking the beginning of the header. markup: <div id="nav"> ... </div>
  • A headline with the H1 element-- this headline text should be the same as the link in the left navigation bar. E.g., $dict.admin_blah
  • A list which contains the navigation elements. Should be short so it fits on one row (multiple rows will break). The markup is simply a <ul> with the class set to navlist
  • Each list item has the following markup: just a standard <li> tag, with an anchor (A) tag inside.
  • Includes:
    • Current page (with the anchor tag id="current" to make it clear which page is current)
    • Links to related actions, e.g., add a new item, preview page, etc., when they make sense at the current level
  • Does not include:
    • Link to the main admin page
    • More than two or three words per-link

<div id="nav">

<ul class="navlist">
   <li><a id="current">Category List</a></li>
   <li><a href="">Generate archives</a></li>


You can also use the navigation list metaphor when a list or table of elements is grouped into multiple logically-related categories. For example, a feature can be current,hidden, or archived. We use the same styles for the navigation list in the header as we do for the links to current, archived, and hidden features. To do that, use this markup:

<ul class="navlist">
<li>{if $tkeys.status == 'c'}<a id="current">{$dict.current}</a>{else}<a href="feature_display_list.php?status=c">{$dict.current}</a>{/if}</li>
<li>{if $tkeys.status == 'a'}<a id="current">{$dict.archived}</a>{else}<a href="feature_display_list.php?status=a">{$dict.archived}</a>{/if}</li>
<li>{if $tkeys.status == 'h'}<a id="current">{$dict.hidden}</a>{else}<a href="feature_display_list.php?status=h">{$dict.hidden}</a>{/if}</li>

Note that you should always identify the current selection, using the id="current" property of the anchor tag. You can choose whether or not to leave in the href property, but you must use the anchor tag in the current stylesheets.

-- QuintenSteenhuis - 13 Jan 2005
Topic revision: r4 - 06 Mar 2005, QuintenSteenhuis
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback