CMS for NodeJS: Using Crafter CMS Javascript SDK on the Server with Node JS

In this blog, we will focus on the language-specific bindings for Javascript, the Crafter CMS Javascript SDK applied on the server side with Node JS. A deep dive on the Javascript SDK and architecture can be found in this blog post: Introducing Crafter CMS Javascript SDK

Pre-requisites for Using the Library

  • NPM / Yarn installed
    • The SDK releases are published to Node Package Manager (NPM.)  Example: https://www.npmjs.com/package/@craftercms/content
    • NPM will help you easily download the proper dependencies.  You can all so use NPM or Yarn to build and execute your application.
    • In our example, I will use Yarn to manage my package.json file and to assist me in building my application.
  • Access to a running Crafter Engine instance and site.

Building a Simple Javascript Application

The point of our application in this blog is to demonstrate how to include and use Crafter CMS’s Javascript SDK in an application and to use it to retrieve content from a running Crafter Engine instance.   We’re going to keep the application extremely bare bones in order to illustrate that this library is independent of any specific frameworks or platforms such as Node.js, React, Angular, Vue etc.

For those looking to get right into the meat of the integration, use of the SDK starts at Step 4.

Step 1: Create a basic structure and build for the app

The first thing we want to do is to create a directory for our application source.  I will call my directory simple-node. Inside that directory add a file called package.json with the following content:

{
 "name": "simple-node",
 "version": "1.0.0",
 "description": "Simple Node JS Server that will use Crafter CMS Javascript SDK",
 "main": "server.js",
 "scripts": {
 "test": "echo \"Error: no test specified\" && exit 1"
 },
 "author": "",
 "license": "ISC",
 "dependencies": {
 "@craftercms/classes": "^1.0.0",
 "@craftercms/content": "^1.0.0",
 "@craftercms/models": "^1.0.0",
 "@craftercms/search": "^1.0.0",
 "@craftercms/utils": "^1.0.0",
 "express": "^4.16.3",
 "url-search-params-polyfill": "^5.0.0",
 "xmlhttprequest": "^1.8.0"
 },
 "proxy": {
 "/api": {
 "target": "http://localhost:8080"
 },
 "/static-assets": {
 "target": "http://localhost:8080"
 }
 }
}

This file describes our application, how to build it and what is needed to build it.  In the content above we can see:

  • The application metadata.
  • The application dependencies we are requiring are the various Crafter CMS Javascript SDK dependencies ( “@craftercms/content”: “^1.0.0”, “@craftercms/search”: “^1.0.0”, etc.)
  • The application build/dev dependencies that help us compile the application for distribution (xmlhttprequest”: “^1.8.0.)
  • Configuration for your Crafter CMS endpoint.

Step 2: Perform an initial build

Run yarn in your application directory.  This will download all of your dependencies.

Step 3: Create an application Javascript

Note that in our package.json we’ve listed server.js listed as the main for the application.

Create a server.js file and place the following content in the file:

console.log('server is starting');

var express = require('express');
var app = express();
var server = app.listen(3000, listening);

app.get('/', test);

function listening() {
 console.log('listening...'); 
}

function test(request, response) {
 response.send('Hello World!');
}

app.use(express.static('website'));

 

Now run the application by typing: node server.js

Finally, access your application via the browser at http://localhost:3000

 

Step 4: Calling Crafter CMS API’s with our application

Now that we have a very basic, working application it’s time to use the Crafter CMS Javascript SDK.

Crafter Engine Instance

In order to use the Crafter CMS APIs, you will need a running Crafter Engine instance with a project set up that you have access to.  It’s easy to get started. Here are some helpful links on getting things set up:

Import the APIs into your application javascript

Add the following code at the very top of your server.js script file.  Here we are declaring the classes we will use and indicating where they are imported from (the SDK.)

var classes = require('@craftercms/classes'),
    content = require('@craftercms/content'),
    crafterConf = classes.crafterConf,
    ContentStoreService = content.ContentStoreService;

XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;

Configure the SDK for your Crafter Engine endpoint base URL (server name, port etc)

Now that you have declared the Crafter CMS SDK services you want to use you are almost ready to start retrieving content.  Before we can, we need to make sure the SDK APIs know where Crafter Engine “endpoint” / server is and what site to pull the content from.  To do that we have two options:

  • We can create a configuration object and pass it with each call
  • Or we can explicitly supply the endpoint configuration with each call

Since we’re going to use the same endpoint and site, we’ll set up a configuration object and pass it when we call the APIs.  To configure the endpoint we add the following code to our script after the import statements:

crafterConf.configure({
 baseUrl: 'http://localhost:8080',
 site: 'editorial'
});

The configuration above states that our API calls will reference the site in Crafter Engine that has the “editorial” ID. By default, the configuration assumes that Crafter Engine is running locally on port 8080. To change this, add the following:

baseUrl: “YOUR_PROTOCOL//YOUR_DOMAIN:YOUR_PORT ”

crafterConf.configure({
 site: 'editorial',
 baseUrl: "https://mydotcomsite"
});

If you want the system to assume that the app and the API endpoints are on the same server you can set base URL to an empty string (“”)

Call a Crafter CMS API and get content

Make the code changes:

Now that the library is imported and configured, we’re ready to use it.  Let’s add the code to our example to make a request for content and put it on the screen for the user.   Below is the entire server.js script for our application with changes:

console.log('server is starting');

var express = require('express');
var classes = require('@craftercms/classes'),
 content = require('@craftercms/content'),
 crafterConf = classes.crafterConf,
 ContentStoreService = content.ContentStoreService;

XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;

var app = express();
var server = app.listen(3000, listening);

app.get('/', test);

crafterConf.configure({
 baseUrl: 'http://localhost:8080',
 site: 'editorial'
});

function listening() {
 console.log('listening...'); 
}

function test(request, response) {
 ContentStoreService.getItem('/site/website/index.xml')
 .subscribe(item => {
  var htmlTitle = item.descriptorDom.page['hero_title'];
  response.send('Hello World: ' + htmlTitle);
 });
}

app.use(express.static('website'));

What we’ve done is replace the code in the test function that was hardcoded to write “Hello World” on the screen for the user with the code that calls Crafter CMS for content and write the retrieved content on the screen instead.

Let’s take a closer look at the API call; ContentStoreService.getItem

  • The first parameter is the path of the content item we want to return.  The example uses the home page of the editorial site.

Test the application

After you have made your changes, stop the Node server (Ctrl+C) and restart it. Once it’s restarted, reload your application in the browser to see content coming from your Crafter CMS site:

 

Congrats!  Your application’s content is now externalized and managed in the CMS.

Step 5: Update your content using the CMS

Now that our code is complete our content authors can update the content at any time via the CMS and we don’t need to rebuild or redeploy the application.  Let’s use Crafter Studio to update the content for our app.   You can find detailed how-to help here:  Creating and working with your First Crafter Site

In Crafter Studio, find the content you want to edit

In our case, the content we’re consuming is the hero title.  Let’s make an edit to that content:
In your site’s content preview, turn on the editing pencils and click the pencil for the Hero Title (as shown above.)


Note that the author has a preview of the content.  This is something very different and ultimately much better than what you see with other Headless CMS systems.

With Crafter, it’s always possible to provide the user with a preview of the content they are editing regardless of the front end framework.  Preview capability is key because it makes editing content easier for authors.

Make a content change and save

After you click the pencil for the Hero text make the change and then click the Save and Close button at the bottom of the form.  You will see your update in the CMS right away.

Refresh the example application

Wow! Those changes in the CMS look great (if I do say so myself :D!)  Now it’s time to see the changes in our application.  Simple, just refresh your application in the browser. No code updates required!

It’s really just that simple!  A few lines of code allows us to create applications with content, configuration and other strings that we can update at any time without needing to update or redeploy our application code.

What about the full API, workflow and publishing?

This blog is meant only to cover the basics of using the Crafter CMS SDK with Node JS. A deep dive on the Javascript SDK and architecture can be found in this blog post: Introducing Crafter CMS Javascript SDK.

Conclusion

Crafter CMS’s Javascript SDK gives front end and full stack developers who work in Javascript and Javascript related technology a native programming API to work with that makes building content-rich applications much easier to do.

When we stop an think about it, almost every application has content in it.  If that content is easy to update and updating the content can be done by non-technical users at any time without a build or deployment everybody wins:

  • The content in the application is richer and much fresher
  • Developers spend time developing rather than making non-code related updates
  • Removing non-feature related deployment distractions gives us more time and makes our teams more agile.
  • Our business users can make their changes at any time which makes the business more agile.

Headless CMS capabilities provide non-technical users with the ability to update, workflow and publish an application’s content at any time without the involvement of developers and IT.

Crafter CMS’s headless capabilities go beyond traditional headless CMS systems by providing authors with an in-context preview for content editing and giving developers the freedom to use whatever front-end technology they want.

CMS for SPAs (2 of 4): Save the Content Authors

In Part 1 of the series CMS for SPAs: Are Single Page Applications and Headless CMS a Slam Dunk?  we looked at the trend toward Single Page Applications (SPA) and Headless Content Management Systems (CMS) in general. SPA applications are becoming the de facto way to build web-based applications and sites. Headless CMS is a decoupled, API-first approach to content management that aligns neatly with SPA architecture. Further, the decoupled nature of the architecture makes content more reusable (multi-channel) and completely divorces development from the CMS allowing for greater freedom and agility for developers. While these can be seen as major wins, several developer and DevOps issues remain while others have been created. Further, most of the headless CMS solutions available today set content authors back nearly 20 years in terms of content editing and workflow tooling and practices.

In this installment, we’ll focus on the various ways content authors have been impacted by headless CMS and how Crafter CMS addresses these issues to provide authors with true headless CMS support for SPA applications.

Authors Forced into the Wayback Machine

Clumsy tools and processes for editing, reviewing and testing content offered by headless CMS platforms have content authors, the primary stakeholder of CMS platforms, wondering if they fell asleep and woke up back in the early 2000’s. Let’s take a look at some of the issues facing authors in the Headless CMS space.

Preview and In-Context Editing

Authors are accustomed to easy-to-use tools that enable them to visually locate, edit and publish content in websites or applications. Many headless CMS platforms provide no way for authors to preview their work prior to publishing it. Authors are forced to change content via content entry forms that are completely disconnected from the presentation.  In order to see what the content will look like on the website or in the application, they must publish the content. No author should be forced to work with slow and clumsy deployment iterations just to ensure their content fits and looks good on destination channels. That’s a major step backward.

Some CMS vendors and practitioners argue that by completely obscuring the presentation from the authors, content gets created in a fashion that is naturally more reusable. That’s not necessarily accurate. Content is more reusable when stored and transmitted in a fashion that is divorced from presentation — but that does not mean authors should be forced to ignore how their content will be presented on key channels. As the saying goes: “the medium is the message.” To most authors, the layout is just as important as the content itself. Authors need tools in their headless CMS that are on the level of the tooling they have become accustomed to with more traditional CMS platforms.

Delivering Editing and Preview tools for SPAs

Crafter CMS gives authors a full, interactive in-context preview and editing experience within SPAs. Authors have exactly the same tooling they have become accustomed to with traditional CMS.

Crafter’s preview capability can sit in front of any web-based application. The specific technology does not matter. Crafter’s preview and editing tools are front-end agnostic. One of the key reasons Crafter is able to do this is that Crafter CMS has always separated authoring and delivery into distinct but integrated components. We’ve been assuming a decoupled architecture for years.

Authors are the main users of any CMS and their needs must be properly addressed. A solid authoring experience with true in-context editing and preview is table-stakes for any headless CMS.

Personalization of Headless / API based Content

Another area that Headless CMS platforms have impacted authors is support for targeted/personalized content. Content authors need to be in control of the rules that drive the right content to the right people at the right place and time.

To support personalization your headless CMS must support the following two capabilities:

  • The ability to design, configure or code business rules behind the services.
  • The ability to preview content and functionality driven by personalization rules prior to publishing.

To date, most headless CMS platforms are simple repositories of content that are retrievable by API call. These systems offer no ability to create rules that can be executed based on the request parameter variations and characteristics of the requester.

Further, based on the previous section, we already know that most Headless CMS platforms don’t support pre-publishing preview of content — let alone the ability to preview content and experience as it would appear in different scenarios. There is little point in writing rules or variations of content without the means to properly test them prior to publishing.

Delivering Personalization for SPAs

Crafter CMS provides excellent support for targeted and personalized content even when content is delivered in a headless environment. Authors can configure scenarios and simple rules via the UI or leverage sophisticated rules built-in scripting languages by the development staff. Further, Crafter CMS provides rich preview tools that allow authors to impersonate different users and other types of content consumers within the authoring tools so that content and scenarios can be properly tested well before they are published.

The Need for Real Versioning and Branching

Most CMS platforms (traditional and headless) support some kind of basic versioning.  For the most part that support extends only to a single content item. Each item has its own history.  There is no way to look at the entire content collection at it existed at a specific point in time. That can be a major challenge for authors if they need to reference a previous campaign or support an audit.  The ability to maintain a version history is paramount and rudimentary versioning is typically not enough.

Another key feature that is missing from CMS platforms is the ability to support branches.  Branches allow us to work on different variants of the content at the same time. A branch not only allows concurrent work but it also enables us to sync up variants when it’s appropriate.  This extraordinarily important to authors who are supporting a re-branding or a major content overhaul. Most CMS systems can’t support that without content freezes and manual “double publishes”

Delivering Real Versioning and Branches

Crafter CMS’ repository is based on Git. Git provides authors using Crafter with a versioning system that is multi-file — meaning that an author can see the entire content collection at any moment in time in its history.  Git also provides support for branches which means that authors using Crafter can support difficult operational scenarios like re-brands without any content freezes or extra publishing.

Content freezes and Other Business Interruptions

New features, design refreshes, and integrations are a way of life for today’s customer-focused market. Agility and innovation at scale and speed are key to winning in this competitive landscape. Wherever you have innovation you will find developers and development process along with its procedures, tools, and environments. Businesses want innovation without disruption. Unfortunately with most CMS platforms, due to their architecture, business disruptions are exactly what content authors and other business users end up with. Outages and complicated deployment processes along with content freezes are realities for most innovative organizations use CMS.

When we look at the reason for the disruptions to the business activity we find that the development and testing process requires that we maintain independent testing environments and that we do code deployments. It’s during this maintenance activity that authors are often told to “hold off” or “stay out of the system.” Content freezes waste time and money and they hurt the business. SPAs and Headless CMS platforms do nothing to solve this problem.

In order to get content to lower environments like Dev, QA, and Test we have to take an export of Production. Authors need to stop working during exports. Imports on the lower environments are no fun either. Every environment needs to be painstakingly and individually updated. When coding is complete it has to be rolled out. Once again authors need to refrain from using the system. Complicated deployment procedures and models can take hours, days and in some cases even weeks. More valuable time and money are wasted.

Uninterrupted Business Activities with SPAs

Crafter CMS has an architecture that is different from other CMS platforms. Crafter is designed and implemented with repository technology specifically designed to handle these processes with minimal effort and friction. Crafter CMS leverages Git at its repository layer. In contrast to CMS platforms that rely on databases or JCR repositories that rely on exports and imports that require outages to sync data between environments, Crafter’s repository is meant to be distributed and as such it natively supports syncing between related stores. We call this push button process “Code Forward, Content Back”™ Crafter CMS allows developers along with their tools and process to live and work in harmony with content authors. This enables collaboration together without interruption and with much less friction so that a greater level of innovation and ongoing operations can all take place at the same time.

Conclusion

The net-net of it is simple. Regardless of any improvement in content reusability or ease of development, authors need to be able to do their jobs easily and efficiently without interruption. New tools and approaches need to move the ball forward, not back. Unfortunately for authors, headless CMS has lost major ground.

Some of these shortcomings can be overcome with time but all of the shortcomings we looked at here are architectural in nature. Architecture changes are the most difficult and time-consuming to make. You don’t have to wait for your current headless CMS to correct course. Crafter CMS is an open source headless CMS with the right architecture to take full advantage of the benefits of SPA applications provided to end users and developers while giving authors the tools, process and uninterrupted service they need to succeed.

What has your experience been working with SPAs and your CMS?

CMS for SPAs (1 of 4): Are Single Page Applications and Headless CMS a Slam Dunk?

From web-based applications like Gmail, Instagram, and Google Maps to websites like The New York Times and Facebook, real-world examples of Single Page Applications (SPA) are everywhere you look. Developers have been turning to SPA frameworks and architectures to create better, more usable, richer applications for their users.

Nearly every Content Management System (CMS) out there purports to support SPA frameworks and architectures. In this blog series, we’ll look at SPA use in the CMS space to learn more about what’s working, what’s not and what we can do about it. Let’s jump in.

SPAs are web-based applications built with rich UI frameworks that run client side and use partial page updates rather than full page refreshes to update data, content, and UI. SPAs have several advantages:

  • Great user experience: SPAs make the user experience more fluid with rich UI interactions that leverage asynchronous calls to the server for data and partial page refreshes.

  • Clean architecture: SPAs architecture promotes a clean separation of the frontend application and backend services and data. This approach makes development faster and more flexible.

  • Great frameworks: There are a lot of great frameworks that make developing SPAs faster and easier including React, Angular, Vue and others.

In the CMS space, SPA applications have been a win for developers but content authors have taken a major hit.


Developers have been keen to adopt SPA technology and CMS vendors have quickly responded with support for Headless CMS (also known as Content as a Service [CaaS]) support.

This shift has been highly promoted by CMS vendors because it has a number of advantages with respect to content management. Returning content as JSON or other presentation-less formats makes content more reusable within and across delivery channels. More importantly, by removing the consuming application from the CMS, the approach seems to solve one of the major challenges in the CMS space: development. It’s no secret that most developers have little interest in working within the toolsets and constraints of a CMS. Developers want control over their tools, frameworks, and process. CMS platforms are notoriously framework laden and don’t integrate well with DevOps tools and process.

The headless approach completely and neatly decouples development and content production workflows. On the surface, the headless approach appears to be a perfect evolutionary step for CMS. New delivery channels and integration opportunities show up all the time. In a customer experience driven market, anything that aids development and reduces time to market is seen as a winner.

However, the reality is that decoupling the CMS from the consuming application does not solve long-standing challenges such as refreshing content in lower environments — in fact, it complicates them. Worse, complete decoupling creates new problems. While software development and content production workflows are best divorced, their products: the code and content are not. There is a time/version specific relationship between the data model, the content and the code at any given moment. To illustrate the point: it’s often not possible to “point” an older version of an application at a newer version of the content and vice versa. It’s extremely difficult to troubleshoot or perform legal and regulatory audits without this capability. Yet, with the clear benefits of better products, a cleaner deployment architecture and faster, easier development in mind, the remaining issues are either unrecognized or a compromise many developers are willing to take. For developers, the SPA and headless approach have largely been a win.

The ironic and unfortunate “dirty little secret” in the CMS space of late is that the biggest losers of the headless CMS movement have been the content authors, CMS’s main stakeholder.

Today’s headless CMS options have the following drawbacks for authors:

  • There is no preview. Authors are used to in-context editing and preview. With headless, they are back to working in forms with no preview and are left to hope and a cumbersome process to ensure that the content will present properly.
  • There is no personalization. Marketers want to be able to target and personalize their messaging to the audience. Most headless CMS platforms don’t give them the capability to describe and execute targeting rules much less test and preview the various scenarios.
  • DevOps are still not supported: Despite investments in new technology, tools and process content authors see zero improvements in DevOps activities related to feature releases. Content freezes and outages are still commonplace during feature deployments with headless CMS.

It doesn’t have to be that way! With the right CMS architecture and platform content authors, developers and DevOps can work together on SPA based sites and applications at speed with the tools and processes they are accustomed to (like in-context editing) without stepping on each other’s toes.

A Better Approach to SPAs, CMS and DevOps

Crafter CMS is an open source CMS platform that takes a completely different approach to headless CMS, SPA development and DevOps. Crafter CMS has a very different architecture from traditional CMS platforms that are monolithic and rely on SQL databases and JCR repositories.

Crafter’s architecture is modular, flexible, and completely elastic with a repository and deployment design that is shared-nothing and based on Git. This architecture enables Crafter CMS the flexibility to support content authors, developers and DevOps to collaborate together to build and release new experiences with minimal friction while using the tools and workflows that work best for them.

Crafter CMS is an API first CMS that is:

  • UI agnostic and can support development and editing and preview for any UI framework
  • Capable of supporting rich, personalized headless CMS content
  • Git-based to support your development frameworks, tools, and process in a way that separates development and content production workflows without needing to separate the deployable (code and content) artifacts.

Conclusion

SPA applications combined with decoupled, headless CMS offer significant advantages in terms of end-user experience, development, and deployment. However, it’s clear that headless is not a silver bullet. Completely divorcing the CMS and the consuming application or site creates significant challenges for DevOps, support and other departments. More importantly, the SPA/headless pairing has left authors out in the cold by taking away the process and tools they have become accustomed to over the past decade.

These shortcomings can be addressed with a new breed of CMS architecture. What’s needed is a flexible headless CMS that support proper authoring tools and process regardless of front-end technology. Moreover, we need a CMS that embraces and integrates development tools and process rather than shunning them. That’s exactly what we’ve set out to do with Crafter CMS. Stay tuned for our next blogs in this series where we’ll dive deeper into these concerns and their solutions.

What has your experience been working with SPAs and your CMS?

Building Angular2 Single Page Applications with Crafter CMS

Single Page Applications (SPA) are quickly becoming the industry standard for HTML5 based applications and responsive websites because they tend to be more user friendly, feel faster and are more responsive.

As with most applications today, SPA’s frequently contain a lot of content and related digital media such as images and videos.  Often times content and digital media are deployed statically along with the application. This approach creates unwanted dependencies for content updates on the developers and requires heavy deployment processes.

In the business context this misalignment and lack of independence can slow activities way down and ultimately impact the bottom line.  To address this common problem developers often build custom applications for non-technical users or leverage content management system (CMS) technology.  Building custom authoring tools doubles development time and creates an additional support burden on your development team. Leveraging a CMS is a great idea, but you need to make the right choice.  Many CMS architectures impose serious limitations on application and API architecture and design. As we’ll see in this article, Crafter CMS supports application developers with Content-as-a-Service that does not force any constraints on the application itself.

In this article we’ll build a simple (but not too trivial) SPA based on Angular2, then we’ll update it so that non-technical users may edit and deploy/publish content through Crafter CMS.

angular-2-pokedex

For our application we’ll start with a fun, simple Angular2 application called Pokedex written by Cory Rylan. The application is freely available via Github the AngularExpo. This application is a great example of a content application because, like most real-world applications, it contains content-oriented data that should be separated from the application code. Smart web/mobile/digital app developers separate content from their code.

The example application has two modes for retrieving data, the first option is via a static JSON data store that’s built at compile time and the second is pulling the data from a traditional data store.  Both out-of-the box options are not ideal for this real world scenario because to add new Pokemon to the Pokedex you need to be technical (i.e., a developer).  In this article we’re going to fix that so that any basic non-technical user can manage the Pokemon content, while the application consumes the data via Crafter’s API that provide Content-as-a-Service.

Step 1: Get Crafter CMS downloaded and installed

The first step is to get the CMS downloaded and installed. Crafter CMS is free and open source software licensed under GPL v3.

1.1 Download the Crafter CMS bundle

1.2 Install Crafter CMS and start it up

  • Unzip the download
  • Execute startup.sh (or startup.bat if windows) inside the unzipped folder
  • Open a browser to http://localhost:8080/studio. I recommend using Chrome. Chrome has the best support for desktop file drag and drop of all the browsers which will come into play later in this article.studio-login
  • Log in with username ‘admin‘ and password ‘adminstudio-no-sites

Step 2: Get the Angular2 application downloaded, compiled and tested

Now we want to get the application source code and get it running. To get and and build the code for this application you will need Git and NPM installed.

2.1 Download the source code

  • On a command line, execute: git clone https://github.com/splintercode/ng-pokedex.git
  • This will give you a folder called ng-pokedex in the same directory where you executed the command.

2.2 Compile the source code

  • On a command line, execute: the following commands
    • cd ng-pokedex
    • ng init (answer (N)o to all questions)
    • ng build –target=development
  • If you get the following error: ‘You have to be inside an angular-cli project in order to use the build command.
    • Simply add “angular-cli”: “1.0.0-beta.28.3”, to your package.json under devDependencies
    • and re-run the ng-build command.
  • To test your build:

angular-2-pokedex

Step 3: Install the application as a project in the CMS

We now have the prerequisites done and we’re ready to party! Let’s install the application into the CMS.

It’s worth noting that this step is completely optional.  You can run and manage the application code itself completely outside the CMS and simply leverage the CMS for the Pokemon content itself.

So why add the whole app to the CMS?

Several reasons:

  1. To show that it’s possible. You’ll note we’re able to load the entire application into the CMS with no changes at all outside of a few static asset path modifications to CSS and Javascript.
  2. Deployment. Once in the CMS, the application is now easily deployed (i.e., published) to any delivery infrastructure at the push of a button.
  3. Ease of Editing. With the app in the CMS we can overlay advanced authoring tools on the application via the CMS and allow the authors to edit In-Context of the application.  That’s sweet.

If you plan to manage the application outside the CMS completely simply follow Step 3.1 and move to Step 4.

3.1 Create and setup a CMS project to manage your application

  • In Step 1.2 you logged into the CMS as the admin user which has an admin role. On the screen you will see a button on the left hand that says “Create Site.” Locate and click this button.create-pokedex-site
  • Enter Pokedex as the application name.  Crafter CMS will generate an Site ID for you.
  • Select “Empty” for you blueprint and click the Create button.  Crafter CMS will create a new project for your Pokedex application with an basic “Hello World” type configuration.hello-site

3.2 Upload your application to the CMS

  • Click on Site Content in the menu at the top of the screen. This will open a panel on the left
  • Click on the Static Assets label this will open the folder.
  • Right click on static-assets folder and choose Bulk Upload Assetsupload-static-assets

3.3 Update the site template with the AngularJS 2 HTML page

  • In your ng-pokedx folder from step 2 you will find a dist folder. If is not there, execute ng build again. Drag the contents of the dist folder on to the upload dialog in the browser. When it’s done you will be able to click Done.Screen Shot 2017-02-26 at 6.09.09 PM
  • By uploading the compiled assets we’ve loaded the app into the CMS.  Now we have to tell the CMS to render our single page.  To do this we must update our out-of-the-box template provided to us by the blueprint.  In Crafter CMS, templates are coded in Freemarker and can contain any kind of markup (typically HTML 5) as well as special Freemarker Directives that make it dynamic.
  • To update the template: click “Site Content” in the menu at the top to hide the Site Content panel.   Then locate the Wrench in the upper right hand corner on the toolbar.  Click the Wrench.  This will open the Preview Tools panel on the right hand side of the screen.  preview-tools
  • Now click on In-context Editing to expand that specific tool.  You will notice this tool allows you to edit content, templates and controllers.  We’re interested in the templates.  Click Edit Template.edit-tempate
  • Replace the code in this template with the HTML found in your build directory at dist/index.html.Screen Shot 2017-02-26 at 6.23.51 PM
  • Note that the build assumes the application assets are at / on the server.  In Crafter CMS, static assets like CSS, Java Scripts and images are served from /static-assets.  You will want to modify the paths in the HTML template to use the /static-assets folder as shown above.  Once done, click update.angular2-app-craftercms
  • Your app is now running in the CMS!  Congrats!   With this complete, we can start working on making the application dynamic, editable by a non-technical user and updatable at any time without a deployment.

Step 4: Content enable the application

The first step in content enabling the application is determining what the content model is.  A content model is a definition and structure of the content.  We maintain the definition of the content structures within Crafter CMS by declaring Content Types.

To figure out what your Content Types should be, look for the NOUNS in the application that you want a non-technical user to be able easily update and publish at any time.  In our case, this is an individual Pokemon creature.

While a Pokemon in this simple application will be pretty basic, real world applications leveraging Crafter CMS can model very complex objects as well as relationships between objects.

Before get into the CMS, let’s figure out what the definition for our Pokemon type should be.  We do this by looking at the application and seeing what fields the app will require.

crafter-pokemon-detail

By clicking around in the application we come to learn that every Pokemon instance will require the following fields:

  1. Title
  2. Number
  3. A list of “Attacks”
  4. Height
  5. Weight
  6. Description

It appears we also need an image; however, looking closely at the application code, we’ll find that the application assumes an image has been uploaded with a filename based on the Pokemon number.  For simplicity sake, we’ll maintain this assumption even though it’s worth noting that enabling authors to upload and pick images, videos and other rich media is very simple in Crafter CMS.

OK! We have a list of fields we need for our Pokemon, let’s get started defining the type inside the CMS:

4.1 Declare a Pokemon Content Type

  • Open the Site Content panel.
  • Locate and click the menu item for Admin Console. This will take you to power user area in the CMS used to manage and perform various site administration tasks.
  • On the left panel in the Admin Console, locate and click the menu option for Content Types. This tool is used to create new Content Types and edit existing ones.content-types-console
  • On the toolbar at the top of your screen you will notice two options: Open Existing Type and Create New Type. Because a Pokemon is a new concept you want to introduce and define in the CMS, click on Create New Type. This action will pop up a dialog to prompt you for some basic information about the content type.
  • Enter Pokemon for the display label. Crafter CMS will suggest a content type name automatically for you.
  • The Type you want to choose is Component. In Crafter CMS anything that you are modeling which is NOT a page is a Component. The main difference in the CMS between pages and components is that page objects are automatically URL addressable while components are not.create-type-dialog
  • Once the dialog is configured, click Create. This will open the content type editor for your Pokemon Content Type. You can learn more about the content type editor in detail at http://docs.craftercms.org/en/stable/developers/content-modeling.htmlnew-pokemon-type
  • The Content Type Editor lets you drag/drop editing field types from the right hand controls list into your Content Type definition. You then click on the individual controls and configure them with Labels, properties, data sources and constraints.
  • For each field you need to add (Title, Number, A list of “Attacks”, Height, Weight. Description), look through the controls list and find the appropriate editing control for that content and drag/drop it into the Pokemon properties area.
  • After you add a field to the Content Type, click on it to configure it  in the Properties Explorer.
    • Add a label. This is the user facing name the author will see by the input control.
    • Crafter CMS will automatically suggest a variable name which you can use later in templates and controllers to access the content values.
    • Scroll down in the Properties Explorer to see all the properties and constraints for the given field. This is how you mark fields as required, change their input length and make other adjustments. pokemon-type-1
  • Notice that “Attacks” is a multi valued field.  Also, it uses a predefined list of attack types.  To support this field we’re going to want to use a control that allows the user to select several values and that gets its values from a list of options.  In Crafter CMS the way picker type controls get their values is via a Data Source.  There are several out of the box Data Sources and it’s possible to define your own as well.  For our example we’re going to use the most basic data source called a Static Key Value Pairs Data Source.  Scroll down in the Data sources area until you see it then drag/drop it on to the Data Sources portion of the Content Type definition.pokemon-ds
    Click on the added Data Source and begin to configure it.  Provide the title “Attacks“.  Crafter CMS will suggest a name automatically.  When you click on Options you will be prompted to enter a list of Key and the Value pairs. The “key” is stored with the user’s selection. The “value” is used for a label in the entry form.  Add a few attacks to the list and click Save.
    Clearly the Static Key Value pair Data Source is pretty basic.  If you need to access a managed taxonomy or re-use the same key value pairs in different content types you’ll want a different Data Source type but for our needs here it works well.
  • Once our Attacks Data Source is defined, lets add a control to the Content Type definition to capture the attack values as data.  The control you want is the “Grouped Checkbox” control.
    • Drag/drop it on the Pokemon properties area then click on it to configure it.
      • Provide the titleAttacks“.
      • Crafter CMS will suggest the variable name.
      • Scroll down in the Property Explorer until you see the “Attacksdata source listed and select it.  This binds the data source you created to this Group Checkbox control.  data-source-pokemon-group-checkboxes
  • Perfect! Your Content Type definition is now complete.  Click Save at the bottom of the screen.Note that you are going to get a warning that the content type does not have a template associated to it. That’s ok.  Not every Content Type needs a template.  In our case the app already knows how to render the content and we don’t need another template.  Click Save on the dialog.  You’ll notice a small save indicator on successful save.no-template-warn

4.2 Create Pokemon Content Objects

Now it’s time to create some test content.  To return to your project Click the Crafter Logo on the toolbar in the top left corner of the screen.  This takes you to your workflow dashboard.  From here you can create content or navigate back to your application preview via the Site Content panel.

  • Click on Site Content in the menu at the top of the screen. This will open a panel on the left
  • Click on the Components label this will open the folder.
  • Right click on components folder and choose New Content. create-content
  • The CMS will prompt you for the type of content you want to create.  You will note the Pokemon option.  Choose Pokemon and click “Ok.”choose-conent-type
  • Once you click OK you will be given the entry form for your Pokemon which you can start filling out.  Awesome! Crafter CMS automatically creates your Pokemon editing interface based on the Content Type Definition.pokemon-form
  • Repeat this process as many times as you want, creating a new Pokemon each time.  When you save the form you will see the Pokemon item listed under the Components folder as whatever value you entered into the Internal Name field (which is only used by the CMS editing tools as a label in the tool.)pokemon-components

Step 5: Configure a JSON based REST service to provide Pokemon content as service to the app

Any CMS worth its salt today can provide content via REST in JSON and other formats. Crafter does this out of the box — but Crafter also provides an important capability a lot of CMS do not and that’s an ability to easily define your own service. The dirty little secret with Content as a Service (CaaS) and CMS’s is that if you use the CMS’s out of the box APIs to get content you may be locking your self into the CMS and you are almost certainly forcing your app to adapt to the CMS. That’s the tail wagging the dog. Let’s look at how we can do small amount of scripting so that our JSON service response matches EXACTLY what the app expects (rather than changing the app to match the CMS.)

5.1 Create a RESTful Controller

  • Click on Site Content in the menu at the top of the screen. This will open a panel on the left
  • Click on the Scripts label this will open the folder.
  • Expand the scripts folder, right click on the rest folder and choose Create Controller.create-controller
  • Once you click Create Controller you will be prompted to enter a controller name.  In Crafter CMS the name of the controller in the REST folder follows a naming convention that defines the HTTP method that the controller responds to.  Our name is going to be “pokemon.get”  This means that we’ll end up with a service at the following URL “http://localhost:8080/api/1/services/pokemon.json”  that responds to GET requests.create-controller-dialog
  • When ready click create and you will be provided with a code editing screen.  In Crafter CMS, controllers are coded in Groovy (or Java).  There are many different kinds of controllers: REST controllers, page controllers, component controllers, request interceptors, scheduled jobs and others.pokemon-code-editor
  • Enter the following code in the editor and click update.
    def data = []// Define a query for pokemon content
    // Crafter CMS uses SOLR query syntax
    def queryStatement = ‘content-type:”/component/pokemon”‘
    def query = searchService.createQuery()
    query = query.setQuery(queryStatement)// Execute the query
    def executedQuery = searchService.search(query)
    def items = executedQuery.response.documents// For each result item, map the content type values to the names and JSON structure that the app expects
    // On the left hand side we see the fields the app expects on the right, the field variable names we defined.
    items.each { item ->
    def pokemon = [:]
    pokemon.id = item.number as Integer
    pokemon.name = item.title
    pokemon.description = item.description
    pokemon.height = item.height as Integer
    pokemon.weight = item.weight as Integer
    pokemon.types = item[“attacks.item.key”]
    data.add(pokemon)
    }

    // Return the data structure, which Crafter CMS will MARSHALL into JSON automatically
    return data

  • Now that our REST service is defined we can test it.  Open a browser to the following URL:      http://localhost:8080/studio/preview/#/?page=/api/1/services/pokemon.json&site=poledexpokemon-test-rest

Step 6: Update the app to use the RESTful Service

We’re in the home stretch now!  We have a dynamic service that updates any time we add, update or remove Pokemon content.  All we have to do now is change the application to use the new service.

6.1 Update src/app/shared/services/pokemon.service.ts

  • Add the following import:
    import { Response } from '@angular/http';
  • Add the following method:
    public getPokemon() {
    return this.http.get('/api/1/services/pokemon.json').map((res: Response) => res.json());
    }
  • Update the constructor to use the new getPokemon method:
    constructor(private http: Http) {
    this.store = { pokemon: pokemonData };
    this._pokemon = new BehaviorSubject(Object.assign({}, this.store).pokemon);
    this.pokemon = this._pokemon.asObservable().map(pokemon => pokemon.map(p =>         this.setPokemon(p)));
    this.pokemon = this.getPokemon();
    }
  • Rebuild your distribution by executing ng buld
  • In the CMS, Under the Site Content Panel:
    • Click on Site Content in the menu at the top of the screen. This will open a panel on the left
    • Click on the Static Assets label this will open the folder.
    • Right click on static-assets folder and choose Bulk Upload Assets
    • Drag/drop main.bundle.js and main.bundle.map to upload the latest build into the CMS.

update-app-js-pokemon

  • Under pages in the Site Content panel click home to load the preview and test the application.updated-pokemon-app
  • Congrats! Your app is now consuming content from the CMS.  You can now use the CMS to add new records or update existing ones!

 

Conclusion

Single Page Applications and the frameworks that help developers build them like AngularJS 2 are quickly becoming the defacto approach for building user-friendly responsive applications.  Smart developers will separate code from content so that non-technical users can quickly and easily update the application’s content without involvement from technical resources for code updates or deployments.  Integrating your CMS with your SPA is a strong pattern for solving this problem — but architects beware, not all CMS platforms are the same.  The wrong CMS will interfere with the development process and force interface and implementation details.  Crafter CMS offers the right architecture for the job. Crafter CMS integrates with your development process and tools and puts you app in control of the interfaces and implementation code while providing content authors with the tools they need  to update and publish the application independently.  To learn more check out Crafter CMS at http://craftersoftware.com and http://craftercms.org.

Special thanks to Cory Rylan and the Angular Expo for providing a fun application!