• Resolved volfro

    (@volfro)


    Hi, everybody.

    I’m building a site that will have two buttons as navigation, with wp_list_pages generating sub-navigation beneath these two main pages using sub-pages.

    It’s listing the sub-pages just fine, but I can’t figure out how to give the parent pages a certain class while you’re on a subpage.

    Right now it looks like this:

    <?php
    	global $wp_query;
    
    	//check to see if current page has a parent:
    
    	if( empty($wp_query->post->post_parent)) {
    
    		$parent = $wp_query->post->ID; //if it doesn't, give it an ID of $parent 
    
    	} else {
    
    		$parent = $wp_query->post->post_parent; //if it does, give its parent an ID of $parent
    
    	}
    	rewind_posts();
    ?>
    <ul id="nav">
    	<li class="commercial"><a href="<?php bloginfo('url') ?>/downtown-commercial/" title="Downtown Commercial"<?php if(is_page('downtown-commercial') || $post->post_parent == $parent) : echo " class=\"active\""; endif ?>>Commercial</a></li>
    	<li class="disaster"><a href="<?php bloginfo('url') ?>/disaster-restoration/" title="Disaster Restoration"<?php if(is_page('disaster-restoration') || $post->post_parent == $parent) : echo " class=\"active\""; endif ?>>Disaster Restoration</a></li>
    </ul>

    and then the call for the subpages looks like this:

    <?php if (is_page()) :
    
    	if (wp_list_pages("title_li=&child_of=$parent&echo=0")) : ?>
    
    		<ul id="subNav">
    			<?php wp_list_pages("title_li=&child_of=$parent"); ?>
    		</ul>
    	<?php endif;
    
    	endif;
    ?>

    Instead of applying the “active” class only to the current page parent, it adds it to both of them, and I can’t quite figure out why.

    Any suggestions?

    Thanks everybody!

Viewing 12 replies - 1 through 12 (of 12 total)
  • Thread Starter volfro

    (@volfro)

    Anybody?

    I know this is possible with wp_list_pages, but I’m not using wp_list_pages for the parent navigation since they both need a unique ID for styling purposes.

    PHP has to be able to take care of this. I just don’t know enough to figure it out.

    Hey volfro, I’m not amazing at PHP yet either, so this might (read: probably will ?? ) be wrong.

    However, for the part when you add the class, you have the ‘||’ , which means ‘or,’ so the text is saying ‘if it is that page is downtown-commercial OR $post->parent == $parent’ Wouldn’t you want that to read as AND (which would be &&), meaning that both of them would have to be true in order to fulfill the if?

    Either way, for sure the is in that area, no? Since you say the sub-pages are working fine.

    Thread Starter volfro

    (@volfro)

    Yeah, I’m pretty sure it’s specifically within that if statement, but I’m not sure why it’s not working.

    I need the or there because the page will only ever meet one of those two conditions (or, what I think are the conditions I’m giving it). The page can either be ‘downtown-commercial’ or ‘disaster-restoration’, or a child of one of those two.

    So what I think I’m saying (or, at least, what I want to say) here is, “If this is the page ‘downtown-commercial’ OR if this is the child of the page ‘downtown-commercial’, insert class=”active”.” For both downtown-commercial and disaster-restoration.

    The is_page condition works just fine; it’s that other one that’s throwing it off, and both are given a class of “active” if I’m on either’s subpage.

    Pulling my hair out here.

    Thread Starter volfro

    (@volfro)

    Oooooh, hey I get what that is doing now. I was confused about what the $post->post_parent=$parent thing was doing at first, but now that you explained that I think I am starting to understand.

    As such, wouldn’t the second part ALWAYS be fulfilled so long as the page is a child and isn’t the parent page itself? The second part of your OR statement appears to go in and check if it is a child; it goes up to the else to see that it assigned $parent to post->parent. So therefore, so long as it is a child page, it matches those requirements, thus, being OR’s, the ‘then’ statement of attaching ‘active’ will be carried out, since the second half will always be true if it is a child page.

    To me, right now the code is saying ‘If this page is the particular page (ex. downtown-commercial) OR if it is a child page IN GENERAL (not specific to either downtown-commercial or disaster-restoration), then assign the class. In this way, the only pages that will actually create only one ‘active’ class given the code are the parent pages, where the first part of the if/else that is at the top of the code is fulfilled ($parent = $wp_query->post->ID;), thus making the second half of your OR statement false.

    (lol It’s really difficult to describe this clearly. ?? )

    For the record, I really like your Big Sweater Design page. Nice work.

    Thread Starter volfro

    (@volfro)

    Your post got me thinking. (It took some reading and re-reading what you said to get it!) I’m pretty sure that the $post->post_parent == $parent was saying what I thought it was saying—if the current post’s parent is the same as $parent then print class="active". However, putting that condition in both list items just said the same thing twice: “If this page’s parent is the same as $parent then print x.”

    What it needed to do was to determine whether the current page’s parent was one of the two pages named. According to the script above the navigation, any page that has children gets named $parent, and any child page’s parent gets named $parent. So my OR statement wasn’t quite specific enough.

    Instead, I need the code to say, in effect, “If this is [for example] the page named disaster-relief OR if this is one of disaster-relief’s children, print ‘class=”active”‘; otherwise, do nothing.” So using the variable $parent, defined earlier in the page, the script now reads

    if (is_page('disaster-relief') || $parent == [page ID number] : echo "class=\"acitve\"

    where [page ID number] is equal to the desired parent page’s ID. It’s the same thing for both lis, but with the appropriate page ID for each.

    This, obviously, is not ideal and isn’t really dynamic; I’d like to store the two pages’ IDs as variables (say, $disaster-restoration and $downtown-commercial) and call them using the variables, instead of the IDs, so that I won’t have to hard-code the IDs in there by editing the header after the theme is uploaded.

    Yes, my PHP knowledge is that limited. Not exactly clear on how to restart the loop to call those pages, then store their IDs in variables, though I’m this close.

    I’m not to worried about keeping it completely dynamic in this case, since there are only two options in the client’s site, and that’s how it’ll stay. But it’d be nice to know how to do that dynamically for future reference.

    Thread Starter volfro

    (@volfro)

    Whoops! Double post. Sorry about that. Connection screwed up.

    Thanks for the compliment, by the way! I’m workoing on changing some things around on my site; I was planning on posting a thread at the FSw forums once it’s straightened out. Glad you like it though.

    Thread Starter volfro

    (@volfro)

    And done.

    The script now looks like this:

    <?php
    global $post;
         //check to see if current page has a parent:
         if(is_page() && $post->post_parent) { //if the current post is a page and has a parent, then:
              $parent = $post->post_parent; //store its ID in a variable called $parent. Otherwise:
         }else{
              $parent = $post->ID; //if it <em>doesn't</em> have a parent, it must be a parent, so its own ID gets stored as $parent.
         }

    That bit is pretty self-explanatory. Next, so that I don’t have to know the IDs of the parents named disaster-restoration and downtown-commercial, I store those IDs as variables as well.

    $downtown_commercial_function = new $wp_query('pagename=downtown-commercial'); //create a new query and store it in a variable called $downtown_commercial_function; similar to doing a query_posts(), but I don't trust query_posts() this early in a script.
         while ($downtown_commercial_function -> have_posts()) : $downtown_commercial_function -> the_post(); //Start the loop using the new query
              $downtown_commercial = $post->ID //store the page named downtown-commercial's ID in a variable called $downtown_commercial
         endwhile; //close the loop
         rewind_posts(); //Rewinds the loop for the next loop(s)

    and that gets repeated, only with the page named disaster-restoration (and variables named accordingly).

    Next, the list items and their classes:

    <?php if(is_page('downtown-commercial') //if the current page is the page named downtown-commercial
         || $parent == $downtown_commercial) : //OR if the page's parent's ID is the same as that of the page named downtown-commercial, then
              echo " class=\"active\"";
    endif; ?>

    And it works. If somebody has a cleaner, quicker way to do this, though, I’d be much obliged. Or if my code needs cleaning up, critiques are welcome.

    Nice job, volfro! I am glad I could be of assistance. I was going to offer up replacing the second half of your or statement with a ‘get_page_parent’ WordPress template tag or something, but it appears that they only have a tag like that for categories. Shame. In my findings it appears that most people did it much as you have.

    This person did write an ‘is_child’ function, though.
    https://www.nicholasroussos.com/general/wordpress-is_child-function/

    perhaps that could clean up a bit of the variable-making.

    Thread Starter volfro

    (@volfro)

    Yeah, it’s nice that pages can be hierarchal, but it would be even nicer if there were more template tags to use in that respect.

    That is_child function is great! It’s in my del.icio.us now. Not sure how I’d use it in this template, but that’s probably because I’m exhausted and really need to think about something other than code.

    I figured, theoretically, you could paste the code to create that function up above, then your ‘active’ code would look like this:

    <?php if(is_page(‘downtown-commercial’) //if the current page is the page named downtown-commercial
    || is_child(‘downtown-commercial’) : //OR if the page is a child of downtown-commercial, then
    echo ” class=\”active\””;
    endif; ?>

    That way, if the parent is NOT downtown-commercial, it won’t run, since the function goes and checks post->parent against the value you put into the single quote in the code I put up above. The parents would fulfill the if due to the first part of the or statement, thus you wouldn’t need that code business you have up above about assigning values to $parent.

    Although, on second inspection, I’m not sure if it will recognize ‘downtown-commercial’ upon re-reading the page about it. However, if this is the case (perhaps put an echo in there to see what it spits out), if it were me, I would just grab the page ID’s of the parent pages from the ‘Manage Pages’ section over in the WP admin panel and plug those in, since this code, if it works, will be far, far cleaner than the one we cobbled together yesterday.

    Thread Starter volfro

    (@volfro)

    Yeah, I think it only works with the numerical ID.

    The $parent variable is actually used further down in the template, for calling the child pages with wp_list_pages. I didn’t necessarily need it for the two buttons, but it comes in handy anyway.

    If I were going to use a numerical ID, I would’ve just foregone the use of variables at all—but, as you can see, I’m a bit stubborn. One, I didn’t want to have to go in and edit the template file after it was uploaded (I’m using a local install of WP, and the page IDs would likely be different once I created them in their final environment), and two, learning how to do this means I can use it in other themes as well. I learned something about PHP in the process, which is an excellent thing.

    Thanks again for all your help!

Viewing 12 replies - 1 through 12 (of 12 total)
  • The topic ‘Parent page highlighting – what am I doing wrong?’ is closed to new replies.