From cea18747d9caed30dbfed28fe79c31b16909541a Mon Sep 17 00:00:00 2001 From: William Patton Date: Mon, 16 Apr 2018 22:28:31 +0100 Subject: [PATCH 1/2] Swap customized walker to latest upstream wp-bootstrap-navwalker class --- functions.php | 2 +- header.php | 11 +- inc/bootstrap-wp-navwalker.php | 216 ----------- inc/class-wp-bootstrap-navwalker.php | 555 +++++++++++++++++++++++++++ 4 files changed, 562 insertions(+), 222 deletions(-) delete mode 100644 inc/bootstrap-wp-navwalker.php create mode 100644 inc/class-wp-bootstrap-navwalker.php diff --git a/functions.php b/functions.php index 55179a9..813e68a 100644 --- a/functions.php +++ b/functions.php @@ -58,7 +58,7 @@ require get_template_directory() . '/inc/jetpack.php'; /** * Load custom WordPress nav walker. */ -require get_template_directory() . '/inc/bootstrap-wp-navwalker.php'; +require get_template_directory() . '/inc/class-wp-bootstrap-navwalker.php'; /** * Load WooCommerce functions. diff --git a/header.php b/header.php index f6dbde3..ec81538 100644 --- a/header.php +++ b/header.php @@ -44,14 +44,14 @@ $container = get_theme_mod( 'understrap_container_type' );

- + - + - - + + @@ -69,7 +69,8 @@ $container = get_theme_mod( 'understrap_container_type' ); 'menu_class' => 'navbar-nav', 'fallback_cb' => '', 'menu_id' => 'main-menu', - 'walker' => new understrap_WP_Bootstrap_Navwalker(), + 'depth' => 2, + 'walker' => new WP_Bootstrap_Navwalker(), ) ); ?> diff --git a/inc/bootstrap-wp-navwalker.php b/inc/bootstrap-wp-navwalker.php deleted file mode 100644 index 54660ec..0000000 --- a/inc/bootstrap-wp-navwalker.php +++ /dev/null @@ -1,216 +0,0 @@ -\n"; - } - - /** - * Open element. - * - * @see Walker::start_el() - * @since 3.0.0 - * - * @param string $output Passed by reference. Used to append additional content. - * @param object $item Menu item data object. - * @param int $depth Depth of menu item. Used for padding. - * @param mixed $args Rest arguments. - * @param int $id Element's ID. - */ - public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { - $indent = ( $depth ) ? str_repeat( "\t", $depth ) : ''; - /** - * Dividers, Headers or Disabled - * ============================= - * Determine whether the item is a Divider, Header, Disabled or regular - * menu item. To prevent errors we use the strcasecmp() function to so a - * comparison that is not case sensitive. The strcasecmp() function returns - * a 0 if the strings are equal. - */ - if ( strcasecmp( $item->attr_title, 'divider' ) == 0 && $depth === 1 ) { - $output .= $indent . ''; - $fb_output .= ''; - if ( $container ) { - $fb_output .= ''; - } - echo $fb_output; - } - } -} - -endif; /* End if class exists */ diff --git a/inc/class-wp-bootstrap-navwalker.php b/inc/class-wp-bootstrap-navwalker.php new file mode 100644 index 0000000..cd598e1 --- /dev/null +++ b/inc/class-wp-bootstrap-navwalker.php @@ -0,0 +1,555 @@ +item_spacing ) && 'discard' === $args->item_spacing ) { + $t = ''; + $n = ''; + } else { + $t = "\t"; + $n = "\n"; + } + $indent = str_repeat( $t, $depth ); + // Default class to add to the file. + $classes = array( 'dropdown-menu' ); + /** + * Filters the CSS class(es) applied to a menu list element. + * + * @since WP 4.8.0 + * + * @param array $classes The CSS classes that are applied to the menu `'; + if ( $container ) { + $fallback_output .= ''; + } + + // if $args has 'echo' key and it's true echo, otherwise return. + if ( array_key_exists( 'echo', $args ) && $args['echo'] ) { + echo $fallback_output; // WPCS: XSS OK. + } else { + return $fallback_output; + } + } + } + + /** + * Find any custom linkmod or icon classes and store in their holder + * arrays then remove them from the main classes array. + * + * Supported linkmods: .disabled, .dropdown-header, .dropdown-divider, .sr-only + * Supported iconsets: Font Awesome 4/5, Glypicons + * + * NOTE: This accepts the linkmod and icon arrays by reference. + * + * @since 4.0.0 + * + * @param array $classes an array of classes currently assigned to the item. + * @param array $linkmod_classes an array to hold linkmod classes. + * @param array $icon_classes an array to hold icon classes. + * @param integer $depth an integer holding current depth level. + * + * @return array $classes a maybe modified array of classnames. + */ + private function seporate_linkmods_and_icons_from_classes( $classes, &$linkmod_classes, &$icon_classes, $depth ) { + // Loop through $classes array to find linkmod or icon classes. + foreach ( $classes as $key => $class ) { + // If any special classes are found, store the class in it's + // holder array and and unset the item from $classes. + if ( preg_match( '/^disabled|^sr-only/i', $class ) ) { + // Test for .disabled or .sr-only classes. + $linkmod_classes[] = $class; + unset( $classes[ $key ] ); + } elseif ( preg_match( '/^dropdown-header|^dropdown-divider|^dropdown-item-text/i', $class ) && $depth > 0 ) { + // Test for .dropdown-header or .dropdown-divider and a + // depth greater than 0 - IE inside a dropdown. + $linkmod_classes[] = $class; + unset( $classes[ $key ] ); + } elseif ( preg_match( '/^fa-(\S*)?|^fa(s|r|l|b)?(\s?)?$/i', $class ) ) { + // Font Awesome. + $icon_classes[] = $class; + unset( $classes[ $key ] ); + } elseif ( preg_match( '/^glyphicon-(\S*)?|^glyphicon(\s?)$/i', $class ) ) { + // Glyphicons. + $icon_classes[] = $class; + unset( $classes[ $key ] ); + } + } + + return $classes; + } + + /** + * Return a string containing a linkmod type and update $atts array + * accordingly depending on the decided. + * + * @since 4.0.0 + * + * @param array $linkmod_classes array of any link modifier classes. + * + * @return string empty for default, a linkmod type string otherwise. + */ + private function get_linkmod_type( $linkmod_classes = array() ) { + $linkmod_type = ''; + // Loop through array of linkmod classes to handle their $atts. + if ( ! empty( $linkmod_classes ) ) { + foreach ( $linkmod_classes as $link_class ) { + if ( ! empty( $link_class ) ) { + + // check for special class types and set a flag for them. + if ( 'dropdown-header' === $link_class ) { + $linkmod_type = 'dropdown-header'; + } elseif ( 'dropdown-divider' === $link_class ) { + $linkmod_type = 'dropdown-divider'; + } elseif ( 'dropdown-item-text' === $link_class ) { + $linkmod_type = 'dropdown-item-text'; + } + } + } + } + return $linkmod_type; + } + + /** + * Update the attributes of a nav item depending on the limkmod classes. + * + * @since 4.0.0 + * + * @param array $atts array of atts for the current link in nav item. + * @param array $linkmod_classes an array of classes that modify link or nav item behaviors or displays. + * + * @return array maybe updated array of attributes for item. + */ + private function update_atts_for_linkmod_type( $atts = array(), $linkmod_classes = array() ) { + if ( ! empty( $linkmod_classes ) ) { + foreach ( $linkmod_classes as $link_class ) { + if ( ! empty( $link_class ) ) { + // update $atts with a space and the extra classname... + // so long as it's not a sr-only class. + if ( 'sr-only' !== $link_class ) { + $atts['class'] .= ' ' . esc_attr( $link_class ); + } + // check for special class types we need additional handling for. + if ( 'disabled' === $link_class ) { + // Convert link to '#' and unset open targets. + $atts['href'] = '#'; + unset( $atts['target'] ); + } elseif ( 'dropdown-header' === $link_class || 'dropdown-divider' === $link_class || 'dropdown-item-text' === $link_class ) { + // Store a type flag and unset href and target. + unset( $atts['href'] ); + unset( $atts['target'] ); + } + } + } + } + return $atts; + } + + /** + * Wraps the passed text in a screen reader only class. + * + * @since 4.0.0 + * + * @param string $text the string of text to be wrapped in a screen reader class. + * @return string the string wrapped in a span with the class. + */ + private function wrap_for_screen_reader( $text = '' ) { + if ( $text ) { + $text = '' . $text . ''; + } + return $text; + } + + /** + * Returns the correct opening element and attributes for a linkmod. + * + * @since 4.0.0 + * + * @param string $linkmod_type a sting containing a linkmod type flag. + * @param string $attributes a string of attributes to add to the element. + * + * @return string a string with the openign tag for the element with attribibutes added. + */ + private function linkmod_element_open( $linkmod_type, $attributes = '' ) { + $output = ''; + if ( 'dropdown-item-text' === $linkmod_type ) { + $output .= ''; + } elseif ( 'dropdown-header' === $linkmod_type ) { + // For a header use a span with the .h6 class instead of a real + // header tag so that it doesn't confuse screen readers. + $output .= ''; + } elseif ( 'dropdown-divider' === $linkmod_type ) { + // this is a divider. + $output .= ''; + } + return $output; + } + } +} From 4f0295ebea3f5a50a2a814aef9b2e37040da2e71 Mon Sep 17 00:00:00 2001 From: William Patton Date: Tue, 17 Apr 2018 17:10:40 +0100 Subject: [PATCH 2/2] Modify walker with 'understarp' prefixed on class name and as textdomain --- header.php | 2 +- inc/class-wp-bootstrap-navwalker.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/header.php b/header.php index ec81538..9af38b8 100644 --- a/header.php +++ b/header.php @@ -70,7 +70,7 @@ $container = get_theme_mod( 'understrap_container_type' ); 'fallback_cb' => '', 'menu_id' => 'main-menu', 'depth' => 2, - 'walker' => new WP_Bootstrap_Navwalker(), + 'walker' => new Understrap_WP_Bootstrap_Navwalker(), ) ); ?> diff --git a/inc/class-wp-bootstrap-navwalker.php b/inc/class-wp-bootstrap-navwalker.php index cd598e1..71b52d9 100644 --- a/inc/class-wp-bootstrap-navwalker.php +++ b/inc/class-wp-bootstrap-navwalker.php @@ -20,13 +20,13 @@ */ /* Check if Class Exists. */ -if ( ! class_exists( 'WP_Bootstrap_Navwalker' ) ) { +if ( ! class_exists( 'Understrap_WP_Bootstrap_Navwalker' ) ) { /** * WP_Bootstrap_Navwalker class. * * @extends Walker_Nav_Menu */ - class WP_Bootstrap_Navwalker extends Walker_Nav_Menu { + class Understrap_WP_Bootstrap_Navwalker extends Walker_Nav_Menu { /** * Starts the list before the elements are added. @@ -363,7 +363,7 @@ if ( ! class_exists( 'WP_Bootstrap_Navwalker' ) ) { if ( $menu_class ) { $fallback_output .= ' class="' . esc_attr( $menu_class ) . '"'; } $fallback_output .= '>'; - $fallback_output .= '
  • ' . esc_html__( 'Add a menu', 'wp-bootstrap-navwalker' ) . '
  • '; + $fallback_output .= '
  • ' . esc_html__( 'Add a menu', 'understrap' ) . '
  • '; $fallback_output .= ''; if ( $container ) { $fallback_output .= '';