When you register custom post types manually, WordPress allows you to set a distinct archive slug. How you configure this determines if the slug will be translated into your secondary language or not.
When registering custom post types manually, you can set a set a distinct archive slug using the has_archive function.
WPML allows has_archive
to be set to a string. However, if the string value is set to something other than rewrite['slug'],
or the custom post type name slug is not set, the archive slug will not be translatable.
Setting a translatable slug
In this code example, we set 'has_archive' => true
. Assuming that the slug book has been translated to libro in Spanish, the archive links are in the following:
- English (default language): http://mydomain.tld/book/
- Spanish (second language): http://mydomain.tld/es/libro/
add_action( 'init', 'create_post_type' ); function create_post_type() { register_post_type( 'book', array( 'labels' => array( 'name' => __( 'Books', 'textdomain' ), 'singular_name' => __( 'Book', 'textdomain' ) ), 'public' => true, 'has_archive' => true, 'publicly_queryable' => true, 'exclude_from_search' => false, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => array('slug' => 'book'), 'supports' => array('title','editor', 'custom-fields','thumbnail') ) ); }
Setting the same slug in default and secondary languages
In this code example, we set a specific string for the parameter 'has_archive' => 'my-books'
. Now the archive links are as follows:
- English (default language): http://mydomain.tld/my-books/
- Spanish (second language): http://mydomain.tld/es/my-books/
add_action( 'init', 'create_post_type' ); function create_post_type() { register_post_type( 'book', array( 'labels' => array( 'name' => __( 'Books', 'textdomain' ), 'singular_name' => __( 'Book', 'textdomain' ) ), 'public' => true, 'has_archive' => 'my-books', // Do not use the gettext functions for this parameter 'publicly_queryable' => true, 'exclude_from_search' => false, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => array('slug' => 'book'), 'supports' => array('title','editor', 'custom-fields','thumbnail') ) ); }
Troubleshooting customizable slugs
Some themes and plugins allow the site administrator to set custom slugs for their custom post types and custom taxonomies.
If your translated custom slugs are returning a 404 error, please check the following:
- The custom type should be always registered with the same slug across all requests: per language, frontend, backend, AJAX, heartbeat, etc. So in
'rewrite' => [ 'slug' => $my_custom_slug ],
the value of$my_custom_slug
should not change from one request to another even if it comes from an option (or any custom setting). - WPML supports only custom slug translation (when the custom type is registered) but not custom permalink structure.
- If the custom slug is stored as an option, it should not be registered as an
admin-texts
in thewpml-config.xml
file. - After updating the value of a custom slug, the theme/plugin should also flush the rewrite rules (by calling
flush_rewrite_rules();
).