Editor shape in type part settings and prefixes

Topics: Writing modules
Feb 2, 2012 at 9:00 PM
Edited Feb 2, 2012 at 9:05 PM

It's for my Facebook Suite module: there are widgets that provide FB social plugins. I'd like to attach these widgets to content types, so e.g. all Pages have FB comments. Doing this with the same part the widgets have has the drawback that the widget settings have to be configured with every content item. Therefore I'd like to configure attached widgets on a per content type basis, with TypePartEditors.

Now the easiest way would be to duplicate widget editors, widget parts, etc. as type part settings, but that's a ridiculously bloated copy-pasta. The idea I had was to basically attach widgets to content types, as following:


public class FacebookCommentsBoxSettingsHooks : ContentDefinitionEditorEventsBase
        public override IEnumerable<TemplateViewModel> TypePartEditor(ContentTypePartDefinition definition)
            var model = new FacebookCommentsBoxTypePartSettings();
            // ...
            model.WidgetEditor = _contentManager.BuildEditor(widgetItem);

            yield return DefinitionTemplate(model);


Then display model.WidgetEditor in the definition template and update the widget content item in TypePartEditorUpdate() with ContentManager.UpdateEditor(). Now this would work except that since the "FacebookCommentsBoxTypePartSettings" prefix is added to the form fields, the widget's fields (which have their own prefix assigned in the parts' driver) are not updated correctly. What could be done?

  1. Return another TemplateViewModel from the TypePartEditor method that only displays the widget's editor shape, without a prefix. That would work but I think the prefix should stay since it makes the fields truly unique. A better solution would be to configure the updater to use the TypePartEditor's prefix too (but I don't think that's possible).
  2. Manually update the widget's interesting part (that stores the social plugin's data) in TypePartEditorUpdate() using the TypePartEditor's and the part's prefix too. This works but sound a bit hackish.
  3. Wait for Orchard 1.5 where AFAIK something is planned for widgets and content items (but it's a question whether widgets could be attached to content items or content types; in this case widgets should be attached to content types).

Or something else... Thank you for reading and for any help in advance.

Feb 3, 2012 at 3:12 PM

Is there any reason you can't just have site-wide Facebook settings, and then a part which simply enables the comments on that type, always using the site settings?

The real issue with this as you found out is that IContentManager.BuildEditor won't accept a prefix. I've spent actually substantial amounts of time trying to figure out ways to make this work to build nested editors on relationships, and I concluded it's just currently not possible, because the prefixes are always - uh, no, wait, I've had an idea half way through that sentence, and curiously it involves Clay Behaviors. I was wondering what to do for my 3rd tutorial and now I know :)

Feb 3, 2012 at 3:15 PM

By the way; you can already attach widgets to content items with the Mechanics module (using Paperclips to push them to zones). But my 1.0 release should do this a lot better, especially if I get nested editors working!

Feb 3, 2012 at 8:49 PM

Thank you for you thoughts!

Site-wide settings would work well but I currently aim for a flexibility where social plugins can be configure per basis of the location of usage (that means, widgets can be independently configured and widgets appearing on a specific content type too). Now regular widgets with properly set-up layers are to an extent suitable too (at least if content types can be distinguished well by url, e.g. blog posts have the url prefix "blog/").

Actually I thought about Science Project :-), but I though what I wanted to do should not be really hard. It isn't, except for the prefix part... And also because I wanted the users to provide a built-in feature for such a seemingly simple task.

Wow, curious about the idea that interrupted your sentence :-).

Feb 4, 2012 at 6:38 AM

It's not hard to do it with Science Project ... and actually it's better than the normal widget interface in some ways because, for instance, a single widget instance can be connected to multiple different places, instead of the layers system often forcing you to duplicate a widget. This would solve your settings problem quite effectively, you can just reuse the same widget everywhere you needed it. If you wanted it automatically on a specific content type, you could program a handler that automatically created a connection (using the Mechanics API) each time that content type was published. That's the only code you'd have to write; most of the Mechanics setup can be done entirely in the UI.

Anyway, that idea I had: I quickly had a go at implementing it and it looks pretty good. Have a look at this behavior: http://scienceproject.codeplex.com/SourceControl/changeset/view/af2aca56b938#Downplay.Origami%2fShapes%2fPrefixPrependingBehavior.cs

It's pretty simple itself; but to use it you'll need your own version of IContentDisplay, because you need to a) send in a prefix (different method signature) and b) modify the line of code where ZoneHoldingBehavior is instanced. But in the Origami module I already have a custom, more flexible replacement for IContentDisplay so it was easy to do ... So technically now you should be able to get recursively nested editors across Mechanics relationships, but I haven't enabled it yet because styling will be a nightmare.

Feb 13, 2012 at 8:46 PM

Thanks again.

I didn't mean it would be hard with Science Project :-), I've meant that I thought implementing the nested editor wouldn't be a complex task.

I took a look at your code: do I correctly understand that you there the Prefix of the shape is set? Would that solve the problem? I tried to alter prefixes from the Debugger, it doesn't seem to do anything (this was on the built editor shape, so it's maybe too late for that there). But anyway, the IUpdateModel in the Driver methods would still use the hard-coded prefix, isn't that a problem?