Custom Part Developing Question

Topics: Customizing Orchard, Writing modules
Jun 2, 2011 at 7:58 PM
Edited Jun 3, 2011 at 8:27 AM

Hello everyone.
I am trying to learn custom developing with Orchard with creating a Profile part that stores a UserID.
The ProfilePart Record has only a UserID property.
When this part is displayed through a content I want to show the users username and a some custom fields (FirstName, LastName, Address) I have added to the User Content type. 
So now I have a ProfileDriver which exposes the ProfilePartModel with only the UserID property

   protected override DriverResult Display(ProfilePart part, string displayType, dynamic shapeHelper)        {
            return ContentShape("Parts_Profile",
                 () => shapeHelper.Parts_Profile(
                 UserID: part.UserID));        }

But I want to expose the values of the whole User Content object with the given UserID. What is the right approach?
If I should guess I would create a ViewModel which exposes the properties Username,FirstName,LastName,Address which will be filled by the values in the User Content object that is instantiated from the UserID property in the ProfilePartRecord. 
But how do I wire up the ViewModel object in the driver? And where will I do the instantiating of the user object?

Jun 5, 2011 at 10:02 AM

Anyone has any thoughts on this?

I'm not expecting anyone to do implement this for me, I just want to do it right

Jun 5, 2011 at 1:02 PM

Hi there,

look at my module:

It depends on the Contrib.Profile module which allows you to extend the User object with Custom Parts.
My module then exposes these custom parts to the standard registration page.
If you look at the code, you will see how this works.
Look at the AccountController (Register actions). 

Jun 6, 2011 at 2:24 PM

@Martin: The easiest way would be to create a separate property on your part (eg. IUser User { get; set; }), which will be filled with an appropriate user object when the part is loaded. This property won't be stored in db, so add it only to your part object. Then, inject IContentManager in your part's handler's ctor, and do something like this:

OnLoaded<ProfilePart>((ctx, part => { part.User = _contentManager.Get<IUser>(part.UserID); })

Now, you will have your user property filled with the user content item and you can use that inside driver to fetch all data you need to fill the ViewModel. Btw, Orchard by default holds only the Username and E-mail, so you would have to use some other module that adds more profile fields (eg. Profile by Sebastien Ros).

So, summarizing - all instantiation of properties on content parts should happen inside content handler (OnLoading/OnLoaded events). This will ensure that every piece of code (eg. driver) using your part will get the fully-loaded object.

Jun 6, 2011 at 6:04 PM

thanks a lot both of you!