orchardcmsorchardcms-1.7orchard-modules

Unable to read Title of TitlePart | Orchard CMS 1.7 |


This is in reference and related to my previous question here.

I am trying to read the Title of the part TitlePart as seen below code:

var query = Services.ContentManager.Query("SideBarLinks").List();
foreach (var sideBarLinks in query)
        {
            foreach(var part in sideBarLinks.Parts)
            {
                if (part is Orchard.Core.Title.Models.TitlePart)
                {
                    // Below Line throws error
                    //string title = part.Title;
                }
            }
        }

Each ContentPart has a title in orchard. So for the TitlePart, Iam trying to read the Title. Also is there any similar property that can be accessed like part.Name ?

Checked the code as well and there is a Public Title property as seen below:

enter image description here


Solution

  • Not all content types have the TitlePart attached. You can check this in your dashboard, and see if your content type has indeed the title part attached to it. For example, the Page content type:

    enter image description here

    In code you can check like this if the content item has a title part:

    var query = Services.ContentManager.Query("SideBarLinks").List();
    foreach (var sideBarLinks in query) {
        // Cast to TitlePart
        var titlePart = sideBarLinks.As<TitlePart>();
        var title = titlePart != null ? titlePart.Title : string.Empty;
    
        // Or:
        // var title = sideBarLinks.Has<TitlePart>() ? sideBarLinks.As<TitlePart>().Title : string.Empty;
    }
    

    The safest and recommended way though to get the display text of a content item, is to use the item metadata:

    var query = Services.ContentManager.Query("SideBarLinks").List();
    foreach (var sideBarLinks in query) {
        // Get display text of the item
        var title = Services.ContentManager.GetItemMetadata(sideBarLinks).DisplayText;
    }
    

    This has multiple advantages. First one being that you don't have to check for the title part, the method itself will take care of that. Another advantage is that you can override what you want to display as the title. Say you have a Movie content type, and you want the title to be displayed as "Some Movie Title (2001)". The only thing you then have to do is implement the ITitleAspect in your custom part:

    public class MoviePart : ContentPart<MoviePartRecord>, ITitleAspect {
    
        // Shortcut to get the title
        public string MovieTitle {
            get { return this.As<TitlePart>().Title }
        }
    
        public int ReleaseYear {
            get { return Retrieve(x => x.ReleaseYear); }
            set { Store(x => x.ReleaseYear, value); }
        }
    
        // other properties
    
        // Implement Title from ITitleAspect
        public string Title {
            get { return string.Format("{0} ({1})", MovieTitle, ReleaseYear); }
        }
    }
    

    The GetItemMetadata(theMovie).DisplayText of this item will then return the formatted title;