How can I add extra settings to TermPart without modify the Core?

Topics: Core, Customizing Orchard
Nov 2, 2015 at 4:40 PM

I have created my own XKProject.TaxonomyHelpers.Settings.TermPartSettings class with its ContentDefinitionEditorEventsBase class and its DefinitionTemplates/TermPartSettings.cshtml. Problem is I get the following exception:
"The model item passed into the dictionary is of type 'Orchard.Taxonomies.Settings.TermPartSettings', but this dictionary requires a model item of type 'PCCom.TaxonomyHelpers.Settings.TermPartSettings'."
As you can see it looks like it is passing the Core TermPartSettings to my template.

Anyone has overcome a similar situation?
Is not possible to extend settings of parts with settings defined in other modules without modifiy original settings class?
Nov 3, 2015 at 5:07 PM
Fixed following the advice of @Devqon (thorugh orchard chat)

The fix is to use a different template name and settings name than the existing ones for TermPart. So I renamed it to XKProject.TaxonomyHelpers.Settings.TermPartCustomSettings

and it worked
Nov 8, 2015 at 5:50 PM
Edited Nov 8, 2015 at 6:28 PM
I thought it worked, because after that change the view was rendered without problems.
However, now the problem looks like the value the user selects is never stored, or maybe that despite it is stored, when the model is retrieved it doesn't load it to the model:

Here is the code:
using System.Collections.Generic;

namespace XKProject.TaxonomyHelpers.Settings {
    public class TermPartCustomSettings {
        public int QueryIdForRetrievingTermContentItems { get; set; }
        public IEnumerable<dynamic> AvailableQueries { get; set; }

    public class TermCustomSettingsHook : ContentDefinitionEditorEventsBase {

        private readonly IContentManager _contentManager;
        public TermCustomSettingsHook(IContentManager contentManager) {
            _contentManager = contentManager;
            T = NullLocalizer.Instance;

        public Localizer T { get; set; }

        public override IEnumerable<TemplateViewModel> TypePartEditor(
            ContentTypePartDefinition definition) {

            if (definition.PartDefinition.Name != "TermPart") yield break;
            var model = definition.Settings.GetModel<TermPartCustomSettings>("TermPartCustomSettings");
            //Here despite the value stored by the user is here definition.Settings["TermPartCustomSettings.QueryIdForTaxonomyTermChildren"]
            //te returned value for model.QueryIdForRetrievingTermContentItems always is 0
            model.AvailableQueries = GetQueries();

            yield return DefinitionTemplate(model);

        public override IEnumerable<TemplateViewModel> TypePartEditorUpdate(
            ContentTypePartDefinitionBuilder builder,
            IUpdateModel updateModel) {

            if (builder.Name != "TermPart") yield break;

            var model = new TermPartCustomSettings();
            updateModel.TryUpdateModel(model, "TermPartCustomSettings", null, null); 
            model.AvailableQueries = GetQueries();
            yield return DefinitionTemplate(model);

        private List<dynamic> GetQueries() {
            var availableQueries = new List<dynamic>(){
                new {
                    Text = T("None"),
                    Value = 0
                .Select(q =>
                new {
                    Text = q.As<TitlePart>().Title,
                    Value = q.Id
            return availableQueries;

The view TermPartCustomSettings.cshtml
@model XKProject.TaxonomyHelpers.Settings.TermPartCustomSettings
    <legend>@T("Query for retrieving contentitems related to a Term")</legend>
        @Html.LabelFor(m => m.QueryIdForRetrievingTermContentItems, @T("Query"))
        @Html.DropDownListFor(m => m.QueryIdForRetrievingTermContentItems,
        new System.Web.Mvc.SelectList(Model.AvailableQueries, "Value", "Text", Model.QueryIdForRetrievingTermContentItems))        
The point is this code never returns the value stored by the user:
//It always is 0
int queryId = part.Settings.GetModel<TermPartCustomSettings>("TermPartCustomSettings").QueryIdForRetrievingTermContentItems;
Nov 9, 2015 at 10:19 AM
Your part property is called QueryIdForRetrievingTermContentItems, but you use QueryIdForTaxonomyTermChildren at the WithSetting. Change this line:
To this:
Nov 10, 2015 at 11:14 AM

Thank you @sanderg!!