Ask your WordPress questions! Pay money and get answers fast! (more info)

CPT custom permalink - 2 URIs that load the same page/post WordPress

  • SOLVED

Here's my current code:
/*
adapted from http://wordpress.stackexchange.com/questions/33551/how-to-rewrite-uri-of-custom-post-type
rewrites permalink (displayed URI) for the 'realestatetours' custom post type to domain.com/%post_id%
technically, it seems to allow any /postidnumber/ to work and redirect, just that this CPT's don't have a URI change (i.e. do not redirect)

if needed: http://www.viper007bond.com/2011/10/07/code-snippet-helper-class-to-add-custom-taxonomy-to-post-permalinks/
for reference: http://shibashake.com/wordpress-theme/custom-post-type-permalinks
*/

add_filter('post_type_link', 'wpse33551_post_type_link', 1, 3);

function wpse33551_post_type_link( $link, $post = 0 ){
if ( $post->post_type == 'realestatetours' ){
return home_url( $post->ID . '/' );
} else {
return $link;
}
}

add_action( 'init', 'wpse33551_rewrites_init' );
// http://codex.wordpress.org/Rewrite_API/add_rewrite_rule
function wpse33551_rewrites_init(){
add_rewrite_rule(
'([0-9]+)?$',
'index.php?post_type=realestatetours&p=$matches[1]',
'top' );
}
// http://codex.wordpress.org/Rewrite_API/add_rewrite_tag#Retrieving_the_Value_of_a_Rewritten_URL
add_rewrite_tag('%tour_id%','([0-9]+)?$'); // do not know if this is right or if it does anything (please tell me)



Here's what it does:
- I have a custom post type (CPT) that is 'realestatetours'
- my main site permalink structure is /%year%/%postname%/
- for my CPT permalink structure, I want /%post_id%/ , which is essentially what I have working in the code above

Here's what I want:
- example of "real" permalink = domain.com/1765/
- example of what I want IN ADDITION = domain.com/1765/u/ (goes to the same CPT post/page -- so it's really this: domain.com/1765/?view=unbranded )
- So .../u/ = ?view=unbranded
- In my page template, I will have something like this:
if($_GET['view'] == 'unbranded'):
DO THIS (displays unbranded version)
else
DO THAT (displays branded version)

Or, instead of the _GET (because of this: [[LINK href="http://codex.wordpress.org/Rewrite_API/add_rewrite_tag#Retrieving_the_Value_of_a_Rewritten_URL"]]http://codex.wordpress.org/Rewrite_API/add_rewrite_tag#Retrieving_the_Value_of_a_Rewritten_URL[[/LINK]] ), I think it might have to be like this:
if($wp_query->query_vars['view'] == 'unbranded'):
DO THIS (displays unbranded version)
else
DO THAT (displays branded version)



Please provide me with:
- verify my current rewrite code is correct or provide a replacement
- code to add the domain.com/1765/u/ effect
- code for the if wp_query or if _GET
- any need-to-know or handy information to have
- does "rewrite endpoint" apply? why or why not?

Thank you.

Answers (1)

2012-10-20

Dbranes answers:

hi, here is one idea, put this into your function.php:

add_filter( 'query_vars', 'my_custom_query_vars' );
function my_custom_query_vars( $query_vars ){
$query_vars[] = 'view';
return $query_vars;
}

add_action( 'init', 'my_custom_rewrites_init' );
function my_custom_rewrites_init(){
add_rewrite_rule('^([0-9]+)?/u$','index.php?post_type=realestatetours&p=$matches[1]&view=unbranded','top' );
add_rewrite_rule('([0-9]+)?$','index.php?post_type=realestatetours&p=$matches[1]','top' );
}


just remember to save permalinks.

Then you might use this in your theme (fx. single.php)

echo "view:".get_query_var('view');


to get the /u/ value (i.e. view=unbranded)

Hope this helps.


Clifford P comments:

Thank you.

I think in total this is my code, right?

add_filter('post_type_link', 'wpse33551_post_type_link', 1, 3);

function wpse33551_post_type_link( $link, $post = 0 ){
if ( $post->post_type == 'realestatetours' ){
return home_url( $post->ID . '/' );
} else {
return $link;
}
}

add_action( 'init', 'wpse33551_rewrites_init' );
// http://codex.wordpress.org/Rewrite_API/add_rewrite_rule
function wpse33551_rewrites_init(){
add_rewrite_rule(
'([0-9]+)?$',
'index.php?post_type=realestatetours&p=$matches[1]',
'top' );
}

// http://codex.wordpress.org/Rewrite_API/add_rewrite_tag#Retrieving_the_Value_of_a_Rewritten_URL
add_rewrite_tag('%tour_id%','([0-9]+)?$');


// 2012-10-20 from http://www.wpquestions.com/question/show/id/7472
add_filter( 'query_vars', 'my_custom_query_vars' );

function my_custom_query_vars( $query_vars ){
$query_vars[] = 'view';
return $query_vars;
}

add_action( 'init', 'my_custom_rewrites_init' );
function my_custom_rewrites_init(){
add_rewrite_rule('^([0-9]+)?/u$','index.php?post_type=realestatetours&p=$matches[1]&view=unbranded','top' );
add_rewrite_rule('([0-9]+)?$','index.php?post_type=realestatetours&p=$matches[1]','top' );
}



I tested and these all loaded the same page (although I didn't try the in-page code yet):
domain.com/1765/
domain.com/1765/u/
domain.com/1765/?view=unbranded

Did I use add_rewrite_tag correctly or should that part be edited or removed?


Clifford P comments:

domain.com/1765/?view=unbranded loaded the page but didn't get rewritten/redirected to domain.com/1765/u/ --- why not?


Clifford P comments:

I tried this:
<?php if ("view:".get_query_var('view') == 'unbranded'): ?>
<h2>Unbranded works</h2>
<?php else: ?>
<h2>Branded works</h2>
<?php endif; ?>

and "Branded works" was the only thing that showed up -- so the if isn't picking up the "view=unbranded" with /u or /?view=unbranded urls.

Looking forward to the resolution.

Thanks so much!


Dbranes comments:

you should rather use:

<?php if( get_query_var('view') == 'unbranded'): ?>

<h2>Unbranded works</h2>

<?php else: ?>

<h2>Branded works</h2>

<?php endif; ?>


I think you can skip the add_rewrite_tag line in your code,
so this might be your code

add_filter('post_type_link', 'wpse33551_post_type_link', 1, 3);
function wpse33551_post_type_link( $link, $post = 0 ){
if ( $post->post_type == 'realestatetours' ){
return home_url( $post->ID . '/' );
} else {
return $link;
}
}

add_filter( 'query_vars', 'my_custom_query_vars' );
function my_custom_query_vars( $query_vars ){
$query_vars[] = 'view';
return $query_vars;
}

add_action( 'init', 'my_custom_rewrites_init' );
function my_custom_rewrites_init(){
add_rewrite_rule('^([0-9]+)?/u$','index.php?post_type=realestatetours&p=$matches[1]&view=unbranded','top' );
add_rewrite_rule('([0-9]+)?$','index.php?post_type=realestatetours&p=$matches[1]','top' );
}



I will see what I can do about the redirect

domain.com/1765/?view=unbranded --> domain.com/1765/u/


Clifford P comments:

Yup, those 2 bits of code do the job. Thanks!

If you could add that redirect:

domain.com/1765/?view=unbranded --> domain.com/1765/u/

I'd appreciate it very much. :-)


Clifford P comments:

Turns out domain.com/?realestatetours=test-tour doesn't redirect to domain.com/1765/ either.
I look forward to your reply. Thank you.


Dbranes comments:

When using add_rewrite_rule all the extra GET parameter information, not used in the rewrite, are not easily accessible.

So one could do the redirect via .htaccess or play with the wp_redirect like in the following:

add_action( 'init', 'custom_redirect_init' );
function custom_redirect_init(){
global $wpdb;
if ( is_trackback() || is_search() || is_comments_popup() || is_admin() || !empty($_POST) || is_preview() || is_robots())
return;

$current_url = is_ssl() ? 'https://' : 'http://';
$current_url .= $_SERVER['HTTP_HOST'];
$current_url .= $_SERVER['REQUEST_URI'];
$parsed=parse_url($current_url);
$req = str_replace(get_home_url(),"",$current_url);

// match if req has the form: domain.com/1765/?view=unbranded
// and redirect to domain.com/1765/u/
if( preg_match('/^\/([0-9]+)?\/\?view=unbranded$/', $req)){
$redirect_url=$parsed['scheme']."://".$parsed['host'].$parsed['path']."u/";
wp_redirect( $redirect_url, "301");

// match if req has the form: domain.com/?realestatetours=test-tour
// and redirect to domain.com/1765/
}elseif( preg_match('/\?realestatetours\=([a-zA-Z0-9-]+)$/', $req,$matches)){
if(isset($matches[1])){
$post_id = $wpdb->get_var($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_type='realestatetours' AND post_name ='%s'", $matches[1]));
if($post_id>0){
$redirect_url=$parsed['scheme']."://".$parsed['host'].$parsed['path']."".$post_id."/";
wp_redirect( $redirect_url, "301");
}
}
}
}


hope this helps.


Clifford P comments:

wow, that was quite a chunk of code. good effort. but it didn't work. neither redirected. maybe if you just give me the regex for it, I can put it into my Redirection plugin, which allows for redirects as long as it starts with the root '/' (e.g. domain.com/1765/u = /1765/u )

This might help: [[LINK href="http://www.regextester.com/index.html"]]http://www.regextester.com/index.html[[/LINK]]
but I'm not a regex pro.

If you don't want, to, you don't have to, but I would appreciate it if you can figure it out. Either for me to use in the plugin or .htaccess rules or fixing your code above.

Thank you.


Dbranes comments:

here is a reduced debug version (without regex and only for the first case) so you can see better how it runs:

(you can change the debug variable into true/false)

add_action( 'init', 'custom_redirect_init_ver2' );
function custom_redirect_init_ver2(){

$debug=true; // debug mode true/false

global $wpdb;
if ( is_trackback() || is_search() || is_comments_popup() || is_admin() || !empty($_POST) || is_preview() || is_robots())
return;

$current_url = is_ssl() ? 'https://' : 'http://';
$current_url .= $_SERVER['HTTP_HOST'];
$current_url .= $_SERVER['REQUEST_URI'];
$parsed=parse_url($current_url);

if(strpos($parsed['query'],"view=unbranded") !==false){
$redirect_url=$parsed['scheme']."://".$parsed['host'].$parsed['path']."u/";
if($debug){
echo "<pre><ul>";
echo "<li> we got a match for ?view=unbranded </li>";
echo "<li> current_url=".$current_url."</li>";
echo "<li> redirect_url=".$redirect_url."</li>";
echo "</ul></pre>";
}else{
wp_redirect( $redirect_url, "301");
}
}
if($debug){
exit();
}
}


Dbranes comments:

ps: this is debug version is better:

add_action( 'init', 'custom_redirect_init_ver2' );
function custom_redirect_init_ver2(){
$debug=true; // debug mode true/false

global $wpdb;
if ( is_trackback() || is_search() || is_comments_popup() || is_admin() || !empty($_POST) || is_preview() || is_robots())
return;

$current_url = is_ssl() ? 'https://' : 'http://';
$current_url .= $_SERVER['HTTP_HOST'];
$current_url .= $_SERVER['REQUEST_URI'];
$parsed=parse_url($current_url);

if(strpos($parsed['query'],"view=unbranded") !==false){
$redirect_url=$parsed['scheme']."://".$parsed['host'].$parsed['path']."u/";
if(!$debug){
wp_redirect( $redirect_url, "301");
}
}
if($debug){
echo "<h1>Debug mode:</h1>";
echo "<pre><ul>";
echo "<li> we got a match for ?view=unbranded </li>";
echo "<li> current_url=".$current_url."</li>";
echo "<li> redirect_url=".$redirect_url."</li>";
echo "</ul></pre>";
exit();
}
}


Dbranes comments:

or this ;-)

(sorry I can't edit previous comments)

add_action( 'init', 'custom_redirect_init_ver2' );
function custom_redirect_init_ver2(){
$debug=true; // debug mode true/false
$match=false;

global $wpdb;
if ( is_trackback() || is_search() || is_comments_popup() || is_admin() || !empty($_POST) || is_preview() || is_robots())
return;

$current_url = is_ssl() ? 'https://' : 'http://';
$current_url .= $_SERVER['HTTP_HOST'];
$current_url .= $_SERVER['REQUEST_URI'];
$parsed=parse_url($current_url);

if(strpos($parsed['query'],"view=unbranded") !==false){
$redirect_url=$parsed['scheme']."://".$parsed['host'].$parsed['path']."u/";
if(!$debug){
wp_redirect( $redirect_url, "301");
}
$match=true;
}
if($debug){
echo "<h1>Debug mode:</h1>";
echo "<pre><ul>";
if($match){
echo "<li> we got a match for ?view=unbranded </li>";
}
echo "<li> current_url=".$current_url."</li>";
if(strlen($redirect_url)>0){
echo "<li> redirect_url=".$redirect_url."</li>";
}else{
echo "<li> no redirect</li>";
}
echo "</ul></pre>";
exit();
}
}


Clifford P comments:

Using the last one you provided, with debug on, I got the message
Debug mode:

we got a match for ?view=unbranded
current_url=http://domain.com/1709/?view=unbranded
redirect_url=http://domain.com/1709/u/

But with debug off, the browser address bar didn't redirect. Isn't that what we're going for?

Thanks.


Dbranes comments:

try replacing

wp_redirect( $redirect_url, "301");


with

wp_redirect( $redirect_url, 301);
exit();


Clifford P comments:

yes, that works. I think that's all I need. thanks so much!