自定义设置
Orchard提供了非常简单的方法,来对你的模块进行全局的设置。
设置的作用域分为两类:
Site scope – 整个站点有效
Content type scope – 对特定的内容类型有效,比如博客、页面
Defining site scope settings (Orchard 1.8 Onwards)
定义全局的配置非常的简单,你只需要一个ContentPart文件,一个Handler文件和一个CSHTML文件。
你可以参考Orchard.Users模块中的RegistrationSettingsPart, RegistrationSetttingsPartHandler 和Users.RegistrationSettings.cshtml 文件。
public class ShareBarSettingsPart : ContentPart {
public string AddThisAccount {
get { return this.Retrieve(x=> x.AddThisAccount); }
set { this.Store(x=> x.AddThisAccount, value); }
}
}
[UsedImplicitly]
public class ShareBarSettingsPartHandler : ContentHandler {
public ShareBarSettingsPartHandler() {
T = NullLocalizer.Instance;
Filters.Add(new ActivatingFilter<ShareBarSettingsPart>("Site"));
Filters.Add(new TemplateFilterForPart<ShareBarSettingsPart>("ShareBarSettings", "Parts/ShareBar.ShareBarSettings", "Modules"));
}
public Localizer T { get; set; }
protected override void GetItemMetadata(GetContentItemMetadataContext context)
{
if (context.ContentItem.ContentType != "Site")
return;
base.GetItemMetadata(context);
context.Metadata.EditorGroupInfo.Add(new GroupInfo(T("Modules")));
}
}
@model Szmyd.Orchard.Modules.Sharing.Models.ShareBarSettingsPart
<fieldset>
<legend>@T("Content sharing settigs")</legend>
<div>
@Html.LabelFor(m => m.AddThisAccount, @T("AddThis service account"))
@Html.EditorFor(m => m.AddThisAccount)
@Html.ValidationMessageFor(m => m.AddThisAccount, "*")
</div>
</fieldset>
是需要一句代码,就可以调取站点配置
var shareSettings = _services.WorkContext.CurrentSite.As<ShareBarSettingsPart>();
注:_services是IOrchardServices 接口的实例。
我们对博客帖子内容类型中的ShareBar元件,自定义配置。
首先,我们创建配置的模型:
public class ShareBarTypePartSettings {
public ShareBarMode Mode { get; set; }
public IEnumerable<dynamic> AvailableModes { get; set; }
}
这个类有一个属性 Mode,类型是ShareBarMode,ShareBarMode是一个枚举类型,用于决定ShareBar的显示方式。我们这里就没有把ShareBarMode的定义代码贴出来,你可以任意定义一个枚举。第二个属性,AvailiableModes中,保存了可以在下拉列表中显示的项。ShareBarTypePartSettings 类,同时还作为ViewModel使用。
下面这个类,用于配置的编辑保存:
public class ShareBarSettingsHooks : ContentDefinitionEditorEventsBase {
public override IEnumerable<TemplateViewModel> TypePartEditor(
ContentTypePartDefinition definition) {
if (definition.PartDefinition.Name != "ShareBarPart") yield break;
var model = definition.Settings.GetModel<ShareBarTypePartSettings>();
model.AvailableModes = Enum.GetValues(typeof(ShareBarMode))
.Cast<int>()
.Select(i =>
new {
Text = Enum.GetName(typeof(ShareBarMode), i),
Value = i
});
yield return DefinitionTemplate(model);
}
public override IEnumerable<TemplateViewModel> TypePartEditorUpdate(
ContentTypePartDefinitionBuilder builder,
IUpdateModel updateModel) {
if (builder.Name != "ShareBarPart") yield break;
var model = new ShareBarTypePartSettings();
updateModel.TryUpdateModel(model, "ShareBarTypePartSettings", null, null);
builder.WithSetting("ShareBarTypePartSettings.Mode",
((int)model.Mode).ToString());
yield return DefinitionTemplate(model);
}
}
我们继承了 ContentDefinitionEditorEventsBase 基类,重新了 TypePartEditor 和 TypePartEditorUpdate。第一个方法会在请求配置页面(get请求)的时候调用,下面的会在提交配置变更(post请求)的时候调用。这两个方法,没有像元件的driver那样,绑定到特定的内容类型,所以,所有的内容类型或者元件请求的时候,都会调用这两个方法,这就是我们在TypePartEditor方法中,判断是否为特定元件的原因。
按照规范,,在TypePartEditorUpdate方法中,配置的命名格式为:<prefix>.<propertyName> , prefix一般是指的配置模型的名称,注意,这个名称要唯一,如果prefix不是使用的你的配置模型名称,那么你不可以使用Settings.GetModel<Your_Settings_Type>() 方法来获取配置,而是使用 Settings.GetModel<Your_Settings_Type>(prefix) (加了一个prefix参数)。
配置会保存在数据库内容类型定义的表里面。所以,你需要确保你的配置能够序列化和反序列化为字符串。
Shapes 定义了编辑页面,你需要将其放在/Views/DefinitionTemplates/ 文件夹中,并命名为 <settingsClassName>.cshtml:
@model Szmyd.Orchard.Modules.Sharing.Settings.ShareBarTypePartSettings
<fieldset>
<div>
@Html.LabelFor(m => m.Mode, T("Share bar display style"))
@Html.DropDownListFor(m => m.Mode,
new System.Web.Mvc.SelectList(
Model.AvailableModes, "Value", "Text", (int)Model.Mode))
</div>
</fieldset>
我们在内容类型定义界面,编辑具有ShareBarPart元件的内容类型,在页面下部,ShareBarPart定义处,我们就可以对其进行配置了。
我们获取配置的语法如下:
var typeSettings = part.Settings.GetModel<ShareBarTypePartSettings>();
我们在ShareBar元件的Driver中,通过上面的语句,调用配置,来格式化显示方式。