Instantly share code, notes, and snippets.
Last active
December 12, 2016 23:15
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save rohmann/23e7b49f4b785ac8702b72889025a4a9 to your computer and use it in GitHub Desktop.
WordPress Custom Nav walker as a template
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
I've not tested it, but this is the result of thinking through how one might output custom navigation menu markup using a theme template file. | |
1. Include this class | |
2. Call a menu in one of your templates, and reference a template using the new arguments available. For example | |
wp_nav_menu( array( | |
'theme_location' => 'primary', | |
'walker' => new Custom_Template_Nav_Walker, | |
'start_el_template' => 'nav-item' | |
) ); | |
3. Have a template called {$start_el_template}.php in your theme folder. For example "your-theme/nav-item.php" | |
In the template, use $el_data to shape any opening markup you like as a template | |
$class = empty($el_data['classes']) ? '' : class="' . esc_attr( join( ' ', $el_data['classes'] ) ); | |
echo "<li $id $class"><a href=""> | |
*/ | |
class Custom_Template_Nav_Walker extends Walker_Nav_Menu { | |
/** | |
* Override these to quickly set static markup when not loading a custom template | |
*/ | |
public $default_start_lvl = '<ul class="sub-menu">'; | |
public $default_end_lvl = '</ul>'; | |
public $default_end_el = '</li>'; | |
/** | |
* You can override this to use your own view loading system. By default this | |
* will mimic get_template_part, but allow $el_data to be accessible in that file. | |
* @param string $_template_name Name of a template passed through custom arguments | |
* For example 'start_lvl_template' => 'my-custom-li' | |
* @param array $el_data Combination of attributes, content, and arguments | |
* @return string Should return a string opening <li> tag | |
*/ | |
public function custom_template_loader( $template_name, $el_data ) { | |
$template = locate_template( array( $template_name ), false, false ); | |
global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID; // 01 | |
if ( is_array( $wp_query->query_vars ) ) { | |
extract( $wp_query->query_vars, EXTR_SKIP ); | |
} | |
if ( isset( $s ) ) { | |
$s = esc_attr( $s ); | |
} | |
ob_start(); | |
include( $_template_file ); | |
return ob_get_clean(); | |
} | |
/** | |
* Outputs the WordPress standard start_el markup. You can override this, | |
* but ideally you'd just override custom_template_loader and pass a template. | |
* @param array $data Combination of attributes, content, and arguments | |
* @return string WordPress default <li> element for this nav item | |
*/ | |
public function default_start_el( $data ) { | |
$class_names = join( ' ', $data['classes'] ); | |
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : ''; | |
$id = $data['id'] ? ' id="' . esc_attr( $data['id'] ) . '"' : ''; | |
$output .= $indent . '<li' . $id . $class_names .'>'; | |
$attributes = ''; | |
foreach ( $data['atts'] as $attr => $value ) { | |
if ( ! empty( $value ) ) { | |
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); | |
$attributes .= ' ' . $attr . '="' . $value . '"'; | |
} | |
} | |
$item_output = $args->before; | |
$item_output .= '<a'. $attributes .'>'; | |
$item_output .= $args->link_before . $data['title'] . $args->link_after; | |
$item_output .= '</a>'; | |
$item_output .= $args->after; | |
return $item_output; | |
} | |
public function start_lvl( &$output, $depth = 0, $args = array() ) { | |
if ( $args['start_lvl_template'] ) { | |
$output .= $this->custom_template_loader( $args['start_lvl_template'], array( | |
'args' => $args, | |
'depth' => $depth | |
) ); | |
} else { | |
$output .= $this->default_start_lvl; | |
} | |
} | |
public function end_lvl( &$output, $depth = 0, $args = array() ) { | |
if ( $args['end_lvl_template'] ) { | |
$output .= $this->custom_template_loader( $args['end_lvl_template'], array( | |
'args' => $args, | |
'depth' => $depth | |
) ); | |
} else { | |
$output .= $this->default_end_lvl; | |
} | |
} | |
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { | |
$classes = empty( $item->classes ) ? array() : (array) $item->classes; | |
$classes[] = 'menu-item-' . $item->ID; | |
$atts = array(); | |
$atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : ''; | |
$atts['target'] = ! empty( $item->target ) ? $item->target : ''; | |
$atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : ''; | |
$atts['href'] = ! empty( $item->url ) ? $item->url : ''; | |
$data = array( | |
'args' => apply_filters( 'nav_menu_item_args', $args, $item, $depth ), | |
'id' => apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args, $depth ), | |
'classes' => apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ), | |
'atts' => apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth ), | |
'title' => apply_filters( 'nav_menu_item_title', apply_filters( 'the_title', $item->title, $item->ID ), $item, $args, $depth ), | |
'item' => $item, | |
); | |
$item_output = isset( $args['start_el_template'] ) ? $this->custom_template_loader( $template, $data ) : $this->default_start_el( $data ); | |
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); | |
} | |
public function end_el( &$output, $item, $depth = 0, $args = array() ) { | |
if ( $args['end_el_template'] ) { | |
$output .= $this->custom_template_loader( $args['end_el_template'], array( | |
'args' => $args, | |
'depth' => $depth | |
) ); | |
} else { | |
$output .= $this->default_end_el; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment