Opened 19 years ago
Closed 17 years ago
#3566 closed enhancement (invalid)
Request for new function get_page_parents
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Priority: | normal | |
| Severity: | normal | Version: | 2.1 |
| Component: | Template | Keywords: | has-patch 2nd-opinion |
| Focuses: | Cc: |
Description
Like there is a get_category_parents, then it would be nice with a get_page_parents:
function get_page_parents($id, $link = FALSE, $separator = '/', $nicename = FALSE){
$chain = '';
$parent = &get_page($id);
if ( $nicename )
$name = $parent->post_title;
else
$name = $parent->post_name;
if ( $parent->post_parent )
$chain .= get_page_parents($parent->post_parent, $link, $separator, $nicename);
if ( $link )
$chain .= '<a href="' . get_page_link($parent->ID) . '" title="' . $parent->post_title . '">'.$name.'</a>' . $separator;
else
$chain .= $name.$separator;
return $chain;
}
Attachments (1)
Change History (17)
#2
@
19 years ago
- Keywords has-patch added; get_category_parents get_page_parents wp_list_pages wp_list_cats removed
- Version changed from 2.0 to 2.1
#9
@
18 years ago
- Keywords needs-patch added; has-patch removed
- Milestone changed from 2.5 to 2.6
Enhancement, no patch, feature freeze ==> 2.6
#11
@
17 years ago
Isn't there a walker method or something like that allows to get a page's ancestors as objects?
#12
@
17 years ago
- Keywords 2nd-opinion added
- Milestone changed from 2.8 to Future Release
dumping to Future, due to apparent lack of interest
#13
@
17 years ago
I don't really know about the walker. Isn't it just to walk downward? lists children?
and I think this implementation is much simpler (and faster).
it will be useful for wordpress as CMS that utilizes pages (rather than posts + categories) to create structured site.
#14
@
17 years ago
Isn't there a walker method or something like that allows to get a page's ancestors as objects?
You'd be thinking of _get_post_ancestors() and get_post_ancestors() in http://core.trac.wordpress.org/browser/trunk/wp-includes/post.php
#15
@
17 years ago
I use the following code in a few of my plugins, in case there is any interest:
function cache_pages() {
if ( is_page() ) {
global $wp_the_query;
$page_id = (int) $wp_the_query->get_queried_object_id();
$page = get_page($page_id);
} elseif ( get_option('show_on_front') == 'page' ) {
$page_id = (int) get_option('page_for_posts');
$page = get_page($page_id);
} else {
$page_id = 0;
$page = null;
}
$ancestors = wp_cache_get($page_id, 'page_ancestors');
if ( $ancestors === false ) {
$ancestors = array();
while ( $page && $page->post_parent != 0 ) {
$ancestors[] = (int) $page->post_parent;
$page = get_page($page->post_parent);
}
$ancestors = array_reverse($ancestors);
wp_cache_set($page_id, $ancestors, 'page_ancestors');
}
$parent_ids = $ancestors;
array_unshift($parent_ids, 0);
if ( $page_id )
$parent_ids[] = $page_id;
$cached = true;
foreach ( $parent_ids as $parent_id ) {
$cached = is_array(wp_cache_get($parent_id, 'page_children'));
if ( $cached === false )
break;
}
if ( $cached )
return;
global $wpdb;
$roots = (array) $wpdb->get_col("
SELECT posts.ID
FROM $wpdb->posts as posts
WHERE posts.post_type = 'page'
AND posts.post_parent IN ( 0, $page_id )
");
$parent_ids = array_merge($parent_ids, $roots, array($page_id));
$parent_ids = array_unique($parent_ids);
$parent_ids = array_map('intval', $parent_ids);
$pages = (array) $wpdb->get_results("
SELECT posts.*
FROM $wpdb->posts as posts
WHERE posts.post_type = 'page'
AND posts.post_status = 'publish'
AND posts.post_parent IN ( " . implode(',', $parent_ids) . " )
ORDER BY posts.menu_order, posts.post_title
");
update_post_cache($pages);
$children = array();
$to_cache = array();
foreach ( $parent_ids as $parent_id )
$children[$parent_id] = array();
foreach ( $pages as $page ) {
$children[$page->post_parent][] = $page->ID;
$to_cache[] = $page->ID;
}
update_postmeta_cache($to_cache);
$all_ancestors = array();
foreach ( $children as $parent => $child_ids ) {
foreach ( $child_ids as $key => $child_id ) {
$all_ancestors[$child_id][] = $parent;
if ( get_post_meta($child_id, '_widgets_exclude', true) )
unset($child_ids[$key]);
}
wp_cache_set($parent, $child_ids, 'page_children');
}
foreach ( $all_ancestors as $child_id => $parent_ids ) {
while ( $parent_ids[0] )
$parent_ids = array_merge($all_ancestors[$parent_ids[0]], $parent_ids);
wp_cache_set($child_id, $parent_ids, 'page_ancestors');
}
} # cache_pages()
It's meant to cache parents and children of a static page, and all of its ancestors sibblings.
Your solution has a bug and returns the page title for $nicename = TRUE and vice-versa, which is wrong. Also, it lacks the check for a valid page object returned. Here's the updated code:
function get_page_parents($id, $link = FALSE, $separator = '/', $nicename = FALSE) { $chain = ''; $parent = &get_page($id); if ( is_wp_error( $parent ) ) return $parent; if ( $nicename ) $name = $parent->post_name; else $name = $parent->post_title; if ( $parent->post_parent ) $chain .= get_page_parents($parent->post_parent, $link, $separator, $nicename); if ( $link ) $chain .= '<a href="' . get_page_link($parent->ID) . '" title="' . $parent->post_title . '">'.$name.'</a>' . $separator; else $chain .= $name.$separator; return $chain; }