【问题标题】:Language Fallback / Setting the language in Sitecore.Globalization.Translate.TextByLanguage(key, language);?语言后备/在 Sitecore.Globalization.Translate.TextByLanguage(key, language) 中设置语言;?
【发布时间】:2015-08-25 20:30:16
【问题描述】:

我正在使用 Language Fallback 提供程序。这似乎对存储在 System > Dictionary 中的项目没有任何影响。

我希望它回退到 Language 项的“Fallback”属性中指定的语言。

更糟糕的情况,我想回退到英语。

我从字典中获取文本的方法可以调用它。

Globalization.Translate.TextByLanguage(key, ????);

我被困住了:

  1. 如何找到当前指定语言的“Fallback”属性值
  2. 如何将它传递给 TextByLanguage。它似乎需要一个 Language 属性,但 Language 似乎没有 任何构造函数。

历史:按照@Jammykam 的建议,我查看了 Verndale 示例,但我的运气为零。它似乎从来没有开过火。

我在我的解决方案中添加了以下类:

using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Pipelines.GetTranslation;
using Sitecore.SharedSource.PartialLanguageFallback.Extensions;
using System;
using System.Collections.Generic;

namespace Sitecore.Web.Pipelines
{
    public class DictionaryFallback : TryGetFromFallbackDomains
    {
        public static bool EnableFallback
        {
            get
            {
                return Sitecore.Context.Site != null &&
                       Sitecore.Context.Site.SiteInfo.Properties["enableFallback"] != null &&
                       Sitecore.Context.Site.SiteInfo.Properties["enableFallback"].Equals("true", StringComparison.InvariantCultureIgnoreCase);
            }
        }

        /// <summary>
        /// Runs the processor.
        /// 
        /// </summary>
        /// <param name="args">The arguments.
        ///             </param>
        public void Process(GetTranslationArgs args)
        {
            Assert.ArgumentNotNull((object)args, "args");
            List<string> processedDomains = new List<string>();
            if (args.HasResult || Context.Site == null || string.IsNullOrEmpty(Context.Site.DictionaryDomain))
                return;
            this.Args = args;
            this.Database = args.Options.Database ?? args.ContentDatabase;
            DictionaryDomain domain;
            if (!DictionaryDomain.TryParse(Context.Site.DictionaryDomain, this.Database, out domain) || domain == null) {
                Log.Info("Error Parsing Dictionary: " + domain.FullyQualifiedName, this);
                return;
            }


            string result;
            if (this.TryGetTranslation(domain, processedDomains, out result) && result != null)
            {
                Log.Info("Normal Translation: " + domain.FullyQualifiedName + ": " + result, this);
                args.Result = result;
            }
            else if (EnableFallback)
            {
                if (this.TryTranslateTextByFallbackLanguage(args, domain, out result) && result != null)
                {
                    Log.Info("Fallback Translation: " + domain.FullyQualifiedName + ": " + result, this);
                    args.Result = result;
                }
            }

        }

        protected virtual bool TryTranslateTextByFallbackLanguage(GetTranslationArgs args, DictionaryDomain domain, out string result)
        {
            result = null;
            List<string> processedDomains = new List<string>();

            // check if the the language passed in with the args has fallback assigned
            // if so, then get that fallback language
            // must try to get the translation based on that language
            var languageFallsBack = args.Language.HasFallbackAssigned(args.ContentDatabase);
            if (languageFallsBack)
            {
                Language fallbackLanguage = args.Language.GetFallbackLanguage(args.ContentDatabase);

                // the following cannot be called from here, because it is an internal method to the Sitecore.Kernel library
                //Translate.TryTranslateTextByLanguage(args.Key, domain, fallbackLanguage, out result, args.Parameters);

                // therefore, we set Args.Language to the fallbacklanguage
                // this.Args is the Args object in TryGetFromFallbackDomains processor
                // then we call this.TryGetTranslation, which is a method in the TryGetFromFallbackDomains processor, 
                // which IS in the Sitecore.Kernel library and therefore can make the call to TryTranslateTextByLanguage

                this.Args.Language = fallbackLanguage;

                if (this.TryGetTranslation(domain, processedDomains, out result) && result != null)
                {
                    return true;
                }
                else
                {
                    // if no results if found, try to see if this fallback language falls back itself to another language
                    // and then if so, try the translation with that
                    // pass into the recursive call this.Args (instead of args), since the language has been updated in this.Args
                    if (result == null)
                    {
                        var isSuccess = TryTranslateTextByFallbackLanguage(this.Args, domain, out result);
                        return isSuccess;
                    }
                    else
                        return false;
                }
            }
            else
            {
                return false;
            }

        }


    }
}

我在补丁文件中添加了以下代码:

<pipelines>
            <getTranslation>
                <processor patch:after="*[@type='Sitecore.Pipelines.GetTranslation.TryGetFromCoreDatabase, Sitecore.Kernel']" type="Sitecore.Web.Pipelines.DictionaryFallback, Sitecore.Web" />
            </getTranslation>
        </pipelines>

我可以使用 showconfig.aspx 看到它:

<getTranslation>
<processor type="Sitecore.Pipelines.GetTranslation.ResolveContentDatabase, Sitecore.Kernel"/>
<processor type="Sitecore.Pipelines.GetTranslation.TryGetFromDomain, Sitecore.Kernel"/>
<processor type="Sitecore.Pipelines.GetTranslation.TryGetFromFallbackDomains, Sitecore.Kernel"/>
<processor type="Sitecore.Pipelines.GetTranslation.TryGetFromSiteDomain, Sitecore.Kernel"/>
<processor type="Sitecore.Pipelines.GetTranslation.TryGetFromContextDatabase, Sitecore.Kernel"/>
<processor type="Sitecore.Pipelines.GetTranslation.TryGetFromCoreDatabase, Sitecore.Kernel"/>
<processor type="Sitecore.Web.Pipelines.DictionaryFallback, Sitecore.Web" patch:source="SitecoreSettings.config"/>
</getTranslation>

您会在我的课堂上看到我投入了一些日志记录,但我从未看到记录的项目。具有所选语言版本的项目正确呈现。但如果他们没有版本,它会显示密钥而不是后退。


这是通过 showconfig.aspx 显示的部分(我的真实域在此处更改为 example.com):

<sites><site name="shell" virtualFolder="/sitecore/shell" physicalFolder="/sitecore/shell" rootPath="/sitecore/content" startItem="/home" language="en" database="core" domain="sitecore" loginPage="/sitecore/login" content="master" contentStartItem="/Home" enableWorkflow="true" enableAnalytics="false" analyticsDefinitions="content" xmlControlPage="/sitecore/shell/default.aspx" browserTitle="Sitecore" htmlCacheSize="10MB" registryCacheSize="15MB" viewStateCacheSize="1MB" xslCacheSize="25MB" disableBrowserCaching="true" itemwebapi.mode="StandardSecurity" itemwebapi.access="ReadWrite" itemwebapi.allowanonymousaccess="false" /><site name="login" virtualFolder="/sitecore/login" physicalFolder="/sitecore/login" enableAnalytics="false" database="core" domain="sitecore" disableXmlControls="true" /><site name="admin" virtualFolder="/sitecore/admin" physicalFolder="/sitecore/admin" enableAnalytics="false" enableWorkflow="true" domain="sitecore" loginPage="/sitecore/admin/login.aspx" /><site name="service" virtualFolder="/sitecore/service" physicalFolder="/sitecore/service" /><site name="modules_shell" virtualFolder="/sitecore modules/shell" physicalFolder="/sitecore modules/shell" rootPath="/sitecore/content" startItem="/home" language="en" database="core" domain="sitecore" content="master" enableAnalytics="false" enableWorkflow="true" /><site name="modules_website" virtualFolder="/sitecore modules/web" physicalFolder="/sitecore modules/web" rootPath="/sitecore/content" startItem="/home" language="en" database="web" domain="extranet" allowDebug="true" cacheHtml="true" /><!-- ITEM WEB API SETTINGS FOR A SITE
           Supported attributes (first is default):
             itemwebapi.mode: [Off|StandardSecurity|AdvancedSecurity]
               If set to Off, Item Web API is turned off.
               If set to StandardSecurity, Item Web API is turned on. Default Sitecore security model is used.
               If set to AdvancedSecurity, Item Web API is turned on. Default Sitecore security model is extended with a requirement to explicitely set the 'remote:fieldread' access right for content fields.
             itemwebapi.access: [ReadOnly|ReadWrite]
               If set to ReadOnly, then only READ operation is allowed.
               If set to ReadWrite, then CREATE, READ, UPDATE, and DELETE operations are allowed.
             itemwebapi.allowanonymousaccess: [false|true].
               Defines if access is allowed for non-authenticated user.
      --><!--<site name="mysite" patch:before="site[@name='website']"
            virtualFolder="/"
            physicalFolder="/"
            rootPath="/sitecore/content"
            startItem="/home"
            database="web"
            domain="extranet"
            allowDebug="true"
            cacheHtml="true"
            htmlCacheSize="50MB"
            enablePreview="true"
            enableWebEdit="true"
            enableDebugger="true"
            disableClientData="false"/>--><site name="english" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" hostName="stage.example.com|127.0.0.1|localhost" language="en" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="1GB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" enableFallback="true" patch:source="SiteDefinition.config" /><site name="chinese" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" hostName="chinesestage.example.com" language="zh-CN" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="500MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" enableFallback="true" patch:source="SiteDefinition.config" /><site name="german" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" hostName="germanstage.example.com" language="de-DE" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="500MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" enableFallback="true" patch:source="SiteDefinition.config" /><site name="spanish" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" hostName="spanishstage.example.com" language="es-ES" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="500MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" enableFallback="true" patch:source="SiteDefinition.config" /><site name="french" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" hostName="frenchstage.example.com" language="fr-FR" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="500MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" enableFallback="true" patch:source="SiteDefinition.config" /><site name="italian" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" hostName="italianstage.example.com" language="it-IT" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="500MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" enableFallback="true" patch:source="SiteDefinition.config" /><site name="japanese" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" hostName="japanesestage.example.com" language="ja-JP" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="500MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" enableFallback="true" patch:source="SiteDefinition.config" /><site name="portuguese" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" hostName="portuguesestage.example.com" language="pt-BR" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="500MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" enableFallback="true" patch:source="SiteDefinition.config" /><site name="russian" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" hostName="russianstage.example.com" language="ru-RU" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="500MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" enableFallback="true" patch:source="SiteDefinition.config" /><site name="website" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" database="web" domain="extranet" allowDebug="true" cacheHtml="true" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="25MB" filteredItemsCacheSize="10MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" cacheRenderingParameters="true" renderingParametersCacheSize="10MB" itemwebapi.mode="Off" itemwebapi.access="ReadOnly" itemwebapi.allowanonymousaccess="false" htmlCacheSize="1GB" /><site name="scheduler" enableAnalytics="false" domain="sitecore" /><site name="system" enableAnalytics="false" domain="sitecore" /><site name="publisher" domain="sitecore" enableAnalytics="false" enableWorkflow="true" /></sites>

关闭更新:我使用了下面接受的答案并对其进行了修改以适合我:https://gist.github.com/eat-sleep-code/0ea3f1bd2be19bbf9fc6

【问题讨论】:

  • 您是否在配置中的 节点上设置了“enableFallback=true”?
  • @jammykam 是的。我添加了上面 showconfig.aspx 的输出部分。
  • 这一切对我来说都是正确的。尝试将您的处理器向上/首先移动并检查它是否运行正确。
  • 我添加了更多的日志记录行。看来 Context.Site.DictionaryDomain 是一个空字符串?这会导致进程退出。我该如何解决?
  • @jammykam 您发送的 Gist 有一个未定义的变量,称为“数据库”,我尝试使用 this.Database 代替它,但它对此并不满意。我试过什么都不用,但还是不开心。

标签: sitecore sitecore-mvc sitecore8


【解决方案1】:

我已经解决了这个问题,请查看以下博客文章,与字典项相关的部分:

Dictionary Items Language Fallback

我还为此构建了一个模块,上传到 sitecore 仍在等待审核。

【讨论】:

  • 我可以在您的代码中看到几个问题。由于您已对字典项 ID 进行了硬编码,因此它不适用于字典域。也没有递归调用 fallbacks 的回退。
  • 这是我需要的解决方案,我只需要一级后备,否则将检索字典项目的键
  • 对上下文域“extranet”的最后更新代码检查,这是我希望我的代码工作的域,任何想法或补充都会很棒
  • 当然,这只是一个观察。字典域与安全域不同,它允许您在多站点实现中为每个网站指定不同的字典 (sitecore.net/learn/blogs/technical-blogs/…)
  • @jammykam 谢谢你,但我认为博客中存在的代码只需 tweeks 就可以解决问题。你怎么看?
【解决方案2】:

默认情况下,字典项不适用于语言后备模块,您必须使用额外的处理器修补 getTranslate 管道,以进行后备语言检查并在后备语言中获取正确的字典项。

您可以在本文中找到有关Using Fallback with the Dictionary 的更多详细信息,之后您可以继续正常使用字典,而无需通过Globalization.Translate.TextByLanguage(key) 的语言。

【讨论】:

  • 我试过了。代码没有成功构建——即使在修复了损坏的引用之后。我的 Sitecore.Kernel.dll 来自 Sitecore 8。我不确定这是否与它有关。
  • 您需要的唯一代码部分是 TryGetFromFallbackLanguage.cs 以及对 getTranslate 管道配置的补充。将它们添加到您自己的解决方案中并尝试重建。代码的其他部分似乎引用了在 Sitecore 7+ 中不再有效的过时库(搜索贡献)。
  • 愚蠢的问题......我会在视图中使用什么语法来使用这种方法从字典中获取文本?
  • 在页面顶部@using Sitecore.Globalization 然后检索字典使用@Translate.Text("key")
  • @eat-sleep-code 该代码在您的站点节点上需要一个 dictionaryDomain 属性。试试这个 Process 方法,我添加了后备:gist.github.com/jammykam/ac3a8919565e9902a0d2
猜你喜欢
  • 1970-01-01
  • 2021-01-31
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
相关资源
最近更新 更多