Converting code to Part and PartRecord

Topics: Troubleshooting, Writing modules
Oct 28, 2012 at 3:18 PM

I am trying to convert some code into a Part and PartRecord. Rather than just turn my code to a module, I wanted to get it working within Orchard so I could hook into the admin interface.

Any thoughts on what I can do with the following (explanation follows):

    public enum Referral
        {
            [Display(Name = "Recent Postcard Mailing")]
            Mailing,
            [Display(Name = "Google / Google+")]
            Google,
        }
        public class ReferralSelectorAttribute : SelectorAttribute
        {
            public override IEnumerable<SelectListItem> GetItems()
            {
                return Selector.GetItemsFromEnum<Referral>();
            }
        }
        [Required(ErrorMessage = "Please select one referral option")]
        [Display(Name = "How did you hear about us?", Description = "Letting us know how you reached us helps us to focus our advertising efforts and ultimately lowers costs")]
        [ReferralSelector(BulkSelectionThreshold = 3)]
        public Referral? ReferralRadioButton { get; set; }
        //
        // POST ReferralRaduiButton
        [ReferralSelector]
        [ReadOnly(true)]
        public Referral? ReferralRadioButtonPost
        {
            get { return ReferralRadioButton; }
        }

Explanation of code:

I have a Selector class which is hooking up into a HtmlFormHelper class. The latter class (with some code in a Selector.cshtml file I have in an MVC4 folder ~/Shared/EditorTemplates) helps to pick the appropriate html field (text, textarea, radiobutton, dropdownlist, etc.). For example, the "BulkSelectionThreshold = 3" picks a radiobuttonlist (if it were, say "0", then a dropdownlist would be picked).

The "ReferralRadioButtonPost" is just a way to display the user selection later (like in a confirm page or on a details page).

I am over thinking this probably (i.e., hopefully its a simple conversion), but I am not sure how to create the Part and PartRecord for the above, particularly because of the type of code I am using (i.e., its not a simple string that I can just put virtual on and then create get/set the way you do with a Part).

Thanks for any advice.

Developer
Oct 29, 2012 at 9:18 AM

If I got this straight, the RefferalSelectorAttribute is an attribute that you can decorate properties on a class with. In your case, you have a Selector class with a ReferralRadioButtonPost property. You have created some EditorTemplates to help rendering the editor for instances of the Selector class and its properties.

Seems like all you would need to do is create a SelectorPart class with the same properties as your Selector class, including the attributes. From the Editor shape template, simply use the Html.EditorForModel helper so that it will render your Selector.cshtml (rename it to SelectorPart.cshtml or specify the template name using the overloaded version).

 

Oct 31, 2012 at 3:55 AM
Edited Oct 31, 2012 at 3:57 AM

Sorry for being dense @sfmskywalker. I've actually been trying to understand your WebShop series - it's top-notch. My problem is, I cannot grasp Orchard's complexity (I get that it's worth the grasping). Your series does a great job explaining it, and I'm using the code to learn. But I cannot break it down and create something simple (there's a lot of good stuff going on in there, I see). What I'm torturing myself doing is trying to learn something complicated by using something complicated. The Docs cover mainly Admin hooks, and I'm trying to do the same for site users.

I'm gonna keep trying though ;).

Developer
Oct 31, 2012 at 8:10 PM

Thanks. Yes it can be challenging, but it gets easy once it clicks. Ok just let us know if you have specific questions and keep it up.

Nov 1, 2012 at 10:05 PM
Edited Nov 1, 2012 at 10:21 PM

@sfmskywalker, going back to my original question and your original response:

Could you suggest how I can convert the above code to part/partrecord? I am getting an NHibernate error that column name is not valid on the Admin page, and in the back end I get a namespace error if I don't type out MyNamespace.Models.MyPartRecord before the Referral? ReferralRadioButton.

I am stumped. Here is what I tried to do in MyPartRecord.cs:

 

        public enum Referral
        {
            [Display(Name = "Recent Postcard Mailing")]
            Mailing,
            [Display(Name = "Google / Google+")]
            Google,
        }
        public class ReferralSelectorAttribute : SelectorAttribute
        {
            public override IEnumerable<SelectListItem> GetItems()
            {
                return Selector.GetItemsFromEnum<Referral>();
            }
        }
        [Required(ErrorMessage = "Please select one referral option")]
        [Display(Name = "How did you hear about us?", Description = "Letting us know how you reached us helps us to focus our advertising efforts and ultimately lowers costs")]
        [ReferralSelector(BulkSelectionThreshold = 3)]
        public virtual Referral? ReferralRadioButton { get; set; }
        //
        // POST ReferralRaduiButton
        [ReferralSelector]
        [ReadOnly(true)]
        public virtual Referral? ReferralRadioButtonPost
        {
            get { return ReferralRadioButton; }
        }

 

And then in the Part.cs file I have:

 

        //Is this necessary?
        public MyPart()
        {
            Record = new MyPartRecord();
        }

        public MyNamespace.Models.MyPartRecord.Referral? ReferralRadioButton // or ReferralRadioButtonPost
        {
            get { return Record.ReferralRadioButton; } // or ReferralRadioButtonPost?
            set { Record.ReferralRadioButton= value; } // or ReferralRadioButtonPost?
        }

For the moment, note that I use the ReferralRadioButtonPost to display back the selected radio button item on screen.  Also, remember that I had to do MyNamespace.Models.MyPartRecord because I was getting a namespace error.

Any advice is much appreciated (and will earn you 100 all new Disney Force Points (TM), redeemable at any Disney themed Star Wars attraction (coming soon!)).

Developer
Nov 2, 2012 at 2:03 AM

Could you try and move the nested enum and attribute definition out of your record class?

You definitely should not new up a record instance from your part's constructor, it will cause an exception in another part when the content item is about to be published. I think it's the StorageFilter's responsibility to new up a record.

When you still get exceptions, please provide the exact exception details + stack trace.

I am definitely in for the Force Points!