Skip to main content
Home  › ... Razor

Content Items / Entities

Tutorial HomeContent
Requirements

Working with Block Contents

In most cases a template will run in a context - so something prepared data for the template, which should now be visualized. These examples assume you're working with 2sxc, which let's editors work with content - and your template only needs to visualize it. The current content item (if it's just one) is always available on the variable called Content. It's a dynamic object, so you can just type things like @Content.FirstName to access the properties.

The samples can differ based on your Razor base class or if you're running an old version.
Selected: Strong-Typed (2sxc 17.06+) Switch to Typed (2sxc 16+) Switch to Dynamic (Razor14 or below)

Show Entity Values from the current Data

Showing values from Data (aka. Entities) is very easy. Normally they are accessed through Item (new Razor) or DynamicEntity (older Razor) objects. 

⬇️ Result | Source ➡️

  • Name: Douglas Adams
  • Birthday: 3/11/1952
  • Award: Hugo Award
@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data

@{
  var person = As<Persons>(MyItem);
}
@person.Img("Mugshot", settings: "Square", width: 100, imgClass: "rounded-circle")
<ul>
  <li>
    Name: @person.FirstName @person.LastName
  </li>
  <li>
    Birthday: @person.Birthday.ToString("d")
  </li>
  <li>
    Award:
    @(person.Awards.FirstOrDefault()?.Name)
  </li>
</ul>

Source Code of Persons.cs

namespace AppCode.Data
{
  public partial class Persons
  {
    /// <summary>
    /// Custom property Presentation - as in these tutorials
    /// the Person always uses a QuickRefContentPresentation content-type for the presentation
    /// </summary>
    public new QuickRefContentPresentation Presentation => _presentation ??= As<QuickRefContentPresentation>(base.Presentation);
    private QuickRefContentPresentation _presentation;
  }
}

Source Code of Persons.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "Persons.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class Persons
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using ToSic.Sxc.Adam;
using ToSic.Sxc.Data;

namespace AppCode.Data
{
  // This is a generated class for Persons 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// Persons data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Awards`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class Persons: AutoGenerated.ZAutoGenPersons
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.Persons in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenPersons: Custom.Data.CustomItem
  {
    /// <summary>
    /// Awards as list of PersonAwards.
    /// </summary>
    /// <remarks>
    /// Generated to return child-list child because field settings had Multi-Value=true. The type PersonAwards was specified in the field settings.
    /// </remarks>
    /// <returns>
    /// An IEnumerable of specified type, but can be empty.
    /// </returns>
    public IEnumerable<PersonAwards> Awards => _awards ??= _item.Children<PersonAwards>("Awards");
    private IEnumerable<PersonAwards> _awards;

    /// <summary>
    /// Biography as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Biography", scrubHtml: true) etc.
    /// </summary>
    public string Biography => _item.String("Biography", fallback: "");

    /// <summary>
    /// Birthday as DateTime.
    /// </summary>
    public DateTime Birthday => _item.DateTime("Birthday");

    /// <summary>
    /// FavoriteNumber as int. <br/>
    /// To get other types use methods such as .Decimal("FavoriteNumber")
    /// </summary>
    public int FavoriteNumber => _item.Int("FavoriteNumber");

    /// <summary>
    /// FirstName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("FirstName", scrubHtml: true) etc.
    /// </summary>
    public string FirstName => _item.String("FirstName", fallback: "");

    /// <summary>
    /// Haters as single item of ITypedItem.
    /// </summary>
    /// <remarks>
    /// Generated to only return 1 child because field settings had Multi-Value=false. 
    /// </remarks>
    /// <returns>
    /// A single item OR null if nothing found, so you can use ?? to provide alternate objects.
    /// </returns>
    public ITypedItem Haters => _haters ??= _item.Child("Haters");
    private ITypedItem _haters;

    /// <summary>
    /// IsAlive as bool. <br/>
    /// To get nullable use .Get("IsAlive") as bool?;
    /// </summary>
    public bool IsAlive => _item.Bool("IsAlive");

    /// <summary>
    /// LastName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("LastName", scrubHtml: true) etc.
    /// </summary>
    public string LastName => _item.String("LastName", fallback: "");

    /// <summary>
    /// Mugshot as link (url). <br/>
    /// To get the underlying value like 'file:72' use String("Mugshot")
    /// </summary>
    public string Mugshot => _item.Url("Mugshot");

    /// <summary>
    /// Get the file object for Mugshot - or null if it's empty or not referencing a file.
    /// </summary>

    [JsonIgnore]
    public IFile MugshotFile => _item.File("Mugshot");

    /// <summary>
    /// Get the folder object for Mugshot.
    /// </summary>

    [JsonIgnore]
    public IFolder MugshotFolder => _item.Folder("Mugshot");

    /// <summary>
    /// Sex as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Sex", scrubHtml: true) etc.
    /// </summary>
    public string Sex => _item.String("Sex", fallback: "");
  }
}

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: Persons
  • Content/Item Data:
    1. Douglas (ID: 48832)

Note that Awards refers to other Entities of the type PersonAwards and has properties like Name. The above example showed the award Name using @Content.Awards.Name - which makes sense when you only expect one award. In other tutorials you'll see how to work with such related Entities if there are more than one.

Work with Content Items - MyItem

MyItem is the object which contains the first thing added by the editor on the current block.

Every view/template receives prepared data, usually on the MyItem object.

⬇️ Result | Source ➡️

Douglas Adams on MyItem

Id, Guid and Title are built-in properties

  1. Id: 48832
  2. Guid: 36726e4e-21cd-4c00-9ce8-72080f8935da
  3. Title: Douglas

Since person is fully typed, you can just call it's properties.

  1. Name: Douglas
  2. Birthday: 3/11/1952 12:00:00 AM
  3. Is Alive: False
  4. Fav Num. Int: 42

Use Get(…) if you don't care about the var type or Get<T>(…) or typed methods such as .String(…).

  1. Name: Douglas
  2. Birthday: 3/11/1952 12:00:00 AM
  3. Birthday Get<string> 03/11/1952 00:00:00
  4. Birthday Get<DateTime> 3/11/1952 12:00:00 AM
  5. Name (strings): Douglas
  6. Birthday: 3/11/1952
  7. Is Alive: False
  8. Fav Num. Int: 42
  9. Fav Num. Float: 41.99

Use fallback: … to handle empty values or conversion problems.

  1. Name (strings): Douglas
  2. Name (int): 12345

Use .Attribute(…) to safely encode properties. Mouse over this to see the effect.

@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data

@{
  var person = As<Persons>(MyItem);
}
<h4>Douglas Adams on <code>MyItem</code></h4>
<p>
  Id, Guid and Title are built-in properties
</p>
<ol>
  <li>Id:             @person.Id</li>
  <li>Guid:           @person.Guid</li>
  <li>Title:          @person.Title</li>
</ol>

<p>Since <code>person</code> is fully typed, you can just call it's properties.</p>
<ol>
  <li>Name:           @person.FirstName</li>
  <li>Birthday:       @person.Birthday</li>
  <li>Is Alive:       @person.IsAlive</li>
  <li>Fav Num. Int:   @person.FavoriteNumber</li>
</ol>

<p>Use <code>Get(…)</code> if you don't care about the var type or <code>Get&lt;T&gt;(…)</code> or typed methods such as <code>.String(…)</code>.</p>
<ol>
  <li>Name:           @person.Get("FirstName")</li>
  <li>Birthday:       @person.Get("Birthday")</li>
  <li>Birthday Get&lt;string&gt;    @(person.Get<string>("Birthday"))</li>
  <li>Birthday Get&lt;DateTime&gt;  @(person.Get<DateTime>("Birthday"))</li>
  <li>Name (strings): @person.String("FirstName")</li>
  <li>Birthday:       @person.DateTime("Birthday").ToString("d")</li>
  <li>Is Alive:       @person.Bool("IsAlive")</li>
  <li>Fav Num. Int:   @person.Int("FavoriteNumber")</li>
  <li>Fav Num. Float: @person.Float("FavoriteNumber")</li>
</ol>

<p>Use <code>fallback: …</code> to handle empty values or conversion problems.</p>
<ol>
  @* this has no effect, as the value works *@
  <li>Name (strings): @person.String("FirstName", fallback: "unknown")
  <li>Name (int):     @person.Int("FirstName", fallback: 12345)
</ol>


<p title='@person.Attribute("FirstName")'>
  Use <code>.Attribute(…)</code> to safely encode properties.
  Mouse over this to see the effect.
</p>

Source Code of Persons.cs

namespace AppCode.Data
{
  public partial class Persons
  {
    /// <summary>
    /// Custom property Presentation - as in these tutorials
    /// the Person always uses a QuickRefContentPresentation content-type for the presentation
    /// </summary>
    public new QuickRefContentPresentation Presentation => _presentation ??= As<QuickRefContentPresentation>(base.Presentation);
    private QuickRefContentPresentation _presentation;
  }
}

Source Code of Persons.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "Persons.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class Persons
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using ToSic.Sxc.Adam;
using ToSic.Sxc.Data;

namespace AppCode.Data
{
  // This is a generated class for Persons 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// Persons data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Awards`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class Persons: AutoGenerated.ZAutoGenPersons
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.Persons in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenPersons: Custom.Data.CustomItem
  {
    /// <summary>
    /// Awards as list of PersonAwards.
    /// </summary>
    /// <remarks>
    /// Generated to return child-list child because field settings had Multi-Value=true. The type PersonAwards was specified in the field settings.
    /// </remarks>
    /// <returns>
    /// An IEnumerable of specified type, but can be empty.
    /// </returns>
    public IEnumerable<PersonAwards> Awards => _awards ??= _item.Children<PersonAwards>("Awards");
    private IEnumerable<PersonAwards> _awards;

    /// <summary>
    /// Biography as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Biography", scrubHtml: true) etc.
    /// </summary>
    public string Biography => _item.String("Biography", fallback: "");

    /// <summary>
    /// Birthday as DateTime.
    /// </summary>
    public DateTime Birthday => _item.DateTime("Birthday");

    /// <summary>
    /// FavoriteNumber as int. <br/>
    /// To get other types use methods such as .Decimal("FavoriteNumber")
    /// </summary>
    public int FavoriteNumber => _item.Int("FavoriteNumber");

    /// <summary>
    /// FirstName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("FirstName", scrubHtml: true) etc.
    /// </summary>
    public string FirstName => _item.String("FirstName", fallback: "");

    /// <summary>
    /// Haters as single item of ITypedItem.
    /// </summary>
    /// <remarks>
    /// Generated to only return 1 child because field settings had Multi-Value=false. 
    /// </remarks>
    /// <returns>
    /// A single item OR null if nothing found, so you can use ?? to provide alternate objects.
    /// </returns>
    public ITypedItem Haters => _haters ??= _item.Child("Haters");
    private ITypedItem _haters;

    /// <summary>
    /// IsAlive as bool. <br/>
    /// To get nullable use .Get("IsAlive") as bool?;
    /// </summary>
    public bool IsAlive => _item.Bool("IsAlive");

    /// <summary>
    /// LastName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("LastName", scrubHtml: true) etc.
    /// </summary>
    public string LastName => _item.String("LastName", fallback: "");

    /// <summary>
    /// Mugshot as link (url). <br/>
    /// To get the underlying value like 'file:72' use String("Mugshot")
    /// </summary>
    public string Mugshot => _item.Url("Mugshot");

    /// <summary>
    /// Get the file object for Mugshot - or null if it's empty or not referencing a file.
    /// </summary>

    [JsonIgnore]
    public IFile MugshotFile => _item.File("Mugshot");

    /// <summary>
    /// Get the folder object for Mugshot.
    /// </summary>

    [JsonIgnore]
    public IFolder MugshotFolder => _item.Folder("Mugshot");

    /// <summary>
    /// Sex as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Sex", scrubHtml: true) etc.
    /// </summary>
    public string Sex => _item.String("Sex", fallback: "");
  }
}

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: Persons
  • Content/Item Data:
    1. Douglas (ID: 48832)
  1. Working with Entity (Item) Values

    Every thing is an Entity. Here some basic examples how to show values like Name, Birthday etc. of such an Entity.

  2. Working with Block Contents

    Show content which was entered for this module

⬇️ Result | Source ➡️

Douglas Adams on MyItem

Note: The Biography contains a LOT of HTML...

Teaser (using .Raw() for Umlauts):
Douglas Noël Adams  (11 March 1952 – 11 May 2001) was an English author,  humorist , and…


Now as rich HTML
(drag size to see responsiv behavior)

Douglas Noël Adams (11 March 1952 – 11 May 2001) was an English author, humorist, and screenwriter, best known for The Hitchhiker's Guide to the Galaxy. Originally a 1978 BBC radio comedyThe Hitchhiker's Guide to the Galaxy developed into a "trilogy" of five books that sold more than 15 million copies in his lifetime. 

@inherits Custom.Hybrid.RazorTyped
@using ToSic.Razor.Blade

<h4>Douglas Adams on <code>MyItem</code></h4>
<p>
  Note: The Biography contains a LOT of HTML...
</p>
@{
  // scrubHtml will clean up Html tags; there are more options
  var bio = MyItem.String("Biography", scrubHtml: true);

  // Text.Ellipsis uses RazorBlade
  var teaser = Text.Ellipsis(bio, 100);
}
<p>
  <strong>Teaser</strong> (using .Raw() for Umlauts): <br>
  <em>@Html.Raw(teaser)</em>
</p>
<hr>
<div>
  <strong>Now as rich HTML</strong> <br>
  (drag size to see responsiv behavior) <br>
  @MyItem.Html("Biography")
</div>

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: Persons
  • Content/Item Data:
    1. Douglas (ID: 48832)

The Presentation property only exists if the view is configured to use Presentation. In which case this is used to specify additional information how something should look or be presented. 

⬇️ Result | Source ➡️

A Person on MyItem

Note that the following should be green (probably green)

Content number 1

@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data

<h4>A Person on <code>MyItem</code></h4>
@{
  var itemPres = As<QuickRefContentPresentation>(MyItem.Presentation);
}

<p>
  Note that the following should be @itemPres.Color (probably green)
</p>
<p style='color: @itemPres.Attribute("Color")'>
  @MyItem.Title
</p>

Source Code of QuickRefContentPresentation.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "QuickRefContentPresentation.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class QuickRefContentPresentation
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
namespace AppCode.Data
{
  // This is a generated class for QuickRefContentPresentation 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// QuickRefContentPresentation data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Color`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class QuickRefContentPresentation: AutoGenerated.ZAutoGenQuickRefContentPresentation
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.QuickRefContentPresentation in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenQuickRefContentPresentation: Custom.Data.CustomItem
  {
    /// <summary>
    /// Color as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Color", scrubHtml: true) etc.
    /// </summary>
    public string Color => _item.String("Color", fallback: "");

    /// <summary>
    /// HeadingType as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("HeadingType", scrubHtml: true) etc.
    /// </summary>
    public string HeadingType => _item.String("HeadingType", fallback: "");

    /// <summary>
    /// Highlight as bool. <br/>
    /// To get nullable use .Get("Highlight") as bool?;
    /// </summary>
    public bool Highlight => _item.Bool("Highlight");
  }
}

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: QuickRefContent
  • Content/Item IsList: True
  • Content/Item Data:
    1. Content number 1 (ID: 49356) - Presentation: green (ID: 49352)
    2. Content two (ID: 49357) - Presentation: red (ID: 49359)
    3. Content three (ID: 49361) - Presentation: cyan (ID: 49360)
  1. Working with Entity (Item) Values

    Every thing is an Entity. Here some basic examples how to show values like Name, Birthday etc. of such an Entity.

  2. Working with Block Contents

    Show content which was entered for this module

Child items such as Awards are accessed using Child("Awards"). There are many ways to work with them.

⬇️ Result | Source ➡️

Use .Child("Awards") to get one

  1. Award ID: 48878
  2. Award Name: Hugo Award
  3. Award Name (Path): Hugo Award

Use ContainsKey(…), IsEmpty(…), IsNotEmpty(…)

  1. ContainsKey("Awards"): True
  2. ContainsKey("Awards2"): False
  3. IsEmpty("Awards"): False
  4. IsNotEmpty("Awards"): True
  5. IsEmpty("Awards.Name"): False
  6. IsEmpty("Awards2.Name"): True
  7. IsEmpty("Awards.NameX"): True

Use .Children("Awards") to get all

Award Count: 2
  1. Award: Hugo Award
  2. Award: Inkpot Award
@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data

<h4>Use <code>.Child("Awards")</code> to get one</h4>
@{
  var person = As<Persons>(MyItem);
  var awards = person.Awards; // of type List<PersonAwards>
  var award = awards.FirstOrDefault();
}
<ol>
  <li>Award ID:          @award.Id</li>
  <li>Award Name:        @award.Name</li>
  <li>Award Name (Path): @person.String("Awards.Name")</li>
</ol>

<p>Use ContainsKey(…), IsEmpty(…), IsNotEmpty(…)</p>
<ol>
  <li>ContainsKey("Awards"):  @person.ContainsKey("Awards")</li>
  <li>ContainsKey("Awards2"): @person.ContainsKey("Awards2")</li>
  <li>IsEmpty("Awards"):      @person.IsEmpty("Awards")</li>
  <li>IsNotEmpty("Awards"):   @person.IsNotEmpty("Awards")</li>
  <li>IsEmpty("Awards.Name"): @person.IsEmpty("Awards.Name")</li>
  <li>IsEmpty("Awards2.Name"): @person.IsEmpty("Awards2.Name")</li>
  <li>IsEmpty("Awards.NameX"): @person.IsEmpty("Awards.NameX")</li>
</ol>

<h4>Use <code>.Children("Awards")</code> to get all</h4>
<span>Award Count:       @person.Awards.Count()</span>
<ol>
  @foreach (var personAward in person.Awards)
  {
    <li>Award: @personAward.Name</li>
  }
</ol>

Source Code of Persons.cs

namespace AppCode.Data
{
  public partial class Persons
  {
    /// <summary>
    /// Custom property Presentation - as in these tutorials
    /// the Person always uses a QuickRefContentPresentation content-type for the presentation
    /// </summary>
    public new QuickRefContentPresentation Presentation => _presentation ??= As<QuickRefContentPresentation>(base.Presentation);
    private QuickRefContentPresentation _presentation;
  }
}

Source Code of Persons.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "Persons.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class Persons
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using ToSic.Sxc.Adam;
using ToSic.Sxc.Data;

namespace AppCode.Data
{
  // This is a generated class for Persons 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// Persons data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Awards`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class Persons: AutoGenerated.ZAutoGenPersons
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.Persons in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenPersons: Custom.Data.CustomItem
  {
    /// <summary>
    /// Awards as list of PersonAwards.
    /// </summary>
    /// <remarks>
    /// Generated to return child-list child because field settings had Multi-Value=true. The type PersonAwards was specified in the field settings.
    /// </remarks>
    /// <returns>
    /// An IEnumerable of specified type, but can be empty.
    /// </returns>
    public IEnumerable<PersonAwards> Awards => _awards ??= _item.Children<PersonAwards>("Awards");
    private IEnumerable<PersonAwards> _awards;

    /// <summary>
    /// Biography as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Biography", scrubHtml: true) etc.
    /// </summary>
    public string Biography => _item.String("Biography", fallback: "");

    /// <summary>
    /// Birthday as DateTime.
    /// </summary>
    public DateTime Birthday => _item.DateTime("Birthday");

    /// <summary>
    /// FavoriteNumber as int. <br/>
    /// To get other types use methods such as .Decimal("FavoriteNumber")
    /// </summary>
    public int FavoriteNumber => _item.Int("FavoriteNumber");

    /// <summary>
    /// FirstName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("FirstName", scrubHtml: true) etc.
    /// </summary>
    public string FirstName => _item.String("FirstName", fallback: "");

    /// <summary>
    /// Haters as single item of ITypedItem.
    /// </summary>
    /// <remarks>
    /// Generated to only return 1 child because field settings had Multi-Value=false. 
    /// </remarks>
    /// <returns>
    /// A single item OR null if nothing found, so you can use ?? to provide alternate objects.
    /// </returns>
    public ITypedItem Haters => _haters ??= _item.Child("Haters");
    private ITypedItem _haters;

    /// <summary>
    /// IsAlive as bool. <br/>
    /// To get nullable use .Get("IsAlive") as bool?;
    /// </summary>
    public bool IsAlive => _item.Bool("IsAlive");

    /// <summary>
    /// LastName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("LastName", scrubHtml: true) etc.
    /// </summary>
    public string LastName => _item.String("LastName", fallback: "");

    /// <summary>
    /// Mugshot as link (url). <br/>
    /// To get the underlying value like 'file:72' use String("Mugshot")
    /// </summary>
    public string Mugshot => _item.Url("Mugshot");

    /// <summary>
    /// Get the file object for Mugshot - or null if it's empty or not referencing a file.
    /// </summary>

    [JsonIgnore]
    public IFile MugshotFile => _item.File("Mugshot");

    /// <summary>
    /// Get the folder object for Mugshot.
    /// </summary>

    [JsonIgnore]
    public IFolder MugshotFolder => _item.Folder("Mugshot");

    /// <summary>
    /// Sex as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Sex", scrubHtml: true) etc.
    /// </summary>
    public string Sex => _item.String("Sex", fallback: "");
  }
}

Source Code of PersonAwards.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "PersonAwards.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class PersonAwards
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
namespace AppCode.Data
{
  // This is a generated class for PersonAwards 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// PersonAwards data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Name`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class PersonAwards: AutoGenerated.ZAutoGenPersonAwards
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.PersonAwards in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenPersonAwards: Custom.Data.CustomItem
  {
    /// <summary>
    /// Name as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Name", scrubHtml: true) etc.
    /// </summary>
    public string Name => _item.String("Name", fallback: "");
  }
}

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: Persons
  • Content/Item Data:
    1. Douglas (ID: 48832)
  1. Working with Entity (Item) Values

    Every thing is an Entity. Here some basic examples how to show values like Name, Birthday etc. of such an Entity.

  2. Working with Block Contents

    Show content which was entered for this module

Properties can contain urls such as /abc.jpg or file references like file:72.

⬇️ Result | Source ➡️

Douglas Adams, the current item (MyItem)

Use .Url(…) to resolve file references such as file:72

  1. Mugshot URL: /Portals/tutorials/adam/Tutorial-Razor/Tm5yNs0hAEyc6HIID4k12g/Mugshot/douglas%20adams.png
  2. Mugshot field Value: file:5212
  3. Mugshot Picture
@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data

<h4>Douglas Adams, the current item (MyItem)</h4>
@{
  var person = As<Persons>(MyItem);
}
<p>Use <code>.Url(…)</code> to resolve file references such as <code>file:72</code></p>
<ol>
  <li>Mugshot URL:          @person.Mugshot</li>
  <li>Mugshot field Value:  @person.String("Mugshot")</li>
  <li>
    Mugshot Picture <br>
    @person.Picture("Mugshot", settings: "Square", width: 100, imgClass: "rounded-circle")
  </li>
</ol>

Source Code of Persons.cs

namespace AppCode.Data
{
  public partial class Persons
  {
    /// <summary>
    /// Custom property Presentation - as in these tutorials
    /// the Person always uses a QuickRefContentPresentation content-type for the presentation
    /// </summary>
    public new QuickRefContentPresentation Presentation => _presentation ??= As<QuickRefContentPresentation>(base.Presentation);
    private QuickRefContentPresentation _presentation;
  }
}

Source Code of Persons.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "Persons.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class Persons
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using ToSic.Sxc.Adam;
using ToSic.Sxc.Data;

namespace AppCode.Data
{
  // This is a generated class for Persons 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// Persons data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Awards`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class Persons: AutoGenerated.ZAutoGenPersons
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.Persons in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenPersons: Custom.Data.CustomItem
  {
    /// <summary>
    /// Awards as list of PersonAwards.
    /// </summary>
    /// <remarks>
    /// Generated to return child-list child because field settings had Multi-Value=true. The type PersonAwards was specified in the field settings.
    /// </remarks>
    /// <returns>
    /// An IEnumerable of specified type, but can be empty.
    /// </returns>
    public IEnumerable<PersonAwards> Awards => _awards ??= _item.Children<PersonAwards>("Awards");
    private IEnumerable<PersonAwards> _awards;

    /// <summary>
    /// Biography as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Biography", scrubHtml: true) etc.
    /// </summary>
    public string Biography => _item.String("Biography", fallback: "");

    /// <summary>
    /// Birthday as DateTime.
    /// </summary>
    public DateTime Birthday => _item.DateTime("Birthday");

    /// <summary>
    /// FavoriteNumber as int. <br/>
    /// To get other types use methods such as .Decimal("FavoriteNumber")
    /// </summary>
    public int FavoriteNumber => _item.Int("FavoriteNumber");

    /// <summary>
    /// FirstName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("FirstName", scrubHtml: true) etc.
    /// </summary>
    public string FirstName => _item.String("FirstName", fallback: "");

    /// <summary>
    /// Haters as single item of ITypedItem.
    /// </summary>
    /// <remarks>
    /// Generated to only return 1 child because field settings had Multi-Value=false. 
    /// </remarks>
    /// <returns>
    /// A single item OR null if nothing found, so you can use ?? to provide alternate objects.
    /// </returns>
    public ITypedItem Haters => _haters ??= _item.Child("Haters");
    private ITypedItem _haters;

    /// <summary>
    /// IsAlive as bool. <br/>
    /// To get nullable use .Get("IsAlive") as bool?;
    /// </summary>
    public bool IsAlive => _item.Bool("IsAlive");

    /// <summary>
    /// LastName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("LastName", scrubHtml: true) etc.
    /// </summary>
    public string LastName => _item.String("LastName", fallback: "");

    /// <summary>
    /// Mugshot as link (url). <br/>
    /// To get the underlying value like 'file:72' use String("Mugshot")
    /// </summary>
    public string Mugshot => _item.Url("Mugshot");

    /// <summary>
    /// Get the file object for Mugshot - or null if it's empty or not referencing a file.
    /// </summary>

    [JsonIgnore]
    public IFile MugshotFile => _item.File("Mugshot");

    /// <summary>
    /// Get the folder object for Mugshot.
    /// </summary>

    [JsonIgnore]
    public IFolder MugshotFolder => _item.Folder("Mugshot");

    /// <summary>
    /// Sex as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Sex", scrubHtml: true) etc.
    /// </summary>
    public string Sex => _item.String("Sex", fallback: "");
  }
}

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: Persons
  • Content/Item Data:
    1. Douglas (ID: 48832)

Properties can contain urls such as /abc.jpg or file references like file:72.

⬇️ Result | Source ➡️

Douglas Adams, the current item (MyItem)

  1. File name: douglas adams
  2. File extension: png
  3. Size (bytes): 39125
  4. SizeInfo: 38.2 KB

Every file-field is actually a folder...

  1. Files count: 2
  2. Sub-Folders: 0

...which could hold many files. If you want to show them, you need Kit.Image...

  1. douglas adams
  2. not-panicking
@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data

<h4>Douglas Adams, the current item (MyItem)</h4>
@{
  var person = As<Persons>(MyItem);
  // The ...File property is autogenerated for every file/link-field
  var file = person.MugshotFile;
  var sizeInfo = file.SizeInfo;
}
<ol>
  <li>File name:        @file.Name</li>
  <li>File extension:   @file.Extension</li>
  <li>Size (bytes):     @file.Size</li>
  <li>SizeInfo:         @sizeInfo.BestSize.ToString("#.#") @sizeInfo.BestUnit</li>
</ol>

<p>Every file-field is actually a folder...</p>
@{
  // The ...Folder property is autogenerated for every file/link-field
  var folder = person.MugshotFolder;
}
<ol>
  <li>Files count:    @folder.Files.Count()</li>
  <li>Sub-Folders:    @folder.Folders.Count()</li>
</ol>
<p>
  ...which could hold many files. 
  If you want to show them, you need <code>Kit.Image...</code></p>
<ol>
  @foreach (var f in folder.Files)
  {
    <li>@f.Name <br> @Kit.Image.Picture(f, width: 100)</li>
  }
</ol>

Source Code of Persons.cs

namespace AppCode.Data
{
  public partial class Persons
  {
    /// <summary>
    /// Custom property Presentation - as in these tutorials
    /// the Person always uses a QuickRefContentPresentation content-type for the presentation
    /// </summary>
    public new QuickRefContentPresentation Presentation => _presentation ??= As<QuickRefContentPresentation>(base.Presentation);
    private QuickRefContentPresentation _presentation;
  }
}

Source Code of Persons.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "Persons.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class Persons
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using ToSic.Sxc.Adam;
using ToSic.Sxc.Data;

namespace AppCode.Data
{
  // This is a generated class for Persons 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// Persons data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Awards`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class Persons: AutoGenerated.ZAutoGenPersons
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.Persons in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenPersons: Custom.Data.CustomItem
  {
    /// <summary>
    /// Awards as list of PersonAwards.
    /// </summary>
    /// <remarks>
    /// Generated to return child-list child because field settings had Multi-Value=true. The type PersonAwards was specified in the field settings.
    /// </remarks>
    /// <returns>
    /// An IEnumerable of specified type, but can be empty.
    /// </returns>
    public IEnumerable<PersonAwards> Awards => _awards ??= _item.Children<PersonAwards>("Awards");
    private IEnumerable<PersonAwards> _awards;

    /// <summary>
    /// Biography as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Biography", scrubHtml: true) etc.
    /// </summary>
    public string Biography => _item.String("Biography", fallback: "");

    /// <summary>
    /// Birthday as DateTime.
    /// </summary>
    public DateTime Birthday => _item.DateTime("Birthday");

    /// <summary>
    /// FavoriteNumber as int. <br/>
    /// To get other types use methods such as .Decimal("FavoriteNumber")
    /// </summary>
    public int FavoriteNumber => _item.Int("FavoriteNumber");

    /// <summary>
    /// FirstName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("FirstName", scrubHtml: true) etc.
    /// </summary>
    public string FirstName => _item.String("FirstName", fallback: "");

    /// <summary>
    /// Haters as single item of ITypedItem.
    /// </summary>
    /// <remarks>
    /// Generated to only return 1 child because field settings had Multi-Value=false. 
    /// </remarks>
    /// <returns>
    /// A single item OR null if nothing found, so you can use ?? to provide alternate objects.
    /// </returns>
    public ITypedItem Haters => _haters ??= _item.Child("Haters");
    private ITypedItem _haters;

    /// <summary>
    /// IsAlive as bool. <br/>
    /// To get nullable use .Get("IsAlive") as bool?;
    /// </summary>
    public bool IsAlive => _item.Bool("IsAlive");

    /// <summary>
    /// LastName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("LastName", scrubHtml: true) etc.
    /// </summary>
    public string LastName => _item.String("LastName", fallback: "");

    /// <summary>
    /// Mugshot as link (url). <br/>
    /// To get the underlying value like 'file:72' use String("Mugshot")
    /// </summary>
    public string Mugshot => _item.Url("Mugshot");

    /// <summary>
    /// Get the file object for Mugshot - or null if it's empty or not referencing a file.
    /// </summary>

    [JsonIgnore]
    public IFile MugshotFile => _item.File("Mugshot");

    /// <summary>
    /// Get the folder object for Mugshot.
    /// </summary>

    [JsonIgnore]
    public IFolder MugshotFolder => _item.Folder("Mugshot");

    /// <summary>
    /// Sex as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Sex", scrubHtml: true) etc.
    /// </summary>
    public string Sex => _item.String("Sex", fallback: "");
  }
}

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: Persons
  • Content/Item Data:
    1. Douglas (ID: 48832)

⬇️ Result | Source ➡️

Inspect the fields of an Item

  1. ✅ LastName: Adams
  2. ✅ IsAlive: False
  3. 🔲 Haters: System.Collections.Generic.List`1[ToSic.Sxc.Data.ITypedItem]
  4. ✅ Birthday: 3/11/1952 12:00:00 AM
  5. ✅ FirstName: Douglas
  6. ✅ Awards: System.Collections.Generic.List`1[ToSic.Sxc.Data.ITypedItem]
  7. 🔲 Sex:
  8. ✅ Mugshot: file:5212
  9. ✅ Biography: <p><strong><img class="wysiwyg-right wysiwyg-50" src="/Portals/tutorial-razor/adam/Tutorial-Razor/Tm5yNs0hAEyc6HIID4k12g/Biography/douglas_adams_portrait.jpg" data-cmsid="file:douglas_adams_portrait.jpg">Douglas No&euml;l Adams</strong>&nbsp;(11 March 1952 &ndash; 11 May 2001) was an English author,&nbsp;<a title="Humorist" href="https://en.wikipedia.org/wiki/Humorist" target="_blank" rel="noopener">humorist</a>, and screenwriter, best known for&nbsp;<i><a title="The Hitchhiker's Guide to the Galaxy" href="https://en.wikipedia.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy" target="_blank" rel="noopener">The Hitchhiker's Guide to the Galaxy</a></i>. Originally a 1978&nbsp;<a title="The Hitchhiker's Guide to the Galaxy (radio series)" href="https://en.wikipedia.org/wiki/The_Hitchhiker%27s_Guide_to_the_Galaxy_(radio_series)" target="_blank" rel="noopener">BBC radio comedy</a>,&nbsp;<i>The Hitchhiker's Guide to the Galaxy</i> developed into a "trilogy" of five books that sold more than 15&nbsp;million copies in his lifetime.&nbsp;<sup id="cite_ref-radioacad_2-0" class="reference"></sup></p>
  10. ✅ FavoriteNumber: 41.99

Let's do some manual inspection

  1. ✅ "FirstName" exits?
  2. 🔲 "FirstName" is empty?
  3. ✅ "FirstName" is not empty?
  4. 🔲 "hello" exits?
  5. ✅ "hello" is empty?
  6. 🔲 "hello" is not empty?
@inherits Custom.Hybrid.RazorTyped

@functions {
  // quick helper to make the output nicer
  string Boolmoji(bool value) { return value ? "✅" : "🔲"; }
}

<h4>Inspect the fields of an Item</h4>
<ol>
  @foreach (var key in MyItem.Keys()) {
    <li>
      @Boolmoji(MyItem.IsNotEmpty(key))
      @key:
      @MyItem.Get(key)
    </li>
  }
</ol>

<h4>Let's do some manual inspection</h4>
<ol>
  <li>@Boolmoji(MyItem.ContainsKey("FirstName")) "FirstName" exits?</li>
  <li>@Boolmoji(MyItem.IsEmpty("FirstName")) "FirstName" is empty?</li>
  <li>@Boolmoji(MyItem.IsNotEmpty("FirstName")) "FirstName" is not empty?</li>
  <li>@Boolmoji(MyItem.ContainsKey("hello")) "hello" exits?</li>
  <li>@Boolmoji(MyItem.IsEmpty("hello")) "hello" is empty?</li>
  <li>@Boolmoji(MyItem.IsNotEmpty("hello")) "hello" is not empty?</li>
</ol>

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: Persons
  • Content/Item Data:
    1. Douglas (ID: 48832)

In some scenarios you need may expect that data isn't there. In that case, you can create fake items to use in your razor.

⬇️ Result | Source ➡️

Inspect the fields of an Item

  1. ✅ FirstName: John
  2. ✅ LastName: Doe
@inherits Custom.Hybrid.RazorTyped

@{
  // Create a mock item, to be used if nothing else is found
  var mockPerson = AsItem(new {
    FirstName = "John",
    LastName = "Doe"
  }, mock: true); // mock: true is required to be sure you wanted this

  // Let's pretend the query may have a stream or may not
  var stream = MyData.GetStream("Guys", emptyIfNotFound: true);

  // Get the item, or the mock if nothing is found
  var guy = AsItem(stream) ?? mockPerson;
}
<h4>Inspect the fields of an Item</h4>
<ol>
  @foreach (var key in guy.Keys()) {
    <li>
      @(guy.IsNotEmpty(key) ? "✅" : "🔲")
      @key:
      @guy.Get(key)
    </li>
  }
</ol>

Work with List of Items - MyItems

⬇️ Result | Source ➡️

Loop persons which were added to this view

  • Douglas Adams
  • Terry Pratchett
  • Neil Gaiman
@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data

<h4>Loop persons which were added to this view</h4>
<ul>
  @foreach (var person in AsList<Persons>(MyItems)) {
    <li>
      @person.Picture("Mugshot", settings: "Square", width: 50, imgClass: "rounded-circle")
      @person.FirstName @person.LastName
    </li>
  }
</ul>

Source Code of Persons.cs

namespace AppCode.Data
{
  public partial class Persons
  {
    /// <summary>
    /// Custom property Presentation - as in these tutorials
    /// the Person always uses a QuickRefContentPresentation content-type for the presentation
    /// </summary>
    public new QuickRefContentPresentation Presentation => _presentation ??= As<QuickRefContentPresentation>(base.Presentation);
    private QuickRefContentPresentation _presentation;
  }
}

Source Code of Persons.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "Persons.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class Persons
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using ToSic.Sxc.Adam;
using ToSic.Sxc.Data;

namespace AppCode.Data
{
  // This is a generated class for Persons 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// Persons data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Awards`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class Persons: AutoGenerated.ZAutoGenPersons
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.Persons in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenPersons: Custom.Data.CustomItem
  {
    /// <summary>
    /// Awards as list of PersonAwards.
    /// </summary>
    /// <remarks>
    /// Generated to return child-list child because field settings had Multi-Value=true. The type PersonAwards was specified in the field settings.
    /// </remarks>
    /// <returns>
    /// An IEnumerable of specified type, but can be empty.
    /// </returns>
    public IEnumerable<PersonAwards> Awards => _awards ??= _item.Children<PersonAwards>("Awards");
    private IEnumerable<PersonAwards> _awards;

    /// <summary>
    /// Biography as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Biography", scrubHtml: true) etc.
    /// </summary>
    public string Biography => _item.String("Biography", fallback: "");

    /// <summary>
    /// Birthday as DateTime.
    /// </summary>
    public DateTime Birthday => _item.DateTime("Birthday");

    /// <summary>
    /// FavoriteNumber as int. <br/>
    /// To get other types use methods such as .Decimal("FavoriteNumber")
    /// </summary>
    public int FavoriteNumber => _item.Int("FavoriteNumber");

    /// <summary>
    /// FirstName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("FirstName", scrubHtml: true) etc.
    /// </summary>
    public string FirstName => _item.String("FirstName", fallback: "");

    /// <summary>
    /// Haters as single item of ITypedItem.
    /// </summary>
    /// <remarks>
    /// Generated to only return 1 child because field settings had Multi-Value=false. 
    /// </remarks>
    /// <returns>
    /// A single item OR null if nothing found, so you can use ?? to provide alternate objects.
    /// </returns>
    public ITypedItem Haters => _haters ??= _item.Child("Haters");
    private ITypedItem _haters;

    /// <summary>
    /// IsAlive as bool. <br/>
    /// To get nullable use .Get("IsAlive") as bool?;
    /// </summary>
    public bool IsAlive => _item.Bool("IsAlive");

    /// <summary>
    /// LastName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("LastName", scrubHtml: true) etc.
    /// </summary>
    public string LastName => _item.String("LastName", fallback: "");

    /// <summary>
    /// Mugshot as link (url). <br/>
    /// To get the underlying value like 'file:72' use String("Mugshot")
    /// </summary>
    public string Mugshot => _item.Url("Mugshot");

    /// <summary>
    /// Get the file object for Mugshot - or null if it's empty or not referencing a file.
    /// </summary>

    [JsonIgnore]
    public IFile MugshotFile => _item.File("Mugshot");

    /// <summary>
    /// Get the folder object for Mugshot.
    /// </summary>

    [JsonIgnore]
    public IFolder MugshotFolder => _item.Folder("Mugshot");

    /// <summary>
    /// Sex as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Sex", scrubHtml: true) etc.
    /// </summary>
    public string Sex => _item.String("Sex", fallback: "");
  }
}

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: Persons
  • Content/Item IsList: True
  • Content/Item Data:
    1. Douglas (ID: 48832)
    2. Terry (ID: 48833)
    3. Neil (ID: 48834)

⬇️ Result | Source ➡️

  • Content number 1
    FYI: Heading none

    We are one!

  • Content two

    FYI: Heading h5

    Two be or !2B

  • Content three 🌟

    FYI: Heading h6

    Three's the charm

@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data

@{
  // Customize the items so that they are typed, with presentation of another known type
  var persons = AsList<Persons>(MyItems);
}
<ul>
  @foreach (var item in persons) {
    // This is typed as QuickRefContentPresentation
    var pres = item.Presentation;
    

    // check if empty, and using nameof to be sure we spelled it right
    var headingTagExists = pres.IsNotEmpty(nameof(pres.HeadingType));
    var title = item.Title + (pres.Highlight ? " 🌟" : "");
    <li>
      @* Create a heading tag the size specified in Presentation *@
      @if (headingTagExists) {
        @Kit.HtmlTags.Custom(pres.HeadingType).Wrap(title)
      } else {
        @title
      }
      <br>
      <em>FYI: Heading @(pres.IsEmpty("HeadingType") ? "none" : pres.HeadingType)</em>
      <div style='color: @pres.Attribute("Color")'>
        @item.Html("Contents")
      </div>
    </li>
  }
</ul>

Source Code of Persons.cs

namespace AppCode.Data
{
  public partial class Persons
  {
    /// <summary>
    /// Custom property Presentation - as in these tutorials
    /// the Person always uses a QuickRefContentPresentation content-type for the presentation
    /// </summary>
    public new QuickRefContentPresentation Presentation => _presentation ??= As<QuickRefContentPresentation>(base.Presentation);
    private QuickRefContentPresentation _presentation;
  }
}

Source Code of Persons.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "Persons.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class Persons
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using ToSic.Sxc.Adam;
using ToSic.Sxc.Data;

namespace AppCode.Data
{
  // This is a generated class for Persons 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// Persons data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Awards`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class Persons: AutoGenerated.ZAutoGenPersons
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.Persons in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenPersons: Custom.Data.CustomItem
  {
    /// <summary>
    /// Awards as list of PersonAwards.
    /// </summary>
    /// <remarks>
    /// Generated to return child-list child because field settings had Multi-Value=true. The type PersonAwards was specified in the field settings.
    /// </remarks>
    /// <returns>
    /// An IEnumerable of specified type, but can be empty.
    /// </returns>
    public IEnumerable<PersonAwards> Awards => _awards ??= _item.Children<PersonAwards>("Awards");
    private IEnumerable<PersonAwards> _awards;

    /// <summary>
    /// Biography as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Biography", scrubHtml: true) etc.
    /// </summary>
    public string Biography => _item.String("Biography", fallback: "");

    /// <summary>
    /// Birthday as DateTime.
    /// </summary>
    public DateTime Birthday => _item.DateTime("Birthday");

    /// <summary>
    /// FavoriteNumber as int. <br/>
    /// To get other types use methods such as .Decimal("FavoriteNumber")
    /// </summary>
    public int FavoriteNumber => _item.Int("FavoriteNumber");

    /// <summary>
    /// FirstName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("FirstName", scrubHtml: true) etc.
    /// </summary>
    public string FirstName => _item.String("FirstName", fallback: "");

    /// <summary>
    /// Haters as single item of ITypedItem.
    /// </summary>
    /// <remarks>
    /// Generated to only return 1 child because field settings had Multi-Value=false. 
    /// </remarks>
    /// <returns>
    /// A single item OR null if nothing found, so you can use ?? to provide alternate objects.
    /// </returns>
    public ITypedItem Haters => _haters ??= _item.Child("Haters");
    private ITypedItem _haters;

    /// <summary>
    /// IsAlive as bool. <br/>
    /// To get nullable use .Get("IsAlive") as bool?;
    /// </summary>
    public bool IsAlive => _item.Bool("IsAlive");

    /// <summary>
    /// LastName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("LastName", scrubHtml: true) etc.
    /// </summary>
    public string LastName => _item.String("LastName", fallback: "");

    /// <summary>
    /// Mugshot as link (url). <br/>
    /// To get the underlying value like 'file:72' use String("Mugshot")
    /// </summary>
    public string Mugshot => _item.Url("Mugshot");

    /// <summary>
    /// Get the file object for Mugshot - or null if it's empty or not referencing a file.
    /// </summary>

    [JsonIgnore]
    public IFile MugshotFile => _item.File("Mugshot");

    /// <summary>
    /// Get the folder object for Mugshot.
    /// </summary>

    [JsonIgnore]
    public IFolder MugshotFolder => _item.Folder("Mugshot");

    /// <summary>
    /// Sex as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Sex", scrubHtml: true) etc.
    /// </summary>
    public string Sex => _item.String("Sex", fallback: "");
  }
}

Source Code of QuickRefContentPresentation.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "QuickRefContentPresentation.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class QuickRefContentPresentation
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
namespace AppCode.Data
{
  // This is a generated class for QuickRefContentPresentation 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// QuickRefContentPresentation data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Color`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class QuickRefContentPresentation: AutoGenerated.ZAutoGenQuickRefContentPresentation
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.QuickRefContentPresentation in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenQuickRefContentPresentation: Custom.Data.CustomItem
  {
    /// <summary>
    /// Color as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Color", scrubHtml: true) etc.
    /// </summary>
    public string Color => _item.String("Color", fallback: "");

    /// <summary>
    /// HeadingType as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("HeadingType", scrubHtml: true) etc.
    /// </summary>
    public string HeadingType => _item.String("HeadingType", fallback: "");

    /// <summary>
    /// Highlight as bool. <br/>
    /// To get nullable use .Get("Highlight") as bool?;
    /// </summary>
    public bool Highlight => _item.Bool("Highlight");
  }
}

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: QuickRefContent
  • Content/Item IsList: True
  • Content/Item Data:
    1. Content number 1 (ID: 49356) - Presentation: green (ID: 49352)
    2. Content two (ID: 49357) - Presentation: red (ID: 49359)
    3. Content three (ID: 49361) - Presentation: cyan (ID: 49360)

⬇️ Result | Source ➡️

Check out this list

  • Content number 1
  • Content two
  • Content three
@inherits Custom.Hybrid.RazorTyped

<h3>@MyHeader.Title</h3>
<ul>
  @foreach (var item in MyItems) {
    <li>
      @item.Title
    </li>
  }
</ul>

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: QuickRefContent
  • Content/Item IsList: True
  • Content/Item Data:
    1. Content number 1 (ID: 49356)
    2. Content two (ID: 49357)
    3. Content three (ID: 49361)
  • Header Type: QuickRefContentHeader
  • Header Item: Check out this list (ID: 49355)

This example builds on the last one, and additionally shows awards these authors have won, which is on the Awards property.

⬇️ Result | Source ➡️

  • Douglas Adams (awards: Hugo Award, Inkpot Award)
  • Terry Pratchett
  • Neil Gaiman
@inherits Custom.Hybrid.RazorTyped
@using AppCode.Data

@{
  var persons = AsList<Persons>(MyItems);
}
<ul>
  @foreach (var person in persons) {
    <li>
      @person.Picture("Mugshot", settings: "Square", width: 50, imgClass: "rounded-circle")
      @person.FirstName @person.LastName
      @if (person.Awards.Any())
      {
        // we just want the award names
        // to understand this, look at the LINQ tutorial
        var awardNames = person.Awards.Select(a => a.String("Name"));
        <span>
          (awards: @string.Join(", ", awardNames))
        </span>
      }
    </li>
  }
</ul>

Source Code of Persons.cs

namespace AppCode.Data
{
  public partial class Persons
  {
    /// <summary>
    /// Custom property Presentation - as in these tutorials
    /// the Person always uses a QuickRefContentPresentation content-type for the presentation
    /// </summary>
    public new QuickRefContentPresentation Presentation => _presentation ??= As<QuickRefContentPresentation>(base.Presentation);
    private QuickRefContentPresentation _presentation;
  }
}

Source Code of Persons.Generated.cs

// DO NOT MODIFY THIS FILE - IT IS AUTO-GENERATED
// See also: https://go.2sxc.org/copilot-data
// To extend it, create a "Persons.cs" with this contents:
/*
namespace AppCode.Data
{
  public partial class Persons
  {
    // Add your own properties and methods here
  }
}
*/

// Generator:   CSharpDataModelsGenerator v17.08.00
// App/Edition: Tutorial-Razor/
// User:        2sic Web-Developer
// When:        2024-05-21 19:46:38Z
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using ToSic.Sxc.Adam;
using ToSic.Sxc.Data;

namespace AppCode.Data
{
  // This is a generated class for Persons 
  // To extend/modify it, see instructions above.

  /// <summary>
  /// Persons data. <br/>
  /// Generated 2024-05-21 19:46:38Z. Re-generate whenever you change the ContentType. <br/>
  /// <br/>
  /// Default properties such as `.Title` or `.Id` are provided in the base class. <br/>
  /// Most properties have a simple access, such as `.Awards`. <br/>
  /// For other properties or uses, use methods such as
  /// .IsNotEmpty("FieldName"), .String("FieldName"), .Children(...), .Picture(...), .Html(...).
  /// </summary>
  public partial class Persons: AutoGenerated.ZAutoGenPersons
  {  }
}

namespace AppCode.Data.AutoGenerated
{
  /// <summary>
  /// Auto-Generated base class for Default.Persons in separate namespace and special name to avoid accidental use.
  /// </summary>
  public abstract class ZAutoGenPersons: Custom.Data.CustomItem
  {
    /// <summary>
    /// Awards as list of PersonAwards.
    /// </summary>
    /// <remarks>
    /// Generated to return child-list child because field settings had Multi-Value=true. The type PersonAwards was specified in the field settings.
    /// </remarks>
    /// <returns>
    /// An IEnumerable of specified type, but can be empty.
    /// </returns>
    public IEnumerable<PersonAwards> Awards => _awards ??= _item.Children<PersonAwards>("Awards");
    private IEnumerable<PersonAwards> _awards;

    /// <summary>
    /// Biography as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Biography", scrubHtml: true) etc.
    /// </summary>
    public string Biography => _item.String("Biography", fallback: "");

    /// <summary>
    /// Birthday as DateTime.
    /// </summary>
    public DateTime Birthday => _item.DateTime("Birthday");

    /// <summary>
    /// FavoriteNumber as int. <br/>
    /// To get other types use methods such as .Decimal("FavoriteNumber")
    /// </summary>
    public int FavoriteNumber => _item.Int("FavoriteNumber");

    /// <summary>
    /// FirstName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("FirstName", scrubHtml: true) etc.
    /// </summary>
    public string FirstName => _item.String("FirstName", fallback: "");

    /// <summary>
    /// Haters as single item of ITypedItem.
    /// </summary>
    /// <remarks>
    /// Generated to only return 1 child because field settings had Multi-Value=false. 
    /// </remarks>
    /// <returns>
    /// A single item OR null if nothing found, so you can use ?? to provide alternate objects.
    /// </returns>
    public ITypedItem Haters => _haters ??= _item.Child("Haters");
    private ITypedItem _haters;

    /// <summary>
    /// IsAlive as bool. <br/>
    /// To get nullable use .Get("IsAlive") as bool?;
    /// </summary>
    public bool IsAlive => _item.Bool("IsAlive");

    /// <summary>
    /// LastName as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("LastName", scrubHtml: true) etc.
    /// </summary>
    public string LastName => _item.String("LastName", fallback: "");

    /// <summary>
    /// Mugshot as link (url). <br/>
    /// To get the underlying value like 'file:72' use String("Mugshot")
    /// </summary>
    public string Mugshot => _item.Url("Mugshot");

    /// <summary>
    /// Get the file object for Mugshot - or null if it's empty or not referencing a file.
    /// </summary>

    [JsonIgnore]
    public IFile MugshotFile => _item.File("Mugshot");

    /// <summary>
    /// Get the folder object for Mugshot.
    /// </summary>

    [JsonIgnore]
    public IFolder MugshotFolder => _item.Folder("Mugshot");

    /// <summary>
    /// Sex as string. <br/>
    /// For advanced manipulation like scrubHtml, use .String("Sex", scrubHtml: true) etc.
    /// </summary>
    public string Sex => _item.String("Sex", fallback: "");
  }
}

View Configuration

This is how this view would be configured for this sample.

  • Content/Item ContentType: Persons
  • Content/Item IsList: True
  • Content/Item Data:
    1. Douglas (ID: 48832)
    2. Terry (ID: 48833)
    3. Neil (ID: 48834)