Opened 7 years ago
Last modified 7 years ago
#42148 new enhancement
url_to_postid plain permalinks for CPTs
Reported by: | soulseekah | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 1.0 |
Component: | Permalinks | Keywords: | needs-patch needs-unit-tests |
Focuses: | Cc: |
Description
Would be nice to have url_to_postid
working with plain permalinks for custom post types.
There's are currently some issues in url_to_postid
where the wrong ID is returned for custom post type plain permalinks (query-based).
<?php add_action( 'init', function() { /** Register a post type */ register_post_type( 'findme', array( 'public' => true ) ); /** Create a post */ $post_id = wp_insert_post( array( 'post_type' => 'findme', 'post_status' => 'publish' ) ); $findme = get_permalink( $post_id ); $found = url_to_postid( $findme ); /** Guess it */ printf( "%s (%s) == %s (%s)", $post_id, $findme, $found, get_permalink( $found ) ); exit; } );
30 (http://localhost:8080/?findme=30) == 0 ()
and 30 (http://localhost:8080/?findme=30) == 2 (http://localhost:8080/)
if the frontpage is setup to point ot a post.
Why is it not working? Why is the frontpage post being returned? Let's see how the {{url_to_postid}} function works:
// First, check to see if there is a 'p=N' or 'page_id=N' to match against if ( preg_match('#[?&](p|page_id|attachment_id)=(\d+)#', $url, $values) ) { $id = absint($values[2]); if ( $id ) return $id; }
Then?
if ( trim( $url, '/' ) === home_url() && 'page' == get_option( 'show_on_front' ) ) { $page_on_front = get_option( 'page_on_front' ); if ( $page_on_front && get_post( $page_on_front ) instanceof WP_Post ) { return (int) $page_on_front; } }
Uh, wait what... already? So a short-circuit without checking the custom post types. And that's understandable, since there is inherently no support for custom post type ID mappings as pointed out by:
// Check to see if we are using rewrite rules $rewrite = $wp_rewrite->wp_rewrite_rules(); // Not using rewrite rules, and 'p=N' and 'page_id=N' methods failed, so we're out of options if ( empty($rewrite) ) return 0;
What stands in our way to find the URL earlier?
- The query var is not one of p, page_id, attachment_id
- The query var value for CPTs is not necessarily, and most often not numeric (the post_title)
A proposed solution would be to look at the query parameters much higher, maybe by injecting the custom ones, ones that support slugs as well, since WordPress sets the page_title
for a CPT itself, so that \d+
check would fail.
Use case? Well, this was encountered when trying to paste plain oEmbed URLs for a custom post type (https://github.com/gravityview/GravityView/issues/927).