Skip to content

自定义网站设置-Custom Site Settings

Sometimes you may need to persist some global settings

有时您可能需要保留一些全局设置

(eg. license code, service login, default width etc.)

(例如,许可证代码,服务登录,默认宽度等)

to be reused across your module. Orchard makes it really

在整个模块中重用。果园真的很棒

simple and I'll show you how to do it.

很简单,我会告诉你如何做到这一点。

Basically, there are two scopes you can define your settings in:

基本上,您可以在以下两个范围中定义设置:

  1. Site scope - for global site settings.

1. 网站范围 - 用于全球网站设置。

  1. Content type scope - for settings common to all items of a given type

2. 内容类型范围 - 用于给定类型的所有项目共有的设置

(eg. a Page, a Blog, a BlogPost and so on).

(例如,页面,博客,BlogPost等)。

Defining site scope settings (Orchard 1.8 Onwards)

定义站点范围设置(Orchard 1.8 Onwards)

Orchard 1.8 drastically simplifies creation of site settings, removing the previous need for "Part Records" and migration files. To create new site settings for your module you now only need three classes; A ContentPart, a Handler and potentially a view file if you want the settings to be edited via the "Site Settings" area of Admin. For a real world example look for the RegistrationSettingsPart, RegistrationSetttingsPartHandler and Users.RegistrationSettings.cshtml files in the Orchard.Users module.

Orchard 1.8大大简化了站点设置的创建,消除了以前对“部件记录”和迁移文件的需求。要为模块创建新的站点设置,您现在只需要三个类;如果您希望通过Admin的“站点设置”区域编辑设置,则可以使用ContentPartHandler和潜在的视图文件。对于一个真实世界的例子,在Orchard.Users模块中查找RegistrationSettingsPartRegistrationSetttingsPartHandler和``Users.RegistrationSettings.cshtml```文件。

The Content Part

内容部分

public class ShareBarSettingsPart : ContentPart {

    public string AddThisAccount {

        get { return this.Retrieve(x=> x.AddThisAccount); }

        set { this.Store(x=> x.AddThisAccount, value); }

        }

    }

The Handler

处理程序

[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")));

    }

}

The View

风景

@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>

Using site scope settings

使用站点范围设置

Accessing your site setting is a simple one liner:

访问您的网站设置是一个简单的一个班轮:

var shareSettings = _services.WorkContext.CurrentSite.As<ShareBarSettingsPart>();

Where _services is the IOrchardServices object (eg. injected in the constructor).

其中_services是IOrchardServices对象(例如,在构造函数中注入)。

Defining site scope settings (Pre-Orchard 1.8)

定义站点范围设置(Pre-Orchard 1.8)

Defining custom site scope settings for before Orchard 1.8 can be in Adding Custom Settings pre Orchard 1.8

在Orchard 1.8之前定义自定义站点范围设置可以在[Orchard 1.8之前添加自定义设置]中(添加 - 自定义设置 - 1.8之前的版本)

Defining settings for Content Types

定义内容类型的设置

We're now going to create settings and defaults wired with specific content type (like Page, User, Blog etc.).

我们现在要创建设置和默认连接特定内容类型(如页面,用户,博客等)。

This looks much different comparing to the previous one, but also requires less coding.

与前一个相比,这看起来有很大不同,但也需要较少的编码。

There are just two classes and one shape involved and that's all.

只有两个类和一个形状参与,这就是全部。

As before, we'll use the simplified examples taken from the

和以前一样,我们将使用从中获取的简化示例

Orchard Sharing project.

[Orchard Sharing](http://orchardsharing.codeplex.com/)项目。

The goal:

目标:

"I want all of my Blog Posts to have ShareBar with the same look."

“我希望我的所有Blog帖子都能让ShareBar具有相同的外观。”

Imagine that you're writing posts via LiveWriter (like me).

想象一下,你是通过LiveWriter(像我一样)写帖子的。

Do you want to log in and edit every post after publishing just to change the share bar?

您是否要在发布后登录并编辑每个帖子以更改共享栏?

I don't. I want to have it defined upfront.

我不。我希望事先定义它。

The first thing you have to do is to create a class holding your settings:

您要做的第一件事是创建一个包含您的设置的类:

public class ShareBarTypePartSettings {

    public ShareBarMode Mode { get; set; }

    public IEnumerable<dynamic> AvailableModes { get; set; }

}

This class has one property - Mode, which holds the default mode for all ShareBarParts

这个类有一个属性 - “Mode”,它保存所有ShareBarParts的默认模式

attached to some content items of a given type.

附加到给定类型的某些内容项。

ShareBarMode is just an enum type defining the display modes.

For the sake of brevity, I won't paste the code here.

为简洁起见,我不会在此处粘贴代码。

This could be any type you want.

这可以是您想要的任何类型。

The second property is just used for the display purposes (holds items for display in drop-down list),

第二个属性仅用于显示目的(保存项目以显示在下拉列表中),

as this class is also used as a ViewModel. It is not being persisted.

因为这个类也用作ViewModel。它没有坚持下去。

The second class can be thought of as a kind of a driver for the settings.

第二类可以被认为是一种设置的驱动程序。

It's not the Orchard ContentDriver we wrote previously, but also it's responsible

这不是我们之前写过的Orchard ContentDriver,但它也是负责任的

for rendering the edit form and saving the posted data:

用于呈现编辑表单并保存发布的数据:

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);

    }

}

This class overrides the ContentDefinitionEditorEventsBase which defines two overridable methods:

该类重写了ContentDefinitionEditorEventsBase,它定义了两个可覆盖的方法:

TypePartEditor and TypePartEditorUpdate.

The first one gets called when the edit form is being rendered (GET) and the second one

第一个在呈现编辑表单(GET)时调用,第二个调用表单

when the edit form data gets posted (POST).

何时发布编辑表单数据(POST)。

Unlike the generic content part drivers, this class is not bound to the specific content type

与通用内容部件驱动程序不同,此类未绑定到特定内容类型

(as the content types are just a list of names for a collection of parts),

(因为内容类型只是部件集合的名称列表),

so each of the methods we just defined will be called for every content type and for every part.

所以我们刚定义的每个方法都会针对每个内容类型和每个部分进行调用。

This is why the yield break statement is used - to filter only the ones containing the part we need, ShareBarPart.

这就是使用yield break语句的原因 - 只过滤包含我们需要的部分的那些,ShareBarPart

By convention, as shown in the TypePartEditorUpdate method, settings should be named as

按照惯例,如TypePartEditorUpdate方法所示,设置应命名为

<prefix>.<propertyName> when passing to builder.WithSetting(...),

where prefix is the string passed to the updateModel.TryUpdateModel.

其中prefix是传递给updateModel.TryUpdateModel的字符串。

Prefix can be anything, but has to be unique. Remember though,

when you use string other than your settings class name,

当您使用除设置类名以外的字符串时,

you cannot use Settings.GetModel<Your_Settings_Type>()

你不能使用Settings.GetModel <Your_Settings_Type>()

(as shown in the TypePartEditor method above).

(如上面的TypePartEditor方法所示)。

In this case you have to use Settings.GetModel<Your_Settings_Type>(prefix) instead.

在这种情况下,您必须使用Settings.GetModel <Your_Settings_Type>(prefix)

  1. It should be considered best practice to use your settings class name as a prefix (as in the code above).

1.将您的设置类名称用作“前缀”(如上面的代码中所示)应该被视为最佳实践。

  1. Settings are persisted within the content type definition in the db in the string form.

2.设置以字符串形式保存在db中的内容类型定义中。

You have to be sure that the properties you define are convertible to and from the string representation.

您必须确保您定义的属性可以转换为字符串表示形式和从字符串表示形式转换。

Notice the usage of Enum.GetValues(typeof(someEnum)), Enum.GetNames(typeof(someEnum))

注意使用Enum.GetValues(typeof(someEnum)),Enum.GetNames(typeof(someEnum))

and Enum.GetName(typeof(someEnum), i).

和'Enum.GetName(typeof(someEnum),i)`。

This methods get very useful when you want to iterate over the names/values of an enum.

当您想要遍历枚举的名称/值时,此方法非常有用。

If you're done with the code above, there's only one thing left:

如果您已完成上述代码,则只剩下一件事:

creating a .cshtml view (shape) to render our form.

创建一个.cshtml视图(形状)来渲染我们的表单。

Shapes defining edit forms for content type settings has to be placed under

定义内容类型设置的编辑表单的形状必须放在下面

/Views/DefinitionTemplates/ with the name <settingsClassName>.cshtml.

So in our case it'll look like on the picture above.

因此,在我们的案例中,它将如上图所示。

Inside, it's just like any other Razor view file:

在里面,它就像任何其他Razor视图文件:

@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>

This renders the dropdown list so user can choose one of the predefined Modes.

这将呈现下拉列表,以便用户可以选择其中一个预定义模式。

Model.AvailableModes contains the available ones: we populated the property with appropriate

data in TypePartEditor method above.

上面的TypePartEditor方法中的数据。

Hooray, we're done!

万岁,我们完成了!

Now you possibly wonder, where will this edit form be shown?

现在您可能想知道,这个编辑表单将在何处显示?

Orchard will render settings form when you'll try to edit the content type containing your part.

当您尝试编辑包含零件的内容类型时,Orchard将呈现设置表单。

The steps are like this: Content Types -> Edit the type you want -> Add your part -> Voila!

步骤如下:内容类型 - >编辑你想要的类型 - >添加你的部分 - > Voila!

There is a nice arrow image next to your part. If you click it - the form shows.

您的零件旁边有一个漂亮的箭头图像。如果单击它 - 表单显示。

Using settings for content type

使用内容类型的设置

As for site-scoped settings, this section is also a one-liner.

至于站点范围设置,此部分也是一个单行。

The part below is some content part (in this case a ShareBarPart from the

下面的部分是一些内容部分(在这种情况下是一个来自的ShareBarPart)

Orchard Sharing project).

[Orchard Sharing](http://orchardsharing.codeplex.com/)项目)。

var typeSettings = part.Settings.GetModel<ShareBarTypePartSettings>();

You can retrieve and use the settings wherever you have access to your part

您可以在有权访问零件的任何地方检索和使用设置

(particularly in the driver Display/Editor methods, but also shapes, handlers and so on).

(特别是在驱动程序显示/编辑器方法中,还有形状,处理程序等)。

I used it in the ShareBarPart driver Display method to change the look of a share bar part.

我在ShareBarPart驱动程序显示方法中使用它来更改共享栏部件的外观。