WordPress.org

Ready to get started?Download WordPress

Forums

wp_list_pages -- expandable menu (14 posts)

  1. kath
    Member
    Posted 7 years ago #

    Hi. I'm working on a site where they really want to have expandable menus. I know CSS and I can make the expandable menu, but I'm not sure how I can make WordPress do what I like.

    Here's what I need to do:

    1. Make headings. These can be pages. I need to remove the href attribute for links which are going to have a drop-down menu underneath them (ie a page which has no children), but there are also pages that have no children which will need to be linked from the "header" style.

    2. Add divs to some of the links. I could potentially style some of the LI/UL tags this way, but I would like to add my own divs.

    3. Add ONCLICK to

    The menu I want is a menu like this: http://www.ideaskids.com/
    The code I am currently using to make the expandable menu is

    <div class="hide" id="teens">
    		<div class="navheader"><div class="text"><a title="Resources for Teens">Resources for Teens</a></div></div>
    			<div class="second">
    				<ul class="drop">
    <li><a href="teens/teensibd.html" title="IBD">IBD</a>
    				</li>
    <li><a href="teens/teensibs.html" title="IBS">IBS</a>
    				</li>
    <li><a href="teens/teensceliac.html" title="Celiac Disease">Celiac Disease</a>
    				</li>
    <li><a href="teens/teensgerd.html" title="GERD">GERD</a>
    				</li>
    <li><a href="teens/teenssupport.html" title="Support">Support</a>
    				</li>
    <li><a href="teens/teensfun.html" title="Fun and Games">Fun and Games</a>
    				<img src="images/navexpandedbot.jpg" alt="bottomimage">
    			</div></li>

    I think MOST important things to do are:
    - *ADD THE ONLCICK FUNCTION*
    - add the image at the bottom of the sub-navs.
    - get the custom ID (though I could change it to use classes) for each top-level page.

    I want to find out where the output of wp_list_pages is defined and change it, essentially. I don't know PHP well, but I am willing to learn.

  2. Doodlebee
    Member
    Posted 7 years ago #

    Try the Fold Page List plugin.

  3. kath
    Member
    Posted 7 years ago #

    I was looking at that but I wasn't sure if I would be able to get it to do what I wanted.

    Does anyone know where the wp_list-pages() function is set? I can't find it in the php files (although I have not searched every single file exhaustively).

  4. MichaelH
    Member
    Posted 7 years ago #

    Used WinGrep to find that function in wp-includes/post-template.php

  5. kath
    Member
    Posted 7 years ago #

    Thank you! Yeah, I think this is what I needed to find ...

    In post-template.php, we get the function:

    function wp_list_pages($args = '') {
    	if ( is_array($args) )
    		$r = &$args;
    	else
    		parse_str($args, $r);
    
    	$defaults = array('depth' => 0, 'show_date' => '', 'date_format' => get_option('date_format'),
    		'child_of' => 0, 'exclude' => '', 'title_li' => __('Pages'), 'echo' => 1, 'authors' => '', 'sort_column' => 'menu_order, post_title');
    	$r = array_merge($defaults, $r);
    
    	$output = '';
    	$current_page = 0;
    
    	// sanitize, mostly to keep spaces out
    	$r['exclude'] = preg_replace('[^0-9,]', '', $r['exclude']);
    
    	// Allow plugins to filter an array of excluded pages
    	$r['exclude'] = implode(',', apply_filters('wp_list_pages_excludes', explode(',', $r['exclude'])));
    
    	// Query pages.
    	$pages = get_pages($r);
    
    	if ( !empty($pages) ) {
    		if ( $r['title_li'] )
    			$output .= '<li class="pagenav">' . $r['title_li'] . '<ul>';
    
    		global $wp_query;
    		if ( is_page() )
    			$current_page = $wp_query->get_queried_object_id();
    		$output .= walk_page_tree($pages, $r['depth'], $current_page, $r);
    
    		if ( $r['title_li'] )
    			$output .= '</ul></li>';
    	}
    
    	$output = apply_filters('wp_list_pages', $output);
    
    	if ( $r['echo'] )
    		echo $output;
    	else
    		return $output;
    }

    So I think that's where I'd be making all of my changes, or copying this function and making a new one. Can you who know more PHP than I tell me if I'm right in thinking that if ( !empty($pages) ) is telling wordpress what to show (because it's got the li - ul - li - /li - /ul -/li). So how would I say "do this if it's got children" vs "do this if it hasn't"? Can I get the URL and ID of a post instead of just whatever $r['title_li'] is (I'm guessing the link to the post ... )?

  6. kath
    Member
    Posted 7 years ago #

    It looks like I can only change the heading things. What is wp_walk_tree?

    OK, I found wp_walk_tree in post-template.php:

    00326: function walk_page_tree() {
    00327: $walker = new Walker_Page;
    00328: $args = func_get_args();
    00329: return call_user_func_array(array(&$walker, 'walk'), $args);
    00330: }

    So that doesn't seem like it includes a lot of formatting.

    I'd like to know what the apply_filters('wp_list_pages') does.

    And I found this in classes.php:

    class Walker_Page extends Walker {
    	var $tree_type = 'page';
    	var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID'); //TODO: decouple this
    
    	function start_lvl($output, $depth) {
    		$indent = str_repeat("\t", $depth);
    		$output .= "\n$indent<ul>\n";
    		return $output;
    	}
    
    	function end_lvl($output, $depth) {
    		$indent = str_repeat("\t", $depth);
    		$output .= "$indent</ul>\n";
    		return $output;
    	}
    
    	function start_el($output, $page, $depth, $current_page, $args) {
    		if ( $depth )
    			$indent = str_repeat("\t", $depth);
    		extract($args);
    		$css_class = 'page_item';
    		$_current_page = get_page( $current_page );
    		if ( $page->ID == $current_page )
    			$css_class .= ' current_page_item';
    		elseif ( $_current_page && $page->ID == $_current_page->post_parent )
    			$css_class .= ' current_page_parent';
    
    		$output .= $indent . '<li class="' . $css_class . '"><a href="' . get_page_link($page->ID) . '" title="' . attribute_escape(apply_filters('the_title', $page->post_title)) . '">' . apply_filters('the_title', $page->post_title) . '</a>';
    
    		if ( !empty($show_date) ) {
    			if ( 'modified' == $show_date )
    				$time = $page->post_modified;
    			else
    				$time = $page->post_date;
    
    			$output .= " " . mysql2date($date_format, $time);
    		}
    
    		return $output;
    	}
    
    	function end_el($output, $page, $depth) {
    		$output .= "</li>\n";
    
    		return $output;
    	}
    
    }

    Which looks like it's FINALLY where the output is actually defined! HUZZAH. Still not sure if I;m going to be able to edit this to my needs. If I put this function, a new wp_walk_tree, a new wp_list_pages, and a new class, all in functions.php, would it end up breaking?

  7. kath
    Member
    Posted 7 years ago #

    Hi. I've figured out how to edit the output of a function once it's set up, but now I think I need to add some conditionals. Here are the related parts of code:

    [long code removed - use something like http://wordpress.pastebin.ca do NOT post long code here!]

    Sorry. Total PHP n00b :S.

  8. kath
    Member
    Posted 7 years ago #

    heh. None of it is working, really -- does anyone know enough PHP to help me out?

    And right now, it only displays pages with a depth of -1.

  9. Mindshare Studios, Inc.
    Member
    Posted 6 years ago #

    I'm working on the same issue... Kath - did you ever have any luck with this?

  10. micharo
    Member
    Posted 6 years ago #

    I'm working on a similar issue. I renamed and extended the Walker class. I added the css I needed for the navigation to display - worked!

    But now I need to put a css class="lastPageInLevelOne" in the htm code.

    I do not know how to ask if this is the last element in base level.
    It looks like it would be somewhere in the Walker class.
    Does anyone have a clue?

  11. GuruXL
    Member
    Posted 6 years ago #

    We need a better wp_list_pages() function for a more complex list option.

    Home
    About
    - Author
    - History
    Features
    - Easy
    - Free
    - Expandable
    Documentation
    - Keywords
    - Functions
    -- Doohickey One
    -- Thing-ama-bob
    - Issues
    -- One
    -- Two
    --- Sub Two
    --- Sub Two B
    Support
    Contact Us

    Dealing with nested navigation on one page is hard.

    The idea would be to compartmentalize the navigation into top-level, one where there is no parent page like "HOme" "About" "contact us", then sub pages where there are sub-sub children like "Issues".

    Displaying these complex menus has been an issue that hasn't been properly addressed.

  12. dressedinvalue
    Member
    Posted 6 years ago #

    F'REAL. This has been making me crazy for a few days now.

  13. chabotjeff
    Member
    Posted 6 years ago #

    from the little work I've done with it Fold Page seems to work pretty good. Although I haven't figured out a way to get back once I've drilled down into sub cats. Here is the developer: http://www.webspaceworks.com/resources/wordpress/30/

    If anyone has any other resources please share! It would be great if this could be built into the core WordPress install.

  14. glastonbomb
    Member
    Posted 6 years ago #

    http://dynamictangentconceptions.dtcnet.co.uk/downloads/wp-plugins/dtabs-dynamic-tabs-wordpress-plugin/

    I've recently found that site. It makes tabs with dynamic dropdown menus which actually work and is very easy to implement. I'm in the process of hacking the code to make it look like a table cell rather than tabs. Only problem I'm having right how is that when I put it in div tags it goes a bit wankery.

    The site I'm working on is not fully functional yet (it's not linked up yet) but I'll post when it's finished.

Topic Closed

This topic has been closed to new replies.

About this Topic