sitecore中媒体库项目的语言回退

时间:2013-06-10 11:18:54

标签: sitecore sitecore6 sitecore-media-library

我有很多英文PDF。我有英文和德文的网页。

如果在德语页面中我希望显示英语版本的PDF,则无法使用德语版PDF,因此我尝试对媒体库项目进行后备,即使没有帮助。

所以有人可以告诉我任何替代方案。

注意:我不想上传德语版的英文文档,因为还有其他语言,客户无法在所有语言中多次上传。

我需要上传一份只有英文的文件,但是要显示在所有其他语言中,无论该文件是否存在。

即使我需要通过代码进行更改也没关系。

提前致谢

3 个答案:

答案 0 :(得分:1)

您使用哪个模板上传PDF?如果您使用的是/sitecore/templates/System/Media/Unversioned/Pdf,那么这将继承自/sitecore/templates/System/Media/Unversioned/File,并且blob字段仍然标记为共享:

File Template

共享字段在语言版本之间共享,因此如果您上传英文PDF并链接到德语项目中的同一媒体项目,则会链接到原始英文PDF。

In Sitecore, when adding a field to a template, there's a checkbox called "shared". What's it for?

答案 1 :(得分:0)

有几种方法可以做到这一点。您可以在渲染代码中执行此操作,也可以使用Sitecore marketplace中的语言回退模块。

要在代码中执行此操作,您需要创建一个新的MediaProvider。创建一个继承自Sitecore.Resources.Media.MediaProvider的类并覆盖protected virtual MediaData GetMediaData(MediaUri mediaUri)方法。

此方法获取上下文语言或Uri中的语言的sitecore项。所以你可以在这里实现回落:

public class MediaProviderWithFallback : Sitecore.Resources.Media.MediaProvider
{
    protected override Sitecore.Resources.Media.MediaData GetMediaData(Sitecore.Resources.Media.MediaUri mediaUri)
    {
        Assert.ArgumentNotNull((object)mediaUri, "mediaUri");
        Database database = mediaUri.Database;
        if (database == null)
        {
            return null;
        }
        string mediaPath = mediaUri.MediaPath;
        if (string.IsNullOrEmpty(mediaPath))
        {
            return null;
        }
        Language language = mediaUri.Language;
        if (language == null)
        {
            language = Context.Language;
        }
        Sitecore.Data.Version version = mediaUri.Version;
        if (version == null)
        {
            version = Sitecore.Data.Version.Latest;
        }
        Sitecore.Data.Items.Item mediaItem = database.GetItem(mediaPath, language, version);
        if (mediaItem == null)
        {
            return (MediaData)null;
        }
        // Check for language fallback
        if (mediaItem.Versions.Count == 0)
        {
            // Workout your language fallback here from config or sitecore settings etc...
            language = Language.Parse("en");
            // Try and get the media item in the fallback language
            mediaItem = database.GetItem(mediaPath, language, version);
            if (mediaItem == null)
            {
                return null;
            }
        }
        return MediaManager.Config.ConstructMediaDataInstance(mediaItem);
    }
}

请注意 - 这是未经测试的代码。您应该将您的后备存储在配置中或修改sitecore中的语言模板。

您拥有该课程后,您需要更新您的web.config以使用您的提供商而不是Sitecores。因此,请在web.config中找到此部分,并将类型更改为您的类和汇编:

    <!-- MEDIA PATH -->
<mediaPath defaultProvider="default">
  <providers>
    <clear />
    <add name="default" type="Sitecore.Resources.Media.MediaPathProvider, Sitecore.Kernel" />
  </providers>
</mediaPath>

答案 2 :(得分:0)

尝试确定媒体是否需要提前版本化是最佳做法。如果您知道需要根据语言对媒体进行版本控制,则应确保在web.config中更新以下属性:

<!--By default, Media items are not versionable and the below setting is set to false in the web.config.  
    If you upload an image in one language, it will persist across all language versions.
    If you change this to true, then versioning will apply and you would have to set the media item into all language versions, 
    or enable fallback, but if enforce version presence is turned on and media template guids are included in EnforceVersionPresenceTemplates, 
    then you'll have to make sure all language versions at least exist-->
  <setting name="Media.UploadAsVersionableByDefault">
    <patch:attribute name="value">true</patch:attribute>
  </setting>

Alex Shyba的Partial Language Fallback模块将成功使用此功能。我建议确保不要在任何媒体模板上强制实施版本(不要强迫管理员创建空白语言版本)。然后他们可以创建英文版本,然后只在需要覆盖它时才创建语言版本。

在使用部分语言回退的情况下,您需要确保在媒体版本化模板字段上选中启用回退复选框。

我还建议更新媒体提供商,以便将语言嵌入到媒体网址中,以便缓存不起作用。 EG:如果您创建一个名为Directions.pdf的pdf并在www.site.com/media/Directions.pdf上加载,当您在语言之间切换时,它可以很好地缓存它。因此,您需要更新媒体提供程序,以使用上下文语言对媒体网址进行编码。

您可以在此处查看演示: https://github.com/Verndale-Corp/Sitecore-Fallback-FullDemo

public class CustomMediaProvider : MediaProvider
{
    public override string GetMediaUrl(MediaItem item, MediaUrlOptions options)
    {
        Assert.ArgumentNotNull((object)item, "item");
        Assert.ArgumentNotNull((object)options, "options");

        string result = base.GetMediaUrl(item, options);

        // Added by Verndale, check if language should be embedded
        UrlOptions urlOptions = UrlOptions.DefaultOptions;
        urlOptions = LanguageHelper.CheckOverrideLanguageEmbedding(urlOptions);
        if (urlOptions.LanguageEmbedding == LanguageEmbedding.Always && options.UseItemPath)
        {
            result = "/" + Sitecore.Context.Language.Name.ToLowerInvariant() + Sitecore.StringUtil.EnsurePrefix('/', result);
        }

        return result;
    }

    public static UrlOptions CheckOverrideLanguageEmbedding(UrlOptions urlOptions)
    {
        var thisSite = Sitecore.Context.Site;

        if (urlOptions.Site != null)
            thisSite = urlOptions.Site;

        if (!String.IsNullOrEmpty(thisSite.SiteInfo.Properties["languageEmbedding"]))
        {
            if (thisSite.SiteInfo.Properties["languageEmbedding"].ToLower() == "never")
                urlOptions.LanguageEmbedding = LanguageEmbedding.Never;
            else if (thisSite.SiteInfo.Properties["languageEmbedding"].ToLower() == "always")
                urlOptions.LanguageEmbedding = LanguageEmbedding.Always;
            else if (thisSite.SiteInfo.Properties["languageEmbedding"].ToLower() == "asneeded")
                urlOptions.LanguageEmbedding = LanguageEmbedding.AsNeeded;
        }

        return urlOptions;
     }
 }