vladimir-s / terms-descriptions

Terms descriptions - WordPress plugin
GNU General Public License v3.0
3 stars 1 forks source link

Add translation awareness #6

Open Unbubble opened 1 year ago

Unbubble commented 1 year ago

Hi,

I've added WPML translation awareness. Please consider adding the two filters as defined below to Terms Descriptions. You may also use my WPML implementation.

Situation: Many terms are the same over similar languages. For example, it is very common to use English terms like "Content" for native German speakers. Another example is "Vitamin C", which may be the same term in many languages. Term links should prefer posts of the current language, if available. Additionally, translations should not link to themselves.

Solution: Add two filters...

a) convert URLs where possible b) extend is_current_post() to match all language versions

Implementation:

Add the two filters this way to Terms Descriptions:

td_simple_parser.php @ line 75:

$translated_url = apply_filters('td_translate_url', $term['t_post_url']);

if (filter_var($translated_url, FILTER_VALIDATE_URL)) {
    $term['t_post_url'] = $translated_url;
}

td_parser.php @ line 123: $is_current_post = apply_filters('td_is_current_post', $id);

WPML implementations

(this is tested on two websites):

add_filter('td_translate_url', 'td_translate_url_with_wpml', 10, 1);
add_filter('td_is_current_post', 'td_is_current_post_with_wpml', 10, 1);

function td_translate_url_with_wpml($t_object_url) {
    // Make sure WPML is activated before using the API
    if (defined('ICL_SITEPRESS_VERSION')) {
        global $sitepress;

        // Try to get the post ID
        $object_id = url_to_postid($t_object_url);

        // If it's not a post, try to get the term ID
        if (!$object_id) {
            $taxonomies = get_taxonomies();
            foreach ($taxonomies as $taxonomy) {
                $term = get_term_by('slug', basename(untrailingslashit($t_object_url)), $taxonomy);
                if ($term) {
                    $object_id = $term->term_id;
                    $object_type = 'term';
                    $taxonomy_slug = $taxonomy;
                    break;
                }
            }
        } else {
            $object_type = 'post';
        }

        // If an object ID was found, proceed with the translation
        if ($object_id) {
            // Get the current language
            $current_language = $sitepress->get_current_language();

            // Try to get the translated object ID
            $translated_object_id = apply_filters('wpml_object_id', $object_id, ($object_type === 'term' ? $taxonomy_slug : 'post'), false, $current_language);

            // Get the translated object URL if the translation is available
            if ($translated_object_id) {
                if ($object_type === 'term') {
                    $t_object_url = get_term_link($translated_object_id, $taxonomy_slug);
                } else {
                    $t_object_url = get_permalink($translated_object_id);
                }
            }
        }
    }

    return $t_object_url;
}

function td_is_current_post_with_wpml($id) {
    global $post, $sitepress;

    $is_current_post = false;

    if (defined('ICL_SITEPRESS_VERSION')) {
        $current_language = $sitepress->get_current_language();
        $original_post_id = apply_filters('wpml_object_id', $post->ID, 'post', true, $current_language);

        if ($original_post_id === (int)$id) {
            return true;
        }

        $languages = apply_filters('wpml_active_languages', NULL, array('skip_missing' => 0));
        foreach ($languages as $language) {
            $translated_post_id = apply_filters('wpml_object_id', $post->ID, 'post', false, $language['code']);
            if ($translated_post_id === (int)$id) {
                return true;
            }
        }
    }

    return $is_current_post;
}
Unbubble commented 1 year ago

One thing's missing: In td_parser.php, $is_current_post must be OR'd to the return value of is_current_post()