Skip to content

Instantly share code, notes, and snippets.

@mrizwan47
Last active March 22, 2024 21:20
Show Gist options
  • Save mrizwan47/c6d873e7610c03df074b94e1e51d73e2 to your computer and use it in GitHub Desktop.
Save mrizwan47/c6d873e7610c03df074b94e1e51d73e2 to your computer and use it in GitHub Desktop.
Show multiple WP Objects on same permalink structure with add_rewrite_rule and pre_get_posts.

Show multiple WP Objects on same permalink structure with add_rewrite_rule and pre_get_posts

In this gist, I'm sharing a method to set up identical permalinks for different types of objects in WordPress, such as posts, pages, and custom post types. By default, WordPress doesn't allow the same permalink structure for different objects. And even if you try to do this with add_rewrite_rule would get confliction and one of then would actually work. I provide a solution by leveraging add_rewrite_rule with pre_get_posts filter.

  1. First, you define a custom query param using the query_vars filter.
  2. Then, you set up rewrite rules using the add_rewrite_rule filter to map the desired permalink structure to the custom query variable. This allows WordPress to differentiate between different objects while maintaining the same permalink.
  3. Finally, you'd need to hook into the pre_get_posts filter to change the main query based on the slug found in the query parameter.

In conclusion, you'd get uniform permalinks for different WordPress objects, enhancing the flexibility and customization of the platform.

If you get into trouble, you can read this article for more details

<?php
// Adding a custom rewrite rule
add_action('init', 'custom_rewrite_rule');
function custom_rewrite_rule() {
add_rewrite_rule('^([^/]*)/?', 'index.php?page_or_city=$matches[1]', 'top');
}
// Registering the custom query variable
add_filter('query_vars', 'custom_query_vars_filter');
function custom_query_vars_filter($vars) {
$vars[] = 'page_or_city';
return $vars;
}
// Modifying the main query using pre_get_posts
add_action('pre_get_posts', 'custom_pre_get_posts');
function custom_pre_get_posts($query) {
if ($query->is_main_query() && !is_admin()) {
$page_or_city = get_query_var('page_or_city');
if (!empty($page_or_city)) {
if ($page = get_page_by_path($page_or_city)) {
$query->set('pagename', $page_or_city);
$query->set('post_type', 'page');
} elseif ($city_term = get_term_by('slug', $page_or_city, 'cities')) {
$query->set('taxonomy', 'cities');
$query->set('term', $city_term->slug);
}
}
}
}
<?php
// Modifying the main query using pre_get_posts
add_action('pre_get_posts', 'custom_pre_get_posts');
function custom_pre_get_posts($query) {
if ($query->is_main_query() && !is_admin()) {
$page_or_city = get_query_var('page_or_city');
if (!empty($page_or_city)) {
if ($page = get_page_by_path($page_or_city)) {
$query->set('pagename', $page_or_city);
$query->set('post_type', 'page');
} elseif ($city_term = get_term_by('slug', $page_or_city, 'cities')) {
$query->set('taxonomy', 'cities');
$query->set('term', $city_term->slug);
}
}
}
}
<?php
// Registering the custom query variable
add_filter('query_vars', 'custom_query_vars_filter');
function custom_query_vars_filter($vars) {
$vars[] = 'page_or_city';
return $vars;
}
<?php
// Adding a custom rewrite rule
add_action('init', 'custom_rewrite_rule');
function custom_rewrite_rule() {
add_rewrite_rule('^([^/]*)/?', 'index.php?page_or_city=$matches[1]', 'top');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment