Search code examples
wordpresspluginshookwpml

WPML custom language switcher plugin: wpml_active_languages hook returns empty array on root page


I'm creating a custom language switcher plugin that can be displayed as a modal on the website, or you can add a WPML root page and only display it on the root page. I'm using the wpml_active_languages hook and it works fine on the modal, but when I try to use it on the root page it returns an empty array. The plugin used to work with WPML's icl_get_languages() function, but since that function is deprecated I'm trying to update the code with wpml_active_languages.

Here's are examples of what the plugin looks like on the frontend:

Modal example - https://shineadstudy.com/

Root page example - https://global.essencetrial.com/

Here is the code for the updated plugin:

// Global modal switch
if ( !defined( 'EHRLS_MODAL_OFF' ) ) {
  if(isset(get_option('wpmllanguageswitcher_options')['wpmllanguageswitcher_disable_modal']) && get_option('wpmllanguageswitcher_options')['wpmllanguageswitcher_disable_modal'] == 'on'){
    define( 'EHRLS_MODAL_OFF', true );
  }else{
    define( 'EHRLS_MODAL_OFF', false );
  }
}

// Require plugin functionality
require_once EHRLS_PATH.'functions.php';
require_once EHRLS_PATH.'options.php';


/* Trigger modal and Save user's language selection as a cookie */
$page_template_slug = get_page_template_slug();

function save_lang() {
    $page_template_slug = get_page_template_slug();

    // do not trigger modal if 'wpmllanguageswitcher_disable_modal' setting is checked and the user is on a non-root page
    if ( !EHRLS_MODAL_OFF || $page_template_slug=='template-root.php' ) :

        $hide_selector = $page_template_slug!=='template-root.php' ? ' hide' : '';
        
        $language_arr = apply_filters( 'wpml_active_languages', NULL, 'orderby=name&order=asc' );
        $language_list = '';

        $selector_heading = !empty( get_option('wpmllanguageswitcher_options')['wpmllanguageswitcher_heading'] ) ? get_option('wpmllanguageswitcher_options')['wpmllanguageswitcher_heading'] : 'Select your language:';
        $selector_location = !empty( get_option('wpmllanguageswitcher_options')['wpmllanguageswitcher_selector_location'] ) ? get_option('wpmllanguageswitcher_options')['wpmllanguageswitcher_selector_location'] : ''; 

        foreach($language_arr as $language) {
            $language_list .=   '<li>'.
                                    '<a id="'. $language['default_locale'] .'" class="redirect-link" href="'. $language['url'] .'" data-url="'. $language['url'] .'">'.
                                        '<img src="'. $language['country_flag_url'] .'">'.
                                        $language['native_name'].
                                        '<span>'. file_get_contents( plugin_dir_url( __FILE__ )."/assets/images/arrow.svg" ) .'</span>'.                                  
                                    '</a>'.
                                '</li>';
        }
?>

<div id="ehrlsContainer" class="ehr-lang-selector__container<?php echo $hide_selector ?>">
    <div class="ehr-lang-selector__wrap <?php echo $selector_location ?>">
        <div class="lang-modal">
            <div id="closeBtn" class="close-modal"><img src="<?php echo plugin_dir_url( __FILE__ ).'/assets/images/close.svg'; ?>"/></div>
            <div class="lang-modal-content">
                <h2><?php echo esc_html($selector_heading); ?></h2>
                <ul class="lang-selectors"><?php echo $language_list ?></ul>
                <!-- <a id="redirectBtn" class="redirect-btn">OK</a> -->
            </div>
        </div>
    </div>
</div>

<?php
    endif;
}

add_action('wp_footer','save_lang');

Here are screenshots of the modal and the root page on the dev site. You can see the modal returns 2 languages in the wpml_active_languages array, but the root page returns an empty array:

enter image description here enter image description here

Here's a link to the wpml_active_languages documentation: https://wpml.org/wpml-hook/wpml_active_languages/

I'm not sure if the save_lang() callback should be called from a different WP action? But that doesn't seem necessary, because it works in the modal.


Solution

  • Received an answer from WPML support:

    The reason is because in WPML->languages->How to handle languages without translation -> Link to home of language for missing translations is enabled (it is not a default option)

    If you instead use 'skip language' the hook will not work as expected as the root page does not have a translation. (you cannot translate it)