Accessing Custom Fields inside a CSHTML file

Feb 2, 2011 at 1:52 AM

I modified the Page content type and added a custom field called BackgroundUrl.  I then created a placement.info file in my theme to supress displaying this in the page content.  Now I want to access this custom field inside Layout.cshtml such as:

@ {

    var contentStyle = "";
    if (Model.Meta.BackgroundUrl != null)
    {
        contentStyle = "style='background-image:url(" + Model.Meta.BackgroundUrl + "); background-repeat: no-repeat;'";
    }

}

....

<div id="content" @contentStyle>

 

Obviously Model.Meta.BackgroundUrl does not work, so what is the syntax to get to that custom field?

Feb 3, 2011 at 5:06 AM

I am still struggling with this.  When I try to explore the Model object using the debugger I can't get very far.

Coordinator
Feb 3, 2011 at 11:57 PM

This example is for a ProfilePart, having a field of type ImageField.

 

@using Orchard.ContentManagement;
@using Contrib.Profile.Models;
@using Contrib.ImageField.Fields;

@{
       var contentItem = (ContentItem)Model.ContentItem;
       var picture = (ImageField)contentItem.As<ProfilePart>().Fields.First(f => f.Name == "Picture");
}

@picture.Width @picture.Height

Feb 6, 2011 at 9:12 AM

Where do I find Contrib.Profile.Models? I installed the profile module but there is no code for Models. I want to add custom fields to the ProfilePart and access it like your showing here, but I don't know where the model is for ProfilePart. I feel like I'm really missing something simple here.

Feb 6, 2011 at 11:35 AM

I was able to get what I was after by doing this:

var accountCode = (TextField)user.ContentItem.Parts.First(p => p.PartDefinition.Name == "User").Fields.First(f => f.Name == "AccountCode");

Is there a better way to do this or is this fine? I figure I can edit the User content type and add whatever fields I want to control there and anything I want the user to be able to edit I can put in the Profile part. One question though, why do I now have a User-2 part?

Feb 6, 2011 at 1:14 PM

So adding fields to the User content type isn't a good idea it turns out. So I've tried creating a PrivateProfilePart and adding it to the User type, but it gets displayed with everything else, so I tried to create a placement.info file to remove it but it still gets displayed. I saw an example of this somewhere but I can't seem to find it now. This is what I tried in the Contrib.Profile module in Placement.info

<Placement>

    <Place Parts_PrivateProfile="-"/>

</Placement>

Feb 8, 2011 at 4:37 AM

I tried what you said.  In layout.cshtml, Model.ContentItem is null.  I added a field to page, and need to access this field from inside Layout.cshtml.  Any help?

 

@using Orchard.ContentManagement;
@using Orchard.Core.Common.Fields;
@{
    Style.Include("styles.css");
    Style.Include("Orchard.css");

    Func<dynamic, dynamic> Zone = x => Display(x);

    Model.Id = "container";
    var tag = Tag(Model, "div");

    var contentStyle = "";
    var contentItem = (ContentItem)Model.ContentItem;
    // contentItem is null here....
    var backgroundUrl = (TextField)contentItem.Parts.First(p => p.PartDefinition.Name == "Page").Fields.First(f => f.Name == "BackgroundUrl");
    if (backgroundUrl != null)
    {
        contentStyle = "style='background-image:url(" + backgroundUrl + "); background-repeat: no-repeat;'";
    }

   
}

Apr 23, 2011 at 4:31 PM

Using dynamic types like this really doesn't make debugging and figuring problems like this out easy! I'm not promising this is the best solution, but it works for me. In Content.cshtml (or the content item specific version if you have one in your theme, for the conent item you are displaying), add something like the following:

    // I created a custom field called StrapLine
    var strapLineField = ((Orchard.ContentManagement.ContentItem)Model.ContentItem).Parts.SelectMany(p => p.Fields).Where(f => f.Name == "StrapLine").FirstOrDefault();
 
    if ( strapLineField != null )
    {
        WorkContext.Layout.StrapLine = strapLineField.Storage.Get<string>(null);
    }

You will then be able to access the StrapLine field in Layout.cshtml:

    @if ( Model.StrapLine != null ) {
        @Zone(Model.StrapLine)
    }

Hope this helps.

Jul 5, 2011 at 5:01 PM

Wouldn't be nice if there was a convention / simple helper method / syntax that would allow us to access field values no matter what the name of the ContentType is?

Coordinator
Jul 5, 2011 at 11:30 PM

Not sure what you are talking about: there is a simpler method since 1.1. Shape tracing even gives you the syntax (look at the Model tab).

Jul 6, 2011 at 2:12 AM
Edited Jul 6, 2011 at 2:12 AM

I've been spending the whole day writing Orchard tutorials for folk WITH html skills but NOT developer skills (I will post them soon). Tomorrow is my first day of Orchard training with my first client.

I've also been looking at WebMatrix quite a bit, and a lot of what I would love to see in Orchard is in there. For example their syntax for the twitter "Helper" in the web matrix intro movie @Twitter.Search("xxxxxxxxx", "xxx", "xxxx").

How can I explain to someone non technical how to render a field value at the moment?