App


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.
Switch to Typed (2sxc 16+) Selected: 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.Razor14

@Kit.Image.Img(Content.Field("Mugshot"), settings: "Square", width: 100, imgClass: "rounded-circle")
<ul>
  <li>Name: @Content.FirstName @Content.LastName</li>
  <li>Birthday: @Content.Birthday.ToString("d")</li>
  <li>Award: @Content.Awards.Name</li>
</ul>

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

View Configuration

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

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

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, the current Content-item

  1. Content item Name: Douglas Adams
  2. Content item Birthday: 3/11/1952
  3. Content item Award: Hugo Award
  4. Content item Mugshot URL: /razortutorial12/app/Tutorial-Razor/adam/Tm5yNs0hAEyc6HIID4k12g/Mugshot/douglas adams.png
  5. Content item Mugshot Raw String: file:137

Loop the persons in the Query for this view

  • Douglas Adams
  • Terry Pratchett
  • Neil Gaiman
@inherits Custom.Hybrid.Razor14
@using ToSic.Razor.Blade;

<h4>Douglas Adams, the current Content-item</h4>
@Kit.Image.Img(Content.Field("Mugshot"), settings: "Square", width: 100, imgClass: "rounded-circle")
<ol>
  <li>Content item Name:        @Content.FirstName @Content.LastName</li>
  <li>Content item Birthday:    @Content.Birthday.ToString("d")</li>
  <li>Content item Award:       @Content.Awards.Name</li>
  <li>Content item Mugshot URL: @Content.Mugshot</li>
  <li>Content item Mugshot Raw String: @(Content.Get<string>("Mugshot"))</li>
</ol>
<h4>Loop the persons in the Query for this view</h4>
<ul>
  @foreach (var person in AsList(Data)) {
    <li>
      @if (Text.Has(person.Mugshot)) {
        @Kit.Image.Img(Content.Field("Mugshot"), settings: "Square", width: 50, imgClass: "rounded-circle")
      }
      @person.FirstName @person.LastName
    </li>
  }
</ul>

View Configuration

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

  • Content/Item ContentType: Persons
  • Content/Item Data:
    1. Douglas (ID: 46284)
  • Query: QuickRef-Persons-Selected
Details for Query: QuickRef-Persons-Selected

This query will retrieve Terry Pratchett on one stream, and 3 other persons an another stream.

  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 Content

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.Razor14
@using ToSic.Razor.Blade

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

  // 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>
  @Html.Raw(Content.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: 46284)

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 Content

Note that the following should be (probably green)

@inherits Custom.Hybrid.Razor14

<h4>A Person on <code>Content</code></h4>
@{
  var itemPres = Content.Presentation;
}

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

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: 46806) - Presentation: green (ID: 46802)
    2. Content two (ID: 46807) - Presentation: red (ID: 46809)
    3. Content three (ID: 46811) - Presentation: cyan (ID: 46810)
  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 .Awards to get one

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

Use .Awards to get all

Award Count: 2
  1. Award: Hugo Award
  2. Award: Inkpot Award
@inherits Custom.Hybrid.Razor14

</hide-silent>
<h4>Use <code>.Awards</code> to get one</h4>
<ol>
  <li>Award ID:          @Content.Awards.Id</li>
  <li>Award Name:        @Content.Awards.Name</li>
  <li>Award Name (Path): @Content.Awards.Name</li>
</ol>



<h4>Use <code>.Awards</code> to get all</h4>
<span>Award Count:       @Content.Awards.Count</span>
<ol>
  @foreach (var award in AsList(Content.Awards as object)) {
    <li>Award: @award.Name</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: 46284)
  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 field Value: /razortutorial12/app/Tutorial-Razor/adam/Tm5yNs0hAEyc6HIID4k12g/Mugshot/douglas adams.png
  2. Mugshot URL: /razortutorial12/app/Tutorial-Razor/adam/Tm5yNs0hAEyc6HIID4k12g/Mugshot/douglas adams.png
  3. Mugshot Picture
@inherits Custom.Hybrid.Razor14

<h4>Douglas Adams, the current item (MyItem)</h4>
<p>Use <code>.Url(…)</code> to resolve file references such as <code>file:72</code></p>
<ol>
  <li>Mugshot field Value:  @Content.Mugshot</li>
  <li>Mugshot URL:          @Content.Mugshot</li>
  <li>
    Mugshot Picture <br>
    @Kit.Image.Picture(Content.Mugshot, settings: "Square", width: 100, imgClass: "rounded-circle")
  </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: 46284)

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

⬇️ Result | Source ➡️

Douglas Adams, the current item (Content)

  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.Razor14
@using System.Linq

<h4>Douglas Adams, the current item (Content)</h4>
@{
  var folder = AsAdam(Content, "Mugshot") as ToSic.Sxc.Adam.IFolder;
  var file = folder.Files.First();
  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>

<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>

View Configuration

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

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

⬇️ Result | Source ➡️

Inspect the fields of an Item

  1. ✅ LastName: Adams
  2. ✅ IsAlive: False
  3. ✅ Haters: ToSic.Sxc.Data.DynamicEntity
  4. ✅ Birthday: 3/11/1952 12:00:00 AM
  5. ✅ FirstName: Douglas
  6. ✅ Awards: ToSic.Sxc.Data.DynamicEntity
  7. ✅ Sex:
  8. ✅ Mugshot: /razortutorial12/app/Tutorial-Razor/adam/Tm5yNs0hAEyc6HIID4k12g/Mugshot/douglas adams.png
  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>

Let's do some manual inspection

  1. ✅ "FirstName" exits and not empty?
  2. 🔲 "FirstName" exits and not empty?
@inherits Custom.Hybrid.Razor14
@using ToSic.Razor.Blade

@functions {
  // quick helper to make the output nicer
  string Boolmoji(bool value) { return value ? "✅" : "🔲"; }
}
@{
  var keys = new [] { "LastName", "IsAlive", "Haters", "Birthday",
    "FirstName", "Awards", "Sex", "Mugshot", "Biography" };
}
<h4>Inspect the fields of an Item</h4>
<ol>
  @foreach (var key in keys) {
    var value = Content.Get(key);
    <li>
      @Boolmoji(value != null || (value is string && Text.Has(value)))
      @key:
      @value
    </li>
  }
</ol>

<h4>Let's do some manual inspection</h4>
<ol>
  <li>@Boolmoji(Text.Has(Content.Firstname)) "FirstName" exits and not empty?</li>
  <li>@Boolmoji(Text.Has(Content.hello)) "FirstName" exits and 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: 46284)

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.Razor14
@using ToSic.Razor.Blade;
@{
  // Create a mock item, to be used if nothing else is found
  var mockPerson = AsDynamic(new {
    FirstName = "John",
    LastName = "Doe"
  });

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

  // Get the item, or the mock if nothing is found
  var guyFromStream = AsDynamic(stream);
  // If EntityId is 0, then this indicates a virtual placeholder
  // This is a bit clumsy - which is why we recommond the typed methods
  var guy = (guyFromStream.EntityId == 0) ? guyFromStream : mockPerson;
}
<h4>Inspect the fields of an Item</h4>
<ol>
  <li>
    @(Text.Has(guy.FirstName) ? "✅" : "🔲")
    FirstName: @guy.FirstName
  </li>
  <li>
    @(Text.Has(guy.LastName) ? "✅" : "🔲")
    LastName: @guy.LastName
  </li>
</ol>

Work with List of Items - MyItems

Every view/template receives prepared data, either entered by the user on this page, or provided through a query. It can contain many items - so to get the list, use AsList(Data).

If a view has many items assigned (called a list) these should be retrieved from Data - if you don't specify a stream, it's treated as Data["Default"]. You will usually want to convert it to a dynamic list using AsList(...). This example also uses Text.Has(...) to only show a picture if it really has a mugshot.

⬇️ Result | Source ➡️

Loop persons which were added to this view

  • Douglas Adams
  • Terry Pratchett
  • Neil Gaiman
@inherits Custom.Hybrid.Razor14
@using ToSic.Razor.Blade

<h4>Loop persons which were added to this view</h4>
<ul>
@foreach (var person in AsList(Data)) {
  <li>
    @if (Text.Has(person.Mugshot)) {
      @Kit.Image.Img(person.Field("Mugshot"), settings: "Square", width: 50, imgClass: "rounded-circle")
    }
    @person.FirstName @person.LastName
  </li>
}
</ul>

View Configuration

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

  • Query: QuickRef-Persons-Selected
Details for Query: QuickRef-Persons-Selected

This query will retrieve Terry Pratchett on one stream, and 3 other persons an another stream.

⬇️ Result | Source ➡️

  • Create a heading tag the size specified in Presentation Content number 1
    FYI: Heading

    We are one!

  • Create a heading tag the size specified in Presentation
    Content two

    FYI: Heading none

    Two be or !2B

  • Create a heading tag the size specified in Presentation
    Content three 🌟

    FYI: Heading none

    Three's the charm

@inherits Custom.Hybrid.Razor14
@using ToSic.Razor.Blade;


<ul>
  @foreach (var item in AsList(Data)) {
    var pres = item.Presentation;
    
    var hType = pres.HeadingType;
    var title = item.Title + (pres.Highlight == true ? " 🌟" : "");
    <li>
      Create a heading tag the size specified in Presentation
      @if (Text.Has(hType)) {
        @Kit.HtmlTags.Custom(hType).Wrap(title)
      } else {
        @title
      }
      <br>
      <em>FYI: Heading @(Text.Has(hType) ? "none" : hType)</em>
      <div style='color: @pres.Color'>
        @item.Html("Contents")
      </div>
    </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: 46806) - Presentation: green (ID: 46802)
    2. Content two (ID: 46807) - Presentation: red (ID: 46809)
    3. Content three (ID: 46811) - Presentation: cyan (ID: 46810)

⬇️ Result | Source ➡️

Check out this list

  • Douglas
  • Terry
  • Neil
@inherits Custom.Hybrid.Razor14

<h3>@Header.Title</h3>
<ul>
  @foreach (var item in AsList(Data)) {
    <li>
      @item.EntityTitle
    </li>
  }
</ul>

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: 46284)
    2. Terry (ID: 46285)
    3. Neil (ID: 46286)
  • Header Type: QuickRefContentHeader
  • Header Item: Check out this list (ID: 46805)

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.Razor14
@using ToSic.Razor.Blade

<ul>
  @foreach (var person in AsList(Data)) {
    <li>
      @if (Text.Has(person.Mugshot)) {
        <img loading="lazy" src="@person.Mugshot?w=50&h=50&mode=crop" width="50px" style="border-radius: 50%">
      }
      @person.FirstName @person.LastName
      @if (person.Awards.Count > 0 ) {
        // we just want the award names
        // to understand this, look at the LINQ tutorial
        var awardNames = AsList(person.Awards as object).Select(a => a.Name);
        <span>
          (awards: @string.Join(",", awardNames))
        </span>
      }
    </li>
  }
</ul>

View Configuration

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

  • Query: QuickRef-Persons-Selected
Details for Query: QuickRef-Persons-Selected

This query will retrieve Terry Pratchett on one stream, and 3 other persons an another stream.