Hierarchical category menu with articles
The idea here is to create a menu based on categories & sub-categories together with their articles, all without using plugins.
Setting up
Create the following forms as follows:
- cat_menu
- cat_menu_article
- cat_submenu1
- cat_submenu2
- cat_submenu3
cat_menu
<txp:category_list wraptag="ul" break="" children="0">
<li<txp:if_category name='<txp:category />'> class="active_cat"</txp:if_category>><txp:category title="1" link="1" />
<txp:output_form form="cat_submenu1"><txp:category /></txp:output_form>
</li>
</txp:category_list>
cat_menu_article
<txp:variable name="active_article_class" value="" />
<txp:if_article_id>
<txp:variable name="active_article_class" value=" active_article" />
</txp:if_article_id>
<txp:permlink class='article_class<txp:variable name="active_article_class"/>'><txp:title/></txp:permlink>
cat_submenu1
<txp:variable name="submenu1_cats_found" value="0" /> <txp:category_list wraptag="ul" break="" parent='<txp:yield />' children="0" exclude='<txp:yield />'> <txp:variable name="submenu1_cats_found" value="1" /> <li<txp:if_category name='<txp:category />'> class="active_cat"</txp:if_category>><txp:category title="1" link="1" /> <txp:output_form form="cat_submenu2"><txp:category /></txp:output_form> </li> <txp:if_variable name="cat_menu_articles" value="1"> <txp:if_last_category> <txp:article_custom category='<txp:yield />' break="li" sort="title asc" form="cat_menu_article" /> </txp:if_last_category> </txp:if_variable> </txp:category_list><txp:if_variable name="cat_menu_articles" value="1"> <txp:if_variable name="submenu1_cats_found" value="1"> <txp:else/> <txp:article_custom category='<txp:yield />' wraptag="ul" break="li" sort="title asc" form="cat_menu_article" /> </txp:if_variable> </txp:if_variable>
cat_submenu2
<txp:variable name="submenu2_cats_found" value="0" /> <txp:category_list wraptag="ul" break="" parent='<txp:yield />' children="0" exclude='<txp:yield />'> <txp:variable name="submenu2_cats_found" value="1" /> <li<txp:if_category name='<txp:category />'> class="active_cat"</txp:if_category>><txp:category title="1" link="1" /> <txp:output_form form="cat_submenu3"><txp:category /></txp:output_form> </li> <txp:if_variable name="cat_menu_articles" value="1"> <txp:if_last_category> <txp:article_custom category='<txp:yield />' break="li" sort="title asc" form="cat_menu_article" /> </txp:if_last_category> </txp:if_variable> </txp:category_list><txp:if_variable name="cat_menu_articles" value="1"> <txp:if_variable name="submenu2_cats_found" value="1"> <txp:else/> <txp:article_custom category='<txp:yield />' wraptag="ul" break="li" sort="title asc" form="cat_menu_article" /> </txp:if_variable> </txp:if_variable>
cat_submenu3
<txp:variable name="submenu3_cats_found" value="0" /> <txp:category_list wraptag="ul" break="" parent='<txp:yield />' children="0" exclude='<txp:yield />'> <txp:variable name="submenu3_cats_found" value="1" /> <li<txp:if_category name='<txp:category />'> class="active_cat"</txp:if_category>><txp:category title="1" link="1" /> <txp:if_variable name="cat_menu_articles" value="1"> <txp:article_custom category='<txp:category />' wraptag="ul" break="li" sort="title asc" form="cat_menu_article" /> </txp:if_variable> </li> <txp:if_variable name="cat_menu_articles" value="1"> <txp:if_last_category> <txp:article_custom category='<txp:yield />' break="li" sort="title asc" form="cat_menu_article" /> </txp:if_last_category> </txp:if_variable> </txp:category_list><txp:if_variable name="cat_menu_articles" value="1"> <txp:if_variable name="submenu3_cats_found" value="1"> <txp:else/> <txp:article_custom category='<txp:yield />' wraptag="ul" break="li" sort="title asc" form="cat_menu_article" /> </txp:if_variable> </txp:if_variable>
Outputting the menu on the page:
<txp:variable name="cat_menu_articles" value="1" />
<txp:output_form form="cat_menu" />
The result
You should end up with something like:
- category1
- subcategory1.1
- subcategory1.1.1
- subcategory1.1.2
- article1.1a
- subcategory1.2
- article1a
- article1b
- subcategory1.1
- category2
- subcategory2.1
- subcategory2.2
- subcategory2.2.1
- subcategory2.2.1.1
- subcategory2.2.1.2
- article2.2.1.2a
- article2.2.1a
- article2.2.1b
- subcategory2.2.1
- subcategory2.3
- category3
- subcategory3.1
- article3.1a
- article3.1b
- subcategory3.1
- category4
- article4a
- article4b
- article4c
Notes
- Textpattern 4.2.0+ is required
- This solution will give you 4 levels of categories & sub-categories, with articles dangling at the appropriate places
- If you don’t want articles, then don’t set the
cat_menu_articlesvariable before running thecat_menuform - The active category will have a class of “active_cat” applied
- The active article will have a class of “active_article” applied
- all article links have a class of “article_class”
4 Comments - Comments RSS Feed
Markus Merz | Hamburg St. Georg
# 6 November 2011
Class active_cat needs to be assigned to the a instead of li. Otherwise the class is applied to the whole li including the submenu ul.
Pls. note the nested tags with one ' and two single quotes. My working code for active anchors (TXP 4.4.1):
<li><txp:category title="1" link="1"
class='<txp:if_category name=''<txp:category />''>
active_cat
</txp:if_category>' />
This needs to be done for cat_menu and all three submenus.
class=“class name”
(X)HTML class attribute, applied to wraptag. If no wraptag is supplied (and link=“1”), the class is applied to the anchor instead.
Default: unset.
(The same is true for articles dangling at the appropriate places. They are listed at the end of the submenu .. still have to check that.)
Markus Merz | Hamburg St. Georg
# 11 November 2011
Another small trap.
Per default the menu outputs li which filter the landing page by section.
Example: If all articles reside in section ‘articles’ the landing page will be empty if you click the menu inside section ‘about’.
Deactivate the section filter: To get consistent landing pages you have to add section="" to txp:category.
<li><txp:category title="1" link="1"
class='<txp:if_category name=''<txp:category />''>
active_cat
</txp:if_category>' />
section=“section name”
Restricts category search to named section.
Default: current section (for backwards compatibility).
Markus Merz | Hamburg St. Georg
# 11 November 2011
Sorry, I forgot to add the section="" to the code. This is the correct one:
<li><txp:category section="" title="1" link="1"
class='<txp:if_category name=''<txp:category />''>
active_cat
</txp:if_category>' />

Markus Merz | Hamburg St. Georg
# 4 November 2011
WOW!
Just trying this on a new website.
Still have to understand how to tweak and style this monster.
Main issue with creating a category driven sidebar menu was that your adi_cat_menu doesn’t offer such multi-level output :)