Language selector and URL Rewriting
Hi all, I am running into a problem using the language selector when on pages that have URL rewriting implemented. For example the browser URL says:
/en/destinations/country/gb/location/lon
which is being rewritten to /en/pages/location?country=gb&city=london
This is all fine but when I use the language selector to change the language to french the URL becomes
/fr/pages/location - which is the correct page but is not the correct URL and it has lost the querystring.
What I need is the language selector control to post back to the proper URL
/fr/destinations/country/gb/location/lon
Before I start building my own custom language selector has anyone seen this problem before and worked around it. For info I am running SF4.1 on IIS 6 using the URLRewritingNET code.
Thanks
Hi David,
Could you provide more details on your page hierarchy? Currently url parameters are ignored from the language selector.
Regards,
Pavel
the Telerik team
My page hierarchy is quite simple. I have a group page called 'pages' and then a page called 'location' - as indicated by the example I have given below.
I guess that I do not need it to support URL parameters, but to be able to post back to the original URL before it was rewritten.
Thanks
Hi David,
We have reproduced the problem and logged it in PITS. You can follow the status of the bug here.
However please note that the bug is that the Language Selector control disregards query string parameters. The thing with UrlRewriting is that the language selector cannot know if some other module is rewriting the request.
Kind regards,
Radoslav Georgiev
the Telerik team
Thank you for your reply regarding the querystring. Regarding the URL rewriting I believe a workaround is possible, you say that the language selector cannot know if a module is rewriting the request. I do not think this is the case, the built in URL rewriting in IIS 7 sends the original URL as the server variable "HTTP_X_ORIGINAL_URL" and URLRewritingNET adds the original URL to the HttpContext.Items collection with the key
"UrlRewritingNet.UrlRewriter.VirtualUrl"
It would require several configuration options to be shown to the administrator when adding the language selector control but in theory it could work. Perhaps this could be looked into for a future version of SF (just for IIS 7) even though it may not be a widely used feature.
In the mean time can you point me to the location in the SF code that generates the URLs used in the language selector so that I can override and try to get it working with URLRewritingNET. If I succeed I will post my code here for others to use.
Hello David,
You need to inherit the LanguageSelectorControl, overriding the followig method:
protected virtual void BindLanguageContainers(IEnumerable<CultureInfo> languages)
if (this.SelectorType == LanguageSelectorType.DropDown)
var dropDown = this.LanguagesDropDown;
if (this.IsDesignMode() == false)
dropDown.Attributes["onChange"] = "document.location.href = this.value;";
//dropDown.Choices.Clear();
foreach (var lang in languages)
var langName = GetDisplayedLanguageName(lang);
var url = GetUrlForLanguage(lang);
url = RouteHelper.ResolveUrl(url, UrlResolveOptions.Absolute);
ListItem item = new ListItem(langName, url);
item.Selected = lang.Equals(CultureInfo.CurrentUICulture);
item.Attributes.Add("lang", lang.TwoLetterISOLanguageName);
dropDown.Items.Add(item);
else
this.LanguagesRepeater.ItemCreated += new RepeaterItemEventHandler(LanguagesRepeater_ItemCreated);
this.LanguagesRepeater.DataSource = languages;
this.LanguagesRepeater.DataBind();
You need to implement the event handler marked in yellow as follows:
void LanguagesRepeater_ItemCreated(object sender, RepeaterItemEventArgs e)
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
CultureInfo ci = (CultureInfo)e.Item.DataItem;
//Get the name of the current language
string languageName = GetDisplayedLanguageName(ci);
//Get the URL of the language version for the current language
var url = this.GetUrlForLanguage(ci);
//add your custom code here
if (this.SelectorType == LanguageSelectorType.DropDown)
HtmlGenericControl langOption = (HtmlGenericControl)e.Item.FindControl("langOption");
langOption.Attributes.Add("lang", ci.Name);
langOption.Attributes.Add("class", "sflangOption_" + ci.Name);
langOption.InnerHtml = languageName;
else
//Add language-specific class to wrapper
HtmlGenericControl langHolder = (HtmlGenericControl)e.Item.FindControl("langHolder");
var classAttribute = langHolder.Attributes["class"];
var langSpecificClass = "sflang_" + ci.Name;
classAttribute = string.IsNullOrEmpty(classAttribute) ? langSpecificClass : classAttribute + " " + langSpecificClass;
//Add selected class, where necessary
if (ci.Equals(CultureInfo.CurrentUICulture))
classAttribute += " " + "sflangSelected";
langHolder.Attributes.Add("class", classAttribute);
//Add href to link
HtmlAnchor langLinkControl = (HtmlAnchor)e.Item.FindControl("langLink");
langLinkControl.HRef = url;
langLinkControl.Attributes.Add("lang", ci.TwoLetterISOLanguageName);
HtmlGenericControl langNameControl = (HtmlGenericControl)e.Item.FindControl("langName");
langNameControl.InnerHtml = languageName;
The code marked in yellow gets the url for each language link in the language selector you can overwrite that url before you set it as href to the langLinkControl.
Please let me know if you have any problems.
Kind regards,
Lilia Messechkova
the Telerik team