KeystoneJS (Node.js CMS & Web Application Platform)

KeystoneJS (Node.js CMS & Web Application Platform)

Akash Kuber

18 Jan, 2018

Introduction of KeystoneJS

KeystoneJS is a generic content management framework, meaning that it can be used for developing a variety of web applications using Javascript. It is especially suitable for developing large-scale applications such as portals, forums, content management systems (CMS), e-commerce projects and RESTful Web services because of its modular architecture and clean separation of various functionality.

KeystoneJS is a powerful Node.js content management system and web app framework built on express and mongoose. Keystone makes it easy to create sophisticated websites and apps and comes with a beautiful auto-generated Admin UI.

Why use KeystoneJS?

KeystoneJS provides a standardized set of components that allow for the fast and easy development of web applications that can be quickly developed, maintained and extended.

KeystoneJS has a number of key features that make it worth using including:

Modularity – Keystone will configure express – the de facto web server for node.js – for you and connect to your MongoDB database using Mongoose, which is the leading ODM package.

Auto-generated Admin UI – Whether you use it while you’re building out your application, or in production as a database content management system, Keystone’s Admin UI will save you time and make managing your data easy.

Session Management – Keystone comes ready out of the box with session management and authentication features, including automatic encryption for password fields.

Email Sending – Keystone makes it easy to set up, preview and send template-based emails for your application. It also integrates with Mandrill.

Form Processing – Want to validate a form, upload an image, and update your database with a single line? Keystone can do that, based on the data models you’ve already defined.

We also recommend that your application will be simpler to build and maintain if you mirror the internal structure of your routes/views and templates/views directories as much as possible.

Models

Before you can start your Keystone app, you’ll need some data models. We’re going to start with the User model, which is special – we need it so that Keystone can do authentication and session management. Create the following two files in the /models folder

models/index.js

This is the script that includes your models. It doesn’t need to export anything.

require('./users.js');

models/users.js

This script initializes the User model. It doesn’t need to export anything, but the model must be registered with Keystone.

Authentication and Session Management

For Keystone to provide authentication and session management to your application, it needs to know a few things (which we’ve now configured).

To recap:

The option user model must be the name of the Model that Keystone should look in to find your users. If you use a different model name, be sure to set the option correctly.

If you want your application to support session management, set the session option to true. Loading sessions incurs a small overhead, so if your application doesn’t need sessions you can turn this off.

Keystone has built-in views for signing in and out. To enable them, set the auth option to true. You can also implement custom signin and signout screens in your applications’ views.

Sessions are persisted using an encrypted cookie storing the user’s ID. Make sure you set the cookie secret option to a long, random string.

The user model must have a canAccessKeystone property (which can be a virtual method or a stored boolean) that says whether a user can access Keystone’s Admin UI or not. *Note* If you choose to use a virtual method setting the value in mongodb directly will not authenticate correctly. A virtual method is useful when the criteria for access is more complex. See Mongoose virtuals

Routes

Our first view controller is going to be very simple – just rendering a template. Create an routes/views/index.jsfile like this:

Middleware functions

Keystone expects middleware functions to accept the following arguments:

req – an express request object

res – an express response object

next – the method to call when the middleware has finished running (including any internal callbacks)

Flash message support (no, not that flash)

Keystone includes support for ‘flashing’ messages to your visitors via session. The default setup above supports four categories, all of which can be styled differently:

info

success

warning

error

You can easily support other types of messages by updating your middleware and the .jade template that renders them (which we’ll get to below).

To use flash messages in your route controllers, do this:

req.flash('info', 'Some information!');

Public Assets

You’ll want to add your own css, javascript, images and other files to your project. In the examples above, we’re including /styles/site.min.css and /js/lib/jquery-1.10.2.min.js.

Keystone will serve any static assets you place in the public directory. This path is specified in web.js by the static option.

It will also automatically generate .css or compressed .min.css files when a corresponding .less file is found in the public folder, as specified in web.js by the less option. For more information on LESS, see lesscss.org.

Production vs. Development

Keystone applies different settings in production and development modes. The environment will default to development, so you should set the NODE_ENV environment variable to production on your production servers for better performance.

Your app can detect which environment it is running in by calling keystone.get(‘env’).

When you deploy your KeystoneJS app to production, be sure to set your ENV environment variable to production. You can do this by setting NODE_ENV=production in your .env file, which gets handled by dotenv.

Creating an admin user

To begin with, we would need a user to manage the admin site. KeystoneJS includes code for the creation of an admin user by default when the app is started for the first time. The user is created using the updates framework provided by KeystoneJS. Updates provide an easy way to seed your database, transition data when your models change, or run transformation scripts against your database.

The default admin is created with the below code that is stored at /updates/0.0.1-admins.js with the following credentials:

The KeystoneJS administration site

Start up our app using the node keystone.js command and open http://127.0.0.1:3000/keystone/signin in your browser. You should see the administration login page shown below.

Log in using the credentials of the user created in the previous step.

Dynamically adding columns to Admin UI

One of the most useful features for looking at data in the admin interface is the ability to dynamically add columns that we are interested in without having to modify the definition of the model in code. The columns dropdown on the top right lists all the fields defined in our model. Columns that have been listed in the default columns option will appear with tick marks next to them. We can then pick any additional columns that we are interested in working with.

If a custom field was chosen, it will be added to the end of the displayed column headers. We can reset the list of displayed columns to the original state by using the ‘Reset to default’ option that will appear in the dropdown once one or more columns have been selected.

Disabling the Admin UI

You can disable the Admin UI by setting the headless option to true. This will allow you to use keystone.start() or keystone.routes(app) without Keystone creating route bindings for the Admin UI routes under /keystone

Services

Google Analytics

Keystone has support for Google Analytics tracking in the Admin UI. To enable tracking, set the following configuration options:

KeystoneJS supports Amazon S3 for file upload and hosting, with the S3File field type. To use the S3File field in your app, sign up for an account, create an S3 bucket, and get your key and secret. Then set the s3 config option to an object containing your configuration (see example below). Alternatively, set the S3_BUCKET,S3_KEYand S3_SECRET environment variable.

KeystoneJS supports Windows Azure Storage for file upload and hosting, with the AzureFile field type. To use the AzureFile field in your app, sign up for an account, enter into Azure Management Portal. Create a storage account with new(button), data services, storage. In storage account page get the access (account name, key (valid primary or secondary key)) with the button “manage access key”. Then set the azurefile config option to an object containing your configuration.

Cloudinary is an image upload/resizing/hosting service that makes it easy to implement image management in your KeystoneJS app using the CloudinaryImage and CloudinaryImages field types. To use the Cloudinary Image fields in your app, sign up for an account (Cloudinary offers a free tier with up to 500MB storage, 50,000 images and 1GB data transfer) and get your cloud name, api key and api secret.

If you are serving over HTTPS and want to ensure that cloudinary images are also serverd over HTTPS, set the cloudinary secure option to true.

Embed.ly is a service that will parse a url (e.g. Youtube embed link) and return a whole lot of useful information, like the provider name, summary metadata, width and height of videos, as well as a clean link to use for embedding media in your views. They offer a free plan for up to 5,000 urls per month. The Embedly field type is an easy way to integrate their API with your KeystoneJS app. To configure KeystoneJS to support the Embed.ly API, simply sign up for an account, get your api key, and set the embedly api key option.

This option will default to the EMBEDLY_API_KEY environment variable if it is set.

keystone.set('embedly api key','your-key');

Mandrill

Mandrill is a scalable and affordable email infrastructure service that allows you to send emails easily. They offer a free plan for up to 12,000 emails per month. To configure KeystoneJS to support the Mandrill API, simply sign up for an account, get your api key, and set both the mandrill api key and mandrill username options. These options will be default to the MANDRILL_API_KEY & MANDRILL_USERNAME environment variable’s if set.