App
Quick Reference for all APIs
This is a quick CheatSheet to provide you with a reference to most APIs you'll use.
This uses a base class of @inherits Custom.Hybrid.Razor14
and would also apply to ...Razor12
. Most samples do not work for the new @inherits Custom.Hybrid.Razorpro
as that provides different objects and methods. that uses a different syntax.
Switch to Typed (2sxc 16+) Selected: Dynamic (Razor14 or below)
- Show firstName (string): Terry
-
Show birthday (DateTime):
4/28/1948 12:00:00 AM -
Show birthday (DateTime, formatted):
1948-04-28 - Show age (int): 76
- Show decades (int): 7
- Show decadesFloat (float): 7.6
- Show decadesInt (int): 7
- Basic set variable and show
Create variables and show using
@variableName
⬇️ Result | Source ➡️
Show old/not old based on Terry's age using
@if
and @else
:
this guy is old
Ternare show old/not old based on age ? ... :
:
this guy is old
- Razor Conditions such as if, if-else and ? :
if/else and ternary operator
(condition ? true : false)
⬇️ Result | Source ➡️
Loop through Pets using
@foreach (var thing in list)
- dog
- cat
- mouse
Loop through Pets using
@for (counter; condition; increment)
- dog - owned by Daniel
- cat - owned by John
- mouse - owned by Markus
- Loops -
for
andforeach
Loops using
for()
andforeach()
⬇️ Result | Source ➡️
Output values (HTML-source shown)
- this is text, it doesn't have tags
- this string <em>has</em> html <strong>tags</strong>
Output values (HTML is used; maybe security risk)
- this is text, it doesn't have tags
- this string has html tags
- Work with HTML Output
Learn the difference of showing variables with
@variable
and@Html.Raw(variable)
, and re-use very simple snippets
⬇️ Result | Source ➡️
You can just use any Emoji in your source. Or you pick them with ternary operations.
- This is just an emoji: 🚀
- Pick emoji from true ⇒ ✔️
- Pick emoji from true ⇒ ❌
- Working with 😃 Emojis / Emoticons
Show Emojis in your output or use them for showing true/false
A common task is to link to a specific page or to stay on the same page but with different URL parameters.
⬇️ Result | Source ➡️
Normally you would use the following in an href
attribute.
Current Page
- This page URL:
https://oqt-apps-dev.2sxc.org/razortutorial12
- This page url params:
mode=set&tut=quickref&variant=dyn
- Link this page without params:
https://oqt-apps-dev.2sxc.org/razortutorial12
- Link this page with same params:
https://oqt-apps-dev.2sxc.org/razortutorial12?mode=set&tut=quickref&variant=dyn
- Link this page with same params:
https://oqt-apps-dev.2sxc.org/razortutorial12?mode=set&tut=quickref&variant=dyn
- Link this page with more params:
https://oqt-apps-dev.2sxc.org/razortutorial12?mode=set&tut=quickref&variant=dyn&another&more=27&more=42
- Link this page remove params:
https://oqt-apps-dev.2sxc.org/razortutorial12?mode=set&tut=quickref&variant=dyn
- Link this page replace params:
https://oqt-apps-dev.2sxc.org/razortutorial12?mode=set&tut=quickref&variant=dyn&quick-ref-typed=test
Another Page
This only works if you don't have a page 12, otherwise you'll see an error in the url.
- Link to page 12 without params:
https://oqt-apps-dev.2sxc.org/admin/profiles
- Link to page 12 with current params:
https://oqt-apps-dev.2sxc.org/admin/profiles?mode=set&tut=quickref&variant=dyn
Reuse Razor and CSharp Files
Don't-Repeat-Yourself (DRY) by reusing code in Razor and helper C# files.
⬇️ Result | Source ➡️
Reuse some functions inside this file
- Boolmoji(true) ⇒ 👍🏽
- Boolmoji(false) ⇒ 👎🏽
- Random number function: 24
- Random number function: 11
- this is a bold item in a list using a Template Delegate
- another bold item in a list using a Template Delegate
- Code - Function and Similar Helpers
Normal C# functions are the basic block for reusing code.
- Reuse Shared Razor Helpers (CreateInstance / GetCode)
Use a shared razor file to hold multiple functions / helpers, and call them one-by-one as needed.
- Reuse Code and Razor Templates
Explains the basics of re-using code across templates and code files.
⬇️ Result | Source ➡️
Call some external Razor files
- Reuse Shared Templates with Html.Partial and MyModel
Reuse Razor files by calling them using
@Html.Partial
and passing parameters in DynamicModel (or MyModel).
⬇️ Result | Source ➡️
Call some external Razor files
-
Hello, this is the first line
-
Second line!
-
Third line!
- Reuse Shared Templates with Html.Partial and MyModel
Reuse Razor files by calling them using
@Html.Partial
and passing parameters in DynamicModel (or MyModel).
Reuse Partial Razor and functions from Helper Code files.
⬇️ Result | Source ➡️
Call some Code in External CSharp Files
- Hello from shared lib: Hello!
- QR Code from shared lib
- Reuse Shared Razor Helpers (CreateInstance / GetCode)
Use a shared razor file to hold multiple functions / helpers, and call them one-by-one as needed.
Razor doesn't know about types inside code files, so you need some tricks to work with objects which are passed around.
⬇️ Result | Source ➡️
Working with anonymous objects
The only way to get values from an anonymous object
created elsewhere is using
AsDynamic(... as object)
.
Everything else will cause difficulties.
- Anon: { Name = John, Age = 30 }
- Anon Type: <>f__AnonymousType0`2[System.String,System.Int32]
- anon.Name 🚫: ⚠️ Exception: 'object' does not contain a definition for 'Name'
- dynAnon.Name ✅: John
Working with ITyped
objects
If the returned object is based on ITyped
, things are a bit easier.
But you must still ensure that Razor knows the type.
- Name ✅: John
Working with real objects
If the returned object is based on a class defined inside the code, things are a bit easier.
- Person: ReturnObjects+Person
- Person Type: ReturnObjects+Person
- Person.Name ✅: John
- dynPerson.Get("Name") ✅: John
Working with dictionaries
If the returned object is based on a dictionary, things are a bit easier.
This is because dynamic
will be able to work with it, but it's not type safe.
- dicDyn: System.Collections.Generic.Dictionary`2[System.String,System.String]
- dicDyn Type: System.Collections.Generic.Dictionary`2[System.String,System.String]
- dicDyn Count ✅: 2
- dicDyn["Name"] ✅: John
- dic: System.Collections.Generic.Dictionary`2[System.String,System.String]
- dic Type: System.Collections.Generic.Dictionary`2[System.String,System.String]
- dic Count ✅: 2
- dic["Name"] ✅: John
- Reuse Shared Razor Helpers (CreateInstance / GetCode)
Use a shared razor file to hold multiple functions / helpers, and call them one-by-one as needed.
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
- Content item Name: Douglas Adams
- Content item Birthday: 3/11/1952
- Content item Award: Hugo Award
- Content item Mugshot URL: /razortutorial12/app/Tutorial-Razor/adam/Tm5yNs0hAEyc6HIID4k12g/Mugshot/douglas adams.png
- Content item Mugshot Raw String: file:137
Loop the persons in the Query for this view
- Douglas Adams
- Terry Pratchett
- Neil Gaiman
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- 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.
- 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.
- 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…
(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 comedy, The Hitchhiker's Guide to the Galaxy developed into a "trilogy" of five books that sold more than 15 million copies in his lifetime.
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- 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)
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: QuickRefContent
- Content/Item IsList: True
- Content/Item Data:
- Content number 1 (ID: 46806) - Presentation: green (ID: 46802)
- Content two (ID: 46807) - Presentation: red (ID: 46809)
- Content three (ID: 46811) - Presentation: cyan (ID: 46810)
- 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.
- 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
- Award ID:
- Award Name: Hugo Award
- Award Name (Path): Hugo Award
Use .Awards
to get all
Award Count: 2
- Award: Hugo Award
- Award: Inkpot Award
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- Douglas (ID: 46284)
- 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.
- 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
- Mugshot field Value: /razortutorial12/app/Tutorial-Razor/adam/Tm5yNs0hAEyc6HIID4k12g/Mugshot/douglas adams.png
- Mugshot URL: /razortutorial12/app/Tutorial-Razor/adam/Tm5yNs0hAEyc6HIID4k12g/Mugshot/douglas adams.png
-
Mugshot Picture
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- 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)
- File name: douglas adams
- File extension: png
- Size (bytes): 39125
- SizeInfo: 38.2 KB
Every file-field is actually a folder...
- Files count: 2
- Sub-Folders: 0
...which could hold many files.
If you want to show them, you need Kit.Image...
- douglas adams
- not-panicking
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- Douglas (ID: 46284)
⬇️ Result | Source ➡️
Inspect the fields of an Item
- ✅ LastName: Adams
- ✅ IsAlive: False
- ✅ Haters: ToSic.Sxc.Data.DynamicEntity
- ✅ Birthday: 3/11/1952 12:00:00 AM
- ✅ FirstName: Douglas
- ✅ Awards: ToSic.Sxc.Data.DynamicEntity
- ✅ Sex:
- ✅ Mugshot: /razortutorial12/app/Tutorial-Razor/adam/Tm5yNs0hAEyc6HIID4k12g/Mugshot/douglas adams.png
- ✅ 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ël Adams</strong> (11 March 1952 – 11 May 2001) was an English author, <a title="Humorist" href="https://en.wikipedia.org/wiki/Humorist" target="_blank" rel="noopener">humorist</a>, and screenwriter, best known for <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 <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>, <i>The Hitchhiker's Guide to the Galaxy</i> developed into a "trilogy" of five books that sold more than 15 million copies in his lifetime. <sup id="cite_ref-radioacad_2-0" class="reference"></sup></p>
Let's do some manual inspection
- ✅ "FirstName" exits and not empty?
- 🔲 "FirstName" exits and not empty?
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item Data:
- 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
- ✅ FirstName: John
- ✅ LastName: Doe
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
⬇️ Result | Source ➡️
-
Create a heading tag the size specified in Presentation
Content number 1
FYI: HeadingWe are one!
-
Create a heading tag the size specified in Presentation
Content two
FYI: Heading noneTwo be or !2B
-
Create a heading tag the size specified in Presentation
Content three 🌟
FYI: Heading noneThree's the charm
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: QuickRefContent
- Content/Item IsList: True
- Content/Item Data:
- Content number 1 (ID: 46806) - Presentation: green (ID: 46802)
- Content two (ID: 46807) - Presentation: red (ID: 46809)
- Content three (ID: 46811) - Presentation: cyan (ID: 46810)
⬇️ Result | Source ➡️
Check out this list
- Douglas
- Terry
- Neil
View Configuration
This is how this view would be configured for this sample.
- Content/Item ContentType: Persons
- Content/Item IsList: True
- Content/Item Data:
- Douglas (ID: 46284)
- Terry (ID: 46285)
- Neil (ID: 46286)
- Header Type: QuickRefContentHeader
- Header Item: Check out this list (ID: 46805)
Every view/template receives prepared data, either entered by the user on this page, or provided through a query.
⬇️ Result | Source ➡️
Loop persons in Query of this view
- Douglas Adams
- Terry Pratchett
- Neil Gaiman
This uses a query which returns a list of Persons and a selected person separately. The Default
stream has persons, and Selected
has a selected person to compare with. Compare using .Equals(…)
.
⬇️ Result | Source ➡️
- Douglas Adams
- Terry Pratchett (selected ⭐)
- Neil Gaiman
⬇️ Result | Source ➡️
Get Books from the Default
stream
- Hitchhikers Guide to the Galaxy
- Good Omens
- Phishing for Phools
- The Last Continent
Get Authors from the Authors
stream
- Douglas
- Terry
- Neil
- George
- Raphael
- Ed
⬇️ Result | Source ➡️
Let's see the if anything exists
- ✅ Authors exists?
- 🔲 Critics exists?
- ✅ Players exists?
- ✅ Critics || Authors exists?
- ✅ Players || Authors exists?
Now let's count what's inside
- Authors: 6
- Critics: skip
- Players: 0
- Critics || Authors: 6
- Players || Authors: 0
Work with Settings and Resources
Settings can be configured at many levels, the most-local (eg. the App) would override the most global (eg. Presets).
⬇️ Result | Source ➡️
Get some App Setting / Resources
- Setting CustomColor:
#E91E63F2
- Setting CsvFile:
/razortutorial12/app/Tutorial-Razor/adam/FP6nrGBJZUKPRnldQOMQEQ/CsvFile/products.csv
/razortutorial12/app/Tutorial-Razor/adam/FP6nrGBJZUKPRnldQOMQEQ/CsvFile/products.csv
- Resource ButtonOrder:
Get Global Settings
- Settings.Get("Images.Content.Width")
1400
- The same with prefix
Settings
1400
- GoogleMaps.DefaultCoordinates
{"latitude":47.1747,"longitude":9.4692}
- GoogleMaps.DefaultCoordinates as Typed
Lat: 47.1747
Lng: 9.4692
- Settings in 2sxc
Settings allow your code to use predefined settings across all apps and sites. And they allow you to overide a setting at any level of the application. You can read more about the settings in the docs 📕 .
Set Page Title, Keywords etc.
⬇️ Result | Source ➡️
Note: you won't see any output here. To see the effect, look at the page source.
Output is Invisible as it only affects the HTML Head
This sample modifies the HTML head, so it's not visible here.
To see the effect, look at the source in the browser
- Set Page Title, Keywords, Descriptions etc.
Get/Set Page Title, Keywords, Description and set meta-tags and more.
- Set <base> tag in header
Add a <base> tag to the header. This is important for SPA JS applications.
- Page Icons for Favicon, Apple/Android
Add various combinations of icons to the page header
- Meta and other Tags in header
Add all kinds of meta-tags to the header.
Set OpenGraph Headers etc.
⬇️ Result | Source ➡️
This uses Kit.Page.SetTitle(...)
and other methods to modify the HTML sent to the browser.
It sets various aspecs such as title
or FavIcons.
meta title
,meta description
,meta keywords
- favicon
- some JsonLd for google
- OpenGraph headers for FaceBook, Twitter, etc.
Output is Invisible as it only affects the HTML Head
This sample modifies the HTML head, so it's not visible here.
To see the effect, look at the source in the browser
- Set Open-Graph headers for Social Media using the IPageService
Add Open-Graph data headers for Facebook, Twitter and other sharing-systems
- JSON-LD Headers for SEO
Add JSON-LD (Linked Data) headers for Google
Get Info about Platform, Culture/Languages etc.
⬇️ Result | Source ➡️
- Platform name: '
Oqtane
' - Platform type: '
Oqtane
' - Platform version: '
5.0.2
' - Culture Current Code: '
en-us
' - Culture Default Code: '
en-us
' - Site Id: '
13
' - Site Url: '
https://oqt-apps-dev.2sxc.org/razortutorial12
' - Site UrlRoot: '
oqt-apps-dev.2sxc.org/razortutorial12
' - Page Id: '
288
' - Page Url: '
https://oqt-apps-dev.2sxc.org/razortutorial12
' - Page Url Parameters: '
mode=set&tut=quickref&variant=dyn
' - Module Id: '
352
' - User Id: '
-1
' - User Name: '
'
- User IsContentAdmin: '
False
' - User IsSiteAdmin: '
False
' - User IsSystemAdmin: '
False
' - View Id: '
47382
' - View Identifier: '
' (blank if no special identifier)
- View Name: '
Default Tutorial Page (new v16)
' - View Edition: '
' (blank if no special CSS Framework edition)
- Work with the Context (Page, Site, etc.)
Whenever you need to know about the current environment, you need Context information. These are the contexts you should know about: Platform Site Page Module View User
Loading JavaScripts is standard HTML using <script src="..."<
tags. What more challenging is getting the right path to scripts in this app or relative to the current Razor file.
⬇️ Result | Source ➡️
Load a JavaScript relative to the App folder (see message/console):
Load a JavaScript relative to the folder of this Razor file (see message/console):
A core challenge is to activate JavaScripts only when needed - and when all dependencies are loaded. This is what turnOn
does. It checks if all specified JS objects exist, and then triggers the JS code.
⬇️ Result | Source ➡️
The following text will be replaced once the JS is triggered:
This example passes data to the JS, so it can be parameterized:
We can also pass in more sophisticated data:
Work with the new UniqueKey with JavaScript - new v16.04 🌟
The UniqueKey
is a new feature in 2sxc 16.04 which allows you to create unique IDs for HTML elements. The value of UniqueKey
is the same in all Razor and C# files for the same Content-Block.
⬇️ Result | Source ➡️
This separate Razor will create a div for the resulting message, based on the same UniqueKey
which is uFdKMEHB
(script didn't run yet - this elements id is demo-uniquekey-msg-uFdKMEHB
)
Sometimes you need a UniqueKey
which also depends on other objects. For example, you may need to have a UniqueKey which also uses another value - or many. This is done using @Kit.Key.UniqueKeyWith(...)
.
⬇️ Result | Source ➡️
-
Unique Key with
12345
:uFdKMEHB-n12345
-
Unique Key with
"hello"
:uFdKMEHB-s-1361190748
-
Unique Key with
"bad chars in id ! % / 👍🏽"
:uFdKMEHB-s1578252860
-
Unique Key with
"this is a long text and should be shortened"
:uFdKMEHB-s-1918196610
-
Unique Key with
12345
and"hello"
:uFdKMEHB-n12345-s-1361190748
If the UniqueKey
is based on known object types such as Entities, this works very well. For example, you may need to loop through a list of items, and each item needs a unique key.
⬇️ Result | Source ➡️
-
Title:
Hitchhikers Guide to the Galaxy
- UniqueKey:uFdKMEHB-eid7md5eRsH
-
Title:
Good Omens
- UniqueKey:uFdKMEHB-eidcAcM-LSz
-
Title:
Phishing for Phools
- UniqueKey:uFdKMEHB-eidlkSe34Oo
-
Title:
The Last Continent
- UniqueKey:uFdKMEHB-eid_EnbtOtU
JSON data can be difficult to work with, because you would need to use System.Text.Json
which has a sophisticated API. Instead, we can convert it to ITyped
and then use a very simple API.
⬇️ Result | Source ➡️
-
name
: Dude -
NAME
(insensitive): Dude
This example shows more advanced scenarios. It uses the previously created dude
object.
⬇️ Result | Source ➡️
Does not exist in old APIs
In old (not-typed) APIs there is no strict way to get JSON properties, unless you simply uses System.Text.Json.
By default, the object is strict, so you can only access fields which are present.
⬇️ Result | Source ➡️
Does not exist in old APIs
In old (not-typed) APIs there is no strict way to get JSON properties, unless you simply uses System.Text.Json.
By default, the object is strict, so you can only access fields which are present.
⬇️ Result | Source ➡️
-
loose.String("Fake")
(typed): -
loose.String("Fake")
: -
loose.String("Fake") ?? fallback
: I don't know! -
loose.Int("Fake")
: -
loose.Int("Fake") ?? -1
: -1
JSON data can be difficult to work with, because you would need to use System.Text.Json
which has a sophisticated API. Instead, we can convert it to ITyped
and then use a very simple API.
⬇️ Result | Source ➡️
Marc
- marc.ToString():
{ "name": "Marc", "age": 33, "car": null, "friends": [ { "name": "John", "age": 33 }, { "name": "Jane", "age": 33 } ] }
- name
.String("Name")
Marc
- age:
33
- birth year:
1991
- car make (will be null):
-
Friends using
AsTypedList(...)
- John
- Jane
Frank
- #2 frank.ToString():
{ "name": "Frank", "age": 44, "car": { "make": "Ford", "model": "Focus" } }
- #2 name:
Frank
- #2 car make:
Ford
- #2 car ToString():
{ "make": "Ford", "model": "Focus" }
⬇️ Result | Source ➡️
1
1
2
3
5
8
13
21
34
55
⬇️ Result | Source ➡️
-
Buchs
: 9470
Partner Cities: Oklohoma, New York -
Grabs
: 0 -
Sevelen
: 0
If you have an array in your Json, you need to use ToTypedList
.
⬇️ Result | Source ➡️
- Name:
Buchs
- Name:
Grabs
- Name:
Sevelen