Samples

Take a look at the samples in the package to learn more about Razor Functions

The Contribution.CompositeC1Contrib.RazorFunctions package comes with a few sample functions (~/App_Data/Razor/Examples/*.cshtml), you can learn from about Razor functions in C1 CMS.

Breadcrumb.cshtml

@inherits CompositeC1Contrib.RazorFunctions.CompositeC1WebPage
              
@using Composite.Data;
@using CompositeC1Contrib.RazorFunctions;

@functions {
    private IEnumerable<PageNode> OpenPages(PageNode selectedPageNode)
    {
        var openPages = new List<PageNode>();
        var openPage = selectedPageNode;

        while  (openPage != null)
        {
            openPages.Add(openPage);
            openPage = openPage.ParentPage; // crawl up
        }

        return openPages;
    }
}

<ul id="Breadcrumb">
    @foreach  (var page in OpenPages(@CurrentPageNode).OrderBy(op => op.Level))
    {
        <li>
            <a href="@(page.Url)" >@(String.IsNullOrWhiteSpace(page.MenuTitle) ? page.Title : page.MenuTitle)</a>
        </li>
    }
</ul>

Sitemap.cshtml

@inherits CompositeC1Contrib.RazorFunctions.CompositeC1WebPage
              
@using Composite.Data;
@using CompositeC1Contrib.RazorFunctions;

<div id="Sitemap">
    @NavigationTree(@HomePageNode.ChildPages, 5)
</div>

@helper NavigationTree(IEnumerable<PageNode> pages, int endRenderLevel)
{
    if (pages.Any() && pages.First().Level <= endRenderLevel)
    {
        <ul class  ="sitemapLevel@(pages.First().Level)">
            @foreach   (var subPage in pages)
            {
                if  (!String.IsNullOrWhiteSpace(subPage.MenuTitle))
                {
                    <li>
                        <a href="@(subPage.Url)">@subPage.MenuTitle</a>
                        @NavigationTree(subPage.ChildPages, endRenderLevel)
                    </li>
                }
            }
        </ul>
    }
}

Subnavigation.cshtml

@inherits CompositeC1Contrib.RazorFunctions.CompositeC1WebPage
              
@using Composite.Data;
@using CompositeC1Contrib.RazorFunctions;

@functions {
    private IEnumerable<PageNode> OpenPages(PageNode selectedPageNode)
    {
        var openPages = new List<PageNode>();
        var openPage = selectedPageNode;

        while  (openPage != null)
        {
            openPages.Add(openPage);
            openPage = openPage.ParentPage; // crawl up
        }

        return openPages;
    }
}

<div id="Subnavigation">
    @if (OpenPages(@CurrentPageNode).Where(p => p.Level == 2).Any())
    {
        var openLevel2Page = OpenPages(@CurrentPageNode).Where(p => p.Level == 2).First();
        <h1>
            <a href="@(openLevel2Page.Url)">@(openLevel2Page.MenuTitle)</a>
        </h1>
        @NavigationTree(openLevel2Page.ChildPages, 5)
    }
</div>

@helper NavigationTree(IEnumerable<PageNode> pages, int endRenderLevel)
{
    if (pages.Any() && pages.First().Level <= endRenderLevel)
    {
        <ul class  ="subnavigationLevel@(pages.First().Level)">
            @foreach   (var subPage in pages)
            {
                if  (!String.IsNullOrWhiteSpace(subPage.MenuTitle))
                {
                    var isOpen = OpenPages(@CurrentPageNode).Any(op => op.Id == subPage.Id);
                    var isSelected = @CurrentPageNode.Id == subPage.Id;
                        
                    <li>
                        <a href="@(subPage.Url)" class  ="@(isOpen ? "  open" : "  closed") @(isSelected ? "  selected" : " ")">
                            @subPage.MenuTitle
                        </a>
                        @if (isOpen)
                        {
                            @NavigationTree(subPage.ChildPages, endRenderLevel);
                        }
                    </li>
                }
            }
        </ul>
    }
}

Topnavigation.cshtml

@inherits CompositeC1Contrib.RazorFunctions.CompositeC1WebPage
              
@using Composite.Data;
@using CompositeC1Contrib.RazorFunctions;

<ul id="Topnavigation">
    @foreach   (var page in @HomePageNode.ChildPages.Where(tp => !String .IsNullOrWhiteSpace(tp.MenuTitle)))
    {
        <li class  ="@SelectedClass(page)">
            <a href="@(page.Url)" >@(String.IsNullOrWhiteSpace(page.MenuTitle) ? page.Title : page.MenuTitle)</a>
        </li>
    }
</ul>

@helper SelectedClass(PageNode page)
{
    if (page.Id == @CurrentPageNode.Id)
    {
        <text>selected</text>
    }
}

ColorCube.cshtml

@inherits CompositeC1Contrib.RazorFunctions.CompositeC1WebPage
              
@using CompositeC1Contrib.RazorFunctions;

@functions {
    // C1 Function parameters defined below...
    [FunctionParameter("Total width" , "How wide the cube should by, in pixels", 500)]
    public int TotalWidth { get; set; }

    [FunctionParameter("Number of columns" , "Specify how many columns the cube should have across the X axis", 10)]
    public int NumOfColumns { get; set; }

    [FunctionParameter("Number of rows" , "Specify how many rows the cube should have along the Y axis", 10)]
    public int NumOfRows { get; set; }

    [FunctionParameter("Minimum Red 0 - 255" , "A higher number will make this color more dominant", 10)]
    public int MinimumRed { get; set; }

    [FunctionParameter("Minimum Green 0 - 255" , "A higher number will make this color more dominant", 10)]
    public int MinimumGreen { get; set; }

    [FunctionParameter("Minimum Blue 0 - 255" , "A higher number will make this color more dominant", 10)]
    public int MinimumBlue { get; set; }

    [FunctionParameter("Border width" , "Increase to make outset border more dominant", 3)]
    public int BorderWidth { get; set; }

    [FunctionParameter("Spacing between boxes" , "If spacing is desired, specify how many pixels", 4)]
    public int SiblingPadding { get; set; }
}
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <style media="screen"  type="text/css">
            #@(InstId) {
                background-color: #bba;
                padding: @SiblingMarginString 0 0 @SiblingMarginString;
                width: @(OuterBoxDimension * NumOfColumns)px;
            
            }
            #@(InstId) .CubeBox {
                width: @(BoxDimension)px;
                height: @(BoxDimension)px;
                margin: 0 @SiblingMarginString @SiblingMarginString 0;
                border: @(BorderWidth)px outset;
                float: left;
            
            }
            .clear { clear: both; }

            @for  (int i = 0; i < NumOfColumns * NumOfRows; i++)
            {
                @String.Format("            #{0} #{0}BoxNumber{1} {{ background-color: {2}; border-color: {2};  }}\n",
                    InstId,
                    i,
                    RandomColor());
            }
        </style>
    </head>
    <body>
        <div id="@(InstId)">
            @for  (int row = 0; row < NumOfRows; row++)
            {
                for  (int col = 0; col < NumOfColumns; col++)
                {
                    <div id="@(InstId)BoxNumber@(row * NumOfColumns + col)" class ="CubeBox"></div>
                }
                
                <div class ="clear"></div>
            }
        </div>
    </body>
</html>

@functions {
    // plumbing that turns the input numbers into things like css width strings etc...

    private string RandomColor()
    {
        return  String.Format("rgb({0},{1},{2})",
            Math.Max(MinimumRed, random.Next(0, 255)),
            Math.Max(MinimumGreen, random.Next(0, 255)),
            Math.Max(MinimumBlue, random.Next(0, 255)));
    }

    private string  SiblingMarginString { get { return  (SiblingPadding == 0 ? "0"  : SiblingPadding + "px"); } }
    private int  OuterBoxDimension { get { return TotalWidth / NumOfColumns; } }
    private int  BoxDimension { get { return OuterBoxDimension - (2 * BorderWidth + SiblingPadding); } }
    private int  SurplusSpace { get { return TotalWidth - (BoxDimension * NumOfColumns); } }
    private  Random random = new Random();
    private string InstId
    {
        get
        {
            if  (_myId == null) _myId = Guid.NewGuid().GetHashCode().ToString();
            
            return "cube" + _myId;
        }
    }
    private string _myId;
}

ExecuteOtherFunctions.cshtml

@inherits CompositeC1Contrib.RazorFunctions.CompositeC1WebPage
              
@using CompositeC1Contrib.RazorFunctions;

@{
    Functions.ExecuteFunction("Examples.ColorCube");
}

@Html.C1().Function("Examples.ColorCube" , new { MinimumRed = 255 }) 

<br /> <br />

@Html.C1().Function("Examples.ColorCube" , new { MinimumGreen = 255, BorderWidth = 10 }) 

<br /> <br />

@Html.C1().Function("Examples.ColorCube",
    new  Dictionary<string , object>() 
    {
        { "MinimumRed", 40 },
        { "BorderWidth", 30 }
    })