语言回退/在 Sitecore.Globalization.Translate.TextByLanguage(key, language) 中设置语言;?

Language Fallback / Setting the language in Sitecore.Globalization.Translate.TextByLanguage(key, language);?

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

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

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

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

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

我卡在了:

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

HISTORICAL:按照@Jammykam 的建议,我查看了 Verndale 示例,但我对它的运气为零。它似乎从未开过火。

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

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>

您会在我的 class 中看到我添加了一些日志记录,但我从来没有看到任何记录的项目。具有所选语言版本的项目可以正确呈现。但如果他们没有版本,它会显示密钥而不是回退。


这是通过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

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

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

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

Dictionary Items Language Fallback

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