Skip to main content
Home  › ... Razor

RazorBlade Fluid HTML API Tutorial

Tutorial HomeRazorBlade Tags

RazorBlade Basic Html5 Tag API Introduction v3.0

Learn how to use ToSic.Razor.Blade fluent Tag API to do really cool stuff. This uses ToSic.Razor.Blade.

This API lets you safely create html from code in an elegant way. This basic introduction shows the most basic principles you can apply, and we'll build on that in the next tutorials.

Basic Principles

  1. Quick, Safe Construction
    @Tag.Div() will created typed objects to generate Html5. The Div can be any known Html5 tag, so @Tag.Img()@Tag.Table()@Tag.Br() will all work.
    👉 Here is the complete list
  2. Wrap Text and Tags in the constructor
    Use @Tag.Div("hello!") to put content into a tag. You can also put tags inside tags like @Tag.Div(Tag.H3("a title")), and also add an unlimited list of things with @Tag.Div(Tag.H3("Title"), Tag.P("some intro text"), ...)
  3. Add more Text & Tags later on
    Sometimes your code will want to add content step-by-step. You can always do this using .Add(...), so you can write @Tag.Div(Tag.H3("title")).Add(Tag.P("body"))
  4. Replace the contents completely
    Maybe you've contstructed some tags but now the code needs to throw away the previous content and replace it. Use .Wrap(...) for this. So
    @Tag.Div(Tag.H3("...")).Wrap("just reset the content") will completely replace the whole contents with the text.
  5. Set Common Attributes
    Each tag object has many commands on it like Id(...)Class(...)Style(...)Title(...). The result of these commands is always the original object, so you can chain these (fluid API). So you can write @Tag.Div().Id("myId").Class("row highlighted").
    Important: Some attributes are extra smart, like Class or Style, which will SmartJoin the values if called multiple times. Read the special tutorial for that.
  6. Set Tag-Specific Attributes
    All known html5 objects are supported, and return specially typed objects. So you can write @Tag.Img().Src("...") or @Tag.A().Href(...), but @Tag.Img().Href(...) won't work.
    Important: Some attributes are extra smart, like Src on Img or Srcset on Source. Read the special tutorial for that.

 

Instead of trying to merge strings like
<div and id='@yourId' and > followed by the content and closed by </div>
you would instead write:
@Tag.Div("your content").Id("wrapper")
Here's what you get with an @Tag.H4(...) and @Tag.Div(...) and when you combine them...

⬇️ Result | Source ➡️

Example 1: This title was code-generated

This div was coded

Example 2a: This h4 title is inside the div

and this text in the div follows the title

Example 2b: This h4 title is inside the div

and this text in the div follows the title
@inherits Custom.Hybrid.RazorTyped
@using ToSic.Razor.Blade

@* this will place an HR in the page - not very useful, but just for a first example *@
@Tag.H3("Example 1: This title was code-generated")

@* now let's create a bootstrap-style box *@
@Tag.Div("This div was coded").Class("alert alert-warning")

@Tag.Div(
  Tag.H4("Example 2a: This h4 title is inside the div"),
  "and this text in the div ",
  Tag.Em("follows the title")
).Class("alert alert-warning")

@* Same example as 2a, but written in a more fluid way *@
@Tag.Div().Class("alert alert-warning").Wrap(
  Tag.H4("Example 2b: This h4 title is inside the div"),
  "and this text in the div ",
  Tag.Em("follows the title")
)

The following example creates the same div as before, but is written in a more fluid style.

Example 3: Using Tag.Div

⬇️ Result | Source ➡️

This is the intro. I hope you like it otherwise it's ok too 😉
@inherits Custom.Hybrid.RazorTyped
@using ToSic.Razor.Blade

@(Tag.Div("This is the intro. ", 
      Tag.B("I hope you like it"), 
      Tag.I(" otherwise it's ok too"), 
      " 😉"
      )
      .Id("wrapper")
      .Class("alert")
      .Class("alert-dark"))

Now the real power start: using the Wrap method, you can add more content to your tag - and this can be both text, more Tag objects or even lists of Tag objects. Wrap always replaces the content, and you could also use Add(...) instead to append stuff.

⬇️ Result | Source ➡️

Did you know, that you can add text...and tags
as well as more tags and strings inside it?
@inherits Custom.Hybrid.RazorTyped
@using ToSic.Razor.Blade

@{
  var darkBox = Tag.Div()
    .Class("alert alert-dark")
    .Wrap(
      "Did you know, that you can add text...",
      Tag.Code("and tags"),
      Tag.Div(
        "as well as more ", 
        Tag.B("tags"),
        " and strings inside it?"
      )
        .Class("alert")
        .Class("alert-danger")
    );

}
@darkBox

A Tag object also has a .TagStart and .TagEnd property, which just contains that part of the tag, allowing you to place these tags around your work.

⬇️ Result | Source ➡️

This tag was written using both .TagStart and .TagEnd because it may be easier for you that way.
@inherits Custom.Hybrid.RazorTyped
@using ToSic.Razor.Blade

@{
  var successBox = Tag.Div().Class("alert alert-success");
}
@successBox.TagStart
  This tag was written using both <code>.TagStart</code> and <code>.TagEnd</code> 
  because it may be easier for you that way.
@successBox.TagEnd

All Html5 tags are available under Tag.xxx(). In case you need a custom tag - like an for angular, you'll need the @Tag.Custom(...).

⬇️ Result | Source ➡️

This is a title

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

@{
  var headingType = "h3";
}
@Tag.Custom(headingType).Wrap("This is a title")

⬇️ Result | Source ➡️

this is a italic text
@inherits Custom.Hybrid.RazorTyped
@using ToSic.Razor.Blade

@Tag.Custom("em").Wrap("this is a italic text")

RazorBlade IdTitleClass(...) and Style(...) with SmartJoin

All html attributes can have these Properties

  • id - made with .Id(...) (replaces previous id)
  • class - made with .Class(...) (expands previous class)
  • style - made with .Style(...) (expands previous style)
  • title - made with .Title(...) (replaces previous title)

So Tag objects have quick commands to set these. What makes it magical is that they always return the main object again, so you can chain them like
@Tag.Div().Id("wrapper").Class("alert").Class("alert-primary)

Info: SmartJoin

Note that some of these, like Id will replace the previous value. Others like Class will add new values to the attribute.

Imagine your code will add attributes step by step by using some kind of logic. In situations where you add more classes, they should be appended - like firstClass secondClass. Others should be appended with a special character like ; in styles because you want width: 75px; height: 25px. And others should replace the previous value - like id should always only have one value.

⬇️ Result | Source ➡️

  1. @Tag.Div().Id("original").Id("replaced") will get you <div id='replaced'></div>
  2. @Tag.Div().Class("original").Class("replaced") will get you <div class='original replaced'></div>
  3. @Tag.Div().Style("width: 75px").Style("height: 100px") will get you <div style='width: 75px;height: 100px'></div>
@inherits Custom.Hybrid.RazorTyped
@using ToSic.Razor.Blade

<ol>
  <li>
    <code>@@Tag.Div().Id("original").Id("replaced")</code>
    will get you 
    <code>@Tag.Div().Id("original").Id("replaced").ToString()</code>
  </li>
  <li>
    <code>@@Tag.Div().Class("original").Class("replaced")</code>
    will get you 
    <code>@Tag.Div().Class("original").Class("replaced").ToString()</code>
  </li>
  <li>
    <code>@@Tag.Div().Style("width: 75px").Style("height: 100px")</code>
    will get you 
    <code>@Tag.Div().Style("width: 75px").Style("height: 100px").ToString()</code>
  </li>
</ol>

RazorBlade Safe Attributes API @Tag.Attr v3

Here we'll go through some examples using @Tag.Attr(...)

⬇️ Result | Source ➡️

This is a simple demo showing how to add the title and class attribute using code.
It switches between warning/primary depending of the second being odd or even. Refresh the page to see the difference.
If you mouse-over, you'll also see the tooltips showing stuff which would cause trouble otherwise.
@inherits Custom.Hybrid.RazorTyped
@using ToSic.Razor.Blade

@{
  var titleWithIssues = "I said \"check this out!\" \n\n even 'different quotes' and line breaks work!";
  var cls = "alert alert-";
  cls += (DateTime.Now.Second % 2 == 0) ? "warning" : "primary";
}
<div @Tag.Attr("title", titleWithIssues) 
  @Tag.Attr("class", cls)
  @Tag.Attr("number", 27)>
  This is a simple demo showing how to add... <!-- unimportant stuff, hidden -->
</div>

Here we'll go through some more advanced examples using @Tag.Attr(...)

⬇️ Result | Source ➡️

This div has an attribute created using an object, because we wanted json. If you look at the source, youll find data-my='{"Name":"razor","Description":"This isn\u0027t your normal text - it has \n line breaks and apostrophes"}'
@inherits Custom.Hybrid.RazorTyped
@using ToSic.Razor.Blade

@{
  // this is the object we want in the data-attribute
  var myObj = new { 
    Name = "razor", 
    Description="This isn't your normal text - it has \n line breaks and apostrophes"
  };
}
<div class="alert alert-secondary" @Tag.Attr("data-my", myObj)>
  This div has an attribute created using... <!-- unimportant stuff, hidden -->
</div>