These days i’ve been working on a WordPress-powered job listing site. And one thing I needed to do is to prepend the author name (user_nicename) at the beginning of the “job_listing” post slugs.

Here’s how I did it:

<?php

// usage: change_post_slug(12,'new-post-slug');
function change_post_slug($post_id, $slug){
  global $wpdb;
  // Use wpdb directly to avoid wp_insert_post action from being triggered
  $sql = "UPDATE $wpdb->posts 
    SET post_name = '$slug'
    WHERE ID = $post_id ";

  return $wpdb->query($sql);
}

// Filter the job_listing slugs creation and prepend the company's nicename to 
// it, like this: tank-directeur-artistique-2
function generate_job_listing_slug($slug, $post_ID, $post_status, $post_type, $post_parent) {
  global $wpdb, $wp_rewrite;

  $prev_slug = $slug;

  $feeds = $wp_rewrite->feeds;
  if ( ! is_array( $feeds ) )
    $feeds = array();

  if ($post_type == 'job_listing') {
    $post = &get_post($post_ID);
    // Get the post's title and generate a slug ( companyname-jobslug )
    $slug = sanitize_title($post->post_title, $post->ID);
    $author = get_user_by('id', $post->post_author);
    $slug = $author->user_nicename . '-' . $slug;

    // job_listing slugs must be unique across all posts
    $check_sql = "SELECT post_name 
      FROM $wpdb->posts 
      WHERE post_name = %s 
      AND post_type = %s 
      AND ID != %d LIMIT 1";
    $post_name_check = $wpdb->get_var( 
      $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) );

    if ( $post_name_check 
      || in_array( $slug, $feeds ) 
      || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {

      $suffix = 2;
      do {
        $alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
        $post_name_check = $wpdb->get_var( 
          $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID ) );
        $suffix++;
      } while ( $post_name_check );
      $slug = $alt_post_name;
    } 

    return $slug;

  } else { // NOT a job_listing post:

    return $prev_slug; 
  }
}

function job_listing_saved($post_id, $post) {
  if ($post->post_type == 'job_listing') {
    $new_slug = generate_job_listing_slug(
      $post->post_name,
      $post_id,
      $post->post_status,
      $post->post_type,
      $post->post_parent);
    $changed = change_post_slug($post_id, $new_slug);
  }
}
add_action('wp_insert_post', 'job_listing_saved', 100, 2);

This should give URLs that look like these: http://jobsite.com/jobs/company-name-job-title