Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

8/7/2015 Adding custom settings - Orchard Documentation

Home Download Documentation Gallery Localization Contribute Discussions and Help

About Us

Adding custom settings Search


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.
Contributors
Basically, there are two scopes you can define your settings in:
1. Site scope - for global site settings. Contributors
2. Content type scope - for settings common to all items of a given type (eg. a Page, a Blog,
a BlogPost and so on). Table of Contents
Defining site scope settings (Orchard 1.8 Onwards) Adding custom settings

Orchard 1.8 drastically simplifies creation of site settings, removing the previous need for Defining site scope settings (Orchard 1.8 Onw
"Part Records" and migration files. To create new site settings for your module you now The Content Part
only need three classes; A ContentPart, a Handlerand potentially a view file if you want The Handler
the settings to be edited via the "Site Settings" area of Admin. For a real world example The View
look for the RegistrationSettingsPart, RegistrationSetttingsPartHandlerand Using site scope settings
Users.RegistrationSettings.cshtmlfiles in the Orchard.Usersmodule.
Defining site scope settings (Pre-Orchard 1.8)

Defining settings for Content Types


The Content Part
Using settings for content type

public class ShareBarSettingsPart : ContentPart {


public string AddThisAccount { Edit this page
get { return this.Retrieve(x=> x.AddThisAccount); } Submit issue
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",
}

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")));
http://docs.orchardproject.net/Documentation/Adding-custom-settings 1/4
8/7/2015 Adding custom settings - Orchard Documentation

}
}

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 IOrchardServicesobject (eg. injected in the constructor).

Defining site scope settings (Pre-Orchard 1.8)


Defining custom site scope settings for before Orchard 1.8 can be in Adding Custom Settings
pre Orchard 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.
The goal:

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

Imagine that you're writing posts via LiveWriter (like me). 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
attached to some content items of a given type. ShareBarModeis 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.
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 for rendering the edit form and
saving the posted data:
http://docs.orchardproject.net/Documentation/Adding-custom-settings 2/4
8/7/2015 Adding custom settings - Orchard Documentation

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 ContentDefinitionEditorEventsBasewhich defines two


overridable methods: TypePartEditorand TypePartEditorUpdate. The first one gets
called when the edit form is being rendered (GET) and the second one when the edit form
data gets posted (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 breakstatement is used - to filter only the ones containing
the part we need, ShareBarPart.
By convention, as shown in the TypePartEditorUpdate method, settings should be named as
<prefix>.<propertyName>when passing to builder.WithSetting(...), where prefix
is the string passed to the updateModel.TryUpdateModel. Prefixcan 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>()(as shown in the
TypePartEditor method above). In this case you have to use
Settings.GetModel<Your_Settings_Type>(prefix)instead.
1. It should be considered best practice to use your settings class name as a prefix(as in the
code above).
2. Settings are persisted within the content type definition in the db in the string form. 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))and Enum.GetName(typeof(someEnum), i). This
methods get very useful when you want to iterate over the names/values of an enum.
http://docs.orchardproject.net/Documentation/Adding-custom-settings 3/4
8/7/2015 Adding custom settings - Orchard Documentation
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.

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:

@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.AvailableModescontains the available ones: we populated the property with
appropriate data in TypePartEditormethod above.
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. The steps are like this:
Content Types -> Edit the type you want -> Add your part -> 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 Orchard Sharing project).

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.

Home Contact Us About Us Terms Of Use Privacy Statement Hosted and Powered by AppHarbor

http://docs.orchardproject.net/Documentation/Adding-custom-settings 4/4

You might also like