WordPress Filter Hooks on Creating Slug – Check Availability of Slug if That is Used by Post, Page, Taxonomy, or by Plugin
I did not find any filter hook for choosing slug for any object. I have a plugin that creates its own URLs. eg. example.com/my-campaign . If someone hits on this url then he will see my plugin generated page. But if there is already a page “My Campaign” then WP is unable to show that page because that permalink already taken by my plugin. So Before creating my plugin slug I need to check ‘WP posts, pages and taxonomies‘ if any of those already used my slug. I also need to check Root directory of WordPress installation if there is a ‘directory with same name‘ of my slug.
WP Core checks available slug in its own database and reserved words. But it doesn’t check slugs those are used by any plugin. If there is a post name “my-campaign” then my plugin don’t let to chose this slug but If my plugin took this before and user want create a page “my-campaign” then WordPress will take the same slug. And here is the main problem.
In the same way my plugin is conflicting with other plugins. My plugin can check WordPress core slugs but not other plugins.
“‘Pretty Link” is one of the most popular plugin. It also creates its own url. It also checks available slug in WordPress db but not in other plugin.
Any plugin may have custom rewrite rule, then my plugin can not handle that.
So I think we need a standard rule that will be followed by WordPress core and all plugins.
I have three different plugins those need own slugs. I made a universal process that I am using in all of my plugins.
I am explaining my process bellow.
I am using a filter hook ‘onetarek_is_slug_available‘ all of my plugin use this filter before choosing a slug.
MY CODES:
function otk_filter_available_slug( $slug, $id=false) { if($slug==false)return false; global $wpdb; #Check if this slug already being used for any posts, pages or categories $has_postname = $wpdb->get_var($wpdb->prepare("SELECT post_name FROM {$wpdb->posts} WHERE post_name=%s LIMIT 1",$slug)); $has_taxonomy = $wpdb->get_var($wpdb->prepare("SELECT taxonomy FROM {$wpdb->term_taxonomy} WHERE taxonomy=%s LIMIT 1",$slug)); if( $has_postname or $has_taxonomy )return false; #Check if any same named file or directory exists in the root of wordpress installation $root_directory = opendir(ABSPATH); $slug_lower=strtolower($slug); #we consider wp-content and Wp-ContENT and WP-CONTENT are same. while (($file = readdir($root_directory)) !== false) { $filename = strtolower($file); if($filename == $slug_lower) return false; } #Check same slug is exists in click jacker database. #if same slug exists and associate for given id then return slug . We allow this if($id){$id=intval($id);} if($id) { $SQL = $wpdb->prepare("SELECT slug FROM ".CLICK_JACKER_CAMPAIGN_TABLE." WHERE slug=%s AND id =%d", $slug, $id); $has_slug = $wpdb->get_var($SQL); if( $has_slug == $slug ){return $slug;} } #if same slug exists and no id given then we don't accept this. $SQL = $wpdb->prepare("SELECT slug FROM ".CLICK_JACKER_CAMPAIGN_TABLE." WHERE slug=%s", $slug); $has_slug = $wpdb->get_var($SQL); if( $has_slug == $slug )return false; return $slug; } add_filter('onetarek_is_slug_available', 'otk_filter_available_slug', 10, 2);
I am calling above filter where I need
$campaign_slug='my-campaign'; $myslug=apply_filters('onetarek_is_slug_available', $campaign_slug); if($myslug) { #use it } else { #chose another slug }
My technique is limited.
In my filter function I run 2 SQL query to check WP slugs , but that is limited. WordPress has reserved words also, those are not being checked in this process. And my other 2 plugins also run the same. Now if any website uses my 3 plugins then same process will be run 3 times and 6 SQL query will be run to check WP slugs. My function is unable to check the slug of “Pretty Links” plugin.
But if ”’WORDPRESS core”’ would have a ”’FILTER HOOK”’ and run a function with this filter to check any kind of WP slugs then my plugins would search only its own database once. AND other plugin developer would attach a function with this filter. And they would check only their own database. Plugins don’t need to check WP slugs because core function already fired with this FILTER HOOK.
In the same way WP core should respect other plugin slugs and ”’custom url rewrite rules”’. When WP check available slug for post, page, taxonomies then it should use this FILTER also.