Blog / Development

Creating the Kentico Cloud Showcase Site


by Bryan Soltis

Jun 1, 2017

Over the past few months the Kentico Roadshow has brought updates and technical information to cities around the world. If you attended any of these sessions, you got to hear about the .NET Core Boilerplate project for Kentico Cloud. As part of the presentation, we showed you how to build a site in minutes using this open-source project. In this article, I’ll share with you the process we covered, as well as all source code for the showcase site. 

If you made it to the Kentico Roadshow, you saw many of the great new features coming Kentico 11, as well as Kentico Cloud. A big part of the event was our new headless CMS and how digital agencies can use it for their projects. This included overview sessions, highlights of new features, demonstrations, and case studies from partners.

At each conference, we showed you how to take the new .NET Core MVC Boilerplate project and create an application in minutes. While the session covered the high-level areas, I wanted to provide you with more detail, and more code! Here’s how we built the Kentico Cloud Showcase site.

Define / Create Content in Kentico Cloud

The first step of the process was to create our Kentico Cloud content. This included defining content types within Kentico Cloud and populating the content inventory. For the Showcase example, this included creating two content types, one for our page content, and one for the project details. 

Content Page
Following previous blogs, I created a generic Content Page content type to hold my page content. This included some standard elements, as well as a Modular Content element to highlight one of the projects. 


Project
This content type contained all the elements that related to individual projects. Notably, I leveraged a Multiple Choice element to specify which technologies the project used.


Inventory

After creating the content types, I added my content items. I created a single Content Page item named Home, and a collection of Project types for the indivudal projects. 


Kentico Cloud Boilerplate

After the content was created, I was ready to utilize the Kentico Cloud .NET Core MVC Boilerplate. This open-source project was created by Kentico and its partners to help companies get started with Kentico Cloud. It includes many proven best practices, as well as innovative features and configurations to help developers get rolling with the project quickly. 

For the presentation, I created a new project using the dotnew command. I then opened the project and tested the functionality.


You can read more about the boilerplate project here.

Code Changes

With the boilerplate project downloaded and running, I was ready to add my custom code. For the presentation, I had several code snippets prepared. Here is an overview of all the changes performed.

Configure Kentico Cloud Project ID
I updated the appsettings.json file with my Kentico Cloud Project ID.

Kentico Cloud Code Generator
I used the Kentico Cloud .NET Code Generator project to create class files for my ContentPage and Project content types in Kentico cloud. 

Here are the generated classes.

    public partial class Contentpage
    {
        public string Title { get; set; }
        public IEnumerable<Asset> Headerimage { get; set; }
        public string Content { get; set; }
        public IEnumerable<object> Featuredproject { get; set; }
        public string Footer { get; set; }
        public ContentItemSystemAttributes System { get; set; }
    }

    public partial class Project
    {
        public string Url { get; set; }
        public DateTime? Datesubmitted { get; set; }
        public IEnumerable<Asset> Screenshot { get; set; }
        public IEnumerable<MultipleChoiceOption> Technologies { get; set; }
        public ContentItemSystemAttributes System { get; set; }
    }

You can find out more about the code generator project here.

Add generated classes to VS project
I added the generated classes to my project. In addition, I created a partial class to add a new property to the ContentPage class. This property (TopProject) would allow me to strongly type my featured project as a Project. 

using System.Linq;

namespace RoadshowShowcase.Models.ContentTypes
{
    public partial class Contentpage
    {
        public Project TopProject { get { return Featuredproject.Cast<Project>().First(); } }
    }
} 

Lastly, I created a new ViewModel named HomeData to pass to my view. This class contained a ContentPage object, as well as a collection of Project objects. This would allow me to pass the page content, as well as the collection of projects as my model. 

    public class HomeData
    {
        public Contentpage Content { get; set; }
        public IEnumerable<Project> Projects { get; set; }
    }

Updating Controllers/Views

With the new classes in place, I updated my HomeController with the Deliver API code to retrieve my Kentico Cloud content. I created a HomeData object, and populated it with separate Kentico Cloud API calls for each property of my HomeData object. 

        public async Task<ViewResult> Index()
        {
            HomeData data = new HomeData();

            // Get the Home ContentPage from Kentico Cloud
            var responseContent = await DeliveryClient.GetItemAsync<Contentpage>("home");
            data.Content = responseContent.Item;

            // Get the KenticoCloudProject items from Kentico Cloud
            var responseProjects = await DeliveryClient.GetItemsAsync<Project>(
                new EqualsFilter("system.type", "project"),
                new OrderParameter("elements.datesubmitted", SortOrder.Descending)
            );
            data.Projects = responseProjects.Items;
            return View(data);
        } 

For the View, I retrieved the ContentPage content property to display my page text. For the FeaturedProject, I leveraged the new TopProject property I defined in my partial class to retrieve its details.

            <div class="featured-project-screenshot-container">
                @foreach (var image in Model.Content.TopProject.Screenshot)
                {
                    <a href="@Model.Content.TopProject.Url" target="_blank"><img src="@image.Url" class="featured-project-screenshot img-responsive" alt="@image.Name" /></a>
                }
            </div>
            <div class="featured-project-details">
                <div class="featured-project-name">
                    @Model.Content.TopProject.System.Name
                </div>
                <div class="project-details-header">URL</div>
                <div class="project-details-innercontent"><a href="@Model.Content.TopProject.Url" target="_blank">@Model.Content.TopProject.Url</a></div>
                <div class="project-details-header">Technologies</div>
                <div class="project-details-innercontent">
                    <ul class="project-technologies-list">
                        @foreach (var technology in @Model.Content.TopProject.Technologies)
                        {
                            <li>@technology.Name</li>
                        }
                    </ul>
                </div>
            </div>

For each Project in my model, I defined the layout to display the screenshot, name, and details.

                @foreach (var project in Model.Projects)
                {
                    if (@project.System.Codename != Model.Content.TopProject.System.Codename)
                    {
                        <div class="project-container">
                            <div class="project-container-background">
                                <div class="project-screenshot-container">
                                    @foreach (var image in project.Screenshot)
                                    {
                                        <a href="@project.Url" target="_blank"><img src="@image.Url" class="project-screenshot img-responsive" alt="@image.Name" /></a>
                                    }
                                </div>
                                <div class="project-details">
                                    <div class="project-details-link">
                                        <a class="project-link-toggle">
                                            <div class="project-link-text">
                                                @project.System.Name
                                            </div>
                                        </a>
                                    </div>
                                    <div class="project-details-content">
                                        <div class="project-details-header">URL</div>
                                        <div class="project-details-innercontent"><a href="@project.Url" target="_blank" class="project-details-link" id="@project.System.Codename">@project.Url</a></div>
                                        <div class="project-details-header">Technologies</div>
                                        <div class="project-details-innercontent">
                                            <ul class="project-technologies-list">
                                                @foreach (var technology in project.Technologies)
                                                {
                                                    <li>@technology.Name</li>
                                                }
                                            </ul>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    }
                }

Styling

After applying the coding changes, I updated the styling and formatting of the site to match my design. This included adding several classes to the site.css file. These styles mainly defined my background color, formatting for projects, and other cosmetic changes. I was sure to leave the layout for the site so it would remain responsive. 


For the JavaScript, I added a reference to jQuery to the Shared/_Layout.cshtml file, and updated the site.js file with the following function. This function would add some animation to my project list. 

$(function () {
    $('.project-link-toggle').click(function () {
        $('.project-details-content').not($(this).parent().next('.project-details-content')).slideUp();
        $(this).parent().next('.project-details-content').slideToggle();
    });
});

Test it!

After applying all the updates, I was ready to test. I built the project, resolved namespace issues in my Startup.cs file, and checked out the site. 


After confirming the site looked correct, I updated my Kentico Cloud content to feature a different project. I then refreshed the site to view the changes. 


Moving Forward

The purpose of this blog and Roadshow presentation was to demonstrate how you can leverage Kentico Cloud and .NET Core MVC boilerplate project for your applications. I encourage you to download the source code and review the functionality. Because it’s an open-source project, it will receive continual updates from the community as new best-practices are defined. And because it’s a community project, why not help make it better and contribute? Good luck!

Get the code

We have added the project to GitHub. You can download the full source code here:

Kentico Cloud GitHub Project