Configuration

How to roll LandmarkJS the way you want it.

Landmark Options

Setting Options

The options for LandmarkJS cover a range of behaviours, from how the express app is configured to enabling features and authentication options for integrated services.

There are three ways to set options:

  • Passing a { key: 'value' } configuration Object to the landmark.init(options) method
  • Calling landmark.set('key', 'value')
  • Setting environment variables in process.env. Only some options support this (noted below).

If you want to keep secret keys and configuration out of your codebase (especially important for open source projects, or projects where not all developers should have access to production config settings) the dotenv module makes this very easy to manage.

Project Options

The following options control the branding and navigation of the LandmarkJS application in the Admin UI:

name String The name of the LandmarkJS application
brand String Displayed in the top left hand corner of the Admin UI
nav Object

An object that specifies the navigation structure for the Admin UI. Create a key for each section that should be visible in the primary navigation. Each key's value can be a single list path (as is seen in the URL when you view a list) or an array of list paths. When an array is used, secondary navigation is rendered in the Admin UI.

The nav is also used to generate the links on the Admin UI home page; any lists that are registered but not included in the nav will be grouped at the bottom of the screen under the 'Other' heading.

Custom Navigation Example

If you had User, Post and PostCategory models, you could group the posts and post categories into a Content navigation item like this:

landmark.set('nav', {
    'users': 'users',
    'content': ['posts', 'post-categories']
});

Web Server Options

The following options control the configuration of your web server and the express app:

env String

The environment setting to use. The keys development and production are supported, and this will have an impact on things like caching compiled templates. Defaults to process.env.NODE_ENV || "development".

You should really set this to production for your production servers using the NODE_ENV environment variable. Several other modules expect this convention also.

port Number

The port to listen for request on. Defaults to process.env.PORT || 3000

host String

The ip address to listen for request on. Defaults to process.env.IP || '127.0.0.1'

port must be set (either by option or env variable) or the host option will be ignored.

views String

The path to your application's view templates. This is required for using the landmark.View Class, and will also be set on the express app.

If you're following the recommended project structure, this should be set to "/templates/views".

view engine String

The template engine to use by default. Any engine with express support should work. Jade is included with Landmark, but you will have to add any alternate engine to your project's dependencies in your package.json.

This option is set on the express app (see docs here).

custom engine Function

If you want to use a custom template engine, set this option to the function that should be used to process your templates.

See below for an example of how to use the Swig template engine.

locals Object

The default local variables to pass to your view templates.

Routes can extend or change local variables by modifying res.locals.

static String or Array

One or more paths to your application's static files. Setting this will include the express.static middleware.

If you're following the recommended project structure, this should be set to 'public'.

less String

If you want Landmark to automatically compile .less files into .css files, set this value to the same path as the static option.

When this option is set, any requests to a .css or .min.css file will first check for a .less file with the same name, and if one is found, the css file will be regenerated.

favicon String

The path to your application's favicon. Setting this will include the express.favicon middleware. Should be relative to your project's root.

If you're following the recommended project structure, this should be set to "/public/favicon.ico".

compress Boolean Set this to true to enable HTTP compression. This will include the express.compress middleware (see docs here).
logger String Set this to include the express.logger middleware. The value will be passed to the middleware initialisation (see docs here).
trust proxy Boolean Set this to enable processing of the HTTP request X-Forwarded-For header. Extracted IP addresses will be available as the array req.ips (see docs here).

Alternate View Engines

By default, Landmark uses the Jade template engine for your views. Here's how you would set up a different engine, e.g. Swig.

var swig = require('swig');
landmark.set('view engine', 'swig');
landmark.set('custom engine', swig.renderFile);

HTTPS Web Server Options

There are two ways to implement HTTPS for your LandmarkJS application: either use a web server (e.g. NGINX) or PAAS (e.g. Heroku) that handles it for you, or set the following options to use the https server provided by node.js.

ssl Boolean or String

Whether to start the SSL Server. Defaults to false.

When set to true, both https and https servers will be started. If ssl key or ssl cert are invalid, just the http server will be started.

When set to "only", only the https server will be started. If ssl key or ssl cert are invalid, LandmarkJS will not start.

ssl key Path

The path to your SSL Key. Should be either absolute or relative to process.cwd() (which is usually your project root).

ssl cert Path

The path to your SSL Certificate. Should be either absolute or relative to process.cwd() (which is usually your project root).

ssl port Number

The port to start the SSL Server on. Defaults to 3001.

ssl host String

The ip address to listen for request on. Defaults to process.env.SSL_IP or the value of the host option.

Database and User Auth Options

The following options control your database configuration and user models / authentication:

mongo String

The url for your MongoDB connection.

You should typically set this to "mongodb://localhost/your-db" || process.env.MONGO_URI

model prefix String

A prefix to apply to all the mongodb collections used by the models.

auth Mixed

Whether to enable built-in auth for Landmark's Admin UI, or a custom function to use to authenticate users.

When this is set to false (or not defined), Landmark's Admin UI will be open to the public (so set it!)

If using a custom function, it should follow the standard for express middleware of function(req, res, next). If a user is not logged in or should not access Landmark's Admin UI, use res.redirect() to redirect them - otherwise call the next callback to enable access.

user model String

The key of the Landmark List for users, required if auth is set to true

Typically this would be set to User.

cookie secret String

The encryption key to use for your cookies. Passed to Express's cookie parser.

It's a really good idea to set this to a long, random string.

session store String

Set this to mongo to use your MongoDB database to persist session data.

By default, Landmark will use the in-memory session store provided by Express, which should only be used in development because it does not scale past a single process, and leaks memory over time.

Valid options are:

  • mongo (or connect-mongo)
  • connect-mongostore (supports replica sets, but requires explicit configuration - see below)
  • connect-redis

Session store packages are not bundled with Landmark, so make sure you explicitly add the selected session store to your project's package.json.

session store options Object

This option allows you to override the default session store configuration, and is passed to the session store package.

It is required when using the connect-mongostore store.

Example for connect-mongostore

"sessionStore": {
  "db": {
    "name": "myDb",
    "servers": [
      { "host": "192.168.1.100", "port": 28001 },
      { "host": "192.168.1.100", "port": 28002 },
      { "host": "192.168.1.101", "port": 27017 }
    ]
  }
}

Example for connect-redis

"sessionStore": {
  "host": "", // Redis server hostname
  "port": "", // Redis server port
  "ttl": "", // Redis session TTL in seconds
  "db": "", // Database index to use
  "pass": "", // Password for Redis authentication
  "prefix": "", // Key prefix defaulting to "sess:"
  "url": "", // e.g. redis://user:pass@host:port/db
}
back url String

href to use for the 'back to (site name)' link in the header of the Admin UI

Defaults to /

signin url String

href to bounce visitors to when they fail the default auth check (e.g. not signed in)

Defaults to /landmark/signin, only used when auth is set to true

signin redirect String

href to bounce visitors to after they successfully sign in via the built-in signin route

Defaults to /landmark

signout url String

href for the signout link in the top right of the UI

Defaults to /landmark/signout if auth is set to true

signout redirect String

href to bounce visitors to after they successfully sign out via the built-in signin route

Defaults to /landmark

For more information about setting up and using database models with Landmark, see the database guide.

Services

Google Analytics

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

ga property String

Your Google Analytics Property

Will default to process.env.GA_PROPERTY

ga domain String

Your Google Analytics Domain

Will default to process.env.GA_DOMAIN

Note if you only want to include Google Analytics tracking in the front-end of your project, you should use different variable names from those above.

Google Maps

Landmark's Location field type supports integration with the Google Maps API to auto-improve values (including discovering latitude and longitude) via the Places Autocomplete API.

To enable these features, obtain an API Key from Google and enable the Google Maps v3 and Google Places APIs for it, then set the following options:

google api key String

Your Google API browser key, used to authenticate the Javascript Maps API in the Admin UI.

Will default to process.env.GOOGLE_BROWSER_KEY

google server api key String

Your Google API server key, used to authenticate requests to the Maps API from the server.

Will default to process.env.GOOGLE_SERVER_KEY

default region String

Optional setting to limit autocomplete results to a specific region.

This option takes a region code, specified as a IANA language region subtag.

Can be specified on a per-field basis by setting the region option on any Location field.

landmark.set('google api key', 'your-browser-key');
landmark.set('google server api key', 'your-server-key');
landmark.set('default region', 'au'); // optional, will limit autocomplete results to Australia

Note that the use of the Places Geocoding API is subject to a query limit of 2,500 geolocation requests per day, except with an enterprise license.

The Places Geocoding API may only be used in conjunction with a Google map; geocoding results without displaying them on a map is prohibited. Please make sure your Landmark app complies with the Google Maps API License.

Amazon S3

LandmarkJS 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_KEY and S3_SECRET environment variables.

landmark.set('s3 config', { bucket: 'my-bucket', key: 'my-key', secret: 'my-secret' });

Windows Azure Storage

LandmarkJS 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 (see example below).

Alternatively, set the AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY environment variables.

Note that the account property should be set to your storage account, not your user account.

landmark.set('azurefile config', { account: 'my storage account', key: 'secret api key' });

Cloudinary

Cloudinary is an image upload / resizing / hosting service that makes it easy to implement image management in your LandmarkJS 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.

Then set the cloudinary config option to

  • an object containing your configuration (see example below), or
  • the environment variable string Cloudinary gives you (e.g. cloudinary://api_key:api_secret@cloud_name)

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

When images are uploaded to Cloudinary via the Admin UI or field methods, they will have some tags automatically set on them. To prefix these tags with a custom string, set the cloudinary prefix option.

The built-in tags that are automatically set include:

  • {list.path}_{field.path}
  • {list.path}_{field.path}_{item.id}
  • {prefix} (if set)
  • dev (if the env option is not set to production)

landmark.set('cloudinary config', { cloud_name: 'my-cloud', api_key: 'abc', api_secret: '123' });
// or
landmark.set('cloudinary config', 'cloudinary://api_key:api_secret@cloud_name' );
 
// optional, will prefix all built-in tags with 'landmark_'
landmark.set('cloudinary prefix', 'landmark-serve');

Embed.ly

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 LandmarkJS app.

To configure LandmarkJS 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.

landmark.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 LandmarkJS 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 default to the MANDRILL_API_KEY & MANDRILL_USERNAME environment variable's if set.

landmark.set('mandrill api key', 'your-key');
landmark.set('mandrill username', 'your-username');

Application Updates

Landmark includes an updates framework, which you can enable by setting the auto update option to true.

Updates provide an easy way to seed your database, transition data when your models change, or run transformation scripts against your database.

Update files should be named using a semantic version followed by an optional key, like 0.0.1-init.js. The version numbers are used to order the update scripts correctly, while the keys are a nice way to identify what each update does.

Each update file should export a single function, which should accept a single argument - the next(err) callback, to be called when the update is complete.

All the update files will be executed (each one waits for the previous update to complete) before the web server is started.

If the next callback is receives an error it will be reported to the console, and application initialisation will halt.

You can temporarily disable updates from running in development by setting a __defer__ property on the exported function to true. Any subsequent updates will be skipped, but the application will be started.

Updates are only run once, and each completed update is logged in an app_updates collection in your database.

Update Script Example

Creates a new admin User

var landmark = require('landmark-serve'),
    User = landmark.list('User');
 
exports = module.exports = function(done) {
    new User.model({
        name: { first: 'Admin', last: 'User' },
        password: 'admin',
        isAdmin: true
    }).save(done);
};

Disabling the Admin UI

You can disable the Admin UI by setting the headless option to true.

This will allow you to use landmark.start() or landmark.routes(app) without Landmark creating route bindings for the Admin UI routes under /landmark.