A Simple Customer Page

Topics: Customizing Orchard, General, Writing modules
Dec 29, 2011 at 4:20 PM

 

This is probably really easy to do, but I am finding it difficult. I have created a Content Type called Client. It has 2 added fields. One is called ClientImage and the other is ClientUrl. It also has the parts of Common, Custom Properties, Route, Containable and Body.

I have created a list called ClientList and populated it with newly created Client entries. I am displaying this list in a Widget in the AsideFirst section of the Widget filtering on one of the Custom One field that I have populated.

My first goal is to have this list in the AsideFirst section, like it is displaying vertically, sorted acsending by the Title., and have the Client's Body in the Content or AsideSecond section when the user clicks on a Client in the list. Think in the lines of the old HTML Frames where the left hand frame is always visible and the right hand frame changes according to the left frames selection.

My second goal is to have a page or widget that displays the Images from the ClientList, determined by the field ClientImage from the Clients in a horizontal listing of 4 clients per row.

Am I missing an easy way to do these using straight Orchard procedures, or will I need to create custom modules to do this?

Thanks for the help.

Dec 29, 2011 at 4:39 PM

All you should need to do is use Placement.info to determine which parts and fields to display in Summary mode. You'd use:

<Match ContentType="Client" DisplayType="Summary"><Place ...>

So you can display the image field for your clients when you click on a ClientList.

Dec 29, 2011 at 7:13 PM

I don't think that that solves my two goals.

First Goal:

This is the section
with the list in
AsideFirst
This is the section with the selected Client's body
in AsideSecond
ABC Company The ABC Company provides...
DEF Company  
XYZ Company  

Second Goal (using ClientList):

Client Image
Client1 Name
Client Image
Client2 Name
Client Image
Client3 Name
Client Image
Client4 Name
Client Image
Client5 Name
Client Image
Client6 Name
Client Image
Client7 Name
Client Image
Client8 Name
Client Image
Client9 Name
Client Image
Client10 Name
Client Image
Client11 Name
Client Image
Client12 Name
Dec 30, 2011 at 1:13 PM

Yes, you can achieve all of that with Placement and with CSS styling. What have you tried so far and what has it produced?

Dec 30, 2011 at 5:02 PM
  • Created a Content Type called Client with 2 fields ClientUrl (not being used) and ClientImage. It has Parts consisting of Common, Custom Properties, Route, Containable and Body. This shows up under New in the Dashboard menu.
  • Created a new List called ClientList and added several Clients to it using the Custom 1 field for the department name. 
  • Created a new page called ClientsAll and made it a Widget.
  • Added a Container Widget to the AsideFirst section and selected the ClientsList in the Show Items From dropdown. Ordered By Title Acending and Filtering by Custom 1=accounting (to only display the accounting clients).

My Placement.info file has the following:

  <Match Content-Type="Client">
    <Match DisplayType="Detail">
      <Place Parts_Common_Body="Content:before"
             Parts_Tags_ShowTags="Content:after"
             Parts_Comments="Footer"
             Parts_Common_Metadata="Nowhere"/>
    </Match>
    <Match DisplayType="Summary">
      <Place Parts_Common_Body_Summary="-"
             Parts_Comments_Count="Nowhere"
             Parts_Tags_ShowTags="Nowhere"
             Parts_Common_Metadata_Summary="Nowhere"
             Fields_Common_Text="Nowhere"
             Parts_Common_Metadata="Nowhere"
    </Match>
  </Match>

When I view the ClientsAll page, I get the list going down the left side as expected, the right hand side has the page title of the ClientsAll page and body.

What my goal is, is to have the menu stay on the left at all times, but the right side change to the Client's "body" that was selected from the menu (List) on the left side. Think of the left as a menu (but using the List and not the Navagation) and the right displaying the contents of the item (client) selected from that menu.

Any help I can get on setting up the Placement.info file or if there is another approach to this that I am missing is much appreciated.

Kim

Jan 4, 2012 at 7:01 PM

Anyone want to chime in on this? Any help would be appreciated.

Jan 4, 2012 at 7:03 PM

Firstly there shouldn't be a hyphen in ContentType, should be:

<Match ContentType="Client">

Secondly you're applying multiple placements in a single tag, I don't actually know whether that will or won't work, but usually I use a separate <Place> element for each placement.

Thirdly there's no zone called "Nowhere", use the "-" instead to hide things.

So try those fixes then let us know how you're getting on.

Jan 4, 2012 at 10:18 PM

Thanks for getting back to me. I removed the hyphen from the word ContentType and changed my Place tags. So the Placement.info now looks like this:

<Placement>
  <!-- Customize where the shapes are rendered  -->
  <!-- Remove the page title from the homepage   -->
  <Match Path="~/">
    <Place Parts_RoutableTitle="-"/>
  </Match>

  <!-- Remove metadata part from all pages and from blogs -->
  <Match ContentType="Page">
    <Place Parts_Common_Metadata="-"/>
  </Match>

  <Match ContentType="Client">
    <Match DisplayType="Detail">
      <Place Parts_Common_Body="Content:before"/>
      <Place Parts_Tags_ShowTags="Content:after"/>
      <Place Parts_Comments="Footer"/>
      <Place Parts_Common_Metadata="-"/>
    </Match>
    <Match DisplayType="Summary">
      <Place Parts_Common_Body_Summary="-"/>
      <Place Parts_Comments_Count="-"/>
      <Place Parts_Tags_ShowTags="-"/>
      <Place Parts_Common_Metadata_Summary="-"/>
      <Place Parts_Common_Metadata="-"/>
      <Place Fields_Contrib_TaxonomyField-ClientImage="-"/>
    </Match>
  </Match>

  <Match ContentType="Blog">
    <Place Parts_Common_Body_Summary="Content"/>
    <Place Parts_Common_Metadata="-"/>
  </Match>

  <!-- Remove comment counts from blog posts and set the summary blog post body alternate -->
  <Match ContentType="BlogPost">
    <Place Parts_Comments_Count="-"/>
    <Match DisplayType="Summary">
      <Place Parts_Common_Body_Summary="Content"/>
    </Match>
  </Match>
</Placement>

It made no difference.  So now I am trying a different approch:
I have created an alternate file called Content-url-client-list.Detail.cshtml  page using the Designer Tools and it is located in my themes View folder.  This is what I have done to alter it. Please see the notes in it to see if it is possible to do what I want it to do. Keep in mind, this is the detail page for the Client.

@using Orchard.Utility.Extensions;
@{
    if (Model.Title != null) {
        Layout.Title = Model.Title;
     }
    var contentTypeClassName = ((string)Model.ContentItem.ContentType).HtmlClassify();
}
<div id"main_container">
    @*This left column div should display the contents of my
    ClientList List*@
    <div id="leftcolumn">
        <article class="widget-container-widget widget">
            <header>
                <h1 class="widget-title">Clients</h1>
            </header>
            @*
            @Display(?????) <===== I need to have my List displayed in here
                                                   Can it be done? Is there some code out
                                                   there to render the list in this section?
            *@
            <footer>
            </footer>
        </article>
    </div>

    @*This rightcolumn div displays correctly, no need to change anything here.*@
    <div id="rightcolumn">
        <article class="content-item @contentTypeClassName">
            <header>
                @if (Model.Meta != null) {
                <div class="metadata">
                    @Display(Model.Meta)
                </div>
                }
            </header>
            @Display(Model.Content)
            @if(Model.Footer != null) {
            <footer>
                @Display(Model.Footer)
            </footer>
            }
        </article>
    </div>
    @*This last div clears the float left from the css style
    set up for the 2 div tags above.*@
    <div class"clear"></div>
</div>

Please look at the commented section in the “leftcolumn” div as to what I would like to do.

Thanks,

Kim

Jan 5, 2012 at 7:41 PM

Is there a way to do the above post? Sorry, I am new to Orchard and up against a deadline with this project.

I tried inserting the following code in the commented section of the div tag, but I only get errors on the page

@using Orchard.ContentManagement; <----- this was inserted under the using Orchard.Utility.Extensions; at the top of the page

@* This was inserted in between the div tags in the commented section above *@
@{
    IEnumerable<object> items = Model.ContentItems;
    Model.ContentItems.Classes.Add("content-items");
    Model.ContentItems.Classes.Add("list-items");
}
@foreach (object item in items)
{
    <div style="display:inline;width:100px">@Display(item)</div>
}

Page Error: Exception Details: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'ClaySharp.Clay' does not contain a definition for 'Add'

Thanks

Coordinator
Jan 5, 2012 at 8:17 PM

Seems like there is no ContentItems property defined on the shape this template is trying to render.

Jan 5, 2012 at 9:10 PM

So are you saying that it can not be done, or is there a way to add ContentItems property to that shape?

Coordinator
Jan 5, 2012 at 9:27 PM

I'm saying nothing of the sort, just pointing out why your code doesn't work. This thread is getting long, so you'll have to define what "it" is exactly. ContentItems would have typically been added by the driver for that part. What part is this by the way?

Jan 5, 2012 at 11:38 PM

Sorry for the confusion. Just to recap, I created a new ContentType (Client). Created a list (Client-List) and added a bunch of Clients to it. In its simplicity, all I want to do is display the Client-List in the AsideFirst zone and when you click on one of the Clients in the list, it will display the detail page of that client in the Content zone so that both the list in AsideFirst and the Content of the selected Client shows up just to the right of the list.

Problem is that clicking on one of the list items, routes to the detail page for that client. No AsideFirst to display the Client-List, so I was wondering if I could display the list on that client's detail page via code.

Shape Tracer on page [Content-url-client-list.Detail.cshtm] drills down to:
Shape: Content
Active Template: ~/Core/Comments/Views/Content.cshtml
Display Type: Detail
and I created an alternate in my theme: ~/Themes/TheThemeMachine/Views/Content-url-client-list.Detail.cshtml which I modified with div columns. The left div, I would like to display the Client-List and the right div displays the detail for the selected client.
I believe that this page has the part: Content

So the "it" would be to display both the list of all the clients and the detail for the selected client on the same page.

Sorry for the long thread, I'm just trying to be detailed on what I am trying to do. I really do appreciate the help. 

Coordinator
Jan 6, 2012 at 12:12 AM

Ok, so the bad news is that in Orchard you can't just traverse the content object graph as if it were all in memory. So going to the parent to get all the siblings of the current item is not going to work just like that. It's not in the template that this sort of work should happen anyway.

The good news is that there are several ways you can make this work.

First, you can build your own content part that will query the content manager to get that list of siblings that you need, from the driver.

Alternatively, you could build this list as a widget, for example with a projection (not in 1.3 but in 1.x, only available through a Mercurial clone of the source for the moment) or with a list widget.

Jan 6, 2012 at 6:03 PM

I think that building a content part might be the way to go.

  1. I see that I can create a new Content Part directly from the Admin menu => Content => Content Parts. I have tried that, added the newly created part to my Content Type and can see that Part under the Model tab using the Client Tools (@Model.ContentItem.ClientListPart) when I click on my Client detail page. But I am not sure what to do from here.
  2. Or do I need to create a new module to do it this way and if so, would I need to create a new Model, Migrations and Driver or would I be using the Orchard.Models to query the Content Manager? I have read the Orchard Documentation on creating a Content Part using codegen: http://docs.orchardproject.net/Documentation/Writing-a-content-part and am not sure if I need to do all the steps just to query on a list that is already in content manager.

Is there a way to do the querying based on option #1 or would the only option be using #2?

Coordinator
Jan 6, 2012 at 9:16 PM

I meant creating a part from code, not from the admin. If you can't program and you can afford to wait a couple of weeks, this would probably be easily done with Projector, which will ne in Orchard 1.4. A list widget might be worth trying as well.