Skip to content

How I built a custom WordPress navigation menu

Recently, I was working on a website that required an accordion, navigation menu that would contain categories or single page links. If a category was chosen, it should expand to show child and grandchild categories, along with lists of posts within those categories. In addition, there was a need for an optional alphabetical list of posts within that category.

Here is the final product:

On top of that, the navigation menu needed to be editable from the WordPress dashboard. Here is how one can edit the menu, without touching PHP or HTML:

Because the navigation is editable from the WordPress dashboard, this means writing some PHP to build the navigation menu based on what the website editor chooses from the navigation builder screen.

Advanced Custom Fields (ACF) to the rescue

I used ACF to build the above navigation builder screen. In this case, I used a ‘flexible content’ field with 2 layout options: Single Page or Category

Cheers to other beginner PHP developers

I’ve been learning PHP deeply the last year or so and this project really tested my skills. The following techniques helped me successfully write PHP functions that would output lists of categories/posts:

  • First, I built the nav menu in HTML/CSS/JS (in CodePen) without dynamic data from WordPress. This helped me get a working demo, albeit with only static text/links.
  • Then I wrote a single PHP function and started with just outputting a basic list of categories or posts.
  • Next, I used the data from my ACF inputs in my PHP function. This way someone could select a category from an edit screen, save, and my function would use that field data to use as the category ID when building a basic list (instead of hardcoding a particular category ID).
  • After this, I further honed my function and began breaking it into separate functions with each function having it’s own singular purpose. This allowed me to reuse a few functions in other functions.
  • Additionally, when I encountered an array of WordPress data, I would var_dump() that array to see what data I was working with. This way I knew how I could use the key-value pairs in my functions.

Using ACF data in my PHP

I wrote PHP in my header.php of my WordPress theme to display the custom field data.

Custom PHP functions to build the category lists

See these 2 functions above?

  • categoryWithABCList($categoryID)
  • categoryWithoutABCList($categoryID)

These functions loop through all the child categories, grandchild categories, and posts of the selected category and it builds an unordered list.

categoryWithABCList($categoryID)

This function runs if the the website editor toggled the option to show an alphabetical list of posts:

categoryWithoutABCList($categoryID)

This function will run if the website editor did not select to show an alphabetical list of posts. It builds a multi-level list with child and grandchild categories as well as the posts in those categories but will exclude the alphabetical list.

Could I combine the above 2 functions into one?

I have a feeling I could have written the above 2 functions as one function with a second parameter, and some conditional code that was utilized depending on whether the website editor selected to show an alphabetical list. Maybe I’ll try to refine my code and accomplish this.

More custom PHP functions

In the above two code snippets, you’ll find the following functions. For brevity, I’ll skip sharing the exact function code, and only describe them.

  • ListCategoryPosts($catID, false)
    • optional second boolean parameter (true/false/left blank) that determines whether list will include a wrapper <ul> tag.
    • This function does what the name implies: it builds a <ul> filled links to posts in the given category.
  • getChildCategories($catID)
    • This function will either list the child and grandchild categories or the posts in the given parent categories if no child/grandchild categories exist.
    • I may run into issues where a category may have a child category and posts in that given category. However, my current use-case is such that if a category has child categories, then it shouldn’t/won’t have posts in that parent category.

HTML/CSS/JS for this multi-level, accordion, navigation menu

As I said above, I started this project building a static navigation menu in CodePen that worked like I wanted. This meant building a jQuery-powered multi-level accordion menu before touching PHP.

Here is the working demo prior to implementing it in WordPress:

See the Pen Responsive navigation – work in progress by Stephen Emlund (@stemlund) on CodePen.

Leave a reply

Leave a Reply

Your email address will not be published.