WordPress.org

Ready to get started?Download WordPress

Forums

Adding Private Pages to WordPress 3 Menus (10 posts)

  1. Brandon Wamboldt
    Member
    Posted 3 years ago #

    I am currently building a site where some pages are only accessible if you are logged in. I want the admin to be able to add these pages to the site navigation (Currently using WP3's menu manager), and they will only show up IF THE USER IS LOGGED IN.

    Currently private pages don't even appear for me to add to the menus. What would be the best way to do what I want? Is there a way to use filters/actions to enable support for this?

  2. webjunk
    Member
    Posted 3 years ago #

    Private Pages are not supposed to display in menus BECAUSE THEY ARE PRIVATE! There are several plugins that might do what you want if you search.
    ou can also place in the navigation a call for like:
    if(current_user_can('read_private_pages'))

    And then put whatever pages you want listed below that.

  3. Brandon Wamboldt
    Member
    Posted 3 years ago #

    You provided me with a completely useless post that could have been avoided if you read my post. I am aware that private pages ARE PRIVATE. Users can have the role read_private. Those users should therefore be able to see these pages when logged in.

  4. webjunk
    Member
    Posted 3 years ago #

    You won't get very far with your attitude.
    First you have the role named incorrectly and it only applies to Administrators and Editors. not anyone else unless you use a plugin which you did not mention in your post.
    Beyond that I gave a functioning solution. If you don't like it then just write something yourself instead of complaining. Like everyone else on here not getting paid anything here to deal with people like you.

  5. Brandon Wamboldt
    Member
    Posted 3 years ago #

    My apologies for being rude and not supplying adequate information. I am using a role manager plugin and I added this bit of code.

    Note: This isn't an ideal fix as you must edit core WordPress files but I couldn't find another way

    wp-includes/nav-menu-template.php

    <?php
    ...
    class Walker_Nav_Menu extends Walker {
        ...
    	function start_el(&$output, $item, $depth, $args) {
    		global $wp_query;
    		$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
    
    		$class_names = $value = '';
    
    		$classes = empty( $item->classes ) ? array() : (array) $item->classes;
    
    		$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
    		$class_names = ' class="' . esc_attr( $class_names ) . '"';
    
    		// Check to see if the user is logged in
    		if ( get_post_meta( $item->object_id , '_members_only' , true ) == 'true' ) {
    			if ( is_user_logged_in() )
    			{
    				$output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';
    			}
    		}
    		else
    		{
    			$output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';
    		}	
    
    		$attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
    		$attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
    		$attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
    		$attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';
    
    		$item_output = $args->before;
    		$item_output .= '<a'. $attributes .'>';
    		$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    		$item_output .= '';
    		$item_output .= $args->after;
    
    		// Check to see if the user is logged in
    		if ( get_post_meta( $item->object_id , '_members_only' , true ) == 'true' ) {
    			if ( is_user_logged_in() )
    			{
    				$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    			}
    		}
    		else
    		{
    			$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    		}
    	}
    }
    ...

    That checks for a meta value called _members_only and if it has a value of 'true' then the page is only displayed in the navigation if you're logged in. You'll need to add similar code to your page template files, as well as this in functions.php or a plugin

    wp-content/themes/your-theme/functions.php

    <?php
    function ibew2010_add_sidebar_meta_box() {
        add_meta_box( 'ibew_sidebar_text' , 'Sidebar Content' , 'create_ibew2010_sidebar_meta' , 'page' , 'normal' , 'high' );
    	add_meta_box( 'ibew_member_ony' , 'Members Only' , 'create_ibew2010_members_meta' , 'page' , 'side' , 'high' );
    }
    add_action( 'add_meta_boxes' , 'ibew2010_add_sidebar_meta_box' );
    
    function create_ibew2010_sidebar_meta() {
        global $post;
    
    	$meta_box_value = get_post_meta( $post->ID , '_sidebar_content_ibew' , true ); 
    
    	echo '<input type="hidden" name="ibew2010_sidebar_nonce" id="ibew2010_sidebar_nonce" value="' . wp_create_nonce( 'ibew2010_sidebar' ) . '" />';
    	the_editor( $meta_box_value , 'sidebar_content_ibew' , 'title' , false );
    	echo '<div style="height:13px;width:100%;"> </div>';
    }
    
    function create_ibew2010_members_meta() {
        global $post;
    
    	$meta_box_value = get_post_meta( $post->ID , '_members_only' , true );
    	if ( $meta_box_value == 'true' ) {
    		$meta_box_value = 'checked="checked"';
    	}
    
    	echo '<input type="checkbox" name="members_only" id="members_only" value="true" '.$meta_box_value .' /> Restrict To Members?';
    }
    
    /* When the post is saved, saves our custom data */
    function ibew2010_save_postdata( $post_id )
    {
        // verify this came from the our screen and with proper authorization,
        // because save_post can be triggered at other times
        if ( !wp_verify_nonce( $_POST['ibew2010_sidebar_nonce'], 'ibew2010_sidebar' ) )
        {
            return $post_id;
        }
    
        // verify if this is an auto save routine. If it is our form has not been submitted, so we dont want
        // to do anything
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
            return $post_id;
    
        // Save
        update_post_meta( $post_id , '_sidebar_content_ibew' , $_POST['sidebar_content_ibew'] );
        update_post_meta( $post_id , '_members_only' , $_POST['members_only'] );
    
        return $post_id;
    }
    add_action( 'save_post' , 'ibew2010_save_postdata' );

    I didn't change the name of my functions as anybody who needs this code can.

  6. webjunk
    Member
    Posted 3 years ago #

    Would NEVER recommend editing core files. WHat do you do when they are updated? Also consider that functions and their code can change. So then you have to start re-writing & debugging your code add-on. EVERYTIME there is an upodate.

  7. Brandon Wamboldt
    Member
    Posted 3 years ago #

    I am aware of this, but as I stated I wasn't able to find another way. I'm going to propose the developers add a hook to certain places in the walker class so that I can do this some other way.

  8. Brandon Wamboldt
    Member
    Posted 3 years ago #

    I was not comfortable with the code I provided so I came up with this instead. It doesn't alter any core files, I just added it to my theme's functions.php. It works perfectly.

    <?php
    /**
     * This allows us to make a page restricted to members (Any authenticated users)
     * still showing up in the menus (Only if authenticated). This functionality
     * sdoes not exist if using Public/Private
     */
    add_action( 'wp' , 'check_for_members_only' );
    
    function check_for_members_only() {
    	global $post;
    
    	if ( get_post_meta( $post->ID , '_members_only' , true ) && !is_user_logged_in() ) {
    		header( 'Location: /wp-login.php' );
    		exit();
    	}
    }
    
    class Walker_Nav_Menu_CMS extends Walker_Nav_Menu {
    	function start_el(&$output, $item, $depth, $args) {
    		global $wp_query;
    
    		$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
    
    		$class_names = $value = '';
    
    		$classes = empty( $item->classes ) ? array() : (array) $item->classes;
    
    		$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
    		$class_names = ' class="' . esc_attr( $class_names ) . '"';
    
    		if ( !get_post_meta( $item->object_id , '_members_only' , true ) || is_user_logged_in() ) {
    			$output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';
    		}
    
    		$attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
    		$attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
    		$attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
    		$attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';
    
    		$item_output = $args->before;
    		$item_output .= '<a'. $attributes .'>';
    		$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    		$item_output .= '</a>';
    		$item_output .= $args->after;
    
    		if ( !get_post_meta( $item->object_id, '_members_only' , true ) || is_user_logged_in() ) {
    			$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    		}
    	}
    }
    function add_members_only_meta_box() {
        add_meta_box( 'add_members_only_meta' , 'Members Only' , 'add_members_only_meta' , 'page' , 'side' , 'high' );
    }
    add_action( 'add_meta_boxes' , 'add_members_only_meta_box' );
    
    function add_members_only_meta() {
        global $post;
    
        $meta_box_value = get_post_meta( $post->ID , '_members_only' , true ); 
    
        if ( $meta_box_value == 'true' ) {
            $meta_box_value = 'checked="checked"';
        }
    
        echo '<input type="hidden" name="members_only_nonce" id="members_only_nonce" value="' . wp_create_nonce( 'members_only' ) . '" />';
        echo '<input type="checkbox" name="members_only" id="members_only" value="true" '.$meta_box_value .' /> Restrict To Members?';
    }
    
    /* When the post is saved, saves our custom data */
    function members_only_save_postdata( $post_id )
    {
        // verify this came from the our screen and with proper authorization,
        // because save_post can be triggered at other times
        if ( !wp_verify_nonce( $_POST['members_only_nonce'], 'members_only' ) )
        {
            return $post_id;
        }
    
        // verify if this is an auto save routine. If it is our form has not been submitted, so we dont want
        // to do anything
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
            return $post_id;
    
        // Save
        update_post_meta( $post_id , '_members_only' , $_POST['members_only'] );
    
        return $post_id;
    }
    add_action( 'save_post' , 'members_only_save_postdata' );
    /** End of code **/
  9. usingmyhead
    Member
    Posted 3 years ago #

    @brandon

    That is awesome - can I ask which role manager you are using? I have been using Role Scoper but am open to any other options if it means I can use your code.

    This is exactly what I have been trying to do - with great difficulty - so thanks a MILLION for posting.

  10. Ammaletu
    Member
    Posted 3 years ago #

    There is something missing from above code. In order to actually use the new walker class, you need this:

    function my_wp_nav_menu_args($args) {
      $args['walker'] = new Walker_Nav_Menu_CMS;
      return $args;
    }
    
    add_filter('wp_nav_menu_args', 'my_wp_nav_menu_args');

Topic Closed

This topic has been closed to new replies.

About this Topic