• rpmtl22

    (@rpmtl22)


    I would like to have a WordPress site re-direct visitors to either an English (/en) or French (/fr) sub-folder of a multisite installation that’s using sub-folders. I’m new to WordPress and first thought I could use an .htaccess redirect but have since learned that with WordPress it’s better to do this using a functions.php file placed in each child theme folder. Someone was kind enough to suggest the following code, but it’s not working. I’m wondering if anyone here knows why?

    The functions.php file inside the English (/en) child theme:

    <?php
    function language_redirect() {
        if ( !is_user_logged_in() && !is_admin() ) {
            $user_lang = substr( $_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2 );
            if ( $user_lang == 'fr' ) {
                wp_redirect( home_url( '/fr/' ) );
                exit();
            }
        }
    }
    add_action( 'template_redirect', 'language_redirect' );

    functions.php file inside the French (/fr) child theme:

    <?php
    function language_redirect() {
        if ( !is_user_logged_in() && !is_admin() ) {
            $user_lang = substr( $_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2 );
            if ( $user_lang == 'en' ) {
                wp_redirect( home_url( '/en/' ) );
                exit();
            }
        }
    }
    add_action( 'template_redirect', 'language_redirect' );

    ( Thank you to narolainfotech (@narolainfotech) )

    I suspect the problem might be that the wp_redirect appends the home_url with either “/en/” or “/fr/”. But as the two home_url’s are already example.com/en and example.com/fr this code results in “example.com/en/fr/“, “example.com/fr/en/“, example.com/en/en/, etc .. which don’t exist.

    Is there a way to fix this? Or is this code correct and the problem is elsewhere (like between my keyboard and my chair <g>) ….?

Viewing 8 replies - 1 through 8 (of 8 total)
  • Moderator bcworkz

    (@bcworkz)

    I tried your code on my site. I got a too many redirects error. You need additional code to verify that the current request is not already with /en/ or /fr/ in its path.

    Your approach should work once that is done, but FWIW I disagree that “template_redirect” is the best approach. Will it work? Sure, but I think it’s rather wasteful of server resource. To handle your code, all of the WP code base must be loaded and the request parsed before the redirect occurs, only to do the entire process all over again. Yes, it all happens in a fraction of a second, but that’s a lot of processing in server time frame.

    I’d advocate for your initial intuition that the redirect should occur in .htaccess. The one thing .htaccess cannot do is check if a user is logged in or not. It’s not clear to me if that’s an important distinction or not.

    Thread Starter rpmtl22

    (@rpmtl22)

    Thanx bcworkx for helping with this ?? My original thought was to do it with an .htaccess file. That’s what currently works on the static html/css version of the site I want to redo using WordPress:

    RewriteEngine On
    
    RewriteCond %{HTTP:Accept-Language} ^fr [NC]
    RewriteRule ^$ /f/ [L,R=302]
    
    # else redirect to the English version
    RewriteRule ^$ /e/ [L,R=302]

    For the PHP (which I’m slowly learning) I’m wondering if rtrim could be used to strip the “en” or “/en” off “example.com/en” before appending it with the new location (/en or /fr)? Or is there a way WordPress can get the parent folder of the site (example.com instead of example.com/en) before appending it?

    If anyone can confirm that an htaccess file can be used with a similar multisite install of WordPress then I would at least know if it can be done … or not.

    When I first asked about .htaccess I was told that “WordPress multisite dynamically generates URLs for each subsite (e.g., /en/ and /fr/), trying to set up language-based redirects directly in .htaccess might be a bit tricky.”

    But the only link that the .htaccess needs to change is example.com as anything that already has /en or /fr will automatically go where it needs to. There’s already an .htaccess file that WordPress creates with the multisite setup, so any redirect would need to be added to the same .htaccess file.

    Moderator bcworkz

    (@bcworkz)

    The only thing tricky that I’m aware of is only redirecting URLs without an language element. Otherwise you’ll get stuck in an infinite loop. Without checking if the element exists, the code will try to build an URL such as
    example.cοm/fr/fr/fr/fr/fr/fr/fr/… looping ad infinitum.

    You need such a check in your code whether it’s in PHP or .htaccess. In .htaccess, add a RewriteCond for not having /en/ or /fr/ elements.

    .htaccess rewrite rules occurring prior to the WP rules will modify the request prior to WP ever seeing it. Such a rewrite would be no different than someone directly requesting example.cοm/fr/

    The other side of the equation is the links WP generates. Assuming your multisite is sub-directory based and the sub-sites are also /en/ and /fr/, then WP will automatically generate the correct URLs.

    Maybe I’m missing something, but I don’t see what the problem would be. Or maybe whoever gave you the avoid .htaccess advice misunderstood your situation. It’s not too much effort to create a .htaccess rewrite rule set. Try it out and see what happens. You do need to exclude URLs already containing the language elements from the rewrite though.

    the only link that the .htaccess needs to change is example.com

    But what about if someone were to request example.cοm/foofoo/? Wouldn’t that also need to be rewritten to one’s preferred language? I think you’d want to capture the request and prepend the language element. For example
    RewriteRule (.*) en/%1
    (syntax might not be quite right, but I hope you get the idea)

    rtrim() is normally used to only remove whitespace. You can specify other chars to trim, but for any random language string you don’t know what those might be. And what if the part to be trimmed contains f,r,e, or n? You’ll end up trimming the wrong content. For checking if the first few chars at the start of a string match what I’m looking for, I typically will do something like:
    if ( 0 === strpos( $_SERVER['HTTP_ACCEPT_LANGUAGE'], 'en')):
    The === operator with 3 ‘=’ signs (match both value and type) is important because strpos() can return false which a 0 value can be interpreted as (boolean type). We want only the integer type value of 0 returned for a true condition. Returning false means no match was found.

    Thread Starter rpmtl22

    (@rpmtl22)

    OK … i’m back to thinking about an .htaccess solution. But the .htaccess file currently in the root folder (example.com and not example.com/en or /fr) states:

    
    # BEGIN WordPress
    # The directives (lines) between "BEGIN WordPress" and "END WordPress" are
    # dynamically generated, and should only be modified via WordPress filters.
    # Any changes to the directives between these markers will be overwritten.

    Are you suggesting I can add code before this section and it could work? I tried adding code after “END WordPress” and the nothing would load.

    As all the website content will be in either /en/ or /fr/ any request for example.com/foofoo will simply end up with page not found”.

    As I don’t need any content in example.com (/foofoo or whatever) I’m tempted to just build the English website in example.com, which will then load by default, and add a menu link to example.com/fr/ (= same pages translated to French). 99% of the visitors will be English speaking anyway so I doubt anyone will be offended if they first land on the English version (as long as the French version link is prominent enough). When someone is where they want to be they’ll bookmark that page if they wish.

    Thread Starter rpmtl22

    (@rpmtl22)

    I moved the English content to the root of the site (example.com) and will only have one sub-folder (example.com/fr) for the French version. I deleted the /en site as it’s no longer needed.

    Now all I need is working .htaccess code for the site root that will redirect French language browsers to example.com/fr. Otherwise visitors will remain on the English version where they’ve landed by default. This seems to be a much simpler solution. I can start designing the pages and sort out the appropriate .htaccess syntax (and where it should go) later.

    Moderator bcworkz

    (@bcworkz)

    Place your French .htaccess redirect directives before the WP section so the redirects occur before WP ever gets control. Be sure to have a rewrite condition that prevents a /fr/ redirect if the URL already has a /fr/ element. Then control moves on to the WP .htaccess rules, then on to WP itself.

    FWIW I agree that it makes more sense to have a main site in a default language than to have an empty main site that always needs a redirect regardless of language.

    Thread Starter rpmtl22

    (@rpmtl22)

    FWIW I agree that it makes more sense to have a main site in a default language than to have an empty main site that always needs a redirect regardless of language.

    I’m redesigning/converting this 2 language website for an artist friend. The previous site/folder structure made sense for a basic html/css site but needs a rethink when adapting to WordPress. I’m hoping WordPress will give her the opportunity to be more involved in the website content. Alas, learning WordPress and PHP is somewhat challenging, but y’r never too old to learn new tricks ??

    Moderator bcworkz

    (@bcworkz)

    I’m hoping WordPress will give her the opportunity to be more involved in the website content.

    That’s certainly the goal of any CMS. Creating content in WP is magnitudes more accessible than HTML/CSS code. While migrating an old site to WP can be technically challenging, once the migration is complete creating new content will be much simpler.

    As simple as it may be, it’s still beyond some people’s abilities. For some, they just lack the confidence to try. For others it really is beyond their capability. For some, they just can’t be bothered to create content, their focus lies elsewhere. For a good long while there will still be a need for us to create content for others. Hopefully your friend is not one of these people, even if she does need a little guidance here and there.

Viewing 8 replies - 1 through 8 (of 8 total)
  • The topic ‘Creating a child theme PHP language redirect’ is closed to new replies.