Home›Support›English Support›[Resolved] language switcher - custom post type archive links to home instead of translation if no posts availa...
[Resolved] language switcher - custom post type archive links to home instead of translation if no posts availa...
This thread is resolved. Here is a description of the problem and solution.
Problem: Generally it is expected that a Custom Post Type Archive will not be accessible if no posts have been translated yet. In this case the client tried to create a custom language switcher to solve the issue. Solution: For custom language switchers, note that you can use the hook wpml_active_languages to manually generate the correct URLs for your language switcher. Here's an example, but take note that you need to adapt the code to your needs. For example "post-type-name" "slug-name" would be the slug that you would like to translate and this hook will make it translatable:
function force_cpt_archive_language_urls($post_type = 'post-type-name') {
$languages = apply_filters( 'wpml_active_languages', NULL, array(
'skip_missing' => 0
) );
if ( !empty($languages) ) {
foreach ($languages as $code => &$lang) {
// Manually generate the archive link for the CPT in this language
$translated_slug = apply_filters( 'wpml_translate_single_string', $post_type, 'slug-name', "URL slug: $post_type", $code );
$lang['url'] = home_url( '/' . $code . '/' . $translated_slug . '/' );
}
}
return $languages;
}
Please note, that this is a custom solution and might not have been tested in every setup. It's beyond WPML's built-in functionality, so our support doesn’t cover debugging custom code. If this solution does not resolve your issue or seems irrelevant due to being outdated or not applicable to your case, we highly recommend checking related known issues at https://wpml.org/known-issues/, verifying the version of the permanent fix, and confirming that you have installed the latest versions of themes and plugins. If further assistance is needed, please open a new support ticket.
This is the technical support forum for WPML - the multilingual WordPress plugin.
Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.
Background of the issue:
I am trying to implement a language switcher using do_action('wpml_add_language_selector') or by building it with the function icl_get_languages('skip_missing=0&orderby=code').
Symptoms:
When there are no posts available for a custom post type archive page, the language switcher links to the home page instead of the translated archive page. For example, it returns 'hidden link' instead of 'hidden link'. If posts are published, it works as expected.
Questions:
Why does the language switcher link to the home page instead of the translated archive page when no posts are available?
How can this issue be fixed so that the language switcher correctly links to the translated archive page?
Languages: English (English )German (Deutsch )French (Français )
Timezone: Europe/Zagreb (GMT+01:00)
Hi,
What if you try something like this? Let’s say your CPT is called stellen. You can try something like this:
<?php
$languages = icl_get_languages('skip_missing=0&orderby=code');
if (!empty($languages)) {
echo '<ul class="language-switcher">';
foreach ($languages as $lang_code => $lang) {
// Get the correct archive URL in this language
$translated_url = apply_filters( 'wpml_permalink', get_post_type_archive_link( 'stellen' ), $lang_code );
// Use WPML's native_name for label
echo '<li>';
echo '<a href="' . esc_url( $translated_url ) . '"';
if ($lang['active']) {
echo ' class="active-language"';
}
echo '>' . esc_html( $lang['native_name'] ) . '</a>';
echo '</li>';
}
echo '</ul>';
}
?>
Does something like this work in your site?
Also, can you confirm if your custom post type is available in the other language (e.g., German)? And if you visit the translated archive URL directly, does it show the archive page or redirect?
When WPML generates archive URLs, it checks if there is at least one published post of that CPT in the target language.
Yes, the CPT URLs exist in all languages, and all translated URLs can be accessed.
.../stellen
.../offeres-demploi
etc.
Your suggested code would work, but needs hardcoded CPTs in the function, where the navigation menu is generated. Could be a solution, but would need hardcoded stuff.
You mention this:
When WPML generates archive URLs, it checks if there is at least one published post of that CPT in the target language.
That sounds like the explanation of the cause. But honestly, I really do not understand this point of view in WPML. Why should it not be usefull to always link to the translated page? If posts are published or not is completly irrelevant. This is always better then linking to the Home, what is done right now.
Okay, this is the function I'm using. I know that icl_get_languages() is deprecated, but do_action('wpml_add_language_selector') returns the same result. ACF Pro is used for the CPT.
function language_selector_flags($output_type = null){
if ( !function_exists('icl_get_languages') ) {
return '';
}
$languages = icl_get_languages('skip_missing=0&orderby=code');
$ret = '';
if(!empty($languages)) {
ksort($languages); //de sonst nicht an erster Stelle
$ret .= '<ul class="d-flex langs-public">';
$i = 0;
foreach($languages as $l){
$css_active = ($l['active']) ? 'active' : '';
$icon = '';
$ret .= '<li><a class="'.$css_active.'" href="'.$l['url'].'">'.$icon.$l['translated_name'].'</a></li>';
$i++;
}
$ret .= '</ul>';
}
}
Note: This is a custom solution and hasn’t been tested in every setup. It's beyond WPML's built-in functionality, so our support doesn’t cover debugging custom code, but we hope this helps point you in the right direction.
I still do not really understand, why this WPML "feature" depends on number of posts. From my point of view, WPML simply should just return the translated slug.