Skip to content
Ray Fan edited this page Jun 3, 2019 · 2 revisions


Designers can fully customize Fanray's public facing site through a theme. A theme consists of client artifacts i.e. CSS, images, JavaScript etc., a set of Razor Views and a manifest file. Let's take a look at the default Clarity theme.

Theme Project

A theme project is really just a Razor Class Library. Create a theme under scr\Themes folder with these steps.

  • Inside Visual Studio, go to File menu, select New > Project.
  • Select ASP.NET Core Web Application.
  • Input project name, for example "Clarity" > OK.
  • Verify ASP.NET Core 2.2 or later is selected.
  • Select Razor Class Library > OK.

Open the .csproj file, make sure the Sdk is Microsoft.NET.Sdk.Razor and TargetFramework is netcoreapp2.2, update them if they are different.

Then copy the following and paste it before the closing Project tag. This will copy necessary artifacts from the plugin project into the Fan.WebApp project at build time.

    <Content Include="theme.json" CopyToOutputDirectory="PreserveNewest" />

  <Target Name="CopyArtifacts" AfterTargets="Build">

      <ManifestToCopy Include="$(OutputPath)\theme.json" />

    <RemoveDir Directories="$(CopyToDir)" />
    <MakeDir Directories="$(CopyToDir)" Condition="!Exists('$(CopyToDir)')" />
    <Copy SourceFiles="@(ManifestToCopy)" DestinationFiles="$(CopyToDir)\%(RecursiveDir)%(FileName)%(Extension)" />

Theme Manifest File

Each theme requires a manifest file called theme.json to be at the root of the theme project. The system loads the theme based on this file, here is the default theme Clarity's manifest file.

  "name": "Clarity",
  "description": "A Bootstrap 4 based theme for Fanray blog.",
  "version": "1.1.0",
  "themeUrl": "",
  "author": "Ray Fan",
  "authorUrl": "",
  "license": "Apache 2.0",
  "licenseUrl": "",
  "tags": [ "responsive", "right-sidebar" ],
  "widgetAreas": [
      "id": "blog-sidebar1",
      "name": "Blog Sidebar"
      "id": "blog-after-post",
      "name": "Blog After Post Content"

Most of the propeties are self-explanatory and they represent plugin information to be displayed inside the Admin Panel. But the widgetAreas requires some explanations.

Widget Areas

Go find and open Clarity > Views > Shared > _Layout.cshtml, you will see <widget-area id="blog-sidebar1" />. This is an widget area with the id registered in the theme.json above. Widget areas are optional, meaning designers can choose not to use any of them, but when used they will display a list of widgets.

The Clarity theme uses two widget areas, blog-sidebar1 and blog-after-post intended display widgets on a sidebar and after a blog post. I say "intended" because the area names are purely suggestive and each widget area renders a div html, the deisnger can really choose to use or place them anywhere on her theme.

There are two kinds of widget areas, System Defined and Theme Defined. Clarity is using two Sytem Defined widget areas, for more info on these see Widgets page. Basically, using System Defined areas has the advantage of maintaining existing widgets when user switches to a different theme. The System Defined areas try to cover common scenarios, but designers have the freedom to create whatever widget areas they want and place these anywhere they want.

To do this just add your area to the widgetAreas array by giving an id and name like this,

      "id": "my-area",
      "name": "My area."

Then you can place it anywhere you want on the theme views, like this <widget-area id="my-area" />. Once the site is launched the system will register your new area.

But be aware 1. once your widget area is registered with the system with the id you give, any update to the id will yield a new area; 2. if the user switches to a different theme, the Theme Defined widgets will not be carried over to the new theme.


A theme has a list Razor Views, below is a break down of these files inside the Clarity > Views folder.

Files Description
   _PostInfo post info, date, info, tags etc.
   Archive posts for a particular year, month
   Category posts for a category
   Index blog main page
   Post a single post
   Rsd used by MetaWeblog API
   Tag posts for a tag
   _Layout the layout
   404 page not found
   Analytics google analytics*
   CookieConsent cookie consent alert*
   Error error page other than 404
   Footer footer*
   Header header*

The (*) are ViewComponents.

The Blog views have to be named as they are, except the partial view _PostInfo, these are part of MVC, see BlogController for their respective action methods.

Since views are just really to present data, designers have the freedom to change the content of these views as they wish, so long the View Models passed in by the controller's action methods are the same. You can find these view models in Fan.Web/Models folder.


Desingers have the freedom to use whatever font-end libraries and technologies they like. For Clarity, I'm using npm, SCSS, Bootstrap 4 etc. All client artifacts are packaged into the dist folder and them copied to Fan.WebApp > wwwroot > themes at build time.

There are two CSS files need attention styles.css and content.css. All Fanray themes must provide these 2 css files,

  • style.css: the theme styles for client site.
  • content.css: the content styles for the editor, it includes typography and the content width from the theme styles. This css file enables user to see the exact post styling while the user is still composing the post.
You can’t perform that action at this time.