Sitefinity中的多语言发布

最初以非默认语言发布您的内容

Sitefinity具有强大的多语言发布功能。 从最终用户/内容管理者的角度来看,后端提供了无数种方法来创建内容项,这些方法既可以使用网站的默认语言,也可以使用网站本身激活/启用的任何其他语言。 通常,只需单击一下即可获得良好的体验。

但是事情的发展方面呢? 假设我们有一个用于创建内容项的自定义小部件,但是该语言必须不同于默认语言,还是在创建发生之前用户可以选择的语言? 我们如何通过API指示Sitefinity以另一种语言发布内容项? 让我们通过尝试创建一个新的News项目来查找(但是我们在此处所做的操作也适用于动态内容)。

收集数据进行创建

假设我们有一个自定义小部件,该小部件为我们提供了一些新闻的基本字段,包括一些自定义字段,并指定了我们要使用的语言。该小部件为我们提供了一个类型为“ CreateNewsViewModel”的对象,该对象已填充了这些字段我们。 CreateNewsViewModel看起来像这样:

 公共类CreateNewsViewModel 
{
//内置新闻字段
公共字符串Title {get; 组; }
公共字符串摘要{get; 组; }
公共字符串Content {get; 组; }

//新闻上的自定义字段
公共字符串CustomStringField {get; 组; }
公共布尔CustomBoolField {get; 组; }

//所选语言
公共字符串SelectedCultureName { 组; }

//分类字段
公共Guid SelectedTagId { 组; }
}

在我们的案例中,我们设置了一些内置字段,几个自定义字段,一个Tag(传递其ID)以及我们希望存储的文化(即语言)。

此时,您可能会问我们如何获得SelectedCultureName。 简单! Sitefinity的API向前端公开了当前可用的语言,我们可以使用该列表在小部件中创建一个下拉选择器,然后在上述模型中传递所选区域性的名称。 获取可用区域性的代码是:

  CultureInfo [] availableCultures = SystemManager.CurrentContext.AppSettings.DefinedFrontendLanguages; 

在我们的方法中(下一位),我们将使用名称,并重新获得Culture对象(因为更容易在MVC模型之间传递字符串,并验证是否没有垃圾数据) /无效的文化信息)。

创建项目

现在我们进入有趣的部分。 多语言发布的第一步是通过调用NewsManager来简单地执行创建新闻项时经常执行的操作:

 私人无效CreateNewsItem(CreateNewsViewModel viewModel) 
{
NewsManager newsManager = NewsManager.GetManager();
NewsItem item = newsManager.CreateNewsItem();

DateTime creationDate = DateTime.UtcNow;
CultureInfo文化= SystemManager.CurrentContext.AppSettings.DefinedFrontendLanguages.Single(c => c.Name == viewModel.SelectedCultureName);

// 还没做完!
}

在这里,我们不仅使用管理器创建了“ item”变量,还获得了当前的DateTime(以UTC为单位),并基于在视图模型中选择的那个获得了CultureInfo对象。 现在,我们将开始使用我们的文化来将字段值设置为我们提供的值,以确保字段的正确翻译获得的是值,而不是网站的默认语言:

 私人无效CreateNewsItem(CreateNewsViewModel viewModel) 
{
// ...先前的代码已被截断...

item.Title.SetString(culture,viewModel.Title);
item.Summary.SetString(culture,viewModel.Summary);
item.SetString(“ Content”,viewModel.Content,culture);

// 还没做完!
}

您会看到我们内置的短文本字段“标题”和“摘要”,我们只是在它们上面调用了“ SetString()”,首先传递了区域性,然后传递了我们希望存储的值。 在多语言发布中,文化对象是关键! 请注意,对于长文本字段(在本例中为“内容”),语法是不同的。 等等什么

暴露的LString方法的陷阱

但是像Content这样的长文本字段呢? 该代码使我们可以调用“ item.Content.SetString(culture,viewModel.Content)”,那么为什么会不一致? 实际上,Sitefinity LStrings中还内置了一个数组索引器,它可以让我们称为“ item.Content [culture] = viewModel.Content”,而不是更麻烦的SetString方法!

事实证明,尽管Sitefinity及其LString类公开了在API中使用的那些功能,但它们无法正常运行。 它们要么仍将数据存储在默认语言字段中,要么根本不记录任何值! 您必须在数据项本身(在本例中为我们创建的“ item”变量)上调用“ SetString”,并传递字段名称,要存储的字符串,然后传递区域性,否则它将无法正常工作。

如果您喜欢一致性,则还可以对短文本字段使用完全相同的语法,以便所有字段设置(短文本或长文本)在代码中保持一致。 虽然我喜欢一致性,但我也喜欢尽可能使用强类型字段(使用item.Title代替item.SetString(“ Title”)),因为直到验证字符串的值(即引发异常),运行。 不过,这完全取决于您!

考虑到这一点,让我们继续进行多语言发布。

将长文本SetString用于自定义字段

这很容易。 由于没有可以为自定义字段设置的强类型属性,因此我们只对长文本字段使用与自定义字段相同的方法:

 私人无效CreateNewsItem(CreateNewsViewModel viewModel) 
{
// ...先前的代码已被截断...

item.SetString(“ CustomStringField”,viewModel.CustomStringField,culture);

// 还没做完!
}

通常设置不可翻译字段

对于分类,非字符串(即布尔值)等字段,请像设置任何普通内容项一样对其进行设置。 它们没有可翻译的字段,因此在进行多语言发布时,在这里没有什么特别的事情要做。 在这里,我们像通常那样设置自定义布尔值字段和标签字段以及样板日期内容字段:

 私人无效CreateNewsItem(CreateNewsViewModel viewModel) 
{
// ...先前的代码已被截断...

item.SetValue(“ CustomBoolField”,viewModel.CustomBoolField);

//添加标签的语法
item.Organizer.AddTaxa(“ Tags”,viewModel.SelectedTagId);

item.DateCreated = creationDate;
item.LastModified = creationDate;
item.PublicationDate = creationDate;

// 还没做完!
}

UrlName需要文化!

由于新闻项的每个版本都有其自己的URL名称,因此我们需要像设置其他任何可翻译字符串一样对其进行设置:

  item.UrlName.SetString(culture,viewModel.Title.SafeUrlName());  // SafeUrlName()是字符串扩展方法,我必须从字符串中删除不安全的URL字符。 

发布项目

我们到了方法的尽头! 我们现在要做的就是调用Sitefinity公开的常规发布方法,仅在必要时传递文化。 完成后,我们的多语言发布过程就完成了!

 私人无效CreateNewsItem(CreateNewsViewModel viewModel) 
{
// ...先前的代码已被截断...

newsManager.SaveChanges();
newsManager.RecompileAndValidateUrls(item);
item.ApprovalWorkflowState.SetString(culture,“ Published”);
newsManager.Lifecycle.Publish(项目,文化);
item.SetWorkflowStatus(newsManager.Provider.ApplicationName,“已发布”,区域性);
newsManager.SaveChanges();
}

在这种情况下,您会看到我们在ApprovalWorkflowState上调用“ SetString”方法,并且还将区域性传递给Publish和SetWorkflowStatus方法。 保存这些更改后,便会使用指定的文化来创建新闻项。 我们做到了!

完整的创作方法

为了方便起见,这是我们上面拼凑的整个方法:

 私人无效CreateNewsItem(CreateNewsViewModel viewModel) 
{
NewsManager newsManager = NewsManager.GetManager();
NewsItem item = newsManager.CreateNewsItem();

DateTime creationDate = DateTime.UtcNow;
CultureInfo文化= SystemManager.CurrentContext.AppSettings.DefinedFrontendLanguages.Single(c => c.Name == viewModel.SelectedCultureName);

item.Title.SetString(culture,viewModel.Title);
item.Summary.SetString(culture,viewModel.Summary);
item.SetString(“ Content”,viewModel.Content,culture);

item.SetString(“ CustomStringField”,viewModel.CustomStringField,culture);
item.SetValue(“ CustomBoolField”,viewModel.CustomBoolField);

//添加标签的语法
item.Organizer.AddTaxa(“ Tags”,viewModel.SelectedTagId);

item.DateCreated = creationDate;
item.LastModified = creationDate;
item.PublicationDate = creationDate;

newsManager.SaveChanges();
newsManager.RecompileAndValidateUrls(item);
item.ApprovalWorkflowState.SetString(culture,“ Published”);
newsManager.Lifecycle.Publish(项目,文化);
item.SetWorkflowStatus(newsManager.Provider.ApplicationName,“已发布”,区域性);
newsManager.SaveChanges();
}

包起来

使用Sitefinity API进行多语言发布很容易。 有一些陷阱需要避免,并且涉及一些语法,但是它主要围绕策划适当的Culture对象,并在需要设置可翻译字段时将其传入。 并非所有字段都是可翻译的,但是对于那些字段,Culture对象完全被忽略,您只需执行通常的操作即可。

上面的内容也可以用于自定义内容类型。 您可以使用DynamicModuleManager代替NewsManager。 并且由于所有内容都是自定义字段,因此您只需使用我们用于新闻项的某些字段的item.SetString(“ MyField”,stringValue,culture)语法。

就是这样。 现在,您可以轻松使用多语言发布功能。