Create sub page of sub pages using “fake pages”

I found this tutorial to make so called fake pages, so I could dynamically create pages with custom fields. It works very well, but I need to tweak it to fit my needs.

Like if for example a book have reviews from different sources:

Read More

mysite.com/books/to-kill-mockingbird/reviews/id-for-review

This mean that to-kill-mockingbird is the slug for post type book and id-for-review is the slug for post type reviews. I can easily get this to work by removing books/to-kill-mockingbird, and just have mysite.com/reviews/id-for-review, but I prefer to have the full url.

Any suggestions?

I’m trying to create a new rewrite rule that puts the id-for-review into a query variable. I have added $review-id for that purpose.

Here’s the rule I tried to make

if ($slug == 'reviews') {
           $newrules['books/([^/]+)/' . $slug . '/([^/]+)/?'] = 'index.php?book=$matches[1]&fpage=' . $slug . '&review-id=$matches[2]';
           $newrules['books/([^/]+)/' . $slug . '/?$'] = 'index.php?book=$matches[1]&fpage=' . $slug;
        }
        else
        {
           $newrules['books/([^/]+)/' . $slug . '/?$'] = 'index.php?book=$matches[1]&fpage=' . $slug;
        }

I have a template named single-book.php where the correct template is being used:

$current_fp = get_query_var('fpage');
$review-id = get_query_var('review-id');

if (!$current_fp) {
        get_template_part( 'single', 'book-index' );
    } else if ($current_fp == 'books') {
    if (!$review-id) {
        get_template_part( 'single', 'book-reviews' );
        }
        else
        {
        get_template_part( 'single', 'book-review' );
        }
    };

If I now go to /books/to-kill-mockingbird/reviews/, it uses the template for listing all reviews. But when I go to a review, it seems to use the standard WordPress template.

Here’s my .htaccess:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Related posts

1 comment

  1. Seems I came closer to the answer than I thought, after some tweaking and editing of my question. Most of my code is now correct.

    Here’s the rules that needs to put replaced in the example from the tutorial. This is put inside the foreach loop, and creates two rules for ‘reviews’.

    if ($slug == 'reviews') {
               $newrules['books/([^/]+)/' . $slug . '/([^/]+)/?'] = 'index.php?book=$matches[1]&fpage=' . $slug . '&review-id=$matches[2]';
               $newrules['books/([^/]+)/' . $slug . '/?$'] = 'index.php?book=$matches[1]&fpage=' . $slug;
            }
            else
            {
               $newrules['books/([^/]+)/' . $slug . '/?$'] = 'index.php?book=$matches[1]&fpage=' . $slug;
            }
    

    Now inside the single-books.php template, use this to get correct template:

    $current_fp = get_query_var('fpage');
    $review-id = get_query_var('review-id');
    
    if (!$current_fp) {
            get_template_part( 'single', 'book-index' );
        } else if ($current_fp == 'books') {
        if (!$review-id) {
            get_template_part( 'single', 'book-reviews' );
            }
            else
            {
            get_template_part( 'single', 'book-review' );
            }
        };
    

    Now inside single-book-review.php template, you use this to get the post data based on the slug from the query var:

    $review_id = get_query_var('review-id');
    
    $post = get_page_by_path( $review_id, OBJECT, 'review' )
    

    Also remember to go to Settings -> Permalinks and click save when you change the rule, to flush the rules.

Comments are closed.