orchardcmscontenttypes

Orchard CMS - Extending Users with Fields - exposing values in Blog Post


I'd like to extend the users content definition to include a short bio and picture that can be viewed on every blog post of an existing blog. I'm unsure of what the best method to do this is.

I have tried extending the User content type with those fields, but I can't seem to see them in the Model using the shape tracing tool on the front end.

Is there a way to pass through fields on the User shape in a blog post? If so, what is the best way to do it?


Solution

  • I also have done this a lot, and always include some custom functionality to achieve this.

    There is a way to do this OOTB, but it's not the best IMO. You always have the 'Owner' property on the CommonPart of any content item, so in your blogpost view you can do this:

    @{
        var owner = Model.ContentItem.CommonPart.Owner;
    }
    
    <!-- This automatically builds anything that is attached to the user, except for what's in the UserPart (email, username, ..) -->
    <h4>@owner.UserName</h4>
    @Display(BuildDisplay((IUser) owner))
    
    <!-- Or, with specific properties: -->
    <h1>@T("Author:")</h1>
    <h4>@owner.UserName</h4>
    <label>@T("Biography")</label>
    <p>
        @Html.Raw(owner.BodyPart.Text)
    </p>
    <!-- <owner content item>.<Part with the image field>.<Name of the image field>.FirstMediaUrl (assuming you use MediaLibraryPickerField) -->
    <img src="@owner.User.Image.FirstMediaUrl" />
    

    What I often do though is creating a custom driver for this, so you can make use of placement.info and follow the orchard's best practices:

    CommonPartDriver:

    public class CommonPartDriver : ContentPartDriver<CommonPart> {
    
        protected override DriverResult Display(CommonPart part, string displayType, dynamic shapeHelper) {
            return ContentShape("Parts_Common_Owner", () => {
                if (part.Owner == null)
                    return null;
    
                var ownerShape = _contentManager.BuildDisplay(part.Owner);
                return shapeHelper.Parts_Common_Owner(Owner: part.Owner, OwnerShape: ownerShape);
            });
        }
    }
    

    Views/Parts.Common.Owner.cshtml:

    <h1>@T("Author")</h1>
    <h3>@Model.Owner.UserName</h3>
    
    @Display(Model.OwnerShape)
    

    Placement.info:

    <Placement>
      <!-- Place in aside second zone -->
      <Place Parts_Common_Owner="/AsideSecond:before" />
    </Placement>