loca1h0st's Blog
loca1h0st's Blog

Learn secondary development with AI and bypass the €99 feature limitations.

Learn secondary development with AI and bypass the €99 feature limitations.
“`html

In a previous article, we discussed how to enable multi-language support on a website using Polylang, and described how to automate multi-language translation of articles using n8n:

After spending some time using the plugin, I found that it fairly well met my needs. However, I discovered a significant limitation: the free version of the Polylang plugin does not support API usage, which severely impacted the user experience. For instance, the following scenarios could not be automated:

  • It was impossible to retrieve the language status of articles. As a result, the webhook would create new articles by translating ones that were already in English, leading to an infinite loop.
  • Automatic association of multi-language articles was not possible. Thus, there was no link between Chinese and English articles on the site, preventing automatic switching of the language for internal pages.

Considering that API support is a strong requirement for me and that the Pro version of Polylang does not offer a reasonable price-to-value ratio for my needs (it costs €99 for a single site), I decided to add the necessary functionality myself.

Understanding the Plugin

I am relatively familiar with PHP and WordPress, but I prefer not to customize and develop through complex code reading. So, I thought about leveraging AI assistance: I provide the ideas and AI helps me accomplish the requirements. Here are the relevant records:

Database Interaction

My first assumption was that the plugin must store relevant information in the database, which is related to the language type of the articles and their mapping relationships:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-27-1024x496.png

Based on that, I searched for relevant code in the Polylang plugin and ultimately found the pll_save_post function and the related code:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-28-1024x422.png

I discovered that GPT-4o recognized this plugin and accurately indicated the purpose of the relevant function, so I directly asked about the data storage result:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-29-1024x559.png

After obtaining the answer, I validated it on the server. I found the keyword post_translations, which serialized and saved the relevant mapping relationships between multi-language articles:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-30-1024x244.png

Identifying Key Functions

Based on the tips from GPT-4o:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-31-1024x322.png

I searched the source code for relevant keywords and found the variable names in the program:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-32-1024x529.png

After learning the variable names, I looked for corresponding method calls. After testing, I found that save_translation was quite relevant in both name and function for practical scenarios:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-33-1024x736.png

After locating the function, I searched to see if there were any higher-level function calls, ultimately finding a call in the api.php file. The function name pll_save_post_translations fits our needs and has been verified to work:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-34-1024x707.png

Calling the Function

After identifying and verifying the function, the next step was to use it. Considering that the Polylang plugin may be updated in the future, I tried not to edit the original plugin. Therefore, I added the following code to the end of my theme’s functions.php file to implement the functionality I needed.

In the code below, key functions worth mentioning are add_action and add_filter. These are built-in WordPress functions that allow us to edit the REST API, including adding endpoints or intercepting and editing request/response data (if needed, you can also seek AI assistance while writing).

// Adding custom API based on Polylang
add_action('rest_api_init', 'register_get_language');
function register_get_language() {
    register_rest_route('pl', '/language', array(
        'methods' => 'GET',
        'callback' => 'get_language_by_post_id',
        'args' => array(
            'id' => array(
                'required' => true,
                'validate_callback' => function($param, $request, $key) {
                    return is_numeric($param);
                }
            ),
        ),
        'permission_callback' => '__return_true'
    ));
}
function get_language_by_post_id($request) {
    // Get the 'id' parameter from the request
    $post_id = $request->get_param('id');

    // Validate the ID
    if (empty($post_id) || !is_numeric($post_id)) {
        return new WP_REST_Response(array(
            'success' => false,
            'message' => 'Invalid post ID.',
        ), 400); // Return 400 error
    }

    // Check if Polylang functions are available
    if (!function_exists('pll_get_post_translations')) {
        return new WP_REST_Response(array(
            'success' => false,
            'message' => 'Polylang plugin is not active or not installed.',
        ), 500); // Return 500 error
    }

    // Get the language information for the specified post
    $languages = pll_get_post_translations($post_id);

    // If no language information is found
    if (empty($languages)) {
        return new WP_REST_Response(array(
            'success' => false,
            'message' => 'No language information found for the given post ID.',
        ), 404); // Return 404 error
    }

    // Return the language information
    return new WP_REST_Response(array(
        'success' => true,
        'language' => $languages,
    ), 200); // Return success with 200
}

// Set up language

add_filter('rest_pre_echo_response', 'save_post_translations', 10, 3);
function save_post_translations($response, $server, $request) {
    // Check if the request is for /wp/v2/posts
    if ($request->get_route() === '/wp/v2/posts') {
        $from_id = $request->get_param('from_id');
        if ($from_id) {
            // Check if Polylang functions are available
            if (!function_exists('pll_save_post_translations')) {
                return new WP_REST_Response(array(
                    'success' => false,
                    'message' => 'Polylang plugin is not active or not installed.',
                ), 500); // Return 500 error
            }
            // Check the submitted post language format
            $languages = pll_get_post_language($response['id']);
            pll_save_post_translations(array(
                'zh' => $from_id,
                $languages => $response['id']
            ));
        }
    }
    return $response;
}

Results

In the code above, we added two API endpoints to support our functionality, specifically /wp-json/pl/language?id={id} and /wp-json/wp/v2/posts?from_id={id}.

Get Article Language List /wp-json/pl/language?id={id}

When the article ID is provided, the server returns a list of multi-language article IDs associated with that ID, which can be used to determine whether translation is needed:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-35-939x1024.png

When all the multi-languages for an article are configured, the next action is not required:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-38-1024x456.png

Create Article and Associate Language Relationship /wp-json/wp/v2/posts?from_id={id}

When creating an article using the API, if the original article ID is included, it automatically binds the language relationship between the two:

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-36-903x1024.png

Complete Workflow

https://blog.mrtblogs.net/wp-content/uploads/2024/12/image-37-1024x309.png
“`
# # # # #
Homepage      随手记      Learn secondary development with AI and bypass the €99 feature limitations.

Leave a Reply

textsms
account_circle
email

loca1h0st's Blog

Learn secondary development with AI and bypass the €99 feature limitations.
```html In a previous article, we discussed how to enable multi-language support on a website using Polylang, and described how to automate multi-language translation of art…
Scan QR code to continue reading
2024-12-22