Taxonomies are the workhorse feature for organizing the content on your site and finding the items you want to display in any situation.
There's a lot of options in what you can do with taxonomies, which are the direct result of all the different needs we've encountered in helping designers build many diverse sites. This makes writing WebvantaScript code to work with taxonomies one of the more complex parts of building sites with Webvanta. But don't despair, we're here to help! If you find your head swimming as you read this (and we don't blame you, especially until you've worked with these features for a while), just submit a helpdesk ticket. Let us know what you're trying to accomplish, and we'll point you in the right direction.
Each member of a taxonomy is called a term. Taxonomies can be either flat — a single-level collection of terms, or hierarchical. In a hierarchical taxonomy, you can nest terms to any depth, like categories and subcategories.
The name of a term should be unique within a taxonomy; it can cause problems if you have two different parent terms, each of which has a child term (i.e., a subcategory) of the same name. Each taxonomy creates an entirely independent namespace, however, so you there's no problem with using the same term name in different taxonomies.
Note: If you've been using Webvanta for some time, you may be accustomed to Categories, Tags, and Taxonomies having three separate interfaces. They've now been merged into one system. It's the Grand Unification Theory of WebvantaScript. Categories are just a hierarchical taxonomy named "categories", and tags are simply a flat taxonomy named "tags". The legacy syntax, such as category="Cats", is still available, but you'll have more flexibility using the taxonomy syntax, which in this case would be taxonomy="Categories:Cats".
When finding items with WebvantaScript, you first set the context that determines what items you want to work with. Then you can easily access the items.
If you're looking for all the items that have been assigned to a given taxonomy term, this is how you'd set the context:
<w:taxonomy name="taxonomy_name:term_name">...</w:taxonomy>
Then you can find all the items with that taxonomy term by using taxonomy = "current"
as an attribute in the item iterator. For example, suppose you have a taxonomy named "Animals" and one of the terms is "Cats". The following code will list all the cats:
<w:taxonomy name="Animals:Cats">
<h1><w:name /></h1> <!-- the name of the taxonomy term -->
<w:kb:items:each taxonomy="current">
<p><w:name /></p> <!-- the name of an item -->
<w:kb:items:each>
</w:taxonomy>
Note: you can also identify terms by their ID, anywhere you can provide a name. This makes the code less readable, but it is more robust because the code will keep working even if the name of the taxonomy term is edited. The ID is not currently displayed directly in the admin interface, but you can see it in the URL if you edit a taxonomy term.
In addition to the name of the taxonomy term, you can access other information about it. Here's all the values that are available:
name | Name of the taxonomy term |
description | Description of the taxonomy term |
id | The ID number of the term |
count | The number of items that have been assigned to the term |
root_name | Name of the highest-level parent term |
root_id | ID number of the highest-level parent term |
path | URL for a page with the term ID as a parameter |
position | Position of this term within the terms for a given parent |
parent_name | Name of the term that is the immediate parent of the current term |
parent_id | ID of the term that is the immediate parent of the current term |
permalink | ID plus first five words of the term's name |
If you don't need to access the taxonomy term name or other attributes of the term itself, you can use this more compact form:
<w:kb:items:each taxonomy="Animals:Cats">
<p><w:name /></p>
<w:kb:items:each>
You can also test for more than one taxonomy term. Suppose you have a taxonomy "Age" that has terms like "Baby", "Youth", and "Adult". You can find all the baby cats as follows:
<w:kb:items:each taxonomy="(Animals:Cats&&Age:Baby)">
<p><w:name /></p>
<w:kb:items:each>
Note that the separator to "AND" together taxonomy terms is &&
. You can also "OR" terms together using a double pipe (||), and you must group using parenthesis. So the following example will find all the baby cats and baby dogs:
<w:kb:items:each taxonomy="((Animals:Cats||Animals:Dogs)&&(Age:Baby))">
<p><w:name /></p>
<w:kb:items:each>
You can use the keyword "current" in place of one of the taxonomy terms. For example, the following code lists all the baby animals of whatever kind is set by the context (as described in the following section):
<w:kb:items:each taxonomy="(current&&Age:Baby)">
<p><w:name /></p>
<w:kb:items:each>
Note that compound taxonomy conditions should always be surrounded by parentheses.
The context can be set in two ways:
Once the taxonomy has been set by the context, you can use the keyword "current" to set the taxonomy name from the context:
<w:taxonomy name="current">...</w:taxonomy>
You can also pass a taxonomy term to a page of any type by setting it as a URL parameter, as follows:
www.example.com/mypage?wtx=taxonomy_name:term_name
The key here is to use the parameter name "wtx", and then you can access the taxonomy using the keyword "auto":
<w:taxonomy name="auto">
You can repeat a block of code for every top-level term in a taxonomy using the basic taxonomy iterator:
<w:taxonomy:each name='taxonomy_name'>
...
</w:taxonomy:each>
For example, this code lists all the major type of animals (the top level terms in the Animals taxonomy):
<w:taxonomy:each name="Animals">
<p><w:name /></p>
</w:taxonomy:each>
If you don't specify a "relative" attribute for the taxonomy:each iterator, it defaults to "roots", which means that it will loop through all the top-level terms in the taxonomy.
There are many other options for the "relative" attribute, as shown below:
<w:taxonomy:each name='taxonomy_name' relative="roots|parents|reversed-parents|children|siblings|item|related-items"
Here's the rundown on what each of these "relative" options do:
parents | Starts from the current term, and provides each of the parent terms (moving up the tree) |
reversed-parents | Starts at the most distant ancestor (top level parent term) and provides each of the child terms down to the current term's immediate parent. Just what you need when you're creating breadcrumbs. |
children | Iterate over all of the immediate children of the current term. (This is the same as subcategories.) |
siblings | Iterate over all the siblings (other terms at the same level, with the same parent) as the current term. |
item | Provides access to a list of terms in the current taxonomy that have been assigned to a particular database item. Must use in an item context and a taxonomy context. |
in.item | As above, but for a related item (as set up by for_each) |
related-items | Returns terms for all related items of the current item (must be used in an item context). |
You can limit the number of taxonomy terms the iterator will go through:
<w:taxonomy:each name='taxonomy_name' limit='n'>
And you can exclude certain terms:
<w:taxonomy:each name='taxonomy_name' exclude='comma separated list of names'>
The iterators described above show only a single level of terms at a time. You can show nested terms by using iterators within iterators.
You can also show a complete tree of all the terms in a taxonomy:
<w:taxonomy:tree name='taxonomy_name' type='html'/>
You can also get the tree in JSON format, which is useful for feeding JavaScript tree widgets:
<w:taxonomy:tree name='taxonomy_name' type='json' />
Note: As with all conditions in WebvantaScript, there is an "unless" version available for every "if" statement. There is no "else", so to achieve if-then-else structures, use an if statement followed by an unless statement with the same condition.
<w:taxonomy:if_root>
Test if current term is a root term or child term
<w:taxonomy:if_term>
Tests if there is any taxonomy term context set.
<w:taxonomy:if_term name="term_name">
Tests if the current taxonomy term context matches the specified term name. Note: you can also provide the term ID instead of the name.
<w:taxonomy:if_current name='term_name'>
Tests if the current term matches the specified name.
<w:taxonomy:if_items type="type_name">
Test if the current term has any items assigned to it of the specified type. If the type is not specified, checks for any type.
<w:taxonomy:if_items type="type_name, type_name, type_name">
Test if the current term has any items assigned to it with any of the specified types.
<w:taxonomy:if_items type="-type_name, -type_name">
Test if the current term has any items assigned to it that are not of any of the specified types.
<w:taxonomy:if_items type="type_name" count=n>
Test if the current term has more than n items assigned to it of the specified type.
<w:taxonomy:if_subterms>
Test to see if current term has any children terms associated with it.
<w:taxonomy:if_subterms count=n>
Test to see if current term has more than n children terms associated with it.
<w:taxonomy:each:if_first>
Test if the current term for taxonomy context is the first one in the iteration.
<w:taxonomy:each:if_last>
Test if the current term for taxonomy context is the last one in the iteration.
If you are testing for items that have more than one taxonomy term, use the item-centric "if_items" instead:
<w:kb:item:if_items taxonomy="Animals:Cats&&Age:Baby">