Translations Hooks

WordPress Filters relating to detecting & translating words

Weglot plugin will detect all the words in your HTML. To do this, it will parse the DOM in PHP and detect the inner text of HTML nodes but also some attributes we have defined, like the "placeholder" attribute in a <input> node or the "alt" attribute of an img node.

This usually ensure all the text in your page is detected and get translated. However, in some case, your text can be located in other location in your HTML. Like it could be in a JavaScript variable like this

<script>
var myAwesomeVar = 'This is a text I would like to translate';
</script>

In that case, your text will not be detected and not be translated.

This is where you will use filters to extend the definitions of the Weglot Parser and instruct it to detect other text

weglot_get_dom_checkers

This filter extend the list of HTML nodes and attribute that are being translated.

Argument

Type

Description

$dom_checkers

String

Names of used DomChecker (extends Weglot\Parser\Check\Dom\AbstractDomChecker)

Use case

It can happen in your HTML that you use data-attributes that are not translated by default. Example with data-slide-title

<div data-slide-title="Title slide">
    New project !
</div>

With this the weglot_get_dom_checkers filter, you will extend the list of "Dom checkers" by adding a class in the list like on the following example. Y

<?php

add_filter( 'weglot_get_dom_checkers', 'custom_weglot_dom_check' );
function custom_weglot_dom_check( $dom_checkers  ) { //$dom_checkers contains the list of all the class we are checking by default
	if (!class_exists('Div_Slide_Title')) {
		class Div_Slide_Title extends Weglot\Parser\Check\Dom\AbstractDomChecker {
			const DOM       = 'div'; //Type of tag you want to detect // CSS Selector
			const PROPERTY  = 'data-slide-title'; //Name of the attribute in that tag uou want to detect
			const WORD_TYPE = Weglot\Client\Api\Enum\WordType::TEXT; //Do not change unless it's not text but a media URL like a .pdf file for example.
		}
		$dom_checkers[] = '\Div_Slide_Title'; //You add your class to the list because you want the parser to also detect it
	}
	return $dom_checkers ;
}

weglot_get_regex_checkers

This filter is a bit more tricky to understand but also very powerful. It allows you to give a Regex to the parser in order for it to detect the text you want in your DOM.

Argument

Type

Description

$regex_checkers

array

Used RegexChecker

$regex_checkers is an array that contains the RegexChecker objects, which determine what elements to treat as well as the type of data it is (TEXT, HTML or JSON).

\Weglot\Parser\Check\Regex\RegexChecker( $regex = '' , $type = '' , $var_number = 0 , $keys = array() );

The RegexChecker constructor settings are as follows:

  • $regex: Regex that target the element you want to be parsed

  • $type: String variable that determines the type of the targeted element ('TEXT', 'HTML' or 'JSON')

  • $var_number: Denotes the number of variable targeted by the regex that you want to parse

  • $key: If the element being treated is a ‘JSON’ element, this variable allows you to specify keys to translate

  • $decode_function: Function callback applied to intercepted content

  • $encode_function: Function callback applied to returned content

Use case

Below are several examples of content that will not be translated by default by Weglot, but that you can translate using this filter

<script type="text/javascript">
    jQuery(document).ready(function ($) {

        // Untranslate text
        alert("My untranslate text");
        console.log("My untranslate text", "My untranslate text");

        // Untranslate HTML
        $("body").append("<p>My <strong>untranslate</strong> text</p>");

        // Untranslate JSON values
        var myJson = {
            "MyKey1": {
                "MyKey1-1": "My untranslate text",
                "MyKey1-2": "My untranslate text"
            },
            "MyKey2": "My untranslate text",
            "some_array" : [ "Hello" , "Translate this"]
        };

    });
</script>
<script type="text/template">"\r\n\t\t\t<div class=\"sticky-sidebar\">\r\n\t\t\t\t\ ....  \t\t<\/div>\r\n\r\n\t\t\t"</script>
<div data-escapedjson="{&quot;schema&quot;:{&quot;content&quot;:{&quot;desktop&quot;:&quot;&lt;h1&gt;Translate it&lt;\/h1&gt;&quot;}}}"><h1>This, no problem</h1></div>

In order for the content in this example to be interpreted, and then translated, we will use the weglot_get_regex_checkers filter as followed.

<?php

add_filter( 'weglot_get_regex_checkers', 'custom_weglot_add_regex_checkers' );

function custom_weglot_add_regex_checkers( $regex_checkers ) {

    // Text
    $regex_checkers[] = new \Weglot\Parser\Check\Regex\RegexChecker( '#alert\(\"(.*)\"\);#', 'TEXT', 1 );
    $regex_checkers[] = new \Weglot\Parser\Check\Regex\RegexChecker( '#console\.log\(\"(.*?)\",.*?\"(.*?)\"\);#', 'TEXT', 2 );

    // HTML
    $regex_checkers[] = new \Weglot\Parser\Check\Regex\RegexChecker( '#\$\(\"body\"\)\.append\(\"(.*)\"\);#', 'HTML', 1 );

    // JSON
    $regex_checkers[] = new \Weglot\Parser\Check\Regex\RegexChecker( '#var myJson = ((.|\s)+?);#', 'JSON', 1, array('MyKey1-1', 'MyKey1-2', 'MyKey2' , 'some_array') );
    
    //More advanced : HTML after a callback
    $regex_checkers[] = new \Weglot\Parser\Check\Regex\RegexChecker( "#<script type=\"text\/template\">(.*)<\/script>#", "HTML", 1, array(),"json_decode" , "json_encode");
    
    //More advanced : JSON after a callback
    $regex_checkers[] = new \Weglot\Parser\Check\Regex\RegexChecker( '#data-escapedjson="((.|\s)+?)"#', 'JSON', 1, array(), "html_entity_decode" , "htmlentities" );
    
    //More advanced : JSON after a callback, version with another regex
    $regex_checkers[] = new \Weglot\Parser\Check\Regex\RegexChecker( '#data-escapedjson="(.*)"#', 'JSON', 1, array(), "html_entity_decode" , "htmlentities" );
    
    return $regex_checkers;
}

weglot_add_json_keys

Weglot also translates JSON response but not all values. Use this filter to target specific values.

Argument

Type

Description

$keys

array

Array of string

The JSON values translated by default are:

  • Value with key: "name"

  • Value with key: "description"

  • Value in HTML format

Use case

You may come across values used in your JSON that are not translated by default.Here’s an example using the message value:

{
    "name":"My name value, already translated", //Will be translated by default because key is "name"
    "description":"My description value, already translated", //Will be translated by default because key is "description"
    "my_custom_key":"<p>HTML content, already translated</p>", //Will be translated by default because we detect this is HTML
    "message":"My message value to translate!" //This will not be translated and you will need to use the filter
}

To do this, we use weglot_add_json_keys filter.

<?php

add_filter( 'weglot_add_json_keys',  'custom_weglot_add_json_keys' );
function custom_weglot_add_json_keys(  $keys  ){ //$keys already contains "name" and "description"
    $keys[]  =  'message'; //This tells Weglot to also look for key "message" when detecting content to translated
    return $keys;
}

Also, note that if a URL is detected in a value of the JSON, it will be replaced by the URL with the language code if and only if it is one of the redirecturl , url , link . For example, if you original JSON is

{
    "url" : "https://mysite.com/contact",
    "redirectURL" : "https://mysite.com/contact",
    "niceURL" : "https://mysite.com/contact",
    "name" : "This is my name"
}

The translated response would be

{
    "url" : "https://mysite.com/fr/contact",
    "redirectURL" : "https://mysite.com/fr/contact",
    "niceURL" : "https://mysite.com/contact",
    "name" : "C'est mon nom"
}

Adding keys to check when replacing URL will be done weglot_ajax_replace_urls

weglot_words_translate

Use this filter to target a specific word literally in your source code

Argument

Type

Description

$words

array

Array of string

You can add words that are present in your HTML page but not translated. It's useful when a word is not being translated by Weglot because it's inside a JavaScript for example and you can't really use other filters.

Use case

<?php

add_filter( 'weglot_words_translate', 'custom_weglot_words_translate' );
function custom_weglot_words_translate( $words ){        
    $words[] = "Monday";       
    $words[] = "Tuesday";    
    $words[] = "Nice to meet you";           
    return $words;
}

This filter will tell Weglot to look literally for words in your source code, then translate it and literally replace these words in your source code. Be very careful to not enter keywords as "head" "body" for example as it could break your page.

weglot_html_treat_page

Use this filter when there is no other solution : It's a very powerful filter that allows you to make manual edition on the final translated DOM in PHP.

Argument

Type

Description

$html

string

HTML content of translated page

Use case 1

The following code replaces all of the “https://codex.wordpress.org/” links with “https://codex.wordpress.org/fr:Accueil” in the translated versions.

<?php

add_filter( 'weglot_html_treat_page', 'custom_weglot_html_treat_page_1' );
function custom_weglot_html_treat_page_1( $html ) {

    $s = 'https://codex.wordpress.org/';
    $r = 'https://codex.wordpress.org/fr:Accueil';

    $html = str_replace( $s, $r, $html );
    return $html;
}

Use case 2

In this example, the replacement occurs according to the chosen language.

<?php

add_filter( 'weglot_html_treat_page', 'custom_weglot_html_treat_page_2' );
function custom_weglot_html_treat_page_2( $html ) {

    $search = 'https://codex.wordpress.org/';

    switch ( weglot_get_current_language() ) {
        case 'fr':
            $html = str_replace( $search, 'https://codex.wordpress.org/fr:Accueil', $html );
            break;
        case 'pt':
            $html = str_replace( $search, 'https://codex.wordpress.org/pt:Página_Inicial', $html );
            break;
    }

    return $html;
}

Note, you can use weglot_render_dom instead, which is the same except there is the HTML of the button and the links are already translated.

Dynamic Selectors

1. Enabling Dynamic Content Translation

To enable the use of dynamic content translation on your website, add the following filter:

add_filter( 'weglot_translate_dynamics', '__return_true' );

This filter allows Weglot to handle the translation of dynamic content, which may change after the initial page load (e.g., content updated via JavaScript).

  1. Defining Custom Selectors

Next, define the selectors that Weglot should use to identify dynamic content. We achieve this by creating a custom function:

function custom_weglot_dynamics_selectors( $default_dynamics ) {
    return [
        ['value' => '.wp-block-woocommerce-cart'],
        ['value' => '.qodef-m-content'],
        ['value' => '.wp-block-woocommerce-checkout'],
    ];
}
  • The function custom_weglot_dynamics_selectors() returns an array of CSS selectors. These selectors specify which parts of your website's content should be treated as dynamic.

  • For example, .wp-block-woocommerce-cart and .wp-block-woocommerce-checkout target WooCommerce cart and checkout blocks.

3. Applying Custom Selectors to Weglot Filters

To use the custom selectors defined above, apply them to both the dynamic and whitelist selector filters:

add_filter( 'weglot_dynamics_selectors', 'custom_weglot_dynamics_selectors' );
add_filter( 'weglot_whitelist_selectors', 'custom_weglot_dynamics_selectors' );
  • weglot_dynamics_selectors: This filter allows Weglot to recognize dynamic content based on the selectors you defined.

  • weglot_whitelist_selectors: This filter specifies elements that Weglot should always translate, ensuring that the specified content is included in translations.

By using the same function for both filters, you can reuse the list of selectors for both dynamic and whitelisted content.

  1. Specifying URLs for Applying Custom Translations

Lastly, define where your custom dynamic translations should be applied. By default, this is set to an empty value, but you can configure it to apply to all URLs or a specific list:

add_filter( 'weglot_allowed_urls', function( $urls ) {
    return 'all'; // This will make $allowed_urls === 'all'
});
  • weglot_allowed_urls: This filter determines on which URLs the custom translation rules will be applied.

  • Setting the value to 'all' ensures that your custom selectors will work on every page of your website. You can also pass an array of specific URLs if you only want the rules to apply to certain pages.

  1. External JavaScript Dependency for Custom Code

    When using the dynamic code, it requires an external JavaScript script to be loaded correctly for it to function as expected.

    Key Considerations:

    1. Script Loading: If the external script fails to load or is not included properly on the page, the custom code will not work. Make sure that the script is loaded before the code is executed.

    2. defer Attribute Issues: If the external script is loaded with the defer attribute, it may cause unexpected behavior or delays, especially if your custom code depends on the script being fully available before execution.

    3. Solution: To ensure that your custom code works seamlessly, you may need to exclude this specific script from being deferred. This way, the script will load immediately and be available when your code is executed, avoiding potential timing issues.

    How to Exclude the Script from defer

    • Check how your scripts are being loaded (especially if you’re using a plugin or optimization tool that automatically adds the defer attribute).

    • Ensure the script tag for your external JavaScript looks like this:

    <script src="https://example.com/your-script.js"></script>

    By excluding the defer attribute, the script will be executed as soon as it is downloaded, ensuring your custom code runs without issues.

Last updated