Static sites with Kentico Cloud, Wyam and Netlify
31st of January, 2018 0 comments

Static sites with Kentico Cloud, Wyam and Netlify

As a content repository, Kentico Cloud offers unlimited possibilities for delivering content to any device, displayed in any format. When it comes to websites, a common use case is to use ASP.NET or .NET Core to create web pages driven by the content from Kentico Cloud. This brings the overheads of .NET development, hosting solutions (primarily Azure), and other requirements to get a website up and running.

In this post I will cover off a use case where a combination of services enabled the "Publish" button in Kentico Cloud to result in a static site being updated with the latest changes.

This blog is no longer running on a CMS

That's right - these pages are now simple HTML files, rendered from content stored in Kentico Cloud.

The process from publishing content changes, to deploying the updates is:

  1. Content updated in Kentico Cloud
  2. Kentico Cloud sends a webhook notification to Azure Logic Apps
  3. Azure Logic Apps trigger a new build on the build server (VSTS)
  4. VSTS starts the new build, cloning the website's templates from Git, alongside the Wyam configuration file. Wyam is started
  5. Wyam retrieves the content from Kentico Cloud, and generates HTML files by combining the content and templates
  6. VSTS deploys the rendered content to Netlify, using the Netlify CLI

Static site setup

Kentico Cloud as the content repository

With content items stored in Kentico Cloud, the Kentico Cloud Delivery API enables easy retrieval of content, for further processing with Wyam. Using a plain text content element, with the appropriate processing in further steps, allows the use of Markdown for formatting the blog post contents.

Asset fields provide an easy way of inserting images & other assets.

Wyam - static content generator

From the wyam.io webpage:

It's a static content toolkit and can be used to generate web sites, produce documentation, create ebooks, and much more. Since everything is configured by chaining together flexible modules (that you can even write yourself), the only limits to what it can create are your imagination.

In a nutshell, Wyam accepts a set of input documents, does processing on the input files, and spits out documents as the output.

The Wyam configuration file (config.wyam) defines the sequence of module execution (known as pipelines). For this blog, the sequence within Wyam is along the lines of:

  • Retrieving content from Kentico Cloud
  • Converting Markdown to HTML
  • Merging the content with Razor templates
  • For some pages (such as the homepage), paginating the content items
  • Saving the HTML output files

The KenticoCloud.Wyam library

To enable Wyam to use content items from Kentico Cloud, the missing piece in the puzzle was a custom library that will enable Wyam to retrieve Kentico Cloud content, and use it as the input for further processing. As there were no readily available solutions, I went ahead with writing a simple library that retrieves content from Kentico Cloud, and allows it to be used within Wyam.

The KenticoCloud.Wyam library is still in a prototype phase, however it is available on GitHub and NuGet, with plans for ongoing development.

The library is loaded with a simple NuGet directive within the config.wyam configuration file, and can then be used as part of a document processing pipeline.

#n KenticoCloud.Wyam

. . .

Pipelines.Add("BlogPosts", 
    KenticoCloud("(project id)")
        .WithContentType("blog_post")
        .WithContentField("body"),
    KenticoCloudAssetParser(),
    Markdown(),
    Meta("Body", @doc.Content),
    Merge(ReadFiles("blogpost.cshtml")),
    Razor(),
    WriteFiles($"blog/{@doc["url_slug"]}.html")
);

Hosted on Netlify

As the goal was to keep the hosting requirements as minimal as possible, Netlify was my choice of hosting service. The features that sealed the deal were:

  • Affordable (including a free tier)
  • Custom domains
  • Command-line interface, for automating deployments
  • Form handling
  • Many other useful features, all accessible through an intuitive UI

Built by VSTS

Wyam runs on the .NET Framework, and requires a Windows environment to run. VSTS is a great continuous integration offering by Microsoft, and a perfect environment to generate the static site in an automated manner.

VSTS acts as a task runner, running the Wyam site generation process, and deploying the generated content to Netlify.

Automated by Kentico Cloud webhooks and Azure Logic Apps

With automated builds set up in VSTS, it would be tedious if a new build of the static site had to be manually triggered within the interface of VSTS. Kentico Cloud's webhooks feature allows for the VSTS build to be triggered every time content is published within Kentico Cloud.

Azure Logic Apps provide a way of easily triggering VSTS builds via a webhook URL. An offering that is part of Azure, Logic Apps help with automating processes and integrating various services, through a simple graphical user interface.

The HTTP request URL for the Logic App is added as a webhook in Kentico Cloud, automating the build trigger in VSTS.

Azure Logic Apps

More to come

The advantages of switching to this setup are:

  • It's all based on services - no hosting platform, CMS or server to manage
  • Content is managed within Kentico Cloud, opening up possibilites to render the content on other platforms
  • Loading speed, and easy ways of using CDN and caching
  • The cost of running a website is proportional to traffic and usage

...and they come with some disadvantages:

  • More effort and planning needs to be put in for dynamic features on the site, that would normally be handled by a server-side framework
  • Content changes are not instant - the build process takes at least a few minutes
  • Creating templates require a mindset shift, as they are only used for generating the final static files

This post marks the beginning of a series of blog posts, where I will cover off the setup & functionality of each of the elements that make these services work together.

Written by Kristian Bortnik



Comments