├── CHANGELOG.md ├── README.md └── be-mega-menu.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file, formatted via [this recommendation](http://keepachangelog.com/). 3 | 4 | ## [1.0.2] - 2016-09-22 5 | ### Added 6 | - Specify a mega menu using a CSS class: `mega-menu-{post_id}` where {post_id} is the ID of the mega menu. To find the ID, look at the URL when editing the mega menu. This can be used as a workaround to pages that have special characters in the title and don't work the standard way. 7 | 8 | ## [1.0.1] - 2016-09-07 9 | ### Added 10 | - WPML Support 11 | - Changelog 12 | 13 | ## [1.0.0] - 2016-08-04 14 | - Initial Commit -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BE Mega Menu # 2 | **Contributors:** billerickson 3 | **Requires at least:** 4.1 4 | **Tested up to:** 4.6.1 5 | **Stable tag:** 1.0.2 6 | **License:** GPLv2 or later 7 | **License URI:** http://www.gnu.org/licenses/gpl-2.0.html 8 | 9 | BE Mega Menu lets you use a visual editor for managing mega menu dropdowns. 10 | 11 | Go to Appearance > Menus to create your top level menu items. Go to Appearance > Mega Menus to manage the mega menu dropdowns. Create a Mega Menu with the same title as the top level menu item under which it should appear. 12 | 13 | This plugin does not add any CSS, so you'll need to customize the styling in your theme. Here is [sample CSS](https://gist.github.com/billerickson/c6c27cd06d9e24305f7d1d2fd8e46425). 14 | 15 | ## Screenshots ## 16 | 17 | #### Backend 18 | ![backend screenshot](https://d3vv6lp55qjaqc.cloudfront.net/items/2a2o0R3V3l3y0v1S3U40/Screen%20Shot%202016-08-04%20at%2012.52.55%20PM.png?v=6ba79d66) 19 | 20 | #### Frontend 21 | ![frontend screenshot](https://d3vv6lp55qjaqc.cloudfront.net/items/180v3e0A1D0E2D3y3R2d/Screen%20Shot%202016-08-04%20at%2012.53.25%20PM.png?v=e6d40355) 22 | 23 | ## Customization ## 24 | 25 | The mega menu applies to the 'header' menu theme location. You can change this using the `be_mega_menu_location` filter. Example: 26 | 27 | ```php 28 | /** 29 | * Mega Menu on Primary Menu 30 | * 31 | */ 32 | function ea_primary_mega_menu( $theme_location ) { 33 | return 'primary'; 34 | } 35 | add_filter( 'be_mega_menu_location', 'ea_primary_mega_menu' ); 36 | ``` 37 | 38 | The opening markup on mega menus is `
`. This can be customized using the `be_mega_menu_opening_markup` filter. 39 | 40 | The mega menu content can be customized using the `ea_the_content` filter. [See this example](http://www.billerickson.net/code/duplicate-the_content-filters/) to duplicate the filters on `the_content` 41 | 42 | The closing markup on mega menus is `
`. This can be customized using the `be_mega_menu_closing_markup` filter. 43 | 44 | You can customize the post type arguments used to create the Mega Menu post type with the `be_mega_menu_post_type_args` filter. 45 | -------------------------------------------------------------------------------- /be-mega-menu.php: -------------------------------------------------------------------------------- 1 | . 22 | * 23 | * @package BE_Mega_Menu 24 | * @author Bill Erickson 25 | * @since 1.0.0 26 | * @license GPL-2.0+ 27 | * @copyright Copyright (c) 2015 28 | */ 29 | 30 | 31 | // Exit if accessed directly 32 | if ( ! defined( 'ABSPATH' ) ) exit; 33 | 34 | 35 | /** 36 | * Main class 37 | * 38 | * @since 1.1.0 39 | * @package BE_Mega_Menu 40 | */ 41 | final class BE_Mega_Menu { 42 | 43 | /** 44 | * Menu Location 45 | * 46 | * @since 1.1.0 47 | */ 48 | public $menu_location = 'header'; 49 | 50 | /** 51 | * Plugin Constructor. 52 | * 53 | * @since 1.1.0 54 | * @return BE_Mega_Menu 55 | */ 56 | function __construct() { 57 | add_action( 'init', array( $this, 'init' ) ); 58 | } 59 | 60 | /** 61 | * Initialize 62 | * 63 | * @since 1.1.0 64 | */ 65 | function init() { 66 | 67 | // Set new location 68 | $this->menu_location = apply_filters( 'be_mega_menu_location', $this->menu_location ); 69 | 70 | add_action( 'init', array( $this, 'register_cpt' ), 20 ); 71 | add_filter( 'wp_nav_menu_args', array( $this, 'limit_menu_depth' ) ); 72 | add_filter( 'nav_menu_css_class', array( $this, 'menu_item_classes' ), 10, 4 ); 73 | add_filter( 'walker_nav_menu_start_el', array( $this, 'display_mega_menus' ), 10, 4 ); 74 | 75 | } 76 | 77 | /** 78 | * Register Mega Menu post type 79 | * 80 | * @since 1.0.0 81 | */ 82 | function register_cpt() { 83 | 84 | $labels = array( 85 | 'name' => 'Mega Menus', 86 | 'singular_name' => 'Mega Menu', 87 | 'add_new' => 'Add New', 88 | 'add_new_item' => 'Add New Mega Menu', 89 | 'edit_item' => 'Edit Mega Menu', 90 | 'new_item' => 'New Mega Menu', 91 | 'view_item' => 'View Mega Menu', 92 | 'search_items' => 'Search Mega Menus', 93 | 'not_found' => 'No Mega Menus found', 94 | 'not_found_in_trash' => 'No Mega Menus found in Trash', 95 | 'parent_item_colon' => 'Parent Mega Menu:', 96 | 'menu_name' => 'Mega Menus', 97 | ); 98 | 99 | $args = array( 100 | 'labels' => $labels, 101 | 'hierarchical' => false, 102 | 'supports' => array( 'title', 'editor', 'revisions' ), 103 | 'public' => false, 104 | 'show_ui' => true, 105 | 'show_in_menu' => 'themes.php', 106 | 'show_in_nav_menus' => false, 107 | 'publicly_queryable' => true, 108 | 'exclude_from_search' => true, 109 | 'has_archive' => false, 110 | 'query_var' => true, 111 | 'can_export' => true, 112 | 'rewrite' => array( 'slug' => 'megamenu', 'with_front' => false ), 113 | 'menu_icon' => 'dashicons-editor-table', // https://developer.wordpress.org/resource/dashicons/ 114 | ); 115 | 116 | register_post_type( 'megamenu', apply_filters( 'be_mega_menu_post_type_args', $args ) ); 117 | 118 | } 119 | 120 | /** 121 | * Limit Menu Depth 122 | * 123 | * @since 1.0.0 124 | * @param array $args 125 | * @return array 126 | */ 127 | function limit_menu_depth( $args ) { 128 | 129 | if( $this->menu_location == $args['theme_location'] ) 130 | $args['depth'] = 1; 131 | 132 | return $args; 133 | } 134 | 135 | /** 136 | * Menu Item Classes 137 | * 138 | * @since 1.1.0 139 | * @param array $classes 140 | * @param object $item 141 | * @param object $args 142 | * @param int $depth 143 | * @return array 144 | */ 145 | function menu_item_classes( $classes, $item, $args, $depth ) { 146 | 147 | if( $this->menu_location != $args->theme_location ) 148 | return $classes; 149 | 150 | if( in_array( 'menu-item-has-children', $classes ) ) 151 | $classes = array_diff( $classes, array( 'menu-item-has-children' ) ); 152 | 153 | if( $this->mega_menu( $item ) ) 154 | $classes[] = 'menu-item-has-children'; 155 | 156 | return $classes; 157 | } 158 | 159 | /** 160 | * Display Mega Menus 161 | * 162 | * @since 1.0.0 163 | * @param string $item_output 164 | * @param object $item 165 | * @param int $depth 166 | * @param object $args 167 | * @return string 168 | */ 169 | function display_mega_menus( $item_output, $item, $depth, $args ) { 170 | 171 | if( ! ( $this->menu_location == $args->theme_location && 0 == $depth ) ) 172 | return $item_output; 173 | 174 | $submenu_object = $this->mega_menu( $item ); 175 | 176 | if( !empty( $submenu_object ) && ! is_wp_error( $submenu_object ) ) { 177 | 178 | $opening_markup = apply_filters( 'be_mega_menu_opening_markup', '
' ); 179 | $closing_markup = apply_filters( 'be_mega_menu_closing_markup', '
' ); 180 | 181 | $submenu = $opening_markup . apply_filters( 'be_mega_menu_content', $submenu_object->post_content, $submenu_object ) . $closing_markup; 182 | $item_output = str_replace( '', '' . $submenu, $item_output ); 183 | 184 | } 185 | 186 | return $item_output; 187 | } 188 | 189 | /** 190 | * Mega Menu 191 | * 192 | * @since 1.1.0 193 | * @param object $item 194 | * @return object $submenu_object 195 | */ 196 | function mega_menu( $item ) { 197 | 198 | $submenu_object = false; 199 | foreach( $item->classes as $class ) { 200 | if( strpos( $class, 'megamenu-' ) !== false ) 201 | $submenu_object = get_post( intval( str_replace( 'megamenu-', '', $class ) ) ); 202 | } 203 | 204 | if( ! $submenu_object ) 205 | $submenu_object = get_page_by_title( $item->title, false, 'megamenu' ); 206 | 207 | // WPML Support 208 | if( function_exists( 'icl_object_id' ) && $submenu_object ) { 209 | $translation = icl_object_id( $submenu_object->ID, 'megamenu', false ); 210 | if( $translation ) { 211 | $submenu_object = get_post( intval( $translation ) ); 212 | } 213 | } 214 | 215 | return $submenu_object; 216 | 217 | } 218 | } 219 | new BE_Mega_Menu; 220 | --------------------------------------------------------------------------------