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

wp_rewrite rule needed for Custom Post Type

  • SOLVED

You're probably wondering why the big prize. It's because I need this DESPERATELY!

I asked a question recently about a problem I have with using a particular "custom post type" post as my static front page. The code I received does work, but not the way it really should.

In looking at this more, I discovered I need to modify wp_rewrite to make this happen.

Here's my questions...

I have want to display a Custom Post Type single post on my front page, by selecting the page from the "Reading Settings" I've managed to add the custom post type to the reading settings so that's not a problem.

My problem is when I select the Custom Post Type from the Reading Settings and set it, the home page now redirects.

Example...

http://example.com redirects to
http://example.com/slug/custom-post-type-post/

I want the home page to simple be http://example.com

This is why I believe I need to add a rewrite rule to make this happen.

I assume I would need first need to query the posts for the specific post type and then add a rewrite rule. My problem is that I'm pretty new to this and I can modify well, but I'm not familiar with what should be done.

PLEASE HELP!

Answers (4)

2011-09-06

Julian Lannigan answers:

Hey Armand,

The only thing you have to do is initialize this class, so add this to your CORE.php

new LoadRewrites();
(be sure to include the class if you put it in a separate file)

Here is a class I reuse to add rewrites to wp:

class LoadRewrites {

public function __construct() {
$this->buildRewrites();
add_filter('rewrite_rules_array', array(&$this, 'addRewrites'));
add_filter('query_vars', array(&$this, 'addQueryVars'));
add_action('wp_loaded', array(&$this, 'flushRules'));
}

public function buildRewrites() {
$newrules = array();

$newrules['/$'] = 'index.php?p='.get_option("page_on_front");

$this->newrules = $newrules;
}

public function addRewrites($rules) {
return $this->newrules + $rules;
}

public function addQueryVars($vars) {
//array_push($vars, 'theCategory');
return $vars;
}

public function flushRules() {
$rules = get_option('rewrite_rules');

foreach ($this->newrules as $rule) {
if (!isset($rules[$rule])) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
return;
}
}
}
}


Armand Morin comments:

Julian,

Ok, I'm missing something here. Does this integrate with what we did yesterday? Or should this be added by itself?

Also, do I have to modify something here to set the custom post type?


Armand Morin comments:

One more thing... the reason I think it must be a rewrite is that the code you did yesterday works fine if the root is www.example.com but when I tested on my test xampp setup where my url is localhost/sandbox/ it didn't work.


Julian Lannigan comments:

Hey Armand,

I fixed the issue using redirects. I added this code, replacing the older code, with the following:

class LoadRewrites {

public function __construct() {
$this->buildRewrites();
add_filter('rewrite_rules_array', array(&$this, 'addRewrites'));
add_filter('query_vars', array(&$this, 'addQueryVars'));
add_action('wp_loaded', array(&$this, 'flushRules'));
}

public function buildRewrites() {
$newrules = array();

$frontPost = get_post(get_option("page_on_front"));
$newrules['^$'] = 'index.php?salesletters='.$frontPost->post_name;

$this->newrules = $newrules;
}

public function addRewrites($rules) {
return $this->newrules + $rules;
}

public function addQueryVars($vars) {
//array_push($vars, 'theCategory');
return $vars;
}

public function flushRules() {
$rules = get_option('rewrite_rules');

foreach ($this->newrules as $rule) {
if (!isset($rules[$rule])) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
return;
}
}
}
}
new LoadRewrites();


Armand Morin comments:

Julian,

Sooo close.

The redirect stopped and that looks great. One minor problem. If you click on a NORMAL PAGE now and want to set that as the homepage, you get page not found.


Julian Lannigan comments:

Fixed, I changed the rewrite to include the post's type. Here is the corrected code:

class LoadRewrites {

public function __construct() {
$this->buildRewrites();
add_filter('rewrite_rules_array', array(&$this, 'addRewrites'));
add_filter('query_vars', array(&$this, 'addQueryVars'));
add_action('wp_loaded', array(&$this, 'flushRules'));
}

public function buildRewrites() {
$newrules = array();

$frontPost = get_post(get_option("page_on_front"));
$newrules['^$'] = 'index.php?'.$frontPost->post_type.'='.$frontPost->post_name;

$this->newrules = $newrules;
}

public function addRewrites($rules) {
return $this->newrules + $rules;
}

public function addQueryVars($vars) {
//array_push($vars, 'theCategory');
return $vars;
}

public function flushRules() {
$rules = get_option('rewrite_rules');

foreach ($this->newrules as $rule) {
if (!isset($rules[$rule])) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
return;
}
}
}
}
new LoadRewrites();


Armand Morin comments:

You're awesome!!! Perfect.

2011-09-06

Julio Potier answers:

Hello

Is it the same problem has here : http://wpquestions.com/question/show/id/2930 ?


Armand Morin comments:

Yes, Julian did provide an answer, but as I said, in further investigation, I believe the proper way to accomplish this is with a wp_rewrite. I'm willing to accept any advice or solutions.

2011-09-06

Utkarsh Kukreti answers:

add_filter('the_posts', 'wpq_the_posts');
function wpq_the_posts($posts) {
if(is_home()) {
$post_id = 10;
$post = get_post($post_id);
return array($post);
} else {
return $posts;
}
}


Armand Morin comments:

Utkarsh,

Thanks the only problem with this is that I won't know the post id, since I'm setting it from the Reading Settings dropdown menu.


Utkarsh Kukreti comments:

add_filter('the_posts', 'wpq_the_posts');

function wpq_the_posts($posts) {
if(is_home()) {
$post_id = get_option("page_on_front");
$post = get_post($post_id);
return array($post);
} else {
return $posts;
}
}


Armand Morin comments:

This still redirects the homepage to the post type url.


Utkarsh Kukreti comments:

Strange. It doesn't for me on WP 3.3-pre.


Armand Morin comments:

Remember, I'm selecting a Custom Post Type I've added to the Reading List. The homepage is redirecting the CPT url instead of staying on the homepage.


Utkarsh Kukreti comments:

How did you add CPT to Reading List? (They aren't there by default..)


Armand Morin comments:

add_filter( 'get_pages', 'add_my_salesletters' );



function add_my_salesletters( $pages ) {

$my_salesletters_pages = new WP_Query( array( 'post_type' => 'salesletters' ) );

if ( $my_salesletters_pages->post_count > 0 )

{

$pages = array_merge( $pages, $my_salesletters_pages->posts );

}

return $pages;

}


Utkarsh Kukreti comments:

Haven't tested, but try. Will test if doesn't work.


add_filter( 'get_pages', 'add_my_salesletters' );
function add_my_salesletters( $pages ) {
if(!is_admin()) return;

$my_salesletters_pages = new WP_Query( array( 'post_type' => 'salesletters' ) );
if ( $my_salesletters_pages->post_count > 0 )
{
$pages = array_merge( $pages, $my_salesletters_pages->posts );
}

return $pages;

}


Utkarsh Kukreti comments:

Sorry,
add_filter( 'get_pages', 'add_my_salesletters' );

function add_my_salesletters( $pages ) {

if(!is_admin()) return $pages;

$my_salesletters_pages = new WP_Query( array( 'post_type' => 'salesletters' ) );
if ( $my_salesletters_pages->post_count > 0 )
{
$pages = array_merge( $pages, $my_salesletters_pages->posts );
}
return $pages;
}


Armand Morin comments:

I think you just posted my original code back to me... am I not reading this right? I already have the CPT in the Reading Settings.


Utkarsh Kukreti comments:

I added.

if(!is_admin()) return $pages;


Armand Morin comments:

Ok. It still redirects.

2011-09-06

John Cotton answers:

Armand

This might be a simpler approach than a rewrite.

I have assumed that your page option is being set as an id and that you have a file called single-YOUR-CUSTOM-POST-TYPE.php.

Pop this in your functions file:


function my_template_redirect() {
if( is_home() ) {
$post_id = get_option("page_on_front");

query_posts( array( 'p' => $post_id ) );

include_once('single-YOUR-CUSTOM-POST-TYPE.php');
exit();
}
}
add_action('template_redirect','my_template_redirect');


Clearly your if statement could become more complex ie if there are only certain circumstances that you want to show the custom post...

Regards

John