Viewing 6 replies - 1 through 6 (of 6 total)
  • Plugin Author Takayuki Miyoshi

    (@takayukister)

    What problems do you have? Where can we see the website in question?

    Thread Starter Saskia Teichmann

    (@jyria)

    Issue Description (Detailed Overview in Thread Link 1)

    When enabling shortcode execution within Contact Form 7 (CF7) forms, the shortcode output fails to be translated, even though the translation files are correctly set up and functional. If the same shortcode is used outside of CF7, such as on a standalone page or post, the translations work perfectly as expected.

    Root Cause Analysis

    The issue appears to originate from how your plugin manages internationalization. Specifically, during form creation, the plugin adds a meta_key named _locale to the form’s post_meta data. The value of this meta_key is set to the current user’s locale rather than using WP_LANG, which is the language setting for the WordPress installation.

    Consequently, when a shortcode is executed within a CF7 form, get_locale() returns either an empty or incorrect value, as described above. At this point, the required text domain fails to load correctly, despite being properly loaded in other contexts (e.g., when the shortcode is placed on a regular page, get_locale() pulls the correct value from WP_LANG, and the text domain loads successfully).

    My Workaround

    To address this incorrect internationalization handling by Contact Form 7, I implemented a custom solution in my child theme:

    1. Helper Function to Fix the Locale

    /**
     * Retrieves the fixed network site locale.
     *
     * Ensures the correct locale is used for the current network site, fixing translation issues within shortcodes.
     *
     * @return string The corrected locale for the current site.
     */
    function get_fixed_networksite_locale() {
        // Retrieve the default locale.
        $locale = get_locale();
    
        // Fix translation issues by fetching the network site's locale.
        $wp_loc = get_blog_option( get_current_blog_id(), 'WPLANG' );
    
        // Use 'en_US' if the 'WPLANG' option is empty.
        $wp_loc = empty( $wp_loc ) ? 'en_US' : $wp_loc;
    
        // If the current locale differs from the network site's locale, use the network site's locale.
        $locale = ( $locale !== $wp_loc ) ? $wp_loc : $locale;
    
        return $locale;
    }

    2. Helper Function to Ensure Text Domain Is Loaded

    /**
     * Ensures the child theme's text domain is loaded.
     *
     * @param string $textdomain The text domain to load.
     */
    function ensure_child_theme_textdomain_loaded( $textdomain ) {
        // Use the fixed locale.
        $locale = get_fixed_networksite_locale();
    
        // Check if the text domain is already loaded.
        if ( ! is_textdomain_loaded( $textdomain ) ) {
            // Construct the .mo file path based on the locale.
            $mofile = sprintf( '%s.mo', $locale );
            $domain_path = get_stylesheet_directory() . '/languages';
            $loaded = load_textdomain( $textdomain, path_join( $domain_path, $mofile ) );
    
            // Log a message if the text domain could not be loaded.
            if ( ! $loaded ) {
                error_log( "Failed to load text domain: {$textdomain}" );
            }
        }
    }

    3. Applying the Fix in My Shortcode

    /**
     * Outputs the GDPR consent notice for artwork uploads.
     *
     * Generates a GDPR notice with translated text using the 'tm-design' text domain.
     *
     * @return string The GDPR notice HTML.
     */
    function tm_upload_dsgvo_ausgabe() {
        // Start output buffering.
        ob_start();
    
        // Load the text domain for translations.
        ensure_child_theme_textdomain_loaded( 'tm-design' );
    
        // Construct the GDPR notice with translations.
        $dsgvo_out = '<span class="newline">' . sprintf(
            __( 
                'Yes, I have read and agree to the %1$s and %2$s. I consent to my uploaded file and provided information being used, for example, as an image in the TOPModel Artwork Gallery or for posting on the TOPModel Instagram page.', 
                'tm-design' 
            ),
            get_privacy_html(), // Privacy policy link.
            get_nutzungsbedingungen_html() // Terms of use link.
        ) . '</span>';
    
        // Output the notice and return the buffered content.
        echo $dsgvo_out;
        return ob_get_clean();
    }
    
    // Register the shortcode for use in CF7 forms.
    add_shortcode( 'tm-upload-dsgvo', 'tm_upload_dsgvo_ausgabe' );

    Demonstration of the Fix

    Thanks to this workaround, the shortcode now outputs translations correctly, even within CF7 forms. Here are examples in different languages:

    Final Note

    Without this code, shortcodes used in Contact Form 7 forms will not be translated. I am puzzled as to why this issue hasn’t been addressed yet, despite being reported multiple times. I hope this explanation helps, and I would be grateful if you could consider fixing this problem.

    Thank you for your attention.

    Saskia

    P.S.: please find a descriptive gist here: https://gist.github.com/s-a-s-k-i-a/b63668a8fef246293ce8931c80e1b0e2

    Plugin Author Takayuki Miyoshi

    (@takayukister)

    If an English user creates a contact form, it becomes an en_US form; if a German user creates a contact form, it becomes a de_DE form. It is natural behavior and how Contact Form 7 is expected to do. I don’t understand why you think it a problem.

    Thread Starter Saskia Teichmann

    (@jyria)

    Good morning @takayukister

    Thank you for your response. I understand that the form’s locale is set based on the user’s language when the form is created, which aligns with Contact Form 7’s design. However, the issue arises when shortcodes are executed within a form, as this behavior leads to unexpected and inconsistent translation results.

    Here’s why it matters:

    When a shortcode is executed in a Contact Form 7 form, get_locale() returns either an empty value or a user-based locale, which does not reflect the current site’s language settings (WP_LANG). This mismatch prevents the correct loading of translation files, even when they are fully functional outside the CF7 context. So, even if the expected behavior is for the form to inherit the user’s locale, it breaks the shortcode translation logic that relies on site-wide language settings.

    In other contexts (like a regular page or post), the translations work perfectly. The workaround I created ensures that the correct locale and text domain are loaded, providing consistent translations.

    Would you be open to considering a solution or modification to address this inconsistency for cases where shortcode translation is crucial?

    Thank you again for your attention to this!

    Saskia

    Plugin Author Takayuki Miyoshi

    (@takayukister)

    Shortcodes are not executed in a Contact Form 7 form.

    Thread Starter Saskia Teichmann

    (@jyria)

    Thanks for the clarification.

    I’d like to point out that Contact Form 7 includes the wpcf7_form_elements filter, which allows developers to execute custom tags and actions within a CF7 form. While detailed documentation on this filter is limited, it is clearly intended for advanced developers who need to extend CF7’s functionality.

    Using this filter is a legitimate and supported approach, but the issue remains: when custom shortcodes are executed using this filter, the translation logic doesn’t function correctly and in line with WordPress Codex due to the locale handling within CF7. My workaround addresses this gap, ensuring that translations are properly applied, which is crucial for multilingual sites.

    It’s important to note that the incorrect locale assignment affects not only the execution of shortcodes but also the form itself. F.e. If a user has set their admin language to en_US in their profile but creates a Contact Form 7 form on a WordPress installation globally set to de_DE via WP_LANG, the form will be displayed in English on the frontend instead of German as expected. This approach to locale handling is problematic and not compliant with the WordPress Codex, as it prevents the proper loading of the text domain. In a multilingual setup, this behavior is simply unacceptable.

    I hope this provides more context on why this issue matters not only for developers using CF7 in custom setups but also for any CF7 user. Thank you for your time and consideration!

Viewing 6 replies - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.