5

I am trying to save my page with permalink "360" but for some reason WP keeps updating the permalink to "360-2". I have checked everywhere in my WP and there is no page or post that uses permalink "360". Is 360 a permalink for something internal? If not, what is the problem?

1
  • 2
    So you're trying to create example.tld/360/? If this would work, then it might conflict with e.g. the year archive example.tld/YYYY/
    – birgire
    Commented Jul 24, 2015 at 18:24

3 Answers 3

5

The problem comes with using only numbers as URLs. Here is a forum thread in WP that discuss this issue. I'll cite Otto:

WordPress 2.3 and up does not allow the post or page slugs to be all numeric. This is because that URL scheme will conflict with multi-page posts.

There is no fix. Change them to something else.

Alternatively, a plugin exists to allow this, if you give up on multi-page posting: http://wordpress.org/extend/plugins/allow-numeric-stubs/

More info here: http://trac.wordpress.org/ticket/5305

3
  • Actually I haven't tried it in a long time. I've tried it a few minutes ago on VVV with WordPress 4.2.3. Here is a screenshot. It still doesn't allow you to use only numeric permalinks. Which WordPress version are you using? Is it installed from wordpress.org or with some script provided from the hosting e.g. softaculous and etc. Commented Jul 24, 2015 at 20:18
  • 1
    I was wrong, because it is a page, anyway I removed the comment, to not confuse others. Commented Jul 24, 2015 at 20:37
  • The sample-permalink ajax call can then be traced to wp_unique_post_slug().
    – birgire
    Commented Jul 24, 2015 at 20:39
3

If we check out the source of the wp_unique_post_slug() function, then we see that this is expected for hierarchical post types, other than nav_menu_item.

If we try for example the slugs 360 or page360, then the -n slug suffix will show up.

We can play with e.g.:

echo wp_unique_post_slug( 
    $slug        = '360', 
    $post_id     = '', 
    $post_status = '', 
    $post_type   = 'page' 
);

or

echo wp_unique_post_slug( 
    $slug        = 'page360', 
    $post_id     = '', 
    $post_status = '', 
    $post_type   = 'page' 
);

to see that.

One of the "bad slug" checks, within wp_unique_post_slug(), is this one:

preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug ) 

It's matched in your case:

preg_match( "@^(page)?\d+$@", '360' ) 

hence the resulting slug suffix.

You can also play with it here:

https://regex101.com/r/jF3kC6/1

Note that it's possible to modify the slug via the wp_unique_post_slug filter, but one should be really careful doing that.

0

Here's what I did if you don't like plugins for a simple job:

// Fix issue with digits can't be slug
add_filter('wp_unique_post_slug', 'my_allow_numeric_slug', 20, 6);

function my_allow_numeric_slug($slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug)
{
    global $wpdb;

    if (preg_match("@^\d+-2$@", $slug) && $post_type !== 'attachment') {
        $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND " .
        "post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1";
        $better_slug = str_replace('-2', '', $slug);
        $post_name_check = $wpdb->get_var($wpdb->prepare($check_sql, $better_slug, $post_type, $post_ID, $post_parent));

        if (!$post_name_check) {
            return $better_slug;
        }
    }
    return $slug;
}

"@^\d+-2$@" matches numeric slug with -2 postfix.

I actually just check for -2 if it has been added cause in the other case it means that you already have e.g. 360-2 page which seems weird to me, but I suppose you got the idea.

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.