0

When a WP user creates a new Post the default behavior is that the Title is used as the basis for the Slug which forms a major part of the URL/Permalink. I am changing this default behavior.

My code (pasted below in case it helps) removes some common words, and reduces Slug length to about 6 words.

The problem is that the WP UI for the Post does not consistently update, and I need it to.

This is a typical chain of events:

  1. Create new Post. URL/Permalink will be similar to: http://example.com/?p=32565
  2. Enter a Title; The Small Dog Has Spoken Truth on Monday
  3. Click "Save Draft"

Upon successful save, there are usually 1 of 2 outcomes.

  • Either the URL now looks like the default WP one: http://example.com/the-small-dog-has-spoken-truth-on-monday/, or
  • It remains as the one using the ID.

If I refresh (or leave and come back to the Post), the URL is http://example.com/small-dog-spoken-truth-monday/ - which is what I want it to be.

Is there another event, or method, be in in PHP or Javascript, where I can trigger WP to update the user interface so the Slug reflects the real (modified) one?

Outside of trial and error I am unsure how to proceed.

function slug_save_post_callback( $post_id, $post, $update ) {

    if (!empty($post->post_name)) { return; }
    if ($post->post_type != 'post' || $post->post_status == 'auto-draft') { return; }

    $slug = preg_replace("/[^A-Za-z0-9 ]/", '', $post->post_title);

    $remove_list = array(
        'a', 'an', 'and', 'are', 'as', 'at', 'be', 'but', 'by', 'can', 'cant', 'did', 'do',
        'for', 'from', 'get', 'got', 'had', 'has', 'hasnt', 'have', 'heres', 'how', 'i', 'in', 'is', 'its', 'just', 
        'k', 'like', 'not', 'o', 'of', 'off', 'on', 'only', 'or', 'ok', 'says', 'than', 'that', 'the', 'their', 'theyre', 'this', 'to', 'use',
        'what', 'whats', 'when', 'where', 'who', 'whom', 'why', 'will', 'with', 'wont', 'you'
    );

    foreach($remove_list as $word) {
        $slug = preg_replace("/\b$word\b/i", "", $slug);
    }

    $slug = explode("-", sanitize_title($slug));
    $slug = implode("-", array_slice($slug, 0, 6));
    if ($slug == $post->post_name) { return; }

    remove_action( 'save_post', 'slug_save_post_callback', 5, 3 );

    wp_update_post(array(
        'ID'        => $post_id,
        'post_name' => $slug
    ));

    add_action( 'save_post', 'slug_save_post_callback', 5, 3 );
    clean_post_cache($post_id);
}
add_action( 'save_post', 'slug_save_post_callback', 5, 3 );

Update: Modified the code to reflect to working version. See Answer below.

1
  • 1
    this might require you to write javascript hooks for the block editor
    – Tom J Nowell
    Commented Dec 18, 2022 at 15:14

1 Answer 1

0

Through trial and error I was able to get this working reliably without further hooks or using JavaScript in the Editor.

After restoring the hook, I added

clean_post_cache($post_id);

Separately, I updated the order of priority (from 10 to 5) for the original action.

The code in the original question has been updated to reflect this.

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.