Jump to content
bcartier

Change default language for homepage

Recommended Posts

I while ago, I started a site on dev branch 2.5.19, and built out a bilingual site in English and French. My default language is English and I added French as a second language. I'm using LanguageSupportPageNames and my homepage names are "/" for english and "/fr" for French.

Everything works great. But... now the client wants to change the site so that French is the default language.

I've tried:

  • setting the Guest user's language preference to French - no effect.
  • detecting the URL and manually setting the $user->language  in _init.php
  • variations on naming the homepage "en" and "fr" istead of "/" and "fr", but the redirect still seems to redirect the homepage URL of the default language  to "/" even if I've specified "en". 
  • I've looked at the LanguageSupportPageNames settings and have tried both the recommended option and including the redirect in combination with URL detection. Still can't get it working.

Does anyone have any recommendations? I really don't want to rebuild the site from scratch just to reset the default language :-(

Thanks for your help,

-Brent

Share this post


Link to post
Share on other sites

Sadly I don't have any tips for you. But I think there should be a more easy way to implement a default language change. I've been working on a clients site the last week and their site should really be german by default and english optional, but they implemented german as second language and you'll get errors all the time about missing titles and stuff as you're just filling in the german value, which is not the default language.

I eventually have a tip for you. Did you refresh you modules some times? Maybe there's stuff cached that is preventing any change. 

Share this post


Link to post
Share on other sites

Hi,

Here is what you can do to redirect the home page '/' to the French home page:

  • Set page names for both languages for the home page ('en' for English, 'fr' for French)
  • In the LanguageSupportPageNames settings, choose the option "No - Root URL performs a redirect to: /name/". When you go to the root url '/' it will redirect you to '/en/'
  • Finally, create a module to hook into Session::redirect to force the redirection of the root url to the French translation as follows:
public function init() {
  $this->session->addHookBefore("redirect", function($event) {
    if ($this->page->id == 1 && $event->arguments(0) == $this->page->localUrl('default')) {
      $event->arguments(0, $this->page->localUrl('fr'));
    }
  });
}

The hook checks whether you are viewing the home page, and whether you are redirecting to the English url, and if so, it changes the url to the French url.

This solves the problem of the home page. The problem remains if someone has saved a direct link to a page without a language prefix, e.g., '/about/', since this will still be redirected to '/en/about/'.

  • Like 4

Share this post


Link to post
Share on other sites

I have the same exact problem and it's driving me totally crazy...I've installed both the module ESRCH suggested and AutoDetect Language module.

It seems to work if I reach the homepage for the first time (redirecting correctly to /it rather than /en (default)), but if I open a new tab in my browser and retry to go to the homepage the /en appears again.

Kinda desperate at this point :(

Share this post


Link to post
Share on other sites

Hi 3fingers,

I'd try taking AutoDetect language out of the picture at first, just to make sure the other part is working. Maybe try testing using a separate browser, or 'incognito/private browsing' tab, so that you're not logged in or anything.

In case it helps, here's full module code I used:

<?php

	class LanguageDefault extends WireData implements Module {

		/**
		 * getModuleInfo is a module required by all modules to tell ProcessWire about them
		 *
		 * @return array
		 *
		 */
		public static function getModuleInfo() {

			return array(
				'title' => 'LanguageDefault', 
				'version' => 1, 
				'summary' => 'A work around to changing the default language.',
				'href' => 'https://processwire.com/talk/topic/9322-change-default-language-for-homepage/?p=89717',
				'singular' => true, 
				'autoload' => true, 
			);
		}

		/**
		 * Initialize the module
		 *
		 * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called
		 * when ProcessWire's API is ready. As a result, this is a good place to attach hooks. 
		 *
		 */
		public function init() {
			$this->session->addHookBefore('redirect', $this, 'setDefaultLanguage'); 
		}

		public function setDefaultLanguage($event) {
			if ($this->page->id == 1 && $event->arguments(0) == $this->page->localUrl('default')) {
		      $event->arguments(0, $this->page->localUrl('fr'));
		    }
		}

	}
  • Like 2

Share this post


Link to post
Share on other sites

Thanks to both of you guys, I "solved" swapping the content of my fields from one language to the other and renaming the default language from /en to /it and viceversa.

Hope someday it will be easier to switch the default language :D

Share this post


Link to post
Share on other sites

A bit OT, but if you can plan the languages hirarchy right from the start of a new site, you can do it this way:

  • enable languages support
     
  • set Title / Label of the default language to your desired none english native language, (e.g. 'Deutsch' (German))
     
  • drop in the none english language pack (for admin backend) into the default language, (e.g. german langpack)
     
  • add a new language to it and drop in a language pack for any none english language or simply don't drop in a language pack to get the english version (but not as the default one!)

As a nice sideeffect every new user in your system gets the native language per default without have it to select from the list.

So, yes, this is no solution if you once have set it up and need to switch the default language afterwards, but just want to note it.

Edited by horst
  • Like 8

Share this post


Link to post
Share on other sites

[…]

It seems to work if I reach the homepage for the first time (redirecting correctly to /it rather than /en (default)), but if I open a new tab in my browser and retry to go to the homepage the /en appears again.

[…]

This is the intended behavior of the AutoDetect Language module. It will only run on the first page load, to set the $user->language setting, which is created from a session variable. There is no need to detect language on each page load (and you really shouldn't, to be honest), as it's set once by PW and it will reuse it on each page load unless it's overwritten by setting $user->language manually. If you need to check if AutoDetect Language has run (and reuse its state somewhere else), there are two session variables I created (that you can read about in the documentation). If you want to force it to run again, you can set $session->languageAlreadyDetected to false, but I wouldn't say it's generally advisable.

  • Like 1

Share this post


Link to post
Share on other sites

Hi 3fingers,

I'd try taking AutoDetect language out of the picture at first, just to make sure the other part is working. Maybe try testing using a separate browser, or 'incognito/private browsing' tab, so that you're not logged in or anything.

In case it helps, here's full module code I used:

Using 2.5.24 dev and your module code, in the LanguageSupportPageNames settings "No - Root URL performs a redirect to: /name/", I still get redirected to /en/ every time I access the home page.

I don't have AutodetectLanguage installed.

In the module info, it has correctly:

Hooks to Session->redirect()

I have my fi name active for the Home page and this line changed accordingly:

$event->arguments(0, $this->page->localUrl('fi'));

What might be the problem?

Share this post


Link to post
Share on other sites

What might be the problem?

Well the problem was that I didn't use my language name! So now I did localUrl('suomi')); and it works.. sorry for the noise.

  • Like 1

Share this post


Link to post
Share on other sites

Just to confirm, proposed module from this thread is working fine for me in a 2.6.23 install.

Share this post


Link to post
Share on other sites

Hello,

how to handle more than 2 languages ?

Ive for example en (as default) , de, tr, cz and maybe there will be more later.

So is it possible to use this module for more than 2 languages too ??

I have the problem that I need some pages only in English and German and some pages in other languages. Special in the news section. The title field on create the page I can't switch off so I can hide all other pages in the settings but not the default.

Tnx

Share this post


Link to post
Share on other sites

Hello iNoize,

I used on a project some time ago three different languages and I think it shouldn't be a problem using even more.

As for your second question: I recently thought about this case too, but could only think of checking in the language switcher, if the default language has content and if not, don't include the option. Of course someone could try to access your default language page by guessing the page name, but in this unlikely case you could also check if this page has content in the default language and if not redirect to the 404 page template.

But maybe there are better solutions for this case. Besides that I think it would be the best idea to provide all pages at least in the default language. ;)  

Share this post


Link to post
Share on other sites

I found a crude but apparently working solution.

I ask if a certain session variable $session->secondvisit exists, which is certainly not the case in the beginning.

If not, it will be created and a crude language switch starts working.

    if (!$session->secondvisit) {

        $session->secondvisit = true;

        $locale = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']);

        if (strpos($locale, 'de') === 0) {
            $user->language = 'de';
        }

        elseif (strpos($locale, 'es') === 0) {
            $user->language = 'es';
        }

    }

This is standing in front of <html>.

Any constructive critique welcome. 

For any language other than German or Spanish, the default language english will be in effect.

As the language string is e.g. "de_DE", strpos returns either 0 or false. So querying simply

if (strpos($locale,'de')) { ..... }

will not work, because the position of 'de' in 'de_DE' is 0 and php takes a 0 for a false, if I am correct.

  • Like 1

Share this post


Link to post
Share on other sites

... Any constructive critique welcome.

:) What is with (Pro)-cached pages? I believe, a JS solution is needed there, as serverside PHP execution is ommitted.

  • Like 1

Share this post


Link to post
Share on other sites
On 28.4.2016 at 7:44 AM, horst said:

:) What is with (Pro)-cached pages? I believe, a JS solution is needed there, as serverside PHP execution is ommitted.

You are probably right, may be I (or somebody else) adds something to it. For the time beeing i don't see i have the resources for it.

Share this post


Link to post
Share on other sites

With this script a strange problem appears: (solution below)

When loading first, i.e. with $session->secondvisit nonexistent and setting $user->language to 'de' (in my case), 

  • the menu is correctly shown in german
  • the language menu correctly shows the german link as active
  • but the content is shown in the english version
  • the url in the address field does not show the /de characteristic for the german content tree

One remark, of which i do not know the importance: the site is redirected to a subdirectory.

The URL ist http://agustin-rivas.com.

If someone has seen this before and can give a clue, i'll be grateful.

--------------------------------------------------------------------------------------------------------

solution

---------------------------------------------------------------------------------------------------------

It was a timing problem. I had put the above function into the main template php file, which is executed  a f t e r  the php files for the different page templates. So the content variables were filled with the $user->language still not correctly set. Moving the function code to the _init.php file, which is executed  b e f o r e  the page template php files, solved the problem. 

Took me 2 hrs to figure it out believe it or not... :-) 

Edited by dlen
added solution to problem

Share this post


Link to post
Share on other sites

How about the effect on search engines with the solution of ESRCH?
I think search engines are not very happy with redirects like that (where the URL changes).

Share this post


Link to post
Share on other sites
27 minutes ago, KarlvonKarton said:

How about the effect on search engines with the solution of ESRCH?
I think search engines are not very happy with redirects like that (where the URL changes).

I think it should be ok: https://en.wikipedia.org/wiki/HTTP_301#Search_engines

When sending with a 301, search engines should update their index. At least it is how I have learned it :)

 

  • Like 1

Share this post


Link to post
Share on other sites

One more thing.
I tested out the solutions of ESRCH, with success. In the LanguageDefault Class the '/' is redirected to /nl/  (in my case)

But since I only need Dutch (nl) and French (fr), but no English, I've hidden English in the setup -> languages -> English (tab settings -> status: hidden).
The great thing(s) about that: in the language selector there is only French and Dutch (on the site) and all options of English are disabled in the admin.
(I can not think of any other reason why the default language can be hidden?)

However, and I don't know if this is some kind of bug, everytime I save a page (or even some other things), then I get an error "missing required value".  I found out that the missing value is actually the English translation.  So all the English options are hidden, but the script still needs the values after posting the form (e.g. saving a page).
When I make English visible again (thus uncheck hidden) then the error disappears.

I find this behavior highly peculiar.  Any comments?

Share this post


Link to post
Share on other sites

default is default, it is required by the system for every other language that has no content in a field.

But you are not forced to use english as default. You can make every thing you want as default, - with only one language or with multiple. For example you can use nl as default and fr as additional language.

 

  • Like 1

Share this post


Link to post
Share on other sites
5 minutes ago, horst said:

default is default, it is required by the system for every other language that has no content in a field.

But you are not forced to use english as default. You can make every thing you want as default, - with only one language or with multiple. For example you can use nl as default and fr as additional language.

Can this only be done during install of PW?  Or what point?

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By wish-fulfillment
      how to change the default language in processwire cms
      from Eng  to Ru


    • By louisstephens
      Hopefully this is the right place, if not, please move it to the proper sub. I installed the multi language module on my development (sandbox) set up not too long ago to test out a few things. From the start, I ran into some issues with dependencies not being met/installed, so I thought that I would simply just uninstall what had been. Unfortunately, that took me down a road of using some code in my home template to remove the modules (cant find it at the moment). After some struggling, I finally got it uninstalled, but it left behind 3 fields,
      language language_files language_files_site I thought that I could simply remove them from the languages template and then delete them, but I get the following error:

      I was wondering, is there a way to remove these using the api? I couldn't add any new users to the setup until I made "language" not required, but I was hoping to just remove all of the fields.
    • By bartelsmedia
      "Deepl" is an unbelievably good (paid) text translation service, that mops the floor with Google Translate.
      They have an API and it would be awesome, if there would be a module, that would integrate it for easy content translation.
      It could be a right-click context menu on the language tab:

      It should ask from which of available other language it shall take translate from.
      What do you think?
    • By franctic-aerobic
      Here's my Norwegian language pack for ProcessWire. I've been adding translations over some time, to suit my own projects users needs.
      Last updated:
      2019/01/04
      Status:
      Not yet complete. Translations that non-superusers will see is prioritized.
      Name:
      ProcessWire-Norwegian-Language-Pack-nb-NO
      Translated using:
      ProcessWire 3.0.123 master
      Number of files:
      177 wire files and 68 site files – ranging from just started to completely translated. The site files includes translation some free and some pro modules, see the complete list in the README.md at GitHub.
      Available at GitHub:
      https://github.com/franctic-aerobic/processwire-norwegian-language-pack-nb-no
    • By Gadgetto
      Hello,
      I'm very new to ProcessWire but already fell in love with this CMS/CMF! I just finished my first small project and as I saw a lot of questions and different answers in this forum on how to set up a nice language switcher for your website, I decided to write my first tutorial.
      ----------
      Please note:
      I rewrote this tutorial since I was made aware and learned that flags should not be used for language selectors!
      There are some threads here in the forum (and from external sources) where this question is discussed:
      https://processwire.com/talk/topic/13196-adding-image-field-to-language/
      http://daily.unitedlanguagegroup.com/stories/editorials/inside-design-language-selector-no-flags
      https://processwire.com/talk/topic/16524-extending-languages-template/
      http://www.flagsarenotlanguages.com/blog/why-flags-do-not-represent-language/
      https://processwire.com/talk/topic/14241-language-names-and-utf8-page-names/
      Thanks,
      @ottogal
      @bernhard
      @jmartsch
      @kongondo
      an all others for your hints!
      ----------
       
      TUTORIAL - Set up a nice language switcher for your website - here we go:
       

      This will be the desired result!
       
      Step 1)
      Setup at least 2 languages in your PW install. In my case it's German (default language) + English:
       

       
      Step 2)
      Add a custom field
      Type = Text
      Name = languagecode
      This will hold the ISO 639-1 two-letter language code for the respective language. The field is needed to provide a simple method for outputting the language code in your templates. Without this field, you will need to programmatically construct your two-letter language code output via PHP (at least for the default language, as ProcessWire doesn't allow to rename the default language and it will always be called default).
      Here is an overview for ISO 639-1 two-letter language codes:
      https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
       

       
      Step 3)
      Add this field to the system template: language.
      To achieve this, go to Setup / Templates and activate the filter Show system templates:
       

       
      Now you can add the previously created field languagecode to the language template.
       

       
      Step 4)
      Edit your languages and fill in the appropriate values.
      a) default (German)
      Name = default (this can't be changed and is read only)
      Title = Deutsch (in both language tabs! - this is important as your visitor should always see his language item ... in his language)
      languagecode = de
       

       
      b) english (English)
      Name = english
      Title = English (in both language tabs! - this is important as your visitor should always see his language item ... in his language)
      languagecode = en
       

       
      Step 5)
      Now we are ready to write our template output!

      As we already have the appropriate two-letter ISO language code (languagecode field), we can use this in our html lang property:
       
      <html lang="<?php echo $user->language->languagecode; ?>">  
      Also the rel alternate output in the html head is simple. Put the following code within your <head></head> area:
       
      <?php // Handle output of 'hreflang' link tags for multi-language (SEO!) foreach ($languages as $language) { if (!$page->viewable($language)) { continue; } // Get the http URL for this page in the given language $url = $page->localHttpUrl($language); // Get the language code using custom languagecode field $languagecode = $language->languagecode; echo PHP_EOL.'<link rel="alternate" hreflang="'.$languagecode.'" href="'.$url.'">'; } ?>  
      In my sample I've used Boostrap 4 and the code below shows a complete navbar with our language switcher (BTW the language switcher will always be visible, even when the bootstrap navbar is collapsed):
       
      <nav id="mainnav" class="navbar navbar-expand-lg navbar-light px-4 px-md-5 sticky-top"> <a class="navbar-brand" href="<?php echo $config->urls->root; ?>"> <img src="<?php echo $config->urls->templates; ?>images/logo-rund-80x80.png" alt=""> Your Site Title </a> <ul class="navbar-nav ml-auto mr-3 mr-lg-0 order-lg-last d-none d-xs-custom-flex language-switcher" aria-label="<?php echo __('Sprache wechseln') ?>"> <?php echo '<li class="nav-item dropdown">'; // Construct the language prompt in the current user language $prompt = $user->language->title.' ('.strtoupper($user->language->languagecode).')'; // Current language = dropdown-toggle echo '<a class="nav-link dropdown-toggle" href="#languages" id="language-select" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">'; echo '<span class="world-icon"></span><span class="sr-only">'._x('(aktuelle Sprache)', 'navigation').': </span> '.$prompt; echo '</a>'; echo '<div id="languages" class="dropdown-menu dropdown-menu-right" aria-labelledby="language-select">'; foreach ($languages as $language) { // Get the http URL for current page in the given language $url = $page->localHttpUrl($language); // Construct the language prompt in the given language $prompt = $language->title.' ('.strtoupper($language->languagecode).')'; // Next language item (except current language) if ($user->language->id != $language->id) { if (!$page->viewable($language)) { echo '<span class="dropdown-item disabled">'.$prompt.'</span>'; } else { echo '<a class="dropdown-item" href="'.$url.'">'.$prompt.'</a>'; } } } echo '</div>'; echo '</li>'; ?> </ul> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarMainMenu" aria-controls="navbarMainMenu" aria-expanded="false" aria-label="<?php echo __('Menü einblenden / ausblenden') ?>"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse my-3 my-lg-0" id="navbarMainMenu"> <ul class="navbar-nav mr-auto"> <?php // Top navigation consists of homepage and its visible children foreach ($homepage->and($homepage->children("template=main-page|news|contact-points")) as $item) { if ($item->id == $page->rootParent->id) { echo '<li class="nav-item active">'; echo '<a class="nav-link" href="'.$item->url.'">'.$item->title.'<span class="sr-only"> '._x('(aktuelle Seite)', 'navigation').'</span></a>'; echo '</li>'; } else { echo '<li class="nav-item">'; echo '<a class="nav-link" href="'.$item->url.'">'.$item->title.'</a>'; echo '</li>'; } } ?> </ul> </div> </nav>  

      That's it! I hope you will like my tutorial and if there are any questions, critics or improvements please let me know!
      Thanks,
      Martin
       
×
×
  • Create New...