Saturday, October 20, 2012

Hide content type fields in Orchard CMS

In Orchard CMS there is a concept of content types. From high vision it is similar to the content types idea in Sharepoint. It has less features of course, but the general idea is the same: you may create your own content types, add new content parts or fields and then create content items based on created content type. Content parts can be found from Dashboard > Content > Content Parts:

image

You can add fields of the following types (available in 1.5.1 version):

  • Boolean
  • Content picker (allows you to select content items like pages and display them on page)
  • Date time
  • Enumeration (shows list of predefined values. You can choose how you want to display values: using listbox, dropdown list, radio button list, checkboxes list)
  • Input (allows to add input fields to your content type, add validation for phones and emails, define max length, watermark, custom css and other features)
  • Link
  • Media picker (allows to show items from Media folder, e.g. images)
  • Numeric
  • Text (can be plain text, multiline text, html)

In order to add new field you should go to the Dashboard > Content > Content types > Edit content type > Add field:

image

What is missing in the current implementation is the ability to hide added fields. E.g. if you need to add metadata for displaying in liftups (or projections in terms of Orchard), but not in Detail view. In Sharepoint you can define fields visibility for each form separately using the following properties of SPField class: ShowInDisplayForm, ShowInEditForm, ShowInNewForm, ShowInViewForms. So how to hide field in e.g. detail view (default view which is used when you open e.g. the page)? I found the following way.

First of all you need to install Designer Tools module and enable Shape Tracing feature in it:

image

At the moment of writing Designer Tools module also has Url Alternates and Widget Alternates features. Once you enabled Shape Tracing, you will see the following icon in the right bottom corner of the page:

image

If you will click on it you will see panel similar to the firebug or IE developer tools:

image

Now you can check all shapes on your page using convenient visual representation like you do in firebug. In order to hide the field at first find its shape on the page. Here you can create alternate template for displaying appropriate field. Click Create button near the template name which is more suitable for you. After that panel will look like that:

image

Active template shows the path to the View which is currently used for rendering the field:

Active Template: ~/Themes/Terra/Views/Fields.Common.Text-Logo.cshtml

Now go to that folder and check the code of the view. For text fields it looks like this:

   1: @using Orchard.Utility.Extensions;
   2: @{
   3:     string name = Model.ContentField.DisplayName;
   4: }
   5:  
   6: if (HasText(name) && HasText(Model.Value)) {
   7:     <p class="text-field"><span class="name">@name:</span>
   8:     <span class="value">@(new MvcHtmlString(Html.Encode((HtmlString) Model.Value)
   9:         .ReplaceNewLinesWith("<br />$1")))</span></p>
  10: }

In order to hide the field we need to modify the view a bit:

   1: @using Orchard.Utility.Extensions;
   2: @{
   3:     string name = Model.ContentField.DisplayName;
   4: }
   5:  
   6: @if (Model.Metadata.DisplayType != "Detail") {
   7:     if (HasText(name) && HasText(Model.Value)) {
   8:         <p class="text-field"><span class="name">@name:</span>
   9:         <span class="value">@(new MvcHtmlString(Html.Encode((HtmlString) Model.Value)
  10:             .ReplaceNewLinesWith("<br />$1")))</span></p>
  11:     }
  12: }

Here on line 6 I added additional condition: @if (Model.Metadata.DisplayType != "Detail"). So view will be rendered only in other than Detail display types. After that you will have content items with metadata which you can use e.g. only in projections, but which won’t be shown in default view.

May be there is better and faster way to do that in Orchard, but I didn’t find it yet. If you know other ways to achieve the same result please share them in comments.

6 comments:

  1. That is terribly hacky. There is a much simpler way, which is to use placement.info.

    ReplyDelete
  2. Unknown,
    placement.info was the first thing which I checked. With this file you may hide all fields of appropriate type:

    Match ContentType="Page"
    Match DisplayType="Detail"
    Place Fields_Common_Text="-"
    Match
    Match

    it will hide _all_ fields of Text type in the Page content type. Can you show example how to hide only one field using placement.info?

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Sure,

      Match ContentType="Page"
      Place Parts_Common_Owner_Edit="-"
      Match

      Delete
  4. Andy,
    as far as I understand you showed how to hide content part, but will it work with fields?

    ReplyDelete
  5. See http://docs.orchardproject.net/Documentation/Understanding-placement-info#"Place"Element

    ReplyDelete