6

We are working on a localization project in WordPress. In fact, we can correctly add the active browser URL with language support. I'll add the details and the entire code below. Don't worry, my question will not be so open-ended and I will make it more specific.

Step 1

First of all, we should add a variable in the link structure to the WordPress algorithm.

function custom_rewrite_basic_query_vars( $query_vars ){
    $query_vars[] = 'lang';
    return $query_vars;
}
add_filter( 'query_vars', 'custom_rewrite_basic_query_vars' );

Thus, WordPress detects a variable such as ?lang= and includes it in the query mechanism.

Step 2

Using the "add_rewrite_rule" function, you need to add the variable ?lang= to run in the background of WordPress's persistent link structure.

Easy Example:

/*
LANG PREFIX + INDEX = localhost/en/ = localhost/?lang=en
*/

add_rewrite_rule(
    '^(en|fr|de|ru|tr)/?$',
    'index.php?lang=$matches[1]',
    'top'
);

I will not add the remaining instances one by one, because you should use close to 20 rewrite rules. (Date, Category, Comment, Page, Text, Pagination, etc.)

NOTE: Those who work on such a project and want to use these rules will add it if requested.


Now our persistent connection structure supports variables for the language option.

localhost/en/hello-world

localhost/ru/hello-world

localhost/de/04/07/2019

localhost/fr/page/2

etc. all the links you can think of.

Step 3

If a variable is detected from the browser (for example: lang = en), we will display the contents of the previously saved inter-language translated.

At this point we do not need any support. But when we get to step 4, we're stuck.

Step 4

Activating the prefix language variable that was added before, users when using the links within the site, on all in-site navigation links.

This means that if a user has access to the localhost/fr/hello-world link, they must reach the localhost/fr/contact link when they return to the Home Page or click the Contact link.

To do this, you need to add the language prefix that is currently active in the browser to all in-site links.

Unfortunately, this is the only point where we hang out and we can't find a solution.

In fact, we tried most things before writing here. (Of course within our knowledge). We even looked at plug-ins that offer some language support.

e.g. <WP Multilang>

Of course, it's so complicated and so much code. We didn't even understand the plug-in.

There is, of course, a logical way of doing this, and I hope that person sees this post and answers. Thank you sincerely for all your supports.


One step to Answer

After a while, I reached the following code and confirmed that it was working correctly.

<?php

function link_fn( $url ){

    $lang = get_query_var('lang', false);       

    if( $lang !== false && strpos( $url, $lang ) !== false )
        $url = $url . $lang . '/';

    return $url;
}

add_filter( 'shortcut_link', 'link_fn' );
add_filter( 'post_link', 'link_fn' );
add_filter( 'page_link', 'link_fn' );
add_filter( 'post_type_link', 'link_fn' );
add_filter( 'attachment_link', 'link_fn' );
add_filter( 'term_link', 'link_fn' );
add_filter( 'author_link', 'link_fn' );
add_filter( 'post_type_archive_link', 'link_fn' );
add_filter( 'day_link', 'link_fn' );
add_filter( 'month_link', 'link_fn' );
add_filter( 'year_link', 'link_fn' );

But at this point, I came across a problem. Here we get data like "localhost/hello-world/[LANG]/".

What I want is "localhost/[LANG]/hello-world".

To resolve this situation, you must add a REGEX query to the existing URL structure, if it does not contain the LANG, add the language code to the BASE URL. As a REGEX query should be added, I could not do this...

I not want to answer my own question and confirm. In addition to the code I have written above, if there is an answer containing the query I want, I will mark it as the answer.


Answer

function link_fn( $url ){

    $lang = get_query_var('lang', false);

    $site_url = get_option('home');

    if( $lang !== false )
    {
        $new_url = str_replace( $site_url, "", $url );

        if( preg_match('/\b$lang\b/', $new_url) !== false )
        {
            $url = $site_url."/".$lang.$new_url;
        }

    }

    return $url;
}

add_filter( 'home_url', 'link_fn' );
BOZ
  • 2,731
  • 11
  • 28
  • How does a user get to the different languages? You could simply store a cookie in their browser with their language choice, then read the cookie to make sure that the URL gets the language abbreviation appended. Also, WPML (https://wpml.org/) is probably one of the easiest multi-language plugins to use - while offering really nice advanced features. – disinfor Sep 12 '19 at 18:03
  • 1
    You looking to redirec based on user's browser language? WPML have good use of it. – Earid Sep 14 '19 at 03:48

4 Answers4

1

You got really far. Very nice effort

I understand that what's between you and victory is only to change the outcome link structure?

If yes, here is a solution:

function link_fn($url){

    $lang = get_query_var('lang', false);
    $url_parts = explode('/', $url);

    if ( $lang && in_array($lang, $url_parts) === false) { // lang does not exists in URL
        array_splice($url_parts, 1, 0, $lang);
    }
    $url = implode('/', $url_parts);
    return $url;

}
Shir Gans
  • 1,976
  • 3
  • 23
  • 40
  • even if this is not the exact answer, I accept it for encouraging me to find the answer. I will soon add the right answer to the bottom of the question. Thank you. – BOZ Sep 21 '19 at 15:53
0

I think one possible approach is to get all the HTML content use ob_start() and ob_get_contents() and then get all the link with regEx.

Note: not all links are post/page, there are some static files too.

Yovi Prasetyo
  • 202
  • 1
  • 3
  • 14
0

Can you language constant be a part of query string instead of path?

instead of

localhost/en/hello-world

like this

localhost/hello-world?lang=en

If so take a look How to pass extra variables in URL with WordPress

illia permiakov
  • 423
  • 3
  • 10
  • Thank you. Unfortunately, all are added to the URL of the active page in the browser. We've already passed that stage. – BOZ Sep 15 '19 at 08:34
0

I suggest to dig into this direction.

add_action( 'pre_get_posts', 'lang_pre_get_posts', 1 );
function lang_pre_get_posts( $query ) {
    if ( is_admin() || ! $query->is_main_query() ){
        return;
    }
    add_query_arg( 'lang', filter_var( $_COOKIE["lang"], FILTER_SANITIZE_STRING ) );
}
Dmitry
  • 347
  • 1
  • 9