Keystonejs CMS

I've just installed KeystoneJS (http://keystonejs.com), a Nodejs CMS based on Mongodb and optional storage policies for binaries like images or files.

First impression? I like it :)

You only need to install NodeJs (NVM is your friend) and a MongoDB instance. After that you will be able to install it locally on your machine typing a couple of commands if you use the official generator-keystone Yeoman generator. Otherwise you can start from scratch as well.

After that no extra work is needed, open http://localhost:3000 in your browser and add new categories or blob posts. Or if you want you can deploy and host your application into the cloud on Paas platform.

  • you can create your own content types with a defined schema
  • admin UI automatically generated (add forms, edit forms)
  • supports logged in users and session management
  • form validations
  • dynamic routes
  • email sending
  • very basic workflow support (just what you need for a simple publishing experience)
  • you can switch to alternative template engines (default: Jade... nooo, I don't like it!)
  • easy customizable templates for object views and listing (just html)
  • mobile ready
  • indexing and search support (no advanced features like pdf-text extraction and indexing)
  • Paas ready for hosting solutions
  • no folder-aware conceps (for example blog items are just reachable from the /blob/posts/blog-slug, you cannot nest items in folders. But it is ok for a wide range of applications)
  • editable slug urls
  • different storage policies for images and files
    • CloudinaryImage(s) for automatically manages images stored in Cloudinary, including uploading, resizing and deleting. See http://cloudinary.com/
    • LocalFile, this field type is not compatible with PAAS hosts like Heroku https://www.heroku.com because it relies on the local file system
    • S3, automatically manages files stored in Amazon S3, including uploading and deleting (http://aws.amazon.com/s3/)
    • AzureFile, automatically manages files stored in Windows Azure Storage, including uploading and deleting
Not supported (or not yet):
  • advanced, configurable and generic workflow engine
  • field level security on content types
  • configurable portlet items or user defined boxes
  • not sure, no out of the box minification assets solutions for css and javascripts when you switch to production mode? (more or less something like already discussed on this old blog post hack http://davidemoro.blogspot.it/2013/08/yeoman-express-and-angularjs.html)
So if you compare its features with enterprise level CMS like Plone (http://plone.org) you might think that it is a very simple CMS solution.

But you should not consider it just like a CMS but as a simple but flexible framework for creating NodeJS/ExpressJS/MongoDB based generic web applications with an autogenerated UI. You can save a lot of time!

It is a very young project and I don't know if it will become the nodejs killer app but the approach sounds very good and probably it is the most advanced CMS solution based on NodeJS at this time of writing.

Very cool guys, keep up the good work!


yeoman generator mongodb interactive installer

In the previous post we have seen how to create your own yeoman generators using custom _.templateSettings rules.

However if you want to dive into yeoman generators you can play with generator-generator, have a look at the code of existing generators and... why not? Create your own whatever-you-want yeoman generator!

I chose to implement a simple generator, based on custom _.templateSettings seen in the previous post, that let you automate the mongodb installation.

Its name is generator-mongodb (https://github.com/davidemoro/generator-mongodb).

Useful or not useful, this is my first whatever-i-want-generator, made just for fun. There is no tests coverage (I got stuck on a problem but the solution is on his way) and I won't maintain it. So that's just an example, anyway I hope you'll find useful hints.

How it is implemented this generator under the hood

This generator is internally based on the buildout build system (http://www.buildout.org).

What is buildout? Buildout is a widely Python-based build system for creating, assembling and deploying applications from multiple parts, some of which may be non-Python-based. It lets you create a buildout configuration and reproduce the same software later.

Don't worry: we are not going to write any line of python code! We need python because it is required by our install system).

Buildout configurations are text-based, versionable, fine-grained reproducible environments that you can share with your team or create software installers (one example is the Plone CMS unified installer - see http://plone.org/products/plone).

There are dozens of published buildout recipes ready to be used. For example:
So with buildout you can enhance your productivity and automate your build process providind a light out of the box solution, instead of relying on virtual machines and huge downloads.

This helps when introducing multiple developers to a project: you can reduce setup times and enhance productivity. This way we can ensure that the whole team we are collaborating with has the right environment and you can save a lot of time.

Another example: if you are the creator of a nice open source project (for example a Node.js CMS based on MongoDB), you shoud consider that your download&install page will be visited by people just interested in evaluating a CMS or specific app solution without any knowledge or interest about the technology involved because they want to install and play with it locally. So you can provide simpler install instructions thanks to buildout (or any other automated system), for example you can replace "be sure you have installed node.js version x.y.z and MongoDB" with "checkout this folder and run this command: done!".

If you don't provide similar easy way to install your solution you are assuming that your users are comfortable with the underlying technologies, they know how to install the external components you need to run your software.  - If you want to explore a different approach you can have a look at http://www.vagrantup.com/ with its virtual environments.

Let's come back to the buildout. Buildout files can be extended, we can build different profiles (production, development, etc) and a very simple buildout.cfg file looks like the following:
parts = mongodb

recipe = rod.recipe.mongodb
darwin-32bit-url = http://downloads.mongodb.org/osx/mongodb-osx-i386-1.6.5.tgz
How it works? Just one command and the buildout process starts, for example:
$ ./bin/buildout [-c buildout.cfg]
So thanks to buildout and existing recipes our generator workflow will be very simple:
  1. read one or more user inputs (version of mongodb, but you can add more advanced options if you want)
  2. render the buildout.cfg following the steps described here http://davidemoro.blogspot.it/2014/03/yeoman-generator-template-settings-lodash-underscore-js.html
  3. setup the right environment (it creates a local and isolated python environment that does not pollute the global python installed on your system)
  4. runs the buildout command for you
At the end of the process you'll find a local environment with all you need. Since each buildout folder is an isolated, self-contained environment, you can install also different MongoDB versions on your machine as well.

For advanced option you can see the rod.recipe.mongodb reference: https://pypi.python.org/pypi/rod.recipe.mongodb.

How to use generator-mongodb

Be sure you have installed node.js (see https://github.com/creationix/nvm), python and virtualenv (>= 1.11.4).

If you are not comfortable with python you can install it with a couple of commands:
$ sudo apt-get install python2.7
$ sudo apt-get install python-pip
$ [update 20140410:  not safe, follow the official doc] sudo pip install --upgrade virtualenv
The install yo:
$ npm install -g yo
If generator-mongodb were released, installing it it would as simple as typing:
$ npm install -g generator-mongodb
Since this package is not released, you'll have to clone the github repository:
$ git clone git@github.com:davidemoro/generator-mongodb.git
$ cd generator-mongodb
$ npm install
$ npm link
$ cd
Then move where you want to install your local mongodb environment and type:
$ mkdir yourmongodir
$ cd yourmongodir
$ yo mongodb
And you'll see something of similar.

Type the mongodb version and wait for the end of the install process (it might take a while).

Once finished you'll find the mongodb executables:
$ ls bin -1 | grep mongo
Update 20140415: actually ./bin/mongod doesn't work because I missed to set the db path option in buildout.cfg. Just type mkdir -p data/db in your buildout root and launch ./bin/mongod --dbpath data/db. If you configure well the mongodb recipe it will work without typing any option.