Using Smarty Templates with the Knowledge Management System

With the lastest version of [Knowledge Management][1] came a huge change in how much flexibility the system gives you to tailor KB to your site’s look and feel. It used to be that the “public” section of KB was a collection of half HTML half PHP pages that were difficult to understand and edit. About the only thing you could do easily was specify a header and footer and change some colors via the master CSS file. Knowledge Management¬† 2.5x now uses the Smarty Template Engine to allow you to completely customize how your KB site looks and how the information is presented.
[1]: http://www.activecampaign.com/kb “Knowledge Management” Software

## Smarty Template Background ##
The Smarty Template Engine ([Smarty][2]) is more of a “presentation framework”, allowing PHP programmers to separate their application’s business logic from the visual display. Smarty accomplishes this by using a light markup language that can be embedded in your HTML to display dynamic data that is generated by the business logic side of your application.

## How we use it ##
A lot of work went into completely separating the logic that manages Categories and Articles in KB from the actual presentation of Categories and Articles. This basically splits the Knowledge Management system into two parts: one part that evaluates the current context (viewing an article, viewing a category, making a comment, subscribing to an article, etc) and fetches the correct data for that context, and one part that displays that raw information. The second part is what is now completely customizable by you.

When any given page loads in the public section of [Knowledge Management][1] (non-admin section that is), the last step in the process is to render the template for that page. Templates for KB live in the `templates` directory, in subdirectories for each *template set*. KB is shipped with three templates: *Default*, *Directory*, and *Simple*. If you are upgrading KB please note that the old KB template directories will not be deleted, but you can tell which ones are the old ones because their directory names start with lowercase letters (if you no longer need these, it’s safe to delete them).

> *Choosing a template:*
> You can choose which template set you want to use in the Admin section under Settings.

*Continue to the next page to learn about how KB’s templating system is structured…*

[1]: http://www.activecampaign.com/kb “Knowledge Management”
[2]: http://smarty.php.net “Smarty”

## KnowledgeBuilder Template Structure ##
When you visit the front page of your [Knowledge Management][1] site you are in the *startup* context. KB loads up the *index.htm* template which in turn (because you’re in the *startup* context) loads *startup.htm* for the internal section. Remember, *index.htm* the the container template for all the pages on your site (with a couple exceptions). This structure can’t be changed, the `index.htm` template is always used first and it is responsible for:

1. Drawing the “frame” of the website
2. Including a *context specific* template, specified in a the [Smarty][2] variable `$content_template`

In the *Default* template set’s `index.htm` line 238 looks like this:
[html num=238]
{ include file=$content_template }

[/html]

Notice the `{ include file=$content_template }`? Thats a [Smarty][2] [*include*][3] statement, the `$content_template` is a variable that holds the name of the content-specific template for whatever context the site is currently in. For example, when viewing an article, `$content_template` has the value `article.htm`, and so line 239 in `index.htm` brings in the contents of the `article.htm` template. Likewise, when looking at a category, the `$content_template` variable has the value `category.htm` and so the contents of the `category.htm` template are brought in. This allows you to maintain a consistant *shell* around the contents of your site.

This structure is about the only one you must keep when designing your own template sets: A central `index.htm` template and various *context specific* templates with the proper names. For reference, here’s a list of the *context* template names:

* category.htm – Used to show the view of a category
* email.htm – Used when emailing an article to someone
* comment.htm – Used when viewing all comments or making a new comment
* article.htm – Used to show a single article
* saved.htm – Used to show/manage your saved articles
* author.htm – Used to view author information about an article
* glossary.htm – Used to show the Glossary terms
* search.htm – Used to show the search page
* similar.htm – Used to show similar articles
* contact.htm – Used to allow the user to ask a question
* login.htm – Used to login for locked content or categories
* startup.htm – Main startup page

*Continue to the next page to get the basics on how to use Smarty markup…*

[1]: http://www.activecampaign.com/kb “Knowledge Management”
[2]: http://smarty.php.net “Smarty”
[3]: http://smarty.php.net/manual/en/language.function.include.php “Smarty Include Function”

## Introduction to Smarty Tags ##
Smarty templates are nothing more than regular HTML with special tags to control the displaying of dynamic data, in our case things like the the article’s title and contents on a Article page, or the listing of sub-categories on a Category page. With that in mind, we’ll dive straight into a small tutorial on the basics of Smarty markup.

### Smarty tags ###
Smarty tags are enclosed in `{ }` characters. Anything you put between these two characters is not shown directly in the page, but is processed by the Smarty engine.

### Variables ###
Smarty variables (for the most part) are assigned from the PHP script before loading the template. They are used to hold dynamic data, and can be simple things like words or numbers, but also more complex things like lists. For example, the Smarty variable `$site_name` is available to every context and contains the name of your site that you configured in the Admin section.

To display the contents of a simple variable in your HTML just put the name of the variable inside a set of smarty tags, like this: `{$site_name}`. So if you wanted to set the title of a page to your site’s name, you could do this:
[html]

[/html]

And when the page is shown, the actual HTML will come out like this:
[html]

[/html]

### Lists ###
*Lists* (or Arrays as they are sometimes called) are a more complex type of variable in Smarty. Instead of holding one value, *lists* hold multiple values and Smarty provides ways of looping over each value in the list. The most common use of *lists* in the knowledge base is for the `category.htm` template, which has lists of subcategories and articles for the current category you are viewing.

One way to loop over all of the values in a *list* is the Smarty `{section} … {/section}` block. Here’s an example from the `category.htm` template:
[html num=23]{section name=cat loop=$categories}

{if $categories[cat].locked}{else}{/if}

{$categories[cat].name} ({$categories[cat].numarticles})
{if $categories[cat].description ne “”}
{$categories[cat].description}

{/if}

{* Every third time we want a new row *}
{cycle assign=tempvalue values=”,,
“}
{$tempvalue}
{/section}[/html]

Now, there are lots of things going on in that block of HTML, but for now we’re only going to focus on the `{section}` block. At the very least (and there are more options that can be found on the [Smarty Documentation][1] site) the `{section}` block needs two parameters in the opening statement: `name` and `loop`. `loop` is the name of the *list* variable that holds the items you want to loop through, and `name` is the name of your section. The name of your section is very important in the block of HTML inside.

What a `{section}…{/section}` block does is print out the everything in between the `{section}` and `{/section}` tags once for every value in the list you specify with the `loop` parameter. So if our `$categories` list has 5 categories in it, the example `{section}` will print out all that HTML 5 times. This is where the `name` parameter comes in. Each time the HTML is printed out, you want to display information from the next value in the `$categories` list, so that you end up displaying information about all 5 categories. Every time through the loop you can access the current value from the list by putting the name of the section in `[]` brackets after the list name, like so: `$categories[cat]`. Each time through the loop, `$categories[cat]` will be a different category in the list of categories.

As for the other things in the example, we’ll cover `{if}` in a bit, and documentation on `{cycle}` can be found [here][2].

### Objects ###
Besides simple variables that contain things like words and numbers a lot of the Smarty variables used in KB hold more complex data in the form of *Objects* and *lists*. An *Object* is like a container for information, a single entity that holds various *properties*. Take the concept of an Article for example. An article has all sorts of information associated with it, things like it’s title, contents, author, creation date, number of times it’s been viewed, a rating, etc. In the knowledge base, the Article smarty object has the following properties:

* id – The ID of the article
* category – The ID of the category that the article is in
* question – The question
* content – The answer
* author – The name of the author
* authorid – The ID of the author
* date – The creation date for the article
* datemodified – The date the article was last modified
* numviews – The number of times the article has been viewed
* locked – Whether or not the article is “locked”
* numstars – The rating of the article (1 – 5)

To access a *Object’s* properties use the following structure: `$variablename.property`. So if you have an article held in the variable `$articleInfo`, and you want to display the question in bold you could do the following:
[html]{$articleInfo.question}[/html]

### Conditionals ###
One of the more powerful aspects of Smarty is it’s *conditionals*: the ability to dynamically determine if you should or shouldn’t print something out based on some property or variable. For example, in the *Category* context, you only want to display the table of sub categories if the current category actually _has_ sub categories right? Well, in the *category* context, there is a Smarty variable named `$num_categories` that holds the number of child categories, so we wrap the entire block of HTML that displays subcategories in a conditional, like so:

[html]{if $num_categories > 0}


{/if}[/html]

Now, every time the page loads to display a category, if there aren’t any sub categories, everything between the `

` tags will just be left out. You can
read more about conditionals and the various comparisons you can make (less than, greater than, equal to, etc) in the [Smarty Documentation][1] site.

### Finding out what information is available on each page ###
To find out exactly what information is available in each context all you need to do is put the smarty tag `{debug}` at the top of `index.htm`. Then, every time you view a new page, a window will pop up showing you every variable that is available to the page and what information it contains. If you’re working on editing or creating a new template set, this debug window is your definitive source of information about what sort of data is available in each context.

Just make sure to take the line out when your site goes into production.

*Continue on to the next page to learn about where to get more information*

[1]: http://smarty.php.net/manual/en “Smarty Template Documentation”
[2]: http://smarty.php.net/manual/en/language.function.cycle.php “Smarty Cycle Function Documentation”

## Where to learn more ##
This is just the surface of what you can do with Smarty. Because of the new templating system in [Knowledge Management][1], you now have the ability to completely customize how your site looks. Smarty is an extremely powerful templating engine, and is quite well established in the PHP world. They have a great tutorial and documentation site over [here][1], be sure to check it out.

If you have any questions, feel free to post them up in our forums [here][2].

-Chris

[1]: http://smarty.php.net “Smarty”
[2]: http://www.activecampaign.com/support/forum/index.php? “Active Campaign Forums”

A trial is worth a thousand words.
Get started today, no credit card required.