• Hello all,

    I have been trying to figure out what changing the permalink structure from the default to the %postname% changes the database query string that WordPress generates for the category names ‘News’.

    Here is what I am doing:

    1. I have a category called ‘News’ which doesn’t contain any posts but for which I’ve created a menu link through the custom menu.
    2. I have then created a ‘pre_get_posts’ filter to modify the query for that category to also include all other categories. This allows me to show all my posts under the ‘News’ page regardless of what category the posts themselves are under.
    3. When my permalink structure is set to the default (ie.: https://localhost/?p=4) the News page shows all of my posts as expected.
    4. When I change my permalink structure to /%postname%/ (ie.:https://localhost/news/) the News page no longer shows any posts.

    Here are my findings:

    When the default permalink structure is used. The ‘request’ that is made (found by dumping $wp_query) is this:

    SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
    	INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
    	WHERE 1=1
    		AND ( wp_term_relationships.term_taxonomy_id IN (1,4,5,7,8,9,10,11,12,13,14,15) )
    		AND wp_posts.post_type = 'post'
    		AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
    	GROUP BY wp_posts.ID
    	ORDER BY wp_posts.post_date DESC
    	LIMIT 0, 15

    When I change my permalink structure to /%postname%/. The ‘request’ that is made (found by dumping $wp_query) is this:

    SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
    	INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
    	INNER JOIN wp_term_relationships AS tt1 ON (wp_posts.ID = tt1.object_id)
    	WHERE 1=1
    		AND ( wp_term_relationships.term_taxonomy_id IN (4) AND tt1.term_taxonomy_id IN (1,4,5,7,8,9,10,11,12,13,14,15) )
    		AND wp_posts.post_type = 'post'
    		AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
    	GROUP BY wp_posts.ID
    	ORDER BY wp_posts.post_date DESC
    	LIMIT 0, 15

    The first thing to notice is that WordPress is joining the same table twice (which is bad practice). The second thing is that the string ‘wp_term_relationships.term_taxonomy_id IN (4)’ is added in the where clause. Since 4 is the id of my ‘News’ category and since this category has no results, the whole statement returns an empty set.

    So here are my questions:
    1. Is this a bug in WordPress?
    2. If not, is there a way that I can cleanly fix this issue (without hacking WordPress’s core files)?

    Here is the section of my functions.php file that is related to this:

    // Modify the Post Get Filter
    function modPreGetPosts( $query ){
    	// Get the Theme Options
    	$themeOptions = get_option('fighers_theme_options');
    
    	// Get posts from all categories when in the news category section
    	if( is_category( 'News' ) && $query->is_main_query() && !is_admin() ){
    		$query->set( 'category__in', get_all_category_ids() );
    	}
    	// Limit number of posts to 6 on the home page
    	if( is_home() && $query->is_main_query() ){
    		$query->set( 'posts_per_page', $themeOptions['topNewsArticles'] );
    	}
    	return $query;
    }
    add_filter( 'pre_get_posts', 'modPreGetPosts' );

    Thanks

  • The topic ‘Permalink Structure Changes SQL Call’ is closed to new replies.