Randy Apps


Convenient Apps changing tomorrow.

[WordPress] How to Fix qTranslate-XT Multilingual Meta Data in “The SEO Framework”


Until now, I’ve been using the multilingual plugin “qTranslate-XT” to create Japanese and English pages on my site without any SEO plugins.
Aiming to optimize my site, I installed the highly-rated and lightweight “The SEO Framework” (TSF). However, I quickly ran into a wall unique to multilingual setups.

In this article, I’ll share how I resolved the conflict between qTranslate-XT and The SEO Framework by customizing functions.php.

1. The Problem: Language Tags ([:en]) Outputting As-Is in Meta Data

When I activated The SEO Framework, the meta description on my pages ended up looking like this: [:en]English description...[:ja]Japanese description...[:].

This simply happens because The SEO Framework doesn’t recognize qTranslate-XT’s custom tags (like [:en]) and outputs the raw text stored in the database as-is. By default, qTranslate-XT’s translation processing doesn’t apply to TSF’s meta data areas.

2. Considering WPSSO vs. Sticking with The SEO Framework

To solve this, I briefly considered using “WPSSO”, another SEO plugin known for its robust multilingual support. WPSSO handles qTranslate-XT perfectly right out of the box, which was very tempting.

However, I was already captivated by The SEO Framework’s overwhelmingly fast performance and simple configuration. I wanted to see if I could clear this hurdle without giving up on TSF.

So, instead of switching plugins, I decided to customize my functions.php to hook qTranslate-XT’s translation processing into TSF’s output.

3. [Prerequisite] Use a Child Theme

The following solution requires adding code directly to your functions.php file. Since a single typo can cause your site to go blank (Fatal Error), I highly recommend doing this in a custom theme or a child theme environment.

Please make sure to back up your file before making any changes.

4. The Solution: Code for functions.php

After some trial and error, I organized the processing into two clean steps: “Text” and “Images”. This allows the meta tags to output perfectly without sacrificing page load speed.

Step 1: Fixing Text (Titles, Descriptions, Excerpts)

First, we apply the translation process (extracting the current language) to the final text output and the raw data before TSF trims it for excerpts.

/**
 * ====================================================================
 * The SEO Framework & qTranslate-XT Integration
 * ====================================================================
 */

/**
 * 1. Translate text (titles, descriptions, excerpts, etc.)
 */
function my_tsf_qtranslate_apply_translation( $text ) {
    // Run translation only if qTranslate-XT is active and text is not empty
    if ( function_exists( 'qtranxf_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) && ! empty( $text ) ) {
        return qtranxf_useCurrentLanguageIfNotFoundUseDefaultLanguage( $text );
    }
    return $text;
}

// List of TSF filters to intercept
$tsf_text_filters = array(
    // --- Final outputs ---
    'the_seo_framework_custom_field_description',
    'the_seo_framework_generated_description',
    'the_seo_framework_description_output',
    'the_seo_framework_title_from_custom_field',
    'the_seo_framework_title_from_generation',
    'the_seo_framework_title_output',
    
    // --- OGP & Twitter Cards (Social share text) ---
    'the_seo_framework_ogtitle_output',
    'the_seo_framework_ogdescription_output',
    'the_seo_framework_twittertitle_output',
    'the_seo_framework_twitterdescription_output',
    
    // --- Raw data before TSF trims it for excerpts ---
    'the_seo_framework_get_excerpt',
    'the_seo_framework_description_excerpt',
    'the_seo_framework_fetched_description_excerpt',
);

// Apply the translation function to all filters in the array
foreach ( $tsf_text_filters as $filter ) {
    add_filter( $filter, 'my_tsf_qtranslate_apply_translation', 10, 1 );
}

Step 2: Fixing the OGP Image Source

Next, we modify the image extraction process so that the social share images (like og:image) are pulled from the current language’s content block.

/**
 * 2. Image extraction (prioritize images from the current language)
 */
function my_tsf_qtranslate_image_generator( $params, $args, $context ) {
    // Run only during social image generation (og:image, twitter:image, etc.)
    if ( 'social' !== $context ) {
        return $params;
    }

    // Intercept only when viewing a single post or page
    if ( null === $args && is_singular() ) {
        $new_cbs = array();
        
        // Loop through TSF's default image search rules
        foreach ( $params['cbs'] as $key => $cb ) {
            // Inject our custom translation extraction rule right before 'content'
            if ( $key === 'content' ) {
                $new_cbs['qtranslate_content'] = 'my_tsf_qtranslate_image_yield';
            }
            $new_cbs[ $key ] = $cb;
        }
        $params['cbs'] = $new_cbs;
    }

    return $params;
}
add_filter( 'the_seo_framework_image_generation_params', 'my_tsf_qtranslate_image_generator', 10, 3 );

// Extract the image from the current language's content and pass it to TSF
function my_tsf_qtranslate_image_yield( $args = null ) {
    // Check if qTranslate-XT is active
    if ( ! function_exists( 'qtranxf_useCurrentLanguageIfNotFoundUseDefaultLanguage' ) ) {
        return;
    }

    $post = get_post();
    if ( ! $post ) {
        return;
    }

    // ① Extract only the content block for the currently viewed language
    $translated_content = qtranxf_useCurrentLanguageIfNotFoundUseDefaultLanguage( $post->post_content );

    // ② Find the URL of the first <img> tag inside the translated content
    if ( preg_match( '/<img[^>]+src=[\'"]([^\'"]+)[\'"][^>]*>/i', $translated_content, $matches ) ) {
        $image_url = $matches[1];
        $attachment_id = attachment_url_to_postid( $image_url );

        // ③ Pass the image URL and ID to TSF
        yield array(
            'url' => $image_url,
            'id'  => $attachment_id ? $attachment_id : 0,
        );
    }
}

5. Conclusion

In the end, I was able to perfectly output qTranslate-XT’s multilingual meta data (including OGP) while maintaining the blazing fast speed of The SEO Framework.

By sticking with TSF and adding these filters, there is absolutely no noticeable slowdown, and pages load just as fast as before.

I hope this helps other developers struggling with the dilemma of “Multilingual vs. SEO vs. Page Speed”!