Add hierarchical support for custom post_types in Rewrite Rules & Querying. See #12643

git-svn-id: http://svn.automattic.com/wordpress/trunk@13774 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
dd32 2010-03-20 02:23:52 +00:00
parent 3fdd2bbdff
commit b16190c496
4 changed files with 53 additions and 19 deletions

View File

@ -187,11 +187,16 @@ function get_post_permalink( $id = 0, $leavename = false, $sample = false ) {
$draft_or_pending = 'draft' == $post->post_status || 'pending' == $post->post_status; $draft_or_pending = 'draft' == $post->post_status || 'pending' == $post->post_status;
$post_type = get_post_type_object($post->post_type);
if ( !empty($post_link) && ( ( isset($post->post_status) && !$draft_or_pending ) || $sample ) ) { if ( !empty($post_link) && ( ( isset($post->post_status) && !$draft_or_pending ) || $sample ) ) {
$post_link = ( $leavename ) ? $post_link : str_replace("%$post->post_type%", $slug, $post_link); if ( ! $leavename ) {
if ( $post_type->hierarchical )
$slug = get_page_uri($id);
$post_link = str_replace("%$post->post_type%", $slug, $post_link);
}
$post_link = home_url( user_trailingslashit($post_link) ); $post_link = home_url( user_trailingslashit($post_link) );
} else { } else {
$post_type = get_post_type_object($post->post_type);
if ( $post_type->query_var && ( isset($post->post_status) && !$draft_or_pending ) ) if ( $post_type->query_var && ( isset($post->post_status) && !$draft_or_pending ) )
$post_link = add_query_arg($post_type->query_var, $slug, ''); $post_link = add_query_arg($post_type->query_var, $slug, '');
else else
@ -295,9 +300,8 @@ function get_attachment_link($id = false) {
$link = false; $link = false;
if (! $id) { if ( ! $id)
$id = (int) $post->ID; $id = (int) $post->ID;
}
$object = get_post($id); $object = get_post($id);
if ( $wp_rewrite->using_permalinks() && ($object->post_parent > 0) && ($object->post_parent != $id) ) { if ( $wp_rewrite->using_permalinks() && ($object->post_parent > 0) && ($object->post_parent != $id) ) {
@ -306,17 +310,18 @@ function get_attachment_link($id = false) {
$parentlink = _get_page_link( $object->post_parent ); // Ignores page_on_front $parentlink = _get_page_link( $object->post_parent ); // Ignores page_on_front
else else
$parentlink = get_permalink( $object->post_parent ); $parentlink = get_permalink( $object->post_parent );
if ( is_numeric($object->post_name) || false !== strpos(get_option('permalink_structure'), '%category%') ) if ( is_numeric($object->post_name) || false !== strpos(get_option('permalink_structure'), '%category%') )
$name = 'attachment/' . $object->post_name; // <permalink>/<int>/ is paged so we use the explicit attachment marker $name = 'attachment/' . $object->post_name; // <permalink>/<int>/ is paged so we use the explicit attachment marker
else else
$name = $object->post_name; $name = $object->post_name;
if (strpos($parentlink, '?') === false)
if ( strpos($parentlink, '?') === false )
$link = user_trailingslashit( trailingslashit($parentlink) . $name ); $link = user_trailingslashit( trailingslashit($parentlink) . $name );
} }
if (! $link ) { if ( ! $link )
$link = trailingslashit(get_bloginfo('url')) . "?attachment_id=$id"; $link = trailingslashit(get_bloginfo('url')) . "?attachment_id=$id";
}
return apply_filters('attachment_link', $link, $id); return apply_filters('attachment_link', $link, $id);
} }

View File

@ -854,7 +854,10 @@ function register_post_type($post_type, $args = array()) {
$args->rewrite['slug'] = $post_type; $args->rewrite['slug'] = $post_type;
if ( !isset($args->rewrite['with_front']) ) if ( !isset($args->rewrite['with_front']) )
$args->rewrite['with_front'] = true; $args->rewrite['with_front'] = true;
$wp_rewrite->add_rewrite_tag("%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name="); if ( $args->hierarchical )
$wp_rewrite->add_rewrite_tag("%$post_type%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name=");
else
$wp_rewrite->add_rewrite_tag("%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name=");
$wp_rewrite->add_permastruct($post_type, "{$args->rewrite['slug']}/%$post_type%", $args->rewrite['with_front'], $args->permalink_epmask); $wp_rewrite->add_permastruct($post_type, "{$args->rewrite['slug']}/%$post_type%", $args->rewrite['with_front'], $args->permalink_epmask);
} }
@ -2749,7 +2752,7 @@ function &get_page(&$page, $output = OBJECT, $filter = 'raw') {
* @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A.
* @return mixed Null when complete. * @return mixed Null when complete.
*/ */
function get_page_by_path($page_path, $output = OBJECT) { function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page') {
global $wpdb; global $wpdb;
$page_path = rawurlencode(urldecode($page_path)); $page_path = rawurlencode(urldecode($page_path));
$page_path = str_replace('%2F', '/', $page_path); $page_path = str_replace('%2F', '/', $page_path);
@ -2761,21 +2764,21 @@ function get_page_by_path($page_path, $output = OBJECT) {
foreach( (array) $page_paths as $pathdir) foreach( (array) $page_paths as $pathdir)
$full_path .= ($pathdir!=''?'/':'') . sanitize_title($pathdir); $full_path .= ($pathdir!=''?'/':'') . sanitize_title($pathdir);
$pages = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name = %s AND (post_type = 'page' OR post_type = 'attachment')", $leaf_path )); $pages = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name = %s AND (post_type = %s OR post_type = 'attachment')", $leaf_path, $post_type ));
if ( empty($pages) ) if ( empty($pages) )
return null; return null;
foreach ($pages as $page) { foreach ( $pages as $page ) {
$path = '/' . $leaf_path; $path = '/' . $leaf_path;
$curpage = $page; $curpage = $page;
while ($curpage->post_parent != 0) { while ( $curpage->post_parent != 0 ) {
$curpage = $wpdb->get_row( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE ID = %d and post_type='page'", $curpage->post_parent )); $curpage = $wpdb->get_row( $wpdb->prepare( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE ID = %d and post_type = %s", $curpage->post_parent, $post_type ));
$path = '/' . $curpage->post_name . $path; $path = '/' . $curpage->post_name . $path;
} }
if ( $path == $full_path ) if ( $path == $full_path )
return get_page($page->ID, $output); return get_page($page->ID, $output, $post_type);
} }
return null; return null;

View File

@ -1712,10 +1712,35 @@ class WP_Query {
if ( $q['day'] ) if ( $q['day'] )
$where .= " AND DAYOFMONTH($wpdb->posts.post_date)='" . $q['day'] . "'"; $where .= " AND DAYOFMONTH($wpdb->posts.post_date)='" . $q['day'] . "'";
if ('' != $q['name']) { if ( !empty($q['post_type']) && !empty($q[ $q['post_type'] ]) ) {
$q[ $q['post_type'] ] = str_replace('%2F', '/', urlencode(urldecode($q[ $q['post_type'] ])));
$post_type_object = get_post_type_object($q['post_type']);
if ( ! $post_type_object->hierarchical || strpos($q[ $q['post_type'] ], '/') === false) {
$q['name'] = $q[ $q['post_type'] ] = sanitize_title($q[ $q['post_type'] ]);
$where .= " AND $wpdb->posts.post_name = '" . $q[ $q['post_type'] ] . "'";
} else {
// Hierarchical post type, need to look deeper to see if its an attachment or this post_type
if ( isset($this->queried_object_id) ) {
$reqpage = $this->queried_object_id;
} else {
$reqpage = get_page_by_path($q[ $q['post_type'] ], OBJECT, $q['post_type']);
if ( !empty($reqpage) )
$reqpage = $reqpage->ID;
else
$reqpage = 0;
}
$where .= " AND ($wpdb->posts.ID = '$reqpage')";
$reqpage_obj = get_page($reqpage);
if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) {
$this->is_attachment = true;
$q['attachment_id'] = $reqpage;
$post_type = $q['post_type'] = 'attachment';
}
}
} elseif ( '' != $q['name'] ) {
$q['name'] = sanitize_title($q['name']); $q['name'] = sanitize_title($q['name']);
$where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'"; $where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'";
} else if ('' != $q['pagename']) { } elseif ( '' != $q['pagename'] ) {
if ( isset($this->queried_object_id) ) if ( isset($this->queried_object_id) )
$reqpage = $this->queried_object_id; $reqpage = $this->queried_object_id;
else { else {
@ -1727,7 +1752,7 @@ class WP_Query {
} }
$page_for_posts = get_option('page_for_posts'); $page_for_posts = get_option('page_for_posts');
if ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) { if ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) {
$q['pagename'] = str_replace('%2F', '/', urlencode(urldecode($q['pagename']))); $q['pagename'] = str_replace('%2F', '/', urlencode(urldecode($q['pagename'])));
$page_paths = '/' . trim($q['pagename'], '/'); $page_paths = '/' . trim($q['pagename'], '/');
$q['pagename'] = sanitize_title(basename($page_paths)); $q['pagename'] = sanitize_title(basename($page_paths));
@ -2802,4 +2827,4 @@ function setup_postdata($post) {
return true; return true;
} }
?> ?>

View File

@ -1436,8 +1436,9 @@ class WP_Rewrite {
// For custom post types, we need to add on endpoints as well. // For custom post types, we need to add on endpoints as well.
foreach ( get_post_types( array('_builtin' => false ) ) as $ptype ) { foreach ( get_post_types( array('_builtin' => false ) ) as $ptype ) {
if ( strpos($struct, "%$ptype%") !== false ) { if ( strpos($struct, "%$ptype%") !== false ) {
$ptype = get_post_type_object($ptype);
$post = true; $post = true;
$page = false; $page = $ptype->hierarchical; // This is for page style attachment url's
break; break;
} }
} }