Custom Menu Item Layouts and Content

Overview

UberMenu provides a system for defining your own Menu Item Layouts and adding your own custom content programmatically, so you can flexibility extend UberMenu. Remember, all content defined in a menu item layout will be inside the anchor. If you want to add custom content outside the anchor, you can use Custom Content, or the ubermenu_dp_subcontent filter for Dynamic Posts.

This process contains four steps:

1. Register your custom layout. This allows you to select your custom layout via the Menu Item Settings.

2. Define your custom layout. This allows you to tell UberMenu what content should be printed in what order.

3. Add custom content (optional). This allows you to provide custom content that UberMenu doesn’t already generate.

4. Style your content. Since your content will be custom, you’ll need to provide styles for it, as it is not native UberMenu functionality.

Steps 1-3 are best added in your child theme’s functions.php or better yet a custom plugin. You should never edit the core plugin files

1. Register your custom layout

In the first step, we’re going to tell UberMenu about your new layout. We’re going to call it “My Layout”. This code will add your custom layout as a selectable option in the UberMenu Menu Item Settings:

You’ll see your new layout appear as an option under “My Custom Layouts” in the Layouts tab of the Menu Item Settings. To switch to this layout, you’ll select it just like a default layout.

/* Add your custom layout as an available menu item setting */
add_filter( 'ubermenu_item_layout_ops' , 'my_custom_ubermenu_layout_ops' );
function my_custom_ubermenu_layout_ops( $ops ){
   
   //Register a custom section if not already present
   if( !isset( $ops['custom'] ) ){
      $ops['custom'] = array(
         'group_title' => __( 'My Custom Layouts' , 'ubermenu' ),
      );
   }
 
   //Register your custom layout, using the ID 'my_layout'
   $ops['custom']['my_layout'] = array(
      'name'   => __( 'My Layout', 'ubermenu' ),
   );
 
   return $ops;
}

Note that we’re going to use my_layout as the ID for this custom layout. This is important as we will need to reference it later

2. Define your custom layout

In this step, we define what content will appear in this layout, and in what order. You simply filter the $layouts array and add your new layout as an array of content components.

Some components are already defined by UberMenu. For example, you can use 'title', 'description', or 'image', as these components are already present.

You can also add your own custom components, which you define labels for in this step, and will generate content for in step 3.

In the following code, we define our layout as printing the title of this menu item, followed by some special_content that we have yet to define. Note that special_content can be any string we want, but we need to use it in Step 3.

/* Define the layout components */
add_filter( 'ubermenu_item_layouts' , 'my_custom_ubermenu_item_layouts' );
function my_custom_ubermenu_item_layouts( $layouts ){
 
   //Use the same ID as used when registering this layout
   $layouts['my_layout'] = array(
 
      //The elements in the 'order' array define the content and order used in this layout
      //Core available layout elements include:
      // -- title
      // -- image
      // -- description
      // You can also use custom layout elements which you must define in another filter
      'order'  => array(
         'title',
         'special_content',
      ),
   );
 
   return $layouts;
}

3. Generate custom content

This step is optional. If you just use the default components, you can skip this. If you want to use custom components, you’ll need to actually do the work of generating the content for them in this step.

This filter is run for each menu item. The filter provides the layout, item ID (the ID of the menu item), and object ID (the ID of the associated content, such as a Post or Term ID). Your function will return an array of the custom content you want accessible to the layout, keyed by any custom component IDs you added to the order array for this layout.

In this example, we first check to make sure we’re dealing with our custom layout. Then we generate our content (that part is up to you – in the example, we get the featured image). Then we add the custom content to the array to make it accessible to the layout.

/* Add the custom content if necessary */
add_filter( 'ubermenu_custom_item_layout_data' , 'my_custom_item_layout_filter' , 10 , 4 );
/**
 * Filter the array of content parameters to inject any custom content you desire
 * @param  array  $custom_pieces  An array indexed with layout elements, which you should add to
 * @param  string $layout         The ID of the layout currently in use
 * @param  int    $item_id        The ID of the menu item being processed
 * @param  int    $object_id      The ID of the associated content (such as Post ID or Term ID)
 * @return array                  You must return the filtered $custom_pieces array
 */
function my_custom_item_layout_filter( $custom_pieces , $layout , $item_id , $object_id ){
 
   //If the custom layout is in use
   if( $layout == 'my_layout' ){
       
      //Determine the content based on the $item_id and/or $object_id
      //This example adds the post thumbnail for the referenced object
      $content = get_the_post_thumbnail( $object_id );
 
      //Add your content to the $custom_pieces array, keyed by the slug you used in 
      //the 'order' array when defining the layout
      $custom_pieces['special_content'] = $content;
   }
 
   return $custom_pieces;
} 

Note that for dynamic items, the $item_id will be the same for each results from a specific dynamic item – however, the $object_id will be different for each resulting post or term.

4. Add custom styles

UberMenu will now output your content in the order defined, but you will likely want to add custom styles to design your visual style for this layout. If you want to target this layout specifically, you can use the class ubermenu-item-layout-my_layout (replace ‘my_layout’ with whatever the ID of your custom layout is), which UberMenu will add automatically. To make all titles using your layout red with a 10px bottom margin, you would add this:

.ubermenu .ubermenu-item-layout-my_layout > .ubermenu-target-text{
    color:red;
    margin-bottom:10px;
}

Here’s an example of the output of this code using a Dynamic Posts item:

On this page