Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
11/09/2012 04:28:30 PM (12 years ago)
Author:
djpaul
Message:

Introduces bp_nav_menu(), which displays a merged navigation list from registered components. Fixes #4629.

BP has historically used bp_get_displayed_user_nav() and bp_get_options_nav() to render the navigation, and these menus have always been visually separate in the Default theme; either in columns before 1.2, and in rows since 1.2.

To provide more customisation for theme authors, and have both parts of the navigation displayed in the same block, this change introduces a merged menu function, with the parts from bp_get_options_nav nested appropriately under bp_get_displayed_user_nav.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/bp-core/bp-core-classes.php

    r6493 r6503  
    17971797    }
    17981798}
     1799
     1800/**
     1801 * Create HTML list of BP nav items
     1802 *
     1803 * @since BuddyPress (1.7)
     1804 */
     1805class BP_Walker_Nav_Menu extends Walker_Nav_Menu {
     1806    /**
     1807     * @since BuddyPress (1.7)
     1808     * @var array
     1809     */
     1810    var $db_fields = array( 'id' => 'css_id', 'parent' => 'parent' );
     1811
     1812    /**
     1813     * @since BuddyPress (1.7)
     1814     * @var string
     1815     */
     1816    var $tree_type = array();
     1817
     1818    /**
     1819     * Display array of elements hierarchically.
     1820     *
     1821     * This method is almost identical to the version in {@link Walker::walk()}. The only change is on one line
     1822     * which has been commented. An IF was comparing 0 to a non-empty string which was preventing child elements
     1823     * being grouped under their parent menu element.
     1824     *
     1825     * This caused a problem for BuddyPress because our primary/secondary navigations doesn't have a unique numerical
     1826     * ID that describes a hierarchy (we use a slug). Obviously, WordPress Menus use Posts, and those have ID/post_parent.
     1827     *
     1828     * @param array $elements
     1829     * @param int $max_depth
     1830     * @return string
     1831     * @see Walker::walk()
     1832     * @since BuddyPress (1.7)
     1833     */
     1834    function walk( $elements, $max_depth ) {
     1835        $args   = array_slice( func_get_args(), 2 );
     1836        $output = '';
     1837
     1838        if ( $max_depth < -1 ) // invalid parameter
     1839            return $output;
     1840
     1841        if ( empty( $elements ) ) // nothing to walk
     1842            return $output;
     1843
     1844        $id_field     = $this->db_fields['id'];
     1845        $parent_field = $this->db_fields['parent'];
     1846
     1847        // flat display
     1848        if ( -1 == $max_depth ) {
     1849
     1850            $empty_array = array();
     1851            foreach ( $elements as $e )
     1852                $this->display_element( $e, $empty_array, 1, 0, $args, $output );
     1853
     1854            return $output;
     1855        }
     1856
     1857        /*
     1858         * need to display in hierarchical order
     1859         * separate elements into two buckets: top level and children elements
     1860         * children_elements is two dimensional array, eg.
     1861         * children_elements[10][] contains all sub-elements whose parent is 10.
     1862         */
     1863        $top_level_elements = array();
     1864        $children_elements  = array();
     1865
     1866        foreach ( $elements as $e ) {
     1867            // BuddyPress: changed '==' to '==='. This is the only change from version in Walker::walk().
     1868            if ( 0 === $e->$parent_field )
     1869                $top_level_elements[] = $e;
     1870            else
     1871                $children_elements[$e->$parent_field][] = $e;
     1872        }
     1873
     1874        /*
     1875         * when none of the elements is top level
     1876         * assume the first one must be root of the sub elements
     1877         */
     1878        if ( empty( $top_level_elements ) ) {
     1879
     1880            $first              = array_slice( $elements, 0, 1 );
     1881            $root               = $first[0];
     1882            $top_level_elements = array();
     1883            $children_elements  = array();
     1884
     1885            foreach ( $elements as $e ) {
     1886                if ( $root->$parent_field == $e->$parent_field )
     1887                    $top_level_elements[] = $e;
     1888                else
     1889                    $children_elements[$e->$parent_field][] = $e;
     1890            }
     1891        }
     1892
     1893        foreach ( $top_level_elements as $e )
     1894            $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
     1895
     1896        /*
     1897         * if we are displaying all levels, and remaining children_elements is not empty,
     1898         * then we got orphans, which should be displayed regardless
     1899         */
     1900        if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
     1901            $empty_array = array();
     1902
     1903            foreach ( $children_elements as $orphans )
     1904                foreach ( $orphans as $op )
     1905                    $this->display_element( $op, $empty_array, 1, 0, $args, $output );
     1906         }
     1907
     1908         return $output;
     1909    }
     1910
     1911    /**
     1912     * Displays the current <li> that we are on.
     1913     *
     1914     * @param string $output Passed by reference. Used to append additional content.
     1915     * @param object $item Menu item data object.
     1916     * @param int $depth Depth of menu item. Used for padding. Optional, defaults to 0.
     1917     * @param array $args Optional
     1918     * @param int $current_page Menu item ID. Optional.
     1919     * @since BuddyPress (1.7)
     1920     */
     1921    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
     1922        // If we're someway down the tree, indent the HTML with the appropriate number of tabs
     1923        $indent = $depth ? str_repeat( "\t", $depth ) : '';
     1924
     1925        // Add HTML classes
     1926        $class_names = join( ' ', apply_filters( 'bp_nav_menu_css_class', array_filter( $item->class ), $item, $args ) );
     1927        $class_names = ! empty( $class_names ) ? ' class="' . esc_attr( $class_names ) . '"' : '';
     1928
     1929        // Add HTML ID
     1930        $id = sanitize_html_class( $item->css_id . '-personal-li' );  // Backpat with BP pre-1.7
     1931        $id = apply_filters( 'bp_nav_menu_item_id', $id, $item, $args );
     1932        $id = ! empty( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';
     1933
     1934        // Opening tag; closing tag is handled in Walker_Nav_Menu::end_el().
     1935        $output .= $indent . '<li' . $id . $class_names . '>';
     1936
     1937        // Add href attribute
     1938        $attributes = ! empty( $item->link ) ? ' href="' . esc_attr( esc_url( $item->link ) ) . '"' : '';
     1939
     1940        // Construct the link
     1941        $item_output = $args->before;
     1942        $item_output .= '<a' . $attributes . '>';
     1943        $item_output .= $args->link_before . apply_filters( 'the_title', $item->name, 0 ) . $args->link_after;
     1944        $item_output .= '</a>';
     1945        $item_output .= $args->after;
     1946
     1947        // $output is byref
     1948        $output .= apply_filters( 'bp_walker_nav_menu_start_el', $item_output, $item, $depth, $args );
     1949    }
     1950}
Note: See TracChangeset for help on using the changeset viewer.