在本Sitecore网站(6.5.0 rev.120706)上,我有一个名为XYZ的sitecore项目。所以我有http://example.com/XYZ/。
我已经添加了法语本地化,所以使用我现在的显示名称:
http://example.com/XYZ-en/ http://example.com/XYZ-fr/
英文版本运行良好,但是法语版没有并且解析为404,除非我先去英语,先点击我的语言切换按钮。当我点击它时,我被重定向到http://example.com/fr-CA/XYZ-fr/,这有效。从那时起,英国网址停止工作,法国网站工作。当我切换这样的语言时,我总是只有两个中的一个有效。
该按钮运行此代码:
protected void LanguageLinkClick(object sender, EventArgs e)
{
var lang = (Sitecore.Context.Language.Name == "en") ? "fr-ca" : "en";
Tools.RedirectToLanguage(lang, Response);
}
该工具函数运行以下代码:
public static void RedirectToLanguage(string pStrLangToSet, HttpResponse pResponse)
{
if (!string.IsNullOrEmpty(pStrLangToSet))
{
var newLang = Language.Parse(pStrLangToSet);
if (newLang != null)
{
Sitecore.Context.SetLanguage(newLang, true);
var itm = Sitecore.Context.Item;
if (Sitecore.Context.Item != null)
{
var itemInLang = Sitecore.Context.Database.Items[itm.ID, newLang];
if (itemInLang != null)
{
pResponse.Redirect(BuildUrl(itemInLang));
}
}
}
}
}
这是旧项目中的旧代码。
我应该寻找什么来拦截默认的显示名称行为?或者这种显示名称的行为是不是开箱即用的东西?
感谢您的帮助!
答案 0 :(得分:2)
这是预期的行为。此article from John West描述了语言解析过程中涉及的步骤,ItemResolver流程的详细信息可以是found here。
我认为您在网站的LinkProvider中设置的内容为useDisplayName=true
,可能为languageEmbedding=false
,如下所示:
<add name="sitecore" type="Sitecore.Links.LinkProvider, Sitecore.Kernel"
alwaysIncludeServerUrl="false" addAspxExtension="true" encodeNames="true"
languageLocation="filePath" lowercaseUrls="false" shortenUrls="true"
languageEmbedding="never" useDisplayName="true" />
这告诉LinkManager使用Item的显示名称构建URL,因此您有多语言URL。您的RedirectToLanguage
方法会切换上下文语言,从EN到FR-CA,反之亦然,这会将Sitecore置于用户的特定语言模式中。
<httpRequestBegin>
中的以下管道尝试解析您请求的网址中的项目:
<processor type="Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel" />
该方法的一个尝试是ResolveUsingDisplayName(args)
。因此,它将尝试解析具有EN显示名称的项目,但是上下文语言设置为FR-CA,因此实际上它永远不会找到该项目,因此404。
这里有2个选项:
languageEmbedding="always"
,这意味着您的网址格式将为“/ en / Nice-Product-With-Lots-Of-Options”和“/ fr-ca / Mon-Produit-Avec- Plusieurs-选项”。以下内容将在您切换到备用语言后调用默认的Sitecore ItemResolver,然后尝试解析,它将尝试使用显示名称查找项目:
public class AlternateLanguageItemResolver : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (Context.Item != null || Context.Database == null || args.Url.ItemPath.Length == 0)
return;
var origLanguage = Sitecore.Context.Language;
Sitecore.Context.Language = AltLanguage;
// try to find it using default ItemResolver with alternate language
var itemResolver = new Sitecore.Pipelines.HttpRequest.ItemResolver();
itemResolver.Process(args);
if (Context.Item == null)
{
// well we didn't find it, so switch the context back so everyting can continue as normal
Sitecore.Context.Language = origLanguage;
return;
}
// We found the Item! Switch the User Language for future requests
Sitecore.Context.SetLanguage(AltLanguage, true);
}
private Language _altLanguage = null;
private Language AltLanguage
{
get
{
if (_altLanguage == null)
{
var altLang = (Sitecore.Context.Language.Name == "en") ? "fr-ca" : "en";
_altLanguage = Language.Parse(altLang);
}
return _altLanguage;
}
}
}
在默认的ItemResolver之后将其修补:
<processor type="Sitecore.Sample.AlternateLanguageItemResolver, Sitecore.Sample"
patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']"/>
这是一个未经测试的原型,检查后续请求是否以正确的切换语言返回。否则,请在原始代码中重定向回自己。
答案 1 :(得分:1)
因此,如果我理解正确,您希望这些网址为您解析语言:
http://example.com/XYZ-en/
http://example.com/XYZ-fr/
LanguageResolver将按此顺序解析语言:
1.语言可以从网址中提取(不能用上面的网址完成)
2.本网站提供语言cookie(sitename#lang)
3.回退到默认配置语言
当您使用切换台切换时,网址路径会以语言代码开头,然后解析程序可以通过网址解析语言并将语言保留在语言Cookie中。这就是您一次遇到一种工作语言的行为的原因。
你可以做的最好的事情就是在网址(linkprovider配置)中使用语言,否则你必须在语言解析器中挂钩并对每种语言的displayname做一些时髦的检查,但这可能会非常昂贵。