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:

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:
does redirect me to:
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:

redirects me to:
with the correct output of the single artist post.

just outputs my front page.

The only more or less working variant is:
/painting/picasso/?artist=picasso&_wpcf_belongs_artist_id=24 and:
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 ) {
    // 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' );

3 Answers 3


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() )

        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.

  • 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, 2013 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. Dec 19, 2013 at 21:44
  • 2
    Also (you've probably heard this before), be sure to flush your rewrite rules, luke.
    – Robbert
    Dec 23, 2013 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, 2014 at 18:52
  • In this case "It doesn't work." means, that "no posts were found".
    – luke
    Jan 8, 2014 at 18:27

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.

  • 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, 2013 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, 2013 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, 2013 at 11:25

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

if( $query->is_admin() || !$query->is_main_query() || $query->is_archive() ) {
//Do your stuff

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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