It is very easy to create a new post type in WordPress, you just need to call the register_post_type() function with all of it's configuration array and the post type will be visible and ready for use.

But if you choose not to utilize the default "title" in the register_post_type() arguments then most likely all of the newly created post under the custom post type will be give "auto-draft-xxx" as it's post title and post name.

To overcome this problem, we need to hook into wp_insert_post_data filters and recreate the post title and post name manualy.

Hooking into wp_insert_post_data_filters :

add_filter('wp_insert_post_data', array('MyClass', 'ChangeTitle'), 99, 2);

 

Performing the manually creating post title and post name :

 

class MyClass {
  /**
   * Manually create the post title and post name since
   * this content type doesn't have post title field.
   * 
   * @param array $data
   * @param array $postarr
   * @return array
   */
  public function ChangeTitle($data, $postarr) {
    // Important to encapsulate this function to only run
    // on the specific post type, use a hidden field or 
    // unique field to determine when to run
    if (!isset($_POST['SomethingUnique'])) {
      // Remember this is a "filter", need to return the data back!
      return $data;
    }
    
    // Filtering Post
    $postData = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
    
    // Grab some field value to serve as the post_title
    $title = $postData['somefield'];
    
    // Record the manually created post title to $data['post_title'] so 
    // WordPress will save it as post title
    $data['post_title'] = $title;

    // Create manually post_name using data from title
    $slug = sanitize_title_with_dashes($title);
    $data['post_name'] = wp_unique_post_slug($slug, $postarr['ID'],  $postarr['post_status'], $postarr['post_type'], $postarr['post_parent']);
    
    // Remember this is a "filter", need to return the data back!
    return $data;
  }
}

 

Now the newly created post with the custom post type without title field will still receive post_title and post_name with the value as you set in the function above.

 

Where to put this?

The filter hook should go in the function.php while the class function can go in a separate file or inside any existing class.