ASP.NET Core Platforms for a Blog

Like a lot of Sitecore developers my blog (at time of writing) is hosted on WordPress. The reason for it not being in Sitecore is simple. Sitecore is an enterprise level platform, which isn’t really needed for a personal blog.

For a .net dev to have there blog on a php platform however just seems plain wrong, but again there’s a logical reason. WordPress is actually really good as a blogging platform, and it doesn’t cost me anything.

Despite this I would much rather take control of my site and use it to play with all the cool features in Azure. It would also be nice to have the ability to do something about the Google PageSpeed result which is currently sitting at 24%. So in aid of this I’ve started looking into .net core based platforms and thought I’d share what I’ve found.

Miniblog.core

https://github.com/madskristensen/Miniblog.Core

As the name suggests Miniblog.core is both very small and based on .net core. Developed by Mads Kristensen its an extremely lightweight bare bones implementation, which if your after something you can help build upon is ideal. The code is straightforward to understand and very simple to adapt. Additionally if your after a 100% page speed score, then this achieves just that.

If on the other hand your after a deluxe admin experience full of functionality then this probably isn’t for you.

Piranha CMS

http://piranhacms.org/

Piranha CMS is built as a lightweight CMS platform rather than specifically as a blog, however it also contains a blog module which for me put’s it at a big advantage over the other CMS platforms I’ve listed below.

On the back end you get a choice of SQL Server, SQLite or MySQL. The documentation isn’t exactly complete, but on the day I tried it out, I found the team building it very responsive on GitHub. They even updated the documentation with one of my suggestions the very next day.

Another aspect I particularly liked about Piranha CMS was it’s block editor, which from the brief look I’ve had so far reminds me of the block editor Umbraco has. Whereas other platforms in this list were restricted to a large rich text field.

Orchard Core

https://github.com/OrchardCMS/OrchardCore

Orchard Core is the dot net core version of the Orchard CMS. It’s currently in beta, but I’m not sure that put’s it at much of a disadvantage over the others on this list.

My initial impressions of Orchard Core however weren’t as high as Piranha CMS. The admin interface wasn’t quite as nice and as far as I could tell, it didn’t have anything like Piranha’s block editor. The solution itself also seemed far more complex and I wasn’t certain what I got for this. I expect Orchard Core is likely better in some ways that I have yet to discover, but for my needs as a blog this is probably not the case. It also didn’t have a blog module out of the box.

Squidex

https://squidex.io/

I have’t had much of a chance to play with Squidex yet, but it does offer an interesting difference to the others mentioned so far.

For a start Squidex is an entirely headless cms, and is built around the concept of CQRS and Event Sourcing. Unlike the others it also uses MongoDB rather than a SQL based database.

Where MongoDB is concerned, I often get the impression people are using it because as developers we tend to have a preference to using something new rather than something adequate. However when it comes to Azure pricing, there is potentially a saving to be made by using Mongo rather than Azure SQL.

Advertisements

Redirecting to login page with AngularJs and .net WebAPI

So here’s the scenario, you have a web application which people log into and some of the pages (like a dashboard) contain ajax functionality. Inevitably the users session expires, they return to the window change a filter and nothing happens. In the background, your JavaScript is making http calls to the server which triggers an unauthorised response. The front end has no way to handle this and some errors appear in the JS console.

A few things are actually combining to make life hard for you here. Lets take a look at each in more detail.

WebAPI and the 301 Response

To protect your API’s from public access a good solution is to use the Authorize attribute. i.e.

[Authorize]
public ActionResult GetDashboardData(int foo)
{
   // Your api logic here
            
}

However chances are your solution also has a login page configured in your web.config so that your regular page controller automatically trigger a 301 response to the login page.

    <authentication mode="Forms">
      <forms timeout="30" loginUrl="/account/sign-in/" />
    </authentication>

So now what happens, is instead or responding with a 401 Unauthorised response, what’s actually returned is a 301 to the login page.

With an AJAX request from a browser you now hit a second issue. The browser is making an XMLHttpRequest. However if that request returns a 301, rather than returning it your JavaScript code to handle, it “helpfully” follows the redirect and returns that to your JavaScript. Which means rather than receiving a 301 redirect status back, your code is getting a 200 Ok.

So to summarise your API was set up to return a 401 Unauthorised, that got turned into a 301 Redirect, which was then followed and turned into a 200 Ok before it gets back to where it was requested from.

To fix this the easiest method is to create are own version of the AuthorizedAttribute which returns a 403 Forbidden for Ajax requests and the regular logic for anything else.

using System;
using System.Web.Mvc;

namespace FooApp
{
    [AttributeUsage(AttributeTargets.Method)]
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new HttpStatusCodeResult(403, "Forbidden");
            }
            else
            {
                base.HandleUnauthorizedRequest(filterContext);
            }
        }
    }
}

Now for any Ajax requests a 403 is returned, for everything else the 301 to the login page is returned.

Redirect 403 Responses in AngularJs to the login page

As our Ajax request is being informed about the unauthorised response, it’s up to our JavaScript code trigger the redirect in the browser to the login page. What would be really helpful would be to define the redirect logic in one place, rather than adding this logic to every api call in our code.

To do this we can use add an interceptor onto the http provider in angular js. The interceptor will inspect the response error coming back from the XmlHttpRequest and if it has a status of 401, use a window.locator to redirect the user to the login page.

app.factory('httpForbiddenInterceptor', ['$q', 'loginUrl', function ($q, loginUrl) {
    return {
        'responseError': function (rejection) {
            if (rejection.status == 403) {
                window.location = loginUrl;
            }
            return $q.reject(rejection);
        }
    };
}]);

app.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
    $httpProvider.interceptors.push('httpForbiddenInterceptor');
}]);

You’ll notice a line updating the headers. This is to make the IsAjaxRequest() method on the api recognise the request as being Ajax.

Finally you’ll also notice the loginUrl being passed into the interceptor. As it’s not a great idea to have strings like urls littered around your code, this is using a value recipe to store the url. The code to do this is follows:

app.value('loginUrl', '/account/sign-in?returnurl=/dashboard/');

Running Gulp tasks in Visual Studio

Over the last decade, front end development has matured from a point where CSS and JavaScript were written in badly organised files containing the exact code a browser would interpret, to something that now more resembles back end development.

Pure CSS has become the byte code of the front end world with LESS and Sass becoming the languages of choice. Instead of MSBuild for running a compilation Gulp can be used to automate workflows to compile Sass files, minify them and do whatever else is needed to produce the code for deployment (not really an exact comparison, but you get the point).

To truly achieve a matured development setup though, the final step is to remove those “compiled” css and js files from source control. After all you wouldn’t check in a dll with the source code for each build. If your using a build server then this is a relatively easy step to add to your workflow. However the bigger issue is not making life hard for your back end developers.

Without the final CSS and JS files in source control your back end devs may now be faced with a site lacking all style and front end functionality when they hit F5. With LESS and Sass also not really being there thing, they’re now left not really knowing what to do, and also not overly happy about having to learn something about front end do continue with there back end work. To make matters worse, Visual Studio often isn’t the front end dev’s choice of tool so copying the front enders setup isn’t an ideal solution either.

The Aim

The ideal solution would be for a back end dev to be able to check out a solution from source control (containing no compiled CSS of JS files), hit F5 in Visual Studio, the final CSS and JS be created as part of the build and the site to run. No opening a command prompt to run a gulp task, or any other process the front end devs may be using. It should be completely invisible to them.

Visual Studio Task Runner

With Visual Studios Task Runner, this is entirely possible.

The Task Runner is built into Visual Studio, so there’s no need for the back end dev to install any extra tools, and more importantly, tasks can be linked into a before build event so that the back end dev doesn’t need to do anything.

A bit of background on gulp and the task runner

When front end developers set up gulp, they will configure a set of gulp tasks within a file named gulpfile.js (in reality they may actually separate the tasks into multiple files referenced by gulpfile.js, but this file is the important bit). These tasks may look a bit like this:

gulp.task("min:js", () => {
  return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
    .pipe(concat(paths.concatJsDest))
    .pipe(uglify())
    .pipe(gulp.dest("."));
});

gulp.task("min:css", () => {
  return gulp.src([paths.css, "!" + paths.minCss])
    .pipe(concat(paths.concatCssDest))
    .pipe(cssmin())
    .pipe(gulp.dest("."));
});

gulp.task("min", gulp.series(["min:js", "min:css"]));

In this example there are 3 tasks. The first minifies some JS while the second minifies some CSS. The third is defining a series which runs the first 2.

Visual Studios task runner will look file the file called gulpfile.js and pull out all the tasks within it. The task runner window may not be open by default, so to open it type task runner in the search box and select it from the results. Alternatively you can right click the gulpfile in the solution and select Task Runner from the context menu.

The task runner window will open at the bottom of the screen, and will list out all the gulp tasks found within the gulpfile.js file. If the front end devs have organised the tasks into separate files, as long as the gulpfile.js file in the root of the project has some way of referencing them, they will still show up.

If you don’t see any of the tasks, and have only just added the file or a task to the file. You may need to click the refresh button.

To run a task, simply right click it and then choose Run.

Automating on build

Being able to run a gulp task is handy, but what we’re really after is for it to be automated as part of the build.

For this we just need to right click the task to be run, and then from the bindings option, select before build.

This will add a comment to the top of the gulpfile.js which Visual Studio will look for to know what task should be run before a build.

/// <binding BeforeBuild='min' />

With this set, the back end devs no longer need to be concerned with not having any compiled css and js, and with a small amount of knowledge also have the ability to make minor changes to css and js where needed.

Some others tips

Depending on your front end devs setup there could be some additional challenges to overcome.

Front end devs not using Visual Studio

Quite often Visual Studio isn’t the choice of dev environment for a front end dev. One issue this can lead to is files missing from the Visual Studio solution. However an easy fix for this is to use wild cards in the csproj file.

If the front end devs code can be grouped into specific folders then use a wild card to include all the files from that folder in the project.

<None Include="build\js\**\*.js" />

CSS/JS not in the web project

If the front end devs have a separate folder for there work. e.g. they might work with static html files. Then the code may not be in the project what will be run, and therefore nothing will trigger the gulp file to have it’s task run.

A simple solution for this is to create a visual studio project for the folder with there work so that it has a build event to be attached to. Make sure your web project also references this project to trigger it to be built when the web project is.

Links

For more info on using Gulp with Visual Studio. Check out Microsofts guide on using Gulp with ASP.NET Core.

What’s new in Sitecore 9.1

At this year’s Sitecore Symposium, Sitecore shared details of the great new features arriving in Sitecore 9.1 that will benefit everyone from developers to marketers, by offering enhancements in everything from machine learning to aid personalisation down to headless support for JavaScript developers.

Sitecore Cortex

Version 9 was the first introduction to Sitecore Cortex name, which is represents the machine learning capabilities found within Sitecore. In version 9 this was limited to Engagement Value, Optimisation and Path Analysis. Version 9.1 however is building on this base by introducing 3 new Cortex powered capabilities to the platform.

Personalisation Suggestions

Sitecore has been offering the ability to create personalised visitor experiences for a long time now, but half the challenge with this has always been knowing what you should personalise and how you should personalise it.

With Sitecore 9.1 you can now direct the results of content tests to be fed into the machine learning server. Sitecore will then analyse the results of the test and if certain segments responded better to one experience over another, if it did then it will suggest that is set up as a personalisation rule.

Content Tag Automation

Search engines and site searches work far better when content has been tagged correctly. However, tagging is a tedious task most content editors would rather do without. Sitecore 9.1 now helps content editors with this task by hooking into the Open Calais API for natural language processing of content-based fields on an item.

Headless Sitecore

At Symposium 2017, Sitecore announced Sitecore JavaScript Services as the first official step into supporting headless setups using Sitecore. Since then this has been available as a preview while the development continued. With Sitecore 9.1 this is now reaching general availability.

The Headless capabilities mean those working with popular frameworks such as Vue, React and Angular can now build rich applications using Sitecore as the backend without needing to write .net code.

Unlike other headless offerings, Sitecore Headless still retains the functionality that makes Sitecore great. Namely, tracking, optimisation, personalisation and there’s even previews in the Sitecore Experience Editor.

And more

These are just 2 of the stand out features coming in Sitecore 9.1, but as well as this there are;

  • Updates to EXM to help avoid spamming recipients while also being able to classify vital emails such as order confirmations to always be sent
  • Enhancements to Sitecore Forms and Marketing Automation that were introduced in Sitecore 9
  • Sitecore Experience Accelerator now supports WCAG 2.0 accessibility guidelines
  • Preview of Project Horizon, the next version of web content editing
  • Simplification of the installation process with SIF 2.0

How to add a table to content in Sitecore

Although most of my blog posts are aimed at developers, this one is really for a content editor. When we build sites and do all the checks to make sure they work well for SEO and hit AAA accessibility standards, it’s easy to forget that once we’re done the content editors are going to take over with the ability to destroy things 🙂 through the rich text editor.

Scenario

As a content editor you need to display some data in your article, and it makes most sense to put in a table.

Adding a table is actually quite straightforward in Sitecore, it’s not much different to doing it in Microsoft Word. You click the insert table button and choose the size you want. However the problem that often gets missed is accessibility. While a table is actually very good for a screen reader, it does need to have a bit of info on things like table headings. e.g. are the they top row, the first column or do they exist at all.

Solution

Adding heading information takes a bit of extra work, but not a lot.

  1. Add you table by clicking the Insert table button and choosing the size you want.
    Table - 1 Insert Table
  2. Fill in your tables content
    Table - 2 Enter Content
  3. Right click the table and select “Table Properties”
    Table - 3 Select Table Properties
  4. Go to the Accessibility tab and set the heading rows and columns. In this example I have set the first row and first column to be marked as headings.
    Table - 4 Set Table Headings
  5. Click on and your table will be updated. If your site has styles for table headings these will also show now too.
    Table - 5 Table Updated
  6. Switching to HTML view will also show the correct HTML tags now being used.
    Table - 6 Correct HTML

An alternative approach to this, is at step 1 to pick table wizard rather than picking the size of the table. This will open the same wizard as in step 4 and allow you to specify the size of the table here too.

API Routes stopped working in Sitecore 9

We recently undertook a Sitecore 9 upgrade and one issue we encountered was controllers we had set up for API routes stopped working on content delivery servers. Content management and single server setups were unaffected.

Our routes had been set up by the controllers inheriting from SitecoreController and then using the default route which Sitecore would create. e.g. /api/sitecore/foo/getFoo

public class FooController : SitecoreController
{
    ...
    [System.Web.Http.HttpPost]
    public ActionResult GetFoo(FooModel queryModel)
    {
        ...
    }
}

MVC.LegalRoutes

After a bit of investigation we found a new setting in Sitecore 9 called MVC.LegalRoutes. From the documentation:

MVC: Pipe separated list of route URL’s that are not valid for use with Sitecore.Mvc.
For instance, the default ASP.NET route ({controller}/{action}/{id}) catches most requests that are actually meant to be handled by the default Sitecore route.
Default: “{controller}/{action}/{id}”

If we added our route to the list everything started to work ok.

<setting name="Mvc.LegalRoutes" value="|Sitecore.Mvc:sitecore/shell/api/sitecore/{controller}/{action}|Sitecore.Mvc.Api:/api/sitecore/{controller}/{action}|" />

A different approach

Not wanting to just change random settings we stumble across we contacted Sitecore support to see what they thought.

The route ‘api/sitecore/{controller}/{action}’ is a pre-defined Sitecore SPEAK route for Sitecore Client usage. So when trying to access on a content delivery server where the Sitecore Client is disabled, it no longer works.

So to get around the issue we can start registering the route on content delivery servers through the Global.asax file.

public override void Application_Start(object sender, EventArgs args)
{
    base.Application_Start(sender, args);

    if (System.Configuration.ConfigurationManager.AppSettings["role:define"] == "ContentDelivery")
    {
        System.Web.Routing.RouteTable.Routes.MapRoute("Sitecore.Speak.Commands", "api/sitecore/{controller}/{action}");
    }
}

Sitecore SXA example site

Recently I’ve been looking into building sites using Sitecore Experience Accelerator (SXA). If you haven’t heard of it, in short SXA cut’s the amount of dev effort by building sites through pre-built re-usable components and then adding some styling. For a brochure type site this can (in some cases) remove virtually all the back end dev. You can read more about it here https://www.sitecore.com/en-gb/products/sitecore-experience-platform/wcm/experience-accelerators

Getting your head around SXA however can be a slight challenge. There is a getting started guide from Sitecore, which covers grid layouts, choosing features etc, but being able to understand how a site should actually be constructed and how the editor will use it can become confusing.

What would really help which Sitecore don’t provide is an example site. However Cognifide have and you can download it from Github here: https://github.com/Cognifide/Sitecore.XA.Showcase

To get started with it:

  1. Install a clean copy of Sitecore with SXA
  2. Download the code from github
  3. Restore the NuGet packages
  4. In the App_Config you will see a config file named Sitecore.XA.Project.Showcase.User.config. This includes one setting that needs updating to point to the folder you downloaded the solution to. This is then going to be used by unicorn to synchronize the items.
  5. Publish the solution into your Sitecore install
  6. Login as an admin and go to http://<yourinstancename>/unicorn.aspx
  7. Click the sync button, to synchronize the items
  8. Publish the site

You will now be able to see the showcase site in the admin and have a click through it on the published version.

SXA Showcase

What’s really great about the SXA showcase site is it’s a site all about SXA with loads of useful information on how you build an SXA site as well as actually be being built in SXA.

Sitecore – Creating an admin menu item

If your building a Sitecore admin application, your going to need to link to them from the Sitecore start screen/launch pad.

To create a menu item on Sitecores start screen:

  1. Log into Sitecore and switch to the core db
  2. Open content editor and navigate to /sitecore/client/Applications/Launch Pad/PageSettings/Buttons
  3. You will see groupings for each of the sections that appears on the start screen/launch pad
    Launchpad buttons
  4. Add a new Launch Pad-Button item to the section you want it to appear in
  5. Give it a name, icon and link
    Button details
  6. Your button now appears on the start screen
    New button

Related Posts

A first look at Sitecore SPEAK 3

Force clients to refresh JS/CSS files

It’s a common problem with an easy solution. You make some changes to a JavaScript of CSS file, but your users still report an issue due to the old version being cached.

You could wait for the browsers cache to expire, but that isn’t a great solution. Worse if they have the old version of one file and the new version of another, there could be compatibility issues.

The solution is simple, just add a querystring value so that it looks like a different path and the browser downloads the new version.

Manually updating that path is a bit annoying though so we use modified time from the actual file to add the number of ticks to the querystring.


DefaultLayout.cshtml

using Utilities;
using UrlHelper = System.Web.Mvc.UrlHelper;

namespace Web.Mvc.Utils
{
    public static class UrlHelperExtensions
    {
        public static string FingerprintedContent(this UrlHelper helper, string contentPath)
        {
            return FileUtils.Fingerprint(helper.Content(contentPath));
        }
    }
}

UrlHelperExtensions.cs

using System;
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Web.Hosting;

namespace Utilities
{
	public class FileUtils
    {
        public static string Fingerprint(string contentPath)
        {
            if (HttpRuntime.Cache[contentPath] == null)
            {
                string filePath = HostingEnvironment.MapPath(contentPath);

                DateTime date = File.GetLastWriteTime(filePath);

                string result = (contentPath += "?v=" + date.Ticks).TrimEnd('0');
                HttpRuntime.Cache.Insert(contentPath, result, new CacheDependency(filePath));
            }

            return HttpRuntime.Cache[contentPath] as string;
        }
    }
}

FileUtils.cs

Sitecore SPEAK 3 – Creating an application

At the end of last year I wrote a post on A first look at Sitecore SPEAK 3 which gave an overview of what Speak is, and the large architecture change that has happened between Speak 1/2 to 3.

In this post I’m going to share my experience on how to set up a Speak 3 application with Angular.

Step 1 – Creating the Angular project

To start your going to need a few things installed:

  • An IDE – I’m using VS Code
  • NodeJs – This is to get access to node package manager and to run your application in debug mode
  • Angular

If you don’t already have Node and Angular installed, I suggest going through Angular’s quick start guide. If your also new to Angular I suggest going through their Tour of Heroes tutorial first. This will give you a good understanding of how Angular applications are built and some knowledge around a few key files.

One you’ve got everything installed, create a new angular project from the command line.

ng new app-name

1 - Create Angular app

At this point you could try manually installing the various modules Sitecore provide, covering things like common components, logout functionality etc. However I personally found this a bit awkward. Unless you know what your doing your probably going to run into issues such as compatibility between the latest version of Angular and the Sitecore components (at time of writing Angular is on version 5 but Speak 3 only supports Angular 4).

Instead I would recommend downloading the sample application from https://dev.sitecore.net/Downloads/Sitecore_SPEAK/3/Sitecore_SPEAK_3.aspx and then copy over the .npmrc and package.json file to your solution.

By including these files, the .npmrc file will add a reference to Sitecores package repository and the package.json file will make sure the right packages and versions will be installed. Use npm to install the packages.

npm install

1 - Install NPM Packages

Next we need to update a couple of files in the application to reference some Sitecore specific bits. This is explained in Sitecores documentation, in my examples though I’ve also included referencing some modules that you are likely to use.

app.module.ts

The app module file defines the modules that are going to be used in the application. Here we need to add the references to the Sitecore modules.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { ScAccountInformationModule } from '@speak/ng-bcl/account-information';
import { ScActionBarModule } from '@speak/ng-bcl/action-bar';
import { ScApplicationHeaderModule } from '@speak/ng-bcl/application-header';
import { ScButtonModule } from '@speak/ng-bcl/button';
import { ScGlobalHeaderModule } from '@speak/ng-bcl/global-header';
import { ScGlobalLogoModule } from '@speak/ng-bcl/global-logo';
import { ScIconModule } from '@speak/ng-bcl/icon';
import { ScMenuCategory, ScMenuItem, ScMenuItemLink, ScMenuModule } from '@speak/ng-bcl/menu';
import { ScTableModule } from '@speak/ng-bcl/table';
import { ScPageModule } from '@speak/ng-bcl/page';
import { CONTEXT, DICTIONARY } from '@speak/ng-bcl';
import { NgScModule } from '@speak/ng-sc';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ScAccountInformationModule,
    ScActionBarModule,
    ScApplicationHeaderModule,
    ScButtonModule,
    ScGlobalHeaderModule,
    ScGlobalLogoModule,
    ScIconModule,
    ScPageModule,
    ScMenuModule,
    ScTableModule,
    NgScModule.forRoot({
      contextToken: CONTEXT, // Provide Sitecore context for SPEAK 3 Components (optional)
      dictionaryToken: DICTIONARY, // Provide translations for SPEAK 3 Components (optional)
      translateItemId: '0C979B7C-077E-4E99-9B15-B49592405891', // ItemId where your application stores translation items (optional)
      authItemId: '1BC79B7C-012E-4E9C-9B15-B4959B123653' // ItemId where your application stores user access authorization (optional)
    })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

The component file needs updating to call init on the ngScService.

import { Component, OnInit  } from '@angular/core';
import { NgScService } from '@speak/ng-sc';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  constructor(
    private ngScService: NgScService
  ) {}

  ngOnInit() {
    this.ngScService.init();
  }
}

.angular-cli.json

In the angular-cli.json file you will see a styles section which references the main css file in the solution. Here you will need to add an additional reference to Sitecores css file.

../node_modules/@speak/styling/dist/styles/sitecore.css

Launch

You can now launch your application from the command line and see the default start screen.

ng serve --open

Step 2 – Building your application

It’s not time to start building your application. If you don’t know Angular I suggest going through a couple of tutorials, and go from there. I’m not going to go into any details about how Angular apps are and should be written, but I am going to go through a few of the Sitecore controls needed to make an application that fit’s the Sitecore admin.

Example Page


To make this page first I cleared out everything from app.component.html and started adding some Sitecore components. Normally you would start generating your own components to represent things like pages, but for the purposes of the example I placing everything in the one file.

To start I have a sc-page containing a header. This comes out of Sitecores demo application and will give you the standard bar that sites at the top of the Sitecore admin, informing users where they are.


<div>
    
      <a href="#"></a>
      <!-- AccountInformation gets accountName and accountImageUrl automatically from Sitecore context which is configured in AppModule -->
      
    </div>

To create the menu I’m using an sc-menu. Notice how some items are marked as active.


<aside>
    
      
        
          <a>Menu item 1</a>
        
        
          <a>Menu item 2</a>
        
      
      
        
          <a>Menu item 3</a>
        
        
          <a>Menu item 4</a>
        
      
    
  </aside>

Lastly to create the main content of the page I’m using a scPageAppHeader, scPageContent and an scTable for the table.

<div>
    </div>
<article>
<table>
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>Created by</th>
<th>Created data</th>
</tr>
</thead>
<tbody>
<tr>
<td>Lorem</td>
<td>Active</td>
<td>sitecore\admin</td>
<td>Jan 20, 2018</td>
</tr>
<tr>
<td>Ipsum</td>
<td>Active</td>
<td>sitecore\admin</td>
<td>Jan 20, 2018</td>
</tr>
<tr>
<td>Foop</td>
<td>Inactive</td>
<td>sitecore\admin</td>
<td>Jan 22, 2018</td>
</tr>
</tbody>
</table>
</article>


The complete code looks like this:


<div>
    
      <a href="#"></a>
      <!-- AccountInformation gets accountName and accountImageUrl automatically from Sitecore context which is configured in AppModule -->
      
    </div>
<aside>
    
      
        
          <a>Menu item 1</a>
        
        
          <a>Menu item 2</a>
        
      
      
        
          <a>Menu item 3</a>
        
        
          <a>Menu item 4</a>
        
      
    
  </aside>
<div>
    </div>
<article>
<table>
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>Created by</th>
<th>Created data</th>
</tr>
</thead>
<tbody>
<tr>
<td>Lorem</td>
<td>Active</td>
<td>sitecore\admin</td>
<td>Jan 20, 2018</td>
</tr>
<tr>
<td>Ipsum</td>
<td>Active</td>
<td>sitecore\admin</td>
<td>Jan 20, 2018</td>
</tr>
<tr>
<td>Foop</td>
<td>Inactive</td>
<td>sitecore\admin</td>
<td>Jan 22, 2018</td>
</tr>
</tbody>
</table>
</article>


To avoid some build errors later on we also need to update the app.components.ts file (think of this as a code behind file), to have an additional property and service.

import { Component, OnInit  } from '@angular/core';
import { NgScService } from '@speak/ng-sc';
import { SciLogoutService } from '@speak/ng-sc/logout';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  isNavigationShown = false;

  constructor(
    private ngScService: NgScService,
    public logoutService: SciLogoutService
  ) {}

  ngOnInit() {
    this.ngScService.init();
  }
}

How to find more components

Unfortunately the Sitecore documentation doesn’t currently contain a list of what’s available. However if you look in your node_modules folder there is a change log containing information on each component here \node_modules\@speak\ng-bcl\CHANGELOG.md.

Step 3 – Publishing the application

Once you’ve built the application you need to publish it and copy it into Sitecore.

There are some differences in the way a Speak 3 Angular application needs to work which differ from the normal way an Angular application runs. Among others these include having an index.apsx page rather than an index.html and the application not being located in the root of a site. You can read more about this in Sitecores documentation. The good news though is Sitecore have provided a post build step to sort this out for you.

If you copied the package.json file at the beginning this will already be set up, one thing you do need to do though is update the base location to be where your application is going to live.

Once this is done you can run a build.

npm run-script build

Note this is using npm to run the build script from the packages.json file rather than doing a regular ng build from Angulars CLI.

If all succeeds your dist folder will now contain a compiled version of the application.

Copy these files into the destination folder in your Sitecore site. For me this is \sitecore\shell\client\Applications\Speak-Example. You should now be able to log in and view your application.

Notice the logout button now functions and the current user is displayed in the top right. The menu sections are also collapsible, but other than that our application doesn’t actually do anything.

Moving on from this there’s lot’s more to cover on building out the functionality in the application and you may have also noticed in the app.module.ts file a reference for translations which I never created, but this should be enough to get anyone started with building an Angular Speak 3 project and then publishing it into Sitecore.

Related Links

Speak 3 Official documentation
Speak 3 Downloads