Model.Content is never null

Topics: Troubleshooting, Writing themes
Feb 18, 2013 at 4:15 AM
Hello -

I am trying to create a home page that has a different layout than the rest of the site. Easy enough if I could just get Model.Content to be null. I created a Page and set it as the home page. I went to TheHomePage layer and made sure that no widgets were enabled in the Content zone. I assumed this would make Model.Content equal to null. The content markup is rendering regardless. I even tried to create a new content type without including body in the Parts. I am totally at a loss here and must admit feeling pretty dumb :)

layout.cshtml
@if (Model.Content != null)
{
<div id="layout-content" class="group">
    <div id="content" class="group">
        @Zone(Model.Content)
    </div>
</div>
}

Thank you for the help,

Jordan
Coordinator
Feb 18, 2013 at 7:30 AM
Why don't you enable url alternates and create layout-url-homepage.cshtml?
Feb 18, 2013 at 9:28 AM
Try:

@if (HasText(Model.Content))
Feb 18, 2013 at 1:53 PM
Edited Feb 18, 2013 at 1:56 PM
I will take a look at the URL alternates. Is there a web site resource you would recommend?

Thanks,

Jordan
Feb 18, 2013 at 1:57 PM
HasText()... duh :) Ill give that one a go. I think I may still run into some meta tag info issues but i'll check those out as well.
Feb 19, 2013 at 4:01 AM
Apparently it has text and I have been struggling to get multiple layouts to work.
Coordinator
Feb 19, 2013 at 5:17 AM
I'll repeat my question: "Why don't you enable url alternates and create layout-url-homepage.cshtml?"
Feb 20, 2013 at 2:45 AM
I do not know how to do that. That would be ideal. I have tried a couple of methods I found but have not been able to get them to work. Do you have a good reference you would recommend?

Jordan

On Feb 18, 2013, at 10:17 PM, "bertrandleroy" <notifications@codeplex.com> wrote:

From: bertrandleroy

I'll repeat my question: "Why don't you enable url alternates and create layout-url-homepage.cshtml?"
Developer
Feb 20, 2013 at 8:57 PM
Just to be sure: you don't know how to enable the Url Alternates feature, or you do but it does not work?
Coordinator
Feb 21, 2013 at 2:18 AM
Go to "modules" in the admin, look for url alternates, and enable it. Then create a template called layout-url-homepage.cshtml under the views folder of your theme. I don't know why you'd need a reference, or a reference of what. Maybe this? http://docs.orchardproject.net/Documentation/Alternates
Feb 21, 2013 at 5:27 AM
Not sure how to do it. I played with some module for it but it didn't work out. I also tinkered with some other class but that didn't turn out well either.

Thanks

Jordan

Sent from my iPhone

On Feb 20, 2013, at 1:57 PM, "sfmskywalker" <notifications@codeplex.com> wrote:

From: sfmskywalker

Just to be sure: you don't know how to enable the Url Alternates feature, or you do but it does not work?
Feb 21, 2013 at 5:27 AM
I give this a try tomorrow. Thanks for all of your guidance on this.

Sent from my iPhone

On Feb 20, 2013, at 7:18 PM, "BertrandLeRoy" <notifications@codeplex.com> wrote:

From: BertrandLeRoy

Go to "modules" in the admin, look for url alternates, and enable it. Then create a template called layout-url-homepage.cshtml under the views folder of your theme. I don't know why you'd need a reference, or a reference of what. Maybe this? http://docs.orchardproject.net/Documentation/Alternates
Feb 22, 2013 at 5:06 AM
That was ridiculously easy. Thank you BertrandLeRoy.



On Wed, Feb 20, 2013 at 10:27 PM, Jordan Papaleo <papaleobus@gmail.com> wrote:
I give this a try tomorrow. Thanks for all of your guidance on this.

Sent from my iPhone

On Feb 20, 2013, at 7:18 PM, "BertrandLeRoy" <notifications@codeplex.com> wrote:

From: BertrandLeRoy

Go to "modules" in the admin, look for url alternates, and enable it. Then create a template called layout-url-homepage.cshtml under the views folder of your theme. I don't know why you'd need a reference, or a reference of what. Maybe this? http://docs.orchardproject.net/Documentation/Alternates

Read the full discussion online.

To add a post to this discussion, reply to this email (orchard@discussions.codeplex.com)

To start a new discussion for this project, email orchard@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Feb 5 at 12:21 PM
Edited Feb 5 at 12:22 PM
I have same question @breck421 had: Why Model.Content is never null ? How can I detect in the layout that content has nothing to show?
I'm using Orchard 1.7.1

The point is URL alternates are not a solution for me because the only condition to change the way a page is rendered is it doesn't have any content in Content Zone. There is not other concrete conditions like only for HomePage. It is for any page where the user is interested on having two blocks of the same width in the middle of the page.

This is the code I want to make work in my layout.cshtml:
                @{               
                    int asideWidth = Model.Content == null ? 6 : 4;
                    int asideColumns = (Model.AsideFirst != null ? 1 : 0) + (Model.AsideSecond != null ? 1 : 0);
                }
                <div class="row page" id="@(pageStyle)">                     
                    @if (Model.AsideFirst != null)
                    {                                        
                        <div class="@("col-md-" + asideWidth +" col-left")">
                            @Display(Model.AsideFirst)
                        </div>
                    }
                    @if (!Model.Content == null)
                    {                        
                        <div class="@("col-md-" + (12 - (asideColumns * 4)) + " col-left")">
                            @Display(Model.Content)
                        </div>
                    }
                    @if (Model.AsideSecond != null)
                    {
                        <div class="@("col-md-" + asideWidth +" col-right")">
                            @Display(Model.AsideSecond)
                        </div>
                    }
                   </div>   
Do you know any workaround for finding out if there's any content in Content zone from the layout?
Feb 5 at 4:54 PM
Maybe you are wondering how is that the user can have different with Content Zone empty. The reason is I let the administrator to set the placement.info file from the administration area and he can do something like this to remove content from the Content Zone:
  <Match ContentType="Company">
    <Place Parts_CarruselWidget="/AsideFirst:1"/>
    <Place Fields_Common_Text__Lema="/AsideFirst:2"/>
    <Place Parts_Common_Body="/AsideSecond:1"/>    
    <Place Parts_Common_Metadata="-"/>      
  </Match>
Developer
Feb 5 at 5:01 PM
The reason most likely is because the Content zone contains at least one shape. You could attach a debugger and set a breakpoint right where the Content zone is being rendered and inspect its model. Finding out which shapes are contained by the Content zone may offer a hint from where these shapes came, which should give some insight on how to proceed next in terms of not rendering the Content zone.
Feb 5 at 11:51 PM
Thank you @smskywalker

I did it but I didn't get nothing clear. These are the values I get:

Model.Content.Metadata.Type="Zone"
Model.Content.Items.Count=1
Model.Content.Items[0].Metadata.Type="PlaceChildContent"
Model.Content.Items[0].Items.Count=0

It fits with what is done in Discover method in Orchard.Core.Shapes.CoreShapes class:
        public void Discover(ShapeTableBuilder builder) {
            // the root page shape named 'Layout' is wrapped with 'Document'
            // and has an automatic zone creating behavior
            builder.Describe("Layout")
                .Configure(descriptor => descriptor.Wrappers.Add("Document"))
                .OnCreating(creating => creating.Create = () => new ZoneHolding(() => creating.New.Zone()))
                .OnCreated(created => {
                    var layout = created.Shape;
                    
                    layout.Head = created.New.DocumentZone(ZoneName: "Head");
                    layout.Body = created.New.DocumentZone(ZoneName: "Body");
                    layout.Tail = created.New.DocumentZone(ZoneName: "Tail");

                    layout.Body.Add(created.New.PlaceChildContent(Source: layout));

                    layout.Content = created.New.Zone();
                    layout.Content.ZoneName = "Content";
                    layout.Content.Add(created.New.PlaceChildContent(Source: layout));

                });
It looks that at layout.cshtml processing time Orchard still is not able of known if Content Zone will have data or not. Am I wrong?
Feb 6 at 8:53 AM
Edited Feb 6 at 8:54 AM
@smsskywalker you were right :)

Model.Content returns Null adding to placement this:

<Place Parts_Contents_Publish="-"/>

Thank you
Feb 6 at 9:15 AM
Edited Feb 6 at 9:15 AM
Sorry I did a mistake checking it.
Maybe it was my desire of seeing it solved. It doesn't work :(
Same result I'm not able of finding out when Content Zone has shapes to render or not from the layout.cshtml
Developer
Feb 6 at 10:28 AM
Edited Feb 6 at 10:28 AM
Well, there you go: that shape table provider adds a PlaceChildContent shape to the Content zone, so that zone will never be null.
One suggestion may be to add a check for the Content zone and treat it as if it were null if it only contains one shape (PlaceChildContent) which itself contains 0 shapes. However, I did something similar a looooong time ago, and I still feel dirty for having done that. Better to find another way around your requirement.
Feb 6 at 12:09 PM
I tried also that dirty thing (less dirty if it would work :) )

The problem is no matter if I browse to a page with or withoyt content in Content Zone I always get the same result:

Model.Content.Metadata.Type="Zone"
Model.Content.Items.Count=1
Model.Content.Items[0].Metadata.Type="PlaceChildContent"
Model.Content.Items[0].Items.Count=0
Feb 6 at 8:36 PM
Edited Feb 6 at 8:37 PM
@sfmskywalker do you think your solution was a bit dirty? Wait to see what finally have worked to me:
bool contentZoneIsEmpty = this.Layout.Metadata.ChildContent.ToString().TrimStart() == "";
This is dirty ;)

Regards!
Developer
Feb 6 at 9:36 PM
Edited Feb 6 at 9:36 PM
OMG you must be taking showers 4 times a day after having written and executed THAT! ;)
Cheers!