Illustration by Astrid Lydia Johannsen

I like to use numbers in my URLs instead of text because it makes more sense to me. Comic pages go up numerically, and I catalog my illustrations by the custom date number in the lower right corner of the site. However, version 4.3 of WordPress introduced a bit of a snag in that setup. No longer is it possible to have a number as the first element of a clean permalink structure. According to the code itself in wp-includes/post.php:

/*
* Potential date clashes are as follows:
*
* – Any integer in the first permastruct position could be a year.
* – An integer between 1 and 12 that follows ‘year’ conflicts with ‘monthnum’.
* – An integer between 1 and 31 that follows ‘monthnum’ conflicts with ‘day’.
*/

This means that in WordPress 4.3+, the numbers I use to make permalinks will always result in them getting a “-2” appended. Well, that just won’t do.

I wrote about this dilemma back in December (two news posts ago) and figured out the first half of a solution by hacking the core code. Of course, hacking the core code is a really bad idea, so I’ve been tinkering with a plugin or functions.php solution to resolve the issue and I think I’ve come up with a solution.

Because years in just about every existing calendar system (except perhaps the French Republican) use four digits, and months generally only have two digits, I decided to have WordPress not allow two or four digit slugs. But it will allow any other integer length. That means I can continue to use my three and five digit post slugs and I (hopefully) won’t cause a date conflict for WordPress. This code works on my local dev site with WP 4.4.2.

If you prefer using numbers for your permalink slugs, maybe this is the code you’re looking for.

It’s getting to be the end of 2015, and so I figured I’d update my website theme for the new year. I use MAMP to make a local install of WordPress on my Mac and then build the theme using the most recent version. As of this writing, the most recent version of WordPress is 4.4. However, I found out that in version 4.3, numeric post slugs began appending a “-2” to the slug to prevent possible conflicts with date-based permalinks.

Sadly, this change completely screws up my permalink structure for my portfolio and webcomic sites. Sure, it would be easy enough to add an additional element to the URL such as “http://ellejohara.com/threads/page/001/” where I add “page”, but I don’t really want to do that.

I picked through the source code and found the new lines that do the check for date conflicts. After puzzling through it for an hour or so, I figured out how to work around the check.

In wp-includes/post.php, the lines of code added to check the permalink structure for numbers begins on line 3616. I’ll comment on what the code does line-by-line.

// Prevent new post slugs that could result in URLs that conflict with date archives.
$post = get_post( $post_ID );
// Get the post ID

$conflicts_with_date_archive = false;
// Make a conflict catcher variable we can use for later

if ( 'post' === $post_type && ( ! $post || $post->post_name !== $slug ) && preg_match( '/^[0-9]+$/', $slug ) && $slug_num = intval( $slug ) ) {
// if the type of post is 'post' AND there is either no post id or the post name is not the same as the post slug AND the slug contains numbers AND those numbers can be successfully converted into an integer, then do the following:

/*
* Potential date clashes are as follows:
*
* - Any integer in the first permastruct position could be a year.
* - An integer between 1 and 12 that follows 'year' conflicts with 'monthnum'.
* - An integer between 1 and 31 that follows 'monthnum' conflicts with 'day'.
*/
// This is a big one, so I'll break it down a bit

if ( 0 === $postname_index
// if '%postname%' is the only element in the permalink structure

|| // OR

( $postname_index && '%year%' === $permastructs[ $postname_index - 1 ] && 13 > $slug_num )
// there is more than one element in the permalink structure AND '%year%' comes before '%postname%' AND the slug integer is less than 13 (1 - 12)

|| // OR

( $postname_index && '%monthnum%' === $permastructs[ $postname_index - 1 ] && 32 > $slug_num )
// there is more than one element in the permalink structure AND '%monthnum%' comes before '%postname%' AND the slug integer is less than 32 (1 - 31)

This $conflicts_with_date_archive variable is then used a few lines later in the if statement that checks bad slugs. If it’s a bad slug, add a 2 to the slug to prevent a possible date-based permalink conflict.

The code clearly states that any integer slug could be interpreted as a date, so it calls it bad and adds the 2. But I figure dates really only need either a two-digit or a four-digit number, one represents days or months, and the other represents the year. So if only two or four-digit numbers are needed for date-based permalinks, then why shut out all numbers?

After line 3619, I added another if statement with a few preg_match rules to look for the number of digits in the slug integer. If it finds a single digit, two digits, or four digits, then it marks the slug as a date conflict and adds the two. If the integer slug is three digits, or five or more digits, there is no conflict and you get the numeric slug you want. Here’s what I did:

Don’t forget to add another closing curly bracket after line 3636 or you’ll break PHP.

WordPress seemed to work just fine for me for years and years with three-digit and five-digit slugs, and I’m hoping it will continue to work now that I’ve added this additional if statement. If you plan on using this fix to get numeric slugs working again, I don’t recommend hacking the WordPress source code itself to do it. It would be better to hook the function with a custom one in the functions.php file in your theme, or to make a plugin. Since I’ve never bothered learning how to make WordPress plugins, I don’t have one here to download. Sorry. But hopefully this will spark the imagination of others to do so.