Content Types

Content types in Weavy are classes of content items. You can also see them as “templates” for content items. When you add a custom content type, Weavy will automatically create user interface elements for adding and editing instances of your content type.

When adding a content type you should do the following:

Model

Your first step when developing a new content type is to create a class extending Content. A good convention to follow is placing your class in the Areas\Apps\Models folder. In the example below we are creating a content type for meeting minutes to be used in the Files app.

using System;
using System.ComponentModel.DataAnnotations;
using System.Runtime.InteropServices;
using System.Web.Mvc;
using Weavy.Core.Models;

namespace Weavy.Areas.Apps.Models {

    [Serializable]
    [Guid("D16FE490-AB4D-4D42-B9F4-D93E6F297940")]
    [Content(Icon = "clipboard-text", Name = "Meeting note", Description = "Keep your notes organized with this meeting minutes template.", Parents = new Type[] { typeof(FilesApp), typeof(Folder) })]    
    public class MeetingMinutes : Content {

        public string Location { get; set; }

        [Display(Name = "Date", Description = "Date and time of the meeting")]
        public DateTime? Date { get; set; }

        public string Attendees { get; set; }
        
        [AllowHtml]
        [Required]
        [DataType(DataType.Html)]
        [Display(Name = "Note text")]
        public string Body { get; set; }
    }
}

Class attributes

As shown above, content types must be decorated with the [Serializable] and [Guid] attributes.

Make sure to give your class a unique Guid, otherwise it will not be recognized by Weavy.

To further customize your content type you can also decorate it with the [Content] attribute. Some of the properties you can set are:

  • Icon – name of an icon to use when displaying the content item.
  • Colorcolor to use for the icon.
  • Name – display name for the content item, e.g. “Meeting note”.
  • Description – a description to use for the content item.
  • SingularName – determines how a singular item will be referred to, e.g. “a meeting note”.
  • PluralName – determines how multiple items will be referred to, e.g. “meeting notes”.
  • Children – a list of allowed child content types
  • Parents – a list of allowed parent apps and/or content types
  • CreateMode – determines if content items of the content type should be created in a modal window, a new page or be hidden.
  • ModifyMode – determines if content items of the content type should be edited in a modal window, a new page or be hidden.

Fields

Content fields are pieces of information that can be added to a content type. Content fields have a name and a type and are specific to a content type. There can be several of each field type on any given content type.

In the example above, we have added 4 fields that make sense for meeting minutes; a text field representing the meeting location, a date field representing the date and time of the meeting, a text field for writing down the names of the people attending the meeting, and finally a text field for the meeting notes.

For a property on a content type to be considered a content field, it must be declared as public read-write, i.e. the property has the public access modifier and have both a get and a set accessor.

Content fields must also have one of the following supported types:

  • enum
  • byte
  • short
  • int
  • long
  • bool
  • double
  • float
  • string
  • Guid
  • DateTime
  • TimeSpan

Nullables and Lists of the above types are also supported, e.g. int?, List<string> and List<DateTime?>.

Field attributes

By decorating your fields with one, or more, of the following attributes you can customize how the field is displayed, edited and/or validated.

Datatype

By default, Weavy will look at the property type (in this case string) when deciding which editor to use for the field. By decorating a field with the [DataType] attribute you can specify an additional type to associate with the field. This value will then be used by the UI to determine which editor to use for the field.

[AllowHtml]
[DataType(DataType.Html)]
public string Body { get; set; }

Here we specify that the Body field should be treated as HTML instead of a plain text string. Note that you should always specify [AllowHtml] on Html fields, otherwise ASP.NET MVC will throw an exception saying that “A potentially dangerous Request.Form value was detected from the client…” when you try to create an instance of your content type from the UI.

Display

The [Display] attribute lets you specify a name and description to use for the field.

[Display(Name = "Date", Description = "Date and time of the meeting")]
public DateTime? Date { get; set; }
Validation

By adding one, or more, [Validation] attributes to your fields you can control they are validated.

[Required]
public string Body { get; set; }

Here we specify that the Body property is required and that it must be a valid and fully qualified url.

For full control of validation you can let your class implement IValidatableObject and add your own validation logic.

Controller

Although creating the MeetingMinutes class is enough for Weavy to detect your content type, without a custom Controller and View files it won’t be very useful. By extending the ContentController<TContent> class you can hook into the rendering flow of your content type and add your own custom logic.

The ContentController<TContent> class has three virtual methods that you can override:

  • Weavy.Web.Controllers.ContentController`1.Get – that is executed when someone navigates to a content item in the browser
  • Weavy.Web.Controllers.ContentController`1.Edit – that is executed when some wants to edit a content item.
  • Weavy.Web.Controllers.ContentController`1.New – that is executed when addingd a new content item

The code below shows what a controller for MeetingMinutes could look like. Since this is a very simple content type we can just return an ActionResult directly, but for a more complex app you could execute whatever custom logic you need before returning with return View(content). When you create a custom Controller and override one or more methods, you must also create the corresponding Views for the action methods.

using System.Web.Mvc;
using Weavy.Core.Models;
using Weavy.Web.Controllers;
using Weavy.Areas.Apps.Models;

namespace Weavy.Areas.Apps.Controllers {

    /// <summary>
    /// Controller for <see cref="MeetingMinutes" />.
    /// </summary>
    [RoutePrefix("content/{id:int}/D16FE490-AB4D-4D42-B9F4-D93E6F297940")]
    public class MeetingMinutesController : ContentController<MeetingMinutes> {

        /// <summary>
        /// Display the meeting minutes.
        /// </summary>
        /// <param name="content">The content item to display.</param>
        /// <param name="query">An object with query parameters for search, paging etc.</param>
        public override ActionResult Get(MeetingMinutes content, Query query) {
            // add custom logic here if needed...
            return View(content);
        }
    }
}

To avoid route conflicts, there is one important convention that you should follow when adding a Content controller. Your should make sure that your controller has a [RoutePrefix] attribute in the format content/{id:int}/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX where the last segment is replaced with the Guid of your content type, in this case D16FE490-AB4D-4D42-B9F4-D93E6F297940 for the MeetingMinutes class.

Additional actions

It is also possible to add custom action methods to your Content controller just as you would in a standard ASP.NET MVC project. Here is a simple example just to show how easy it is.

/// <summary>
/// A test action to show that you can add custom actions to Content controllers.
/// </summary>
/// <param name="id">Id of content item</param>
[HttpGet]
[Route("test")]
public ActionResult Test(int id) {
    return Content("Test result");
}
Note that action urls must be specified via attribute routing with the [Route] attribute, and since we also have the [RoutePrefix] attribute on the Controller class the full url to the action above will be /content/{id:int}/D16FE490-AB4D-4D42-B9F4-D93E6F297940/test.

Views

Weavy has built-in generic view files for rendering any content type, but by adding custom View files (.cshtml) you can customize the rendering of your content type. Your view files should be placed in a subdirectory under the Areas\Apps\Views folder matching the name of your Controller.

For the MeetingMinutesController content type, that means you should add your view files in the Areas\Apps\Views\MeetingMinutes folder. And just as in any standard ASP.NET MVC project the name of your view file should match the corresponding Action. So, by adding a file called Get.cshtml to this folder you can override the default view file Views\Content\Get.cshtml.

  • Areas
    • Apps
      • Controllers
        • MeetingMinutesController.cs
      • Models
        • MeetingMinutes.cs
      • Views
        • MeetingMinutes
          • Get.cshtml