Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

General Info

I used the plugin WP Types (wp-types.com) to create a custom post type called "artist".
In WP Types you can also set another post type as parent post type. This is not possible by default; they implemented this feature by a meta query with the key:
"_wpcf_belongs_%POSTTYPE%_id" (in my case "_wpcf_belongs_artist_id")
and the value is the ID of the parent post.

The Problem

Normally if you set a page X as a child of page Y you would have the following permalink structure:
/page-y/page-x/

I thought this plugin would adopt this but it does not. For example I use "painting" with the ID 24 as the parent page and "picasso" with the ID 72 as the child post with the post type "artist". So this:
/painting/picasso/
does redirect me to:
/artist/picasso/
but outputs the right content.

My solution approaches

As the paid support could not help me I have to try on my own. For writing my own "custom" rewrite rules I have to know the correct query at first. I tried to get my content manually:

index.php?_wpcf_belongs_artist_id=24&artist=picasso
redirects me to:
/artist/picasso?_wpcf_belongs_artist_id=24&artist=picasso
with the correct output of the single artist post.

This:
index.php?_wpcf_belongs_artist_id=24
just outputs my front page.

The only more or less working variant is:
/painting/picasso/?artist=picasso&_wpcf_belongs_artist_id=24 and:
/painting/picasso/?artist=picasso
These don't redirect me to /artist/picasso/… or anywhere but output the correct single artist post.

Here you can find some more variants and the whole thread in the support forums of WP Types.

First step probably would be to get the right content with a queryvar like "parent_id". After that I can start dealing with the rewrite rules itself, there might be problems because of the double usage of the top level (%pagename% and %parent_id%). This probably will confuse WordPress.

UPDATE 12/17

I tried this code to get all posts with the meta field '_wpcf_belongs_artist_id' and the meta value retrieved from the URL (/?parent_id=24). Unfortunately, it doesn't seem to work. It crashes my submenu's auxiliary queries and outputs just the result of the normal query.

add_filter('query_vars', 'custom_query_vars');
function custom_query_vars($vars) {
    $vars[] = 'parent_id';
    return $vars;
}

function parent_query( $query ) {
    // Exclude
    if( $query->is_admin == 1 && !$query->is_main_query() && !$query->is_archive == 1 ) {
        return;
    }
    // retrieve field name / value from URL if exist
    $custom_field = '_wpcf_belongs_artist_id';
    $custom_value = ( $_GET['parent_id'] ) ? stripslashes( $_GET['parent_id'] ) : '';
    if( $custom_field ) {
        // add meta key requirement -- we’ll return all posts with some ‘color’
        $query->set( 'meta_key', '_wpcf_belongs_artist_id' );
        if( $custom_value ) {
            // build meta value requirement -- we’ll return only blue
            $query->set( 'meta_value', $custom_value );
        }
    }
}
add_action( 'pre_get_posts', 'parent_query' );
share|improve this question
5  
Please, please, please edit that mess so that it is readable: wordpress.stackexchange.com/editing-help –  s_ha_dum Dec 13 '13 at 15:11
    
Oh, I didn't notice that when I submitted. Is it readable to you now? –  luke Dec 13 '13 at 15:52

3 Answers 3

You don't need to return anything from your function when using pre_get_posts:

function 
if( $query->is_admin() || !$query->is_main_query() || $query->is_archive() ) {
//Do your stuff
share|improve this answer

I think the problem is ill-posed. What happens as soon as you add two paintings by Picasso? You want both /painting1/picasso and /painting2/picasso to point to the same 'single artist post'? I suppose this is possible but I'm pretty sure it's unnecessarily complicated (and may cause SEO issues).

On the other hand, because artists and paintings are different kind of entities, I think it's perfectly fine that Picasso is displayed under /artist/picasso, and that this post is linked to from any paintings he authored.

Using the parent relationship is wrong. A painting has (usually) only one author, but an artist can produce many paintings. But a post can only have one parent, so an artist post should not be made the child of one of its paintings, or else you're in trouble as soon as you add another painting by the same author.

Instead, you should have the artist be a property of paintings. You can do this by adding a custom field for paintings, and maybe using Types' posts relationships or some other device to enforce that the value of this custom field refers to an artist post type.

With this approach, your problems are not 'solved', they just go away.

share|improve this answer
    
Thanks for your thoughts adelval. 'Painting' is not meant to be a single post with a specific painting but like a category to which the artist belongs. Other categories would for example be photography, performance art and so on. The site is not meant to be a database for pieces of art but for artists. –  luke Dec 22 '13 at 21:46
1  
I see. So why don't you just make the art form a category (maybe a custom taxonomy created with Types) associated to artists? What do you want to do with things like /painting/picasso and /sculpture/picasso? Would they point to the same single artist post? Would Picasso be a child of both 'sculpture' and 'painting'? (No, it can't) With a taxonomy, on the other hand, you can have picasso under both paintings and scultpure, but they would just be archive pages for each term, that would show all painters/sculptors in your database –  adelval Dec 23 '13 at 7:08
    
You are absolutely right. It was also my first idea to create a custom taxonomy of course. But as I didn't get my permalinks right, I asked a colleague and he advised me to do it like this. Anyway I now have the same problems like before … I am waiting for some data for phpmyadmin and will try Matthews solution, but if this doesn't solve my problem I will try to use a custom taxonomy again. –  luke Dec 23 '13 at 11:25

You got it pretty close. Here's a working example of what you're trying to do:

class Wpse_126374 {

    public function __construct() {
        add_action( 'init', array( $this, 'rewrites' ) );
        add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
    }

    public function rewrites() {
        add_rewrite_tag( '%parent_id%', '(\d+)' );
    }

    public function pre_get_posts( $query ) {
        // Don't run this on admin pages or secondary queries
        if ( is_admin() || ! $query->is_main_query() || $query->is_archive() )
            return;

        if ( '' != ( $parent_id = get_query_var( 'parent_id' ) ) ) {
            $query->set( 'meta_key', '_wpcf_belongs_artist_id' );
            $query->set( 'meta_value', $parent_id );
        }
    }

}
$wpse_126374 = new Wpse_126374;

This should allow you to have parent_id=24 in the URL.

share|improve this answer
    
With and without commenting out my approaches is does not work for me. "No posts found.". I just added this to my functions.php and visited index.php?parent_id=24. –  luke Dec 19 '13 at 20:12
    
When I drop this code in an empty theme, the generated SQL is correct. Check out the Debug Bar plugin to see the generated query and that will tell you what your issue is. You might not have any posts with that meta key/value pair, or index.php may only be querying the "post" post type, etc. –  Matthew Boynes Dec 19 '13 at 21:44
2  
Also (you've probably heard this before), be sure to flush your rewrite rules, luke. –  Robbert Dec 23 '13 at 11:52
    
Sorry for the late answer: Finally I received the login data to the phpmyadmin to check if I query with the correct values. First fault: it is not _wpcf_belongs_artist_id but _wpcf_belongs_page_id. But unfortunately it isn't working either with the adapted code. I also fulshed the rewrite rules twice. Any ideas? –  luke Jan 4 at 18:52
    
In this case "It doesn't work." means, that "no posts were found". –  luke Jan 8 at 18:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.