Is there a way to loop through every fields in Model.Content?

Topics: Writing themes
Mar 31, 2011 at 9:21 AM

I  mean... in Content.cshtml we have @Display(Model.Content), and that return all the views of the fields and parts that are binded to that content right?

So... we only can change the html in the views of that fields or parts, right?

But... i want to take over the html structure.. i want to do something like this:

 

foreach(ContentField field in Model.Content)

{

if(field.name == "ImageDetail")

{

@<div class="image">

<img src="field.path" alt="field.name"/>

</div>

<div>

<p>field.name</p>

</div>

}

}

Is this possible? i dont know how to do it... :S

Mar 31, 2011 at 10:21 AM

The way it works is completely different from that; so basically, no you can't.

But what you can do is override the template for the ImageDetail field. Or any other part of the display.

Really you need to be using 1.x source branch, so you get the "Shape Tracing" feature. You can mouse over the part of the page and see a list of alternate / override template names (with a Create button to handily clone the corresponding view).

Mar 31, 2011 at 11:00 AM

Thanks for the replay!

Yes, i already test shape tracing and it's really helpfull.

And yes i already override the field views.

I'm sad that is not possible to do what i want...

Mar 31, 2011 at 12:05 PM

What I meant was that "foreach(ContentField field in Model.Content)" isn't possible because that's not what the model looks like.

But it's possible to customise any part of the template, how you do it depends on exactly what you're trying to achieve. If you give some more information on how and why you want to change the HTML structure then maybe someone can help you.

For instance it's very easy if you just want to change the ordering of fields, you don't have to override any templates at all; you can just use a Placement.info.

Mar 31, 2011 at 12:35 PM

Ok, i'll give you one example.

I create a ContentType News, that have:
 - Image Field (ImageList),
 - Image Field (ImageDetail),
- DateTime Field (Date)
 - Html Field (Resume)
 - Html Field (Text)

And i override the views for this fields im my theme using placement.info for ordering them in case of DisplayType summary or detail.

Html in the fields views

Image -> <div><img src="#" title="" /><div/>

Date -> <span>10/12/2008</span>

Html -> <div class="cleanStyle"><p>here is some text!</p></div>

 

Ok, now i creat one list and many Item News(ContentType News) related do this new list.

And i see them on the List like this:

ImageList
ImageDetail
Date
Resume
Text

===================

That is what @Display(Model.Content) return to that item...

===================

What i want to do is replace this:

ImageList
ImageDetail
Date
Resume
Text

By this:

<div class="Item">

ImageList

<div class="textElements">

Date
Resume

</div>

</div>

Somehow looping into @Model.Content

Mar 31, 2011 at 1:01 PM
Edited Mar 31, 2011 at 1:03 PM

Ok, I get it more now.

The important thing is to forget about manually looping through any part of Model.Content; the way Orchard has been set up is so you don't have to do that. If you replaced the whole of Content.cshtml then you lose out on all the benefits of Orchard, such as the ability to add modules at a later stage that will supplement your existing layout.

All you need to do is override Content.cshtml with your preferred markup, and rearrange its Display calls how you want them:

 

@using Orchard.Utility.Extensions;
@{
    if (Model.Title != null) {
        Layout.Title = Model.Title;
    }
    var contentTypeClassName = ((string)Model.ContentItem.ContentType).HtmlClassify();
}
<div class="Item @contentTypeClassName">
    @Display(Model.Header)
    @Display(Model.Content)

    <div class="textElements">
        @Display(Model.Meta)
        @Display(Model.Footer)
    </div>
</div>

 

Then you can use Placement.info to send whichever shapes you want to the Header, Content, Meta and Footer local zones of that template. If you don't want the ImageDetail shape, you can remove it by sending it to "-" position also in Placement.info.

Edit: I just looked again at your OP and that's not quite what you want to do. But you get the general idea. If you like you can use a whole new local zone such as @Display(Model.TextElements) if you want finer control over everything.

Mar 31, 2011 at 9:35 PM

Sorry for delay...

I think i undertand you now! And i manage to do it, but still... due the fact that in this version of orchard (1.0.20) that's not possible to select fields by name in the placement.info i have to duplicate the field module and rename it for full control in placement.info if i need to have multiple fields of same type. I know that the new version has this issue resolved.

Thank you very mutch for your replay!

I Get it ;) =D

Coordinator
Mar 31, 2011 at 9:42 PM

Yeah, it's not really that you can't, it's that you shouldn't :)

May 10, 2011 at 6:10 PM

I'm using Orchard 1.1.30 and when I defined local zones all values of specifiec field are displaying in last defined zone. e.g.

<Match ContentType="Clinic">
<Match DisplayType="Detail">
<Place Fields_Common_Text__Nazwa="Name" />
<Place Fields_Contrib_Html__Contact="Contact" />
<Place Fields_Contrib_Html__OpeningHours="OpeningHours" />
<Place Fields_Contrib_Html__Payment="Payment" />
<Place Fields_Contrib_Image="Logo" />
<Place Parts_BingMap="Map" />
</Match>
</Match>

All HTML fields are displaying in Payment zone and all Images are displaying in Logo zone.
P.S. I have modified HTML fields. I add differentiator in field driver.
Coordinator
May 10, 2011 at 8:02 PM

It should really be this:

<Match ContentType="Clinic">
  <Match DisplayType="Detail">
    <Place Fields_Common_Text-Nazwa="Name" />
    <Place Fields_Contrib_Html-Contact="Contact" />
    <Place Fields_Contrib_Html-OpeningHours="OpeningHours" />
    <Place Fields_Contrib_Html-Payment="Payment" />
    <Place Fields_Contrib_Image="Logo" />
    <Place Parts_BingMap="Map" />
  </Match>
</Match>

And all fields need to have a driver that provides the differentiator to use (i.e. the field name).

May 10, 2011 at 8:39 PM

Thank you, now it's work.