I have been at this for days now, going through plenty of answers here, guides on using .htaccess, guides on using add_rewrite_rule() within Wordpress and examples throughout the web. I am not sure if there is a malfunction in my regex to detect the correct URL, or a disconnect between what I want to accomplish and what can be accomplished.

Basically, I am trying to separate comments from posts (or better yet, comments from content) by forcing them to a separate page "associated" with the content. So for example, http://localhost/wp/2011/02/25/hello-world-2/ is a post, and the comments for that post should appear at http://localhost/wp/2011/02/25/hello-world-2/comments/. Now, a "little bird" once said that this could be done with the following:

RewriteRule ^archives/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)/comments/?$ /index.php?year=$1&monthnum=$2&day=$3&name=$4&comments=1 [QSA,L] (seeing as I do not really need to work inside the /archives/ for my above example to work, I removed it), which I translated into this plugin:

Plugin Name: Gingah Permalink Rewrite
Plugin URI: http://gingahmail.com/wordpress/
Description: Useful Permalink-structures, that required a plugin to work.
Version: 1.0
Author: Gingah
Author URI: http://gingahmail.com/

register_activation_hook( __FILE__, 'gingah_rewrite_activate' );
function gingah_rewrite_activate() {
register_deactivation_hook( __FILE__, 'gingah_rewrite_deactivate' );
function gingah_rewrite_deactivate() {
add_action('admin_init', 'gingah_rewrite');
function gingah_rewrite() {
    add_rewrite_rule( '^([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)/comments/?$', '/index.php?year=$1&monthnum=$2&day=$3&name=$4&comments=1 [QSA,L]', 'top' );

(based on countless examples just like it, around the web)

This does, however, not work. Even though, visiting http://localhost/wp/2011/02/25/hello-world-2/?comments=1 does produce the expected result. So what is going wrong here?

1 Answer 1


WordPress rewrite rules by default are no longer stored in the Apache configuration, but are handled by WordPress itself. This was probably not the case when that forum topic was written (5 years ago), but currently only "external" rules end up in the Apache configuration, all others are stored in the database and handled by the WP::parse_request() function.

This means you should leave off the Apache-specific parts in your add_rewrite_rule() call. The following code looks better:

    // The beginning `^` is added by WordPress
    // `$1` should be replaced with `$matches[1]`

When I tested this with my Rewrite analyzer plugin, I noticed that comments is not a standard query variable, so remember that you will have to handle that too.

  • At the very least, this now shows the post itself. I tried adding the suggested at http://wordpress.stackexchange.com/questions/3537/need-help-with-friendly-urls-in-wordpress/3575#3575 (substituting designer_name with comments to fix the query variable as you suggest, but http://localhost/wp/2011/02/25/hello-world-2/comments/ still shows just the post.
    – OleVik
    Mar 24, 2011 at 13:45
  • @Gingah: But if you can set this extra query variable, then you can also hook into template_include to select a specific theme file that will only show the comments and not the posts.
    – Jan Fabry
    Mar 24, 2011 at 13:59
  • I guess that would work, but will that still allow http://localhost/wp/2011/02/25/hello-world-2/comments/ to show the comments?
    – OleVik
    Mar 24, 2011 at 14:24
  • @Gingah: Yes, you can think of it as two different theme files, based on the same single.php: one that shows the post but no comments, and one that shows the comments but no post. You could even do this in one single.php if you read the query variable there.
    – Jan Fabry
    Mar 24, 2011 at 14:40
  • I added the functionality to the single.php-file. So, when a post is view, comments are hidden, but if a GET variable called comments is passed to the page (and is equal to 1), only comments are shown. Is this the right way? I still cannot get /comments/ to only show comments (using if (isset($_GET['comments']) && $_GET['comments'] == 1) to check if the comments-variable is set).
    – OleVik
    Mar 24, 2011 at 14:45

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.