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:

  1. cat_menu
  2. cat_menu_article
  3. cat_submenu1
  4. cat_submenu2
  5. 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
  • 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.3
  • category3
    • subcategory3.1
      • article3.1a
      • article3.1b
  • 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_articles variable before running the cat_menu form
  • 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”
comments powered by Disqus