1

I am developing a single page site within WordPress, that contains multiple sections. These sections are pages in WordPress.

In my index.php I loop through all pages within WordPress and add them to the index file - front page with a custom loop.

Loop through all pages

<?php 
    $args = array('post_type' => 'page', 'orderby' => 'menu_order', 'posts_per_page' => -1);
    $loop = new WP_Query($args); 
?>
<?php if ($loop) : while ($loop->have_posts()) : $loop->the_post(); ?>

    <?php $slides = get_field('flexslider'); ?>
    <?php 
        if ($slides) { 
            get_template_part( 'templates/slideshow' );
        } else {
            get_template_part( 'templates/parallax' );
        } 
    ?>

<?php endwhile; ?>
<?php endif; ?>

MENU

Because I developing a single page layout, I should modify the basic WordPress navigation to output the right menu links specific for this type of layout. So the normal output (I removed the id and class attributes to focus on the right thing) should be replaced for a hashtag and the slug of the page.

Basic menu link markup:

<li id="" class=""><a href="http://prachtelectronica.nl/wordpress/?page_id=10" class="menu-link main-menu-link">Lightning</a></li>

Modified menu link (what I wish):

<li id="" class=""><a href="#lightning" class="menu-link main-menu-link">Lightning</a></li>

I use the following WordPress function to build a menu:

<?php wp_nav_menu( array(
       'theme_location' => 'primary-menu',
       'menu' => 'primary-menu',
       'container' => 'nav',
       'container_id' => 'primary-navwrapper',
       'menu_id' => 'listnav',
    ));
?>

I would like that the position of each section (page) will be determine by the menu order that is set in Appearance > Menu, so the customer has only three thing to do when creating a new section (page). (1) Create a page, (2) add the page to the menu (3) and order it inside the menu structure.

I already using the menu_order property inside my page loop (as you can see above) to display the pages inside the index.php file. The order of the menu is used to position the sections (pages) in the right order.

One extra option for the pages is that the user can add a custom template to a page by selecting the template ads inside the WP editor. Pages that make use of this template named, "ads", should be displayed in index.php as a section, but not appears as a menu item in the list of menu item, because these sections are not relevant for the primary content.

I hope there is a solution for my wish. If you have any questions, please let me know it in the comments below. For now, thanks in advance.

  • Your query does not fetch the pages added to the menu, but all pages published. And the ordering is not the order in which they have been ordered in the menu (this is independent of menu_order, which is used for wp_page_menu(), admin pages and queries ordered by menu_order). To get the pages in a specific menu and in its order check the function wp_get_nav_menu_items() – JHoffmann Nov 21 '15 at 21:47
1

To be able to change the Link, you can hook into the nav_menu_link_attributes filter.

if ( ! function_exists( 'wpse_209457_nav_menu_link_attributes' ) ) {
    function wpse_209457_nav_menu_link_attributes( $atts, $item, $args ) {
        if ( 'primary-menu' == $args->theme_location ) {
            // Get the target posts slug
            $object_data = get_post( $item->object_id );
            $atts['href'] = '#'.$object_data->post_name;
            return $atts;
        }
    }
}
 add_filter( 'nav_menu_link_attributes', 'wpse_209457_nav_menu_link_attributes', 10, 3 );

To make specific items not appear in menus depending on the template they use would be better suited in a separate question, but I'm going to post the solution anyway. You need to use another hook here:

if ( ! function_exists( 'wpse_209457_wp_nav_menu_objects' ) ) {
    function wpse_209457_wp_nav_menu_objects( $sorted_menu_items, $args ) {
        foreach ( $sorted_menu_items as $key => $item ) {
            $template = get_post_meta( $item->object_id, '_wp_page_template', true );
            if ( "templates/ads.php" == $template ) {
                unset( $sorted_menu_items[$key] );
            }
        }
        return $sorted_menu_items;
    }
}
add_filter ( 'wp_nav_menu_objects', 'wpse_209457_wp_nav_menu_objects', 10, 2 );

I didn't run this code, I hope it works for you.

  • Thank you JHoffmann, is this also possible with wp_page_menu? Because I also need this for wp_page_menu . If you have also an code for that, it would be absolute great. I am very greatful! – Casper Nov 21 '15 at 20:25
  • I guess this is not possible, as the filter is called in Walker_Nav_Menu class and as far as I know wp_page_menu does not work with Walkers. – JHoffmann Nov 21 '15 at 20:31
  • Hmm, I ask this because I am stuck with the following: I create a single page site. In index.php I loop through all pages within WordPress and add them to the index file - front page with a custom loop. What I want is that the menu order determine on which position each section (page) should be placed. I use the menu_order to order the sections. But there are some sections that are using a custom template. These sections should not appear in the menu as a link, only as the page. And the links should be replaced with #slug. Do you have any ideas how to achieve this. It would help me so much. – Casper Nov 21 '15 at 20:49
  • Please extend your question to include this information. And please make it clear what you mean by "These sections should not appear in the menu as a link, only as the page." I guess I have the solution you need, I will extend my answer when your question states clearer, what you need. – JHoffmann Nov 21 '15 at 20:59
  • My apologize for that it is not entirely clear, I've updated my question. Sounds at least promising. Would be very nice if you have an answer to this question! – Casper Nov 21 '15 at 21:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.