GetPage and LanguageSelector - problem selecting correct language version

Vote:
 

I've created a page that has "en" as MasterLanguageBranch, and only has an "en" version of the page.

With the following line of code I don't expect to get this page in return (pageRef is a PageReference referring to this page):

PageData

 

page = DataFactory.Instance.GetPage(pageRef, LanguageSelector.Fallback("sv", false));

But still a PageData object is returned, containg the "en" version of the page. Howcome?

Another question regarding the same topic: can I somehow get the custom language fallback settings on a PageData object?

 

/Jakob

#35269
Dec 02, 2009 9:54
Vote:
 

Hi Jakob!

I did some testing of the multi language functionality some months ago and found a couple of bugs and glitches. They were mostly ui-bugs but one core bugs was found that I think matches your bug report:

"Page that does not exist for language is still loaded with master language content instead of showing 404"

As far as I can see in the code and functionality the problem occurs when you try to load a page directly, the page is not returned in lists. There might be a reason why this is but we are planning to address the issues found after we have gotten the CMS 6 release out. So unfortunately it might take some time before a fix for this is released so you might have to try and find a work around at the moment.

Regarding language settings you can get them by:

PageLanguageSetting setting = PageLanguageSettingsTree.Instance.Get(pagelink);

Regards
Linus Ekström
EPiServer Development Team

#35271
Dec 02, 2009 12:27
Vote:
 

Hi Linus.

Do you know a good workaround for this?

Br, Tore

#36389
Jan 27, 2010 10:16
Vote:
 

The fallback method will use any fallback settings as defined in edit mode, are there any defined that could be causing this behaviour ?

You could also try this instead that only loads a specific language:

page = DataFactory.Instance.GetPage(pageRef, new LanguageSelector("sv"));

#36407
Jan 27, 2010 16:42
Vote:
 

 

var pd = DataFactory.Instance.GetPage(new PageReference(1038), LanguageSelector.AutoDetect());
// this gives the page on the fallback language
var pd1 = DataFactory.Instance.GetPage(new PageReference(1038), LanguageSelector.AutoDetect(false));
// this gives me null because the page does not exist on en-GB.
var pd2 = DataFactory.Instance.GetPage(new PageReference(1038), new LanguageSelector("en-GB"));
This scenario does not work:
Language en-GB. Page 2477 only exists on da. en-GB has en as fallback.
// this gives the page on the masterlanguage
var pd = DataFactory.Instance.GetPage(new PageReference(2477), LanguageSelector.AutoDetect());
// this gives the page on the masterlanguage even if i have said I do not want it
var pd1 = DataFactory.Instance.GetPage(new PageReference(2477), LanguageSelector.AutoDetect(false));
// this gives me null because the page does not exist on en-GB.
var pd2 = DataFactory.Instance.GetPage(new PageReference(2477), new LanguageSelector("en-GB")); 
Since I get the masterlanguage LanguageSelector.AutoDetect(false), I can not use this method. Is there another way I can get the page on the current languge with fallback language if the current language does not exist?
LanguageSelector.Fallback("en-GB", true/false) gives me the same problem.
Br, Tore Gjerdrum

Hi Per,
My Problem is that i want to use LanguageSelector.AutoDetect(false) to get the page on either the current language or the fallback language. I am sending in false so I do not get the MasterLanguage as fallback.
This scenario works fine here:
Language en-GB. Page 1038 exits on no, sv and en. en-GB has en as fallback.

 

// this gives the page on the fallback language
var pd = DataFactory.Instance.GetPage(new PageReference(1038), LanguageSelector.AutoDetect());
// this gives the page on the fallback language
var pd1 = DataFactory.Instance.GetPage(new PageReference(1038), LanguageSelector.AutoDetect(false));
// this gives me null because the page does not exist on en-GB.
var pd2 = DataFactory.Instance.GetPage(new PageReference(1038), new LanguageSelector("en-GB"));

This scenario does not work:

Language en-GB. Page 2477 only exists on da. en-GB has en as fallback.

// this gives the page on the masterlanguage
var pd = DataFactory.Instance.GetPage(new PageReference(2477), LanguageSelector.AutoDetect());
// this gives the page on the masterlanguage even if i have said I do not want it
var pd1 = DataFactory.Instance.GetPage(new PageReference(2477), LanguageSelector.AutoDetect(false));
// this gives me null because the page does not exist on en-GB.
var pd2 = DataFactory.Instance.GetPage(new PageReference(2477), new LanguageSelector("en-GB")); 


Since I get the masterlanguage when using LanguageSelector.AutoDetect(false), I can not use this method. Is there another way I can get the page on the current languge with fallback language if the current language does not exist? LanguageSelector.Fallback("en-GB", true/false) gives me the same problem.
Br, Tore Gjerdrum

 

#36411
Edited, Jan 27, 2010 17:40
Vote:
 

Ok, some more investigation from our side. You are correct that GetPage overrides the behaviour of the LanguageSelector and always return a language (with an argument that better return something than nothing from back in the days when nothing ment an exception). GetChildren does not override this haviour since it is a list. We have it reported as a bug but it will probably be fixed in a version after CMS 6 since this behaviour has been there for ever by design and we are a bit careful changing a behaviour this late in the game, it requires a lot of testing.

An workaround is that you run the language selector yourself because it does the right thing:

LanguageSelectorContext c = new LanguageSelectorContext(CurrentPage);
LanguageSelector.AutoDetect(false).SelectPageLanguage(c);
Response.Write(String.Format("Lang: {0}",c.SelectedLanguage));

The value c.SelectedLanguage should tell you if a language matching your critiera was found or not.

Let us know if it works for you.

#36413
Jan 27, 2010 18:15
Vote:
 

Hi Per,

Thanks for your workaround. It seems to solve my problem when I use GetPage. But is there any way to check the private fields on the LanguageSelector?

private bool _auto;
private bool _fallBackToMaster;
private string _languageBranch;
I have a global method to return a lot of pages and do not want to use your workaround if _fallBackToMaster is set to true.

Another ting. How can I use FindPagesWithCriteria for the same purpose?

// this gives me nothing
var categorizedPages1 = DataFactory.Instance.FindPagesWithCriteria(searchRoot, criterias, "en-GB");
// This gives me the page that has danish as masterlanguage
var categorizedPages2 = DataFactory.Instance.FindPagesWithCriteria(searchRoot, criterias, "en-GB", LanguageSelector.AutoDetect(true));
// This gives me the page that has danish as masterlanguage
var categorizedPages3 = DataFactory.Instance.FindPagesWithCriteria(searchRoot, criterias, "en-GB", LanguageSelector.AutoDetect(false));
// This gives me the page that has danish as masterlanguage
var categorizedPages4 = DataFactory.Instance.FindPagesWithCriteria(searchRoot, criterias, null, LanguageSelector.AutoDetect(true));
// This gives me the page that has danish as masterlanguage
var categorizedPages5 = DataFactory.Instance.FindPagesWithCriteria(searchRoot, criterias, null, LanguageSelector.AutoDetect(false));

Can I get all pages that exits on the current language with fallback language if the current language does not exist?

Br, Tore

#36414
Jan 27, 2010 19:22
Vote:
 

I do not know if this is the best way to do it, but if you still want to use FindPagesWithCriteria, you can use this extenstion method to filter the collection afterwards.

public static void FilterMasterLanguageBranch(this PageDataCollection collection, string languageBranch)
{
	for (int i = collection.Count - 1; i >= 0; i--)
	{
		PageData pageData = collection[i];
		// Check if page languagebranch is the langugebranch we want
		if (pageData.LanguageBranch == languageBranch) continue;
		// It is not, so check if it is the fallback langugebranch
		var languageSelectorContext = new LanguageSelectorContext(pageData);
		LanguageSelector.AutoDetect(false).SelectPageLanguage(languageSelectorContext);
		// The langugebranch is not fallback, so remove from collection
		if (string.IsNullOrEmpty(languageSelectorContext.SelectedLanguage))
		{
			collection.RemoveAt(i);
		}
	}
}

Only use this filter if you set you do not want the MasterLanguage as final fallback, e.g LanguageSelector.AutoDetect(false).

Hope this helps others with this problem.

Br, Tore

#36443
Jan 28, 2010 15:13