Database

Setting up and using Data Models

Concepts

In LandmarkJS, your data schema and models are controlled by Lists, and documents in your database are often called Items.

To define a data model, you create a new landmark.List, and pass it list options.

You then add fields to the list. Behind the scenes, a Landmark List will create a mongoose schema, and add the appropriate paths to it for the fields you define.

The schema is accessible, allowing you to plug in other mongoose functionality like virtuals, methods and pre / post hooks.

When you have finished setting up your List, call list.register() to initialise it and register it with Landmark.

To query your data, you use the list.model (which is a mongoose model).

List Items are mongoose documents. To create new items, use new list.model() and when you're ready to save it (or to save changes to an existing Item), call item.save().

Lists

Usage

new landmark.List(key[, options]);

The syntax for creating a Landmark List is very similar to the syntax for creating a Mongoose Schema, with the exception of the constructor, which is var MyList = new landmark.List(key, options).

Once you have created a new List, add fields to it using MyList.add(fields), where fields is an object of keys (for field paths) and values (for field types, or options).

Fields are defined by an object with a type property, which must be a valid Field Type or basic data type. Using the object syntax you can specify additional options for the field. Common field options and field-type-specific options are detailed in the fields documentation.

When all the fields and options have been set on the list, call MyList.register() to register the list with Landmark and finalise its configuration.

Example

A simple Post model for a blog might look like this:

Post.js

var landmark = require('landmark-serve'),
    Types = landmark.Field.Types;
 
var Post = new landmark.List('Post', {
    autokey: { path: 'slug', from: 'title', unique: true },
    map: { name: 'title' },
    defaultSort: '-createdAt'
});
 
Post.add({
    title: { type: String, required: true },
    state: { type: Types.Select, options: 'draft, published, archived', default: 'draft' },
    author: { type: Types.Relationship, ref: 'User' },
    createdAt: { type: Date, default: Date.now },
    publishedAt: Date,
    image: { type: Types.CloudinaryImage },
    content: {
        brief: { type: Types.Html, wysiwyg: true, height: 150 },
        extended: { type: Types.Html, wysiwyg: true, height: 400 }
    }
});
 
Post.defaultColumns = 'title, state|20%, author, publishedAt|15%'
Post.register();

This example implements the optional map, autokey and defaultSort options, described below.

It also specifies title, state, author and publishedAt as the default columns to display in the Admin UI, with state and publishedAt being given column widths.

The author field is a relationship with the User model, as described in the getting started guide.

Options

Lists support the following options:

label String The label used for the list in the Admin UI. Defaults to a friendly form of key
path String The path used for the list in the Admin UI. Defaults to a slugified form of key.
singular String The singular label for the items in the list. Used in the Admin UI, defaults to a singular form of label
plural String The plural label for the items in the list. Used in the Admin UI, defaults to a plural form of singular
schema String

Options for the Mongoose Schema for the List. Among other things, this option lets you specify a custom name for the collection. See the mongoose schema docs for a list of available options.

Warning: do not modify the id or _id schema options; the default behaviour is required by Landmark

drilldown String A space-delimited list of relationships to display as drilldown in the Admin UI
sortable Boolean Adds a hidden field sortOrder to the schema, and enables drag and drop sorting in the Admin UI
sortContext String A List:relationship pair to control when drag and drop sorting is available in the Admin UI
searchFields String A space-delimited list of paths to use for searching in Admin UI
defaultSort String The default column or path to sort on in the Admin UI
defaultColumns String A comma-delimited list of default columns to display in the Admin UI List View. You can specify width in either pixels or percent after a | pipe character.
map Object An object that maps fields to special list paths. Each path defaults to its key if a field with that key is added. Mappable paths include
  • name - the field that contains the name of the item, for display in the Admin UI
autokey Object Adds a plugin to the list that automatically generates a key for each document when it is saved, based on the value of another field or path. The value of the option should be an object with the following keys:
  • from String - the field or path to generate the key from, can be a space-delimited list of fields
  • path String - the path to store the key at
  • unique Boolean - whether the key should be unique or not
Autokey paths are automatically be indexed; you may also want to include them in compound indexes.
noedit Boolean Prevents editing of items in the list through the Landmark Admin UI
nocreate Boolean Prevents creation of new items in the list through the Landmark Admin UI
nodelete Boolean Prevents deletion of items from the list through the Landmark Admin UI
hidden Boolean Hides the list in the Landmark Admin UI

If you're wondering how to control which navigation area Lists are categorised under in the Admin UI, check out the nav option in the LandmarkJS Configuration docs.

Drilldown example

The drilldown option is a nice way to improve the usability of the Admin UI by providing context to the item a user is currently editing.

By default, the drilldown will just show the list that the item belongs to.

You can, however, set it to a Relationship field in the schema, and it will display the item currently stored in that relationship field.

If there would be several relationships that may be relevant to display in the drilldown list, you can separate their paths with spaces.

Example: Including the author in the drilldown for Posts

var Post = new landmark.List('Post', {
    autokey: { path: 'slug', from: 'title', unique: true },
    map: { name: 'title' },
    defaultSort: '-createdAt',
    drilldown: 'author' // author is defined as a Relationship field in the example above
});

Schema Plugins

You can specify virtuals, methods, statics as well as pre and post hooks for your Lists using the schema. You can also use mongoose plugins from the plugins website.

For example, in our Post list above, we might want to automatically set the publishedAt value when the state is changed to published (but only if it hasn't already been set).

We might also want to add a method to check whether the post is published, rather than checking the state field value directly.

Before calling Post.register(), we would add the following code:

Post.schema.methods.isPublished = function() {
    return this.state == 'published';
}
 
Post.schema.pre('save', function(next) {
    if (this.isModified('state') && this.isPublished() && !this.publishedAt) {
        this.publishedAt = new Date();
    }
    next();
});

Querying Data

To query data, you can use any of the mongoose query methods on the list.model.

For example: to load the last 5 posts with the state published, populating the linked author, sorted by reverse published date:

Loading Posts

var landmark = require('landmark-serve'),
    Post = landmark.list('Post');
 
Post.model.find()
    .where('state', 'published')
    .populate('author')
    .sort('-publishedAt')
    .limit(5)
    .exec(function(err, posts) {
        // do something with posts
    });

Promises

There exist another way to work with events in Javascript that is included in mongoose query methods. Instead of passing a callback to the exec method, we can use what it returns: a Promise. Promises are very useful for clean chaining of events with propagation of error.

For example: load 100 posts, then do something asynchronous, then do something with result:

Loading Posts, doing something asynchronous, doing something

var landmark = require('landmark-serve'),
    Post = landmark.list('Post');
 
Post.model.find()
    .limit(100)
    .exec()
    .then(function (posts) { //first promise fulfilled
        //return another async promise
    }, function (err) { //first promise rejected
        throw err;
    }).then(function (result) { //second promise fulfilled
        //do something with final results
    }, function (err) { //something happened
        //catch the error, it can be thrown by any promise in the chain
        console.log(err);
    });

Creating Items

To create new items, again use the mongoose model:

Creating Posts

var landmark = require('landmark-serve'),
    Post = landmark.list('Post');
 
var newPost = new Post.model({
    title: 'New Post'
});
 
if (shouldBePublished) {
    newPost.state = 'published';
}
 
newPost.save(function(err) {
    // post has been saved	
});

Automatic keys

Because we set the autokey option on our Post list, it will have generated a unique key based on the title before it was saved to the database.

newPost.slug == 'new-post';

Deleting Items

To delete items, first load the data, then use the remove method:

Deleting a Post

var landmark = require('landmark-serve'),
    Post = landmark.list('Post');
 
Post.model.findById(postId)
    .remove(function(err) {
        // post has been deleted
    });

Fields

When adding fields to Lists, you can either specify basic data types or Landmark Field Types.

Overview

Landmark Fields allow you to easily add rich, functional fields to your application's models. They are designed to describe not just the structure of your data, but also the intention of your data. They provide:

  • Rich controls in Landmark's Admin UI
  • Complex data types; e.g. the location field stores several strings and an GeoJSON lng/lat point
  • Formatting and validation methods
  • Additional virtual properties; e.g. the name field provides a name.full virtual which concatenates the stored name.first and name.last
  • Underscore methods; e.g. the password field provides a password.compare method for testing against the encrypted hash
  • Metadata about how fields relate to each other; e.g. which fields depend on certain values in other fields

Basic data types are mapped to their corresponding Landmark field types:

Data type Field type
String Text
Number Number
Date DateTime
Boolean Boolean

Field Options

All field types support several common options, which can specify database settings (such as index and default), or can provide information for Landmark's Admin UI (such as label).

Fields can be nested inside objects, as in mongoose schemas.

All mongoose schema type options are passed to the mongoose schema, so you can also use any options mongoose supports.

Common field options include:

label String The label of each field is generated from the field path; set this option to override the default.
required Boolean Validates that the field has a value before an item can be saved (also passed to mongoose and enforced using a database index).
initial Boolean Causes the field to be displayed in the Create Item form, in the Admin UI.
noedit Boolean Renders the field as read-only in the admin UI.
note String Is displayed with the field in the admin UI.
hidden Boolean The field will always be hidden in the Admin UI if this is set to true

Conditional Fields

To improve the usability of the Admin UI, it is possible to hide fields when no value is set, or depending on the value of other fields.

collapse Boolean Displays an + add link in the admin UI when the field has no value. Will completely hide field UI when noedit is also set to true, when the field has no value
dependsOn Object The field will only be displayed when the paths specified in the object match the current data for the item

Generated values and watching fields

Landmark's fields support a simple syntax for configuring dynamically updated fields. You can set a field to update its value whenever:

  • The item is saved
  • The value of any other field (or fields) changes
  • The value of any other field (or fields) changes to a specific value

To use the watching functionaliy, set the following two options:

watch Boolean or String or Object

When true, the field value will be recalculated every time an item is saved.

Provide a space-delimited list of paths to recalculate the field value whenever one of those paths changes.

Provide an object of key / value pairs to recalculate the field value whenever one of those paths changes to the value specified.

value Function

The function to generate the field value when a watched path is changed. Must return the new value.

The this context of the function will be the item being saved.

Underscore Methods

Some field types include helpful underscore methods, which are available on the item at the field's path preceded by an underscore.

For example: use the format underscore method of the createdAt DateTime field of the Posts List (above) like this

var landmark = require('landmark-serve'),
    Post = landmark.list('Post');
 
Post.model.findById(postId).exec(function(err, post) {
   console.log(post._.createdAt.format('Do MMMM YYYY')); // 25th August 2013
});

Relationships

Landmark enhances MongoDB's ability to store the ObjectIDs of related documents in a field (or many related ObjectIDs in an Array) with support for Relationship fields and Definitions in Models.

Relationship Fields

ObjectId or Array — Displayed as an auto-suggest field in the Admin UI

Stores references to ObjectIDs from another Model in an ObjectID field or array to create one-many or many-many relationships.

Specify the related Model using the ref option. For a many-many relationship, set the many option to true.

For example, if you wanted to link a Post model to a single Author and many PostCategories, you would do it like this:

Post.add({
    author: { type: Types.Relationship, ref: 'User' },
    categories: { type: Types.Relationship, ref: 'PostCategory', many: true }
});
Populating related data in queries

You can populate related data for relationship fields thanks to Mongoose's populate functionality. To populate the author and category documents when loading a Post from the example above, you would do this:

Post.model.findOne().populate('author categories').exec(function(err, post) {
    // the author is a fully populated User document
    console.log(post.author.name);
});

Note that if no ObjectId is stored, or an invalid ObjectId is stored (e.g. a document has been deleted), author will be undefined in the example above.

Relationship Definitions

What if, in the example above, you wanted to see a list of the Posts by each Author? Because the relationship field is on the Post, you need to tell the Author (and the PostCategory) Model that it is being referred to. Doing so allows the Admin UI to represent the relationship from both sides.

You do this by calling the relationship method on the Model like this:

User.relationship({ path: 'posts', ref: 'Post', refPath: 'author' });
Options

path String - the path of the relationship reference on the Model

ref String - the key of the referred Model (the one that has the relationship field)

refPath String - the path of the relationship being referred to in the referred Model

As you can see, the options provided to the relationship method mirror those of the relationship field it refers to.

Relationship definitions are optional; if you leave them out, the relationships simply won't be displayed in the Admin UI from the other side of the relationship. The relationship field will still work as expected.

Loading related items

Filtering one-to-many related items is easy; simply specify the ID of the item you wish to filter on like any other value:

Post.model.find().where('author', author.id).exec(function(err, posts) {
    // ...
});

To filter many-to-many related items, use an in condition and specify one (or more) ids as an array:

Post.model.find().where('categories').in([category.id]).exec(function(err, posts) {
    // ...
});

Field Types

Boolean

Boolean — Displayed as a checkbox in the Admin UI

{ type: Types.Boolean }

Text

String — Displayed as a text field in the Admin UI

{ type: Types.Text }

Textarea

String — Displayed as a textarea field in the Admin UI

{ type: Types.Textarea }
Options

height Number - the height of the field (in pixels)

Email

String — Displayed as a text field in the Admin UI

Input must look like a valid email address (can be blank unless field is required)

{ type: Types.Email, displayGravatar: true }
Options

displayGravatar Boolean - whether to display a gravatar image in the Admin UI

Underscore methods:

gravatarUrl(input, size, defaultImage, rating) - generates a gravatar image request url

item.email = "demo@getlandmarkproject.com";
item._.email.gravatarUrl(); // "//www.gravatar.com/avatar/74a0071e5f3a7107b570b7d4a1a7619d?s=80&d=identicon&r=g"
item._.email.gravatarUrl(200,'mm','r'); // "//www.gravatar.com/avatar/74a0071e5f3a7107b570b7d4a1a7619d?s=200&d=mm&r=r"

Url

String — Displayed as a text field in the Admin UI.

{ type: Types.Url }
Underscore methods:

format() - formats the stored value by stripping the leading protocol (if any)

item.url = "http://getlandmarkproject.com";
item._.url.format(); // "getlandmarkproject.com"

Html

String — Displayed as a text field or WYSIWYG Editor in the Admin UI.

{ type: Types.Html, wysiwyg: true }
Options

wysiwyg Boolean - whether to display a WYSIWYG editor in the Admin UI

height Number - the height of the field (in pixels)

Color

Color — Displayed as a text field with a color picker

{ type: Types.Color }

Date

Date — Displayed as a date picker in the Admin UI

Input should either be a valid Date, or a string in the format YYYY-MM-DD (can be blank unless field is required)

To default Date fields to the current time, set the default option to Date.now

{ type: Types.Date }
Options

format string - the default format pattern to use, defaults to Do MMM YYYY

See the momentjs format docs for information on the supported formats and options.

Underscore methods

format(string) - formats the stored value using momentjs

moment() - returns a momentjs object initialised with the value of the field

parse(input, format, ...) - parses input using momentjs, sets the field value and returns the moment object

See the momentjs parse docs for information on the supported formats and options for the parse method.

item.cretedDate = Date.now();
item._.createdDate.format(); // returns today's date using the default format string
item._.createdDate.parse('2013-12-04'); // returns a moment object with the parsed date
item._.createdDate.format('YYYY-MM-DD'); // returns '2013-12-04'

Datetime

Datetime — Displayed as a date and time picker in the Admin UI

Input should either be a valid Date, or a string in the format YYYY-MM-DD (can be blank unless field is required)

To default Date fields to the current time, set the default option to Date.now

{ type: Types.Datetime, default: Date.now }
Options:

format string - the default format pattern to use, defaults to Do MMM YYYY hh:mm:ss a

See the momentjs format docs for information on the supported formats and options.

Underscore methods:

format(string) - formats the stored value using momentjs

moment() - returns a momentjs object initialised with the value of the field

parse(input, format, ...) - parses input using momentjs, sets the field value and returns the moment object

See the momentjs parse docs for information on the supported formats and options for the parse method.

Key

String — Displayed as a text field in the Admin UI

Automatically converts input to a valid key (no spaces or special characters). White space is replaced with a separator.

{ type: Types.Key }
Options

separator String - the separator to use when replace white space in the input; defaults to -

Number

Number — Displayed as a number field in the Admin UI

Input should either be a valid Number, or a string that can be converted to a number (can be blank unless field is required)

{ type: Types.Number }
Underscore methods

format(string) - formats the stored value using numeraljs.

Format string defaults to 0,0[.][000000000000]

Money

Number — Displayed as a number field in the Admin UI

Input should either be a valid Number, or a string that can be converted to a number (leading symbols are allowed; can be blank unless field is required). Money fields do not understand currency.

{ type: Types.Money }
Underscore methods

format(string) - formats the stored value using numeraljs.

Format string defaults to $0,0.00

Select

String or Number — Displayed as a select field in the Admin UI

{ type: Types.Select, options: 'first, second, third' }
Options

numeric Boolean when true, causes the value of the field to be stored as a Number instead of a String

{ type: Types.Select, numeric: true, options: [{ value: 1, label: 'One' }, { value: 2, label: 'Two' }] }

emptyOption Boolean when undefined || true, includes a blank value as the first option in the <select> field.

{ type: Types.Select, required: true, options: 'first, second', emptyOption: false }

options String or Array - the options for the select field

Option values can be provided as a comma-delimited list String of values, in which the string is split into an Array.

For an Array of options, each option should be either a

  • String representing the value of the option; the label is automatically generated
  • Object with value and label String properties

You can mix String and Object items in the options Array:

{ type: Types.Select, options: ['first', 'second', { value: 'third', label: 'The third one' }] }

Object options can have additional properties which are accessible when the current options data, or fields options are retrieved.

{ type: Types.Select, options: [
    { value: 'first', label: 'The first option', custom: 'value' },
    { value: 'second', label: 'Second' }
]}
Properties

ops Array - the field options array

values Array - all option.value properties

labels Object - app option.label properties, keyed by option.value

map Object - map of options, keyed by option.value

Schema

The value of the current option will be stored at {path}. In addition, these virtuals are provided:

pathLabel String - the label of the currently selected option

pathData Object - the currently selected option, including any custom properties

pathOptions Array - the field options array

pathOptionsMap Object - map of options, keyed by option.value

Underscore methods:

pluck(property, default) - returns property value of the currently selected option, or default. Useful in conjunction with custom properties for options.

MyList.add({ state: { type: Types.Select, options: 'draft, published, archived', default: 'draft' });
 
MyList.fields.state.values == 'draft,published,archived';
MyList.fields.state.labels == { draft: 'Draft', published: 'Published', archived: 'Archived' };
MyList.fields.state.ops == [
    { value: 'draft', label: 'Draft' },
    { value: 'published', label: 'Published' },
    { value: 'archived', label: 'Archived' }
];
MyList.fields.state.map == {
    draft: { value: 'draft', label: 'Draft' },
    published: { value: 'published', label: 'Published' },
    archived: { value: 'archived', label: 'Archived' }
};
 
var item = new MyList.model();
item.state == 'draft';
item.stateLabel == 'Draft';
item.stateData == { value: 'draft', label: 'Draft' };
item.stateOptions == MyList.fields.state.ops;
item.stateOptionsMap == MyList.fields.state.map;

Markdown

Object — Displayed as a textarea field in the Admin UI

{ type: Types.Markdown }
Schema

The markdown field will automatically convert markdown to html when the md property is changed, via a setter on the md path.

md String - source markdown text

html String - generated html code

Page.add({ content: Types.Markdown });
 
var page = new Page.model();
page.content.md = "# Hello World";
page.content.html == "<h1>Hello World</h1>";
 
// or...
 
Page.fields.content.updateItem(page, "* list item");
page.fields.content.format(page) == "<ul><li>list item</ul></li>";

Name

Object — Displayed as firstname lastname fields in the Admin UI

{ type: Types.Name }
Schema

The name field adds first and last String paths to the schema, as well as a full virtual getter and setter.

first String - first name

last String - last name

Virtuals

full String - first and last name, concatenated with a space (if both have a value)

The name.full setter splits input at the first space.

Password

String — Displayed as a password field in the Admin UI, with a 'change' button.

Passwords are automatically encrypted with bcrypt, and expose a method to compare a string to the encrypted hash.

The encryption happens with a pre-save hook added to the schema, so passwords set will not be encrypted until an item has been saved to the database.

{ type: Types.Password }
Options

workFactor Number - the bcrypt workfactor to use when generating the hash, higher numbers are slower but more secure (defaults to 10)

Underscore methods

compare(candidate, callback) - encrypts the candidate and compares it against the encrypted hash

  • candidate String to compare
  • callback(err, result) - result is true if the candidate matches the stored password, or false if it doesn't
Special paths

{path}_compare - when provided to the updateHandler, it will be checked against {path} and validation will fail if they don't match.

Location

Object — Displayed as a combination of fields in the Admin UI

Contains a standard set of strings for storing an address, and a longitude / latitude point with a 2dsphere index.

Also provides autocomplete functionality using Google's Places API (requires a Google Maps API Key to be provided, must only be used in accordance with Google's terms of service).

See the Google configuration documentation for details on how to set up Google Maps in LandmarkJS.

{ type: Types.Location }

Note: the schema paths are based on Australian address formats, and should be updated to be more appropriate for other international formats. If you have feedback on how the structure should be internationalised, please open a ticket.

Schema

name String - building name

number String - unit or shop number

street1 String - street address

street2 String - street address line 2

suburb String

state String

postcode String

country String

geo Array longitude, latitude

Important: as per the MongoDB convention, the order for the geo array must be lng, lat which is the opposite of the order used by Google's API.

Underscore methods

googleLookup(region, update, callback) - autodetect the full address and lng, lat from the stored value.

  • region String is passed to the Places API for regional biasing and filtering.
  • update String passing "overwrite" will completely overwrite existing data with the result. true will set blank properties on the field with the result.
  • callback(err, location, result) - is passed the parsed location object, and the raw result from Google.

Internal status codes mimic the Google API status codes. See https://developers.google.com/maps/documentation/geocoding/ for more information.

Use of the Google Geocoding API is subject to a query limit of 2,500 geolocation requests per day, except with an enterprise license.

The 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.

CloudinaryImage

Object — Displayed as an image upload field in the Admin UI

Automatically manages images stored in Cloudinary, including uploading, resizing and deleting.

See the Cloudinary configuration documentation for details on how to set up Cloudinary in LandmarkJS.

{ type: Types.CloudinaryImage }
Schema

public_id String

version Number

signature String

format String

resource_type String

url String

width Number

height Number

secure_url String

Virtuals
exists Boolean - whether there is a stored image
Special paths

{path}_upload - when a file is provided to the updateHandler, it will be uploaded to cloudinary and the details will be stored in the field.

Underscore methods

src(options) String - returns the url of the image, accepts all options cloudinary supports

tag(options) String - returns an <img> tag

scale(width, height, options) String - scales the image to fit the exact width and height, retaining aspect ratio

fit(width, height, options) String - scales the image to fit within the specified width and height, retaining aspect ratio

lfit(width, height, options) String - scales the image to fit within the specified width and height, retaining aspect ratio (without exceeding the original dimensions)

limit(width, height, options) String - scales the image (down only) to fit within the specified width and height, retaining aspect ratio

fill(width, height, options) String - scales the image to fill the specified width and height

crop(width, height, options) String - crops the image to fill the specified width and height

pad(width, height, options) String - pads the image to fill the specified width and height

lpad(width, height, options) String - pads the image to fill the specified width and height (without exceeding the original dimensions)

thumbnail(width, height, options) String - crops the image to fill the specified width and height

In all methods, options is an optional Object. See Cloudinary's Transformation Documentation for more information on the supported options and transformations.

Remember that if you are uploading images to a CloudinaryImage field using an HTML form, you need to specify enctype="multipart/form-data" in your form tag.

CloudinaryImages

Array — Displayed as a series of images, and an upload field in the Admin UI

Stores multiple images in a array as a nested Schema, each of which expose the same methods as the cloudinaryimage field.

{ type: Types.CloudinaryImages }

LocalFile

This field type is not compatible with PAAS Hosts like Heroku because it relies on the local file system

Object — Displayed as a file upload field in the Admin UI

Stores files on the local file system.

{ type: Types.LocalFile }
Options

dest String - required, the path to store uploaded file

prefix String - the path prefix in browser, if it different with dest

datePrefix String - if set, prefixes the file name with the current date in this format (see moment.js for format options)

allowedTypes Array of String - optional white-list of allowed mime types for uploaded file

filename Function - function with arguments current model and client file name to return the new filename to upload.

format Function - function with two arguments: current model and file object to return representation of this file in Admin UI.

{
 type: Types.LocalFile,
 dest: '/data/files',
 prefix: '/files/',
 format: function(item, file){
  return '<img src="/files/'+file.filename+'" style="max-width: 300px">'
 }
}

Schema

filename String

path String

size Number

filetype String

Virtuals
exists Boolean - whether there is a file path stored
Underscore methods

uploadFile(file, update, callback) - uploads a file to the local storage, stores the details in the field and provides the file data to the callback.

  • file File should be a file as provided by express when a file is uploaded, i.e. req.files.path
  • update Boolean whether to update the field with the details of the file after upload completes
  • callback(err, fileData) - is passed the object that will be stored in the field (see schema above)

S3 File

Object — Displayed as an file upload field in the Admin UI

Automatically manages files stored in Amazon S3, including uploading and deleting.

{ type: Types.S3File }
Options

s3path String - the path to store uploaded files under in the S3 bucket

datePrefix String - if set, prefixes the file name with the current date in this format (see moment.js for format options)

allowedTypes Array of String - optional white-list of allowed mime types for uploaded files

Schema

filename String

type String

filesize Number

url String

Virtuals
exists Boolean - whether there is a stored file
Special paths

{path}_upload - when a file is provided to the updateHandler, it will be uploaded to s3 and the details will be stored in the field.

Underscore methods

uploadFile(file, update, callback) - uploads a file to the s3 bucket, stores the details in the field and provides the file data to the callback.

  • file File should be a file as provided by express when a file is uploaded, i.e. req.files.path
  • update Boolean whether to update the field with the details of the file after upload completes
  • callback(err, fileData) - is passed the object that will be stored in the field (see schema above)

AzureFile

Object — Displayed as an file upload field in the Admin UI

Automatically manages files stored in Windows Azure Storage, including uploading and deleting.

{ type: Types.AzureFile }
Options

filenameFormatter Callback - function with arguments current model and client file name to return the new filename to upload.

{ type: Types.AzureFile, filenameFormatter: function(item, filename) {
	return item._id + require('path').extname(filename);
} }

containerFormatter Callback - function with arguments current model and client file name to return the new container name (container are a root folder in Azure Storage Account).

{ type: Types.AzureFile, containerFormatter: containerFormatter: function(item, filename) {
	return item.modelProperty;
} }
Schema

filename String

type String

filesize Number

url String

etag String

Virtuals
exists Boolean - whether there is a stored file
Underscore methods

uploadFile(file, update, callback) - uploads a file to the Azure Storage Account, stores the details in the field and provides the file data to the callback.

  • file File should be a file as provided by express when a file is uploaded, i.e. req.files.path
  • update Boolean whether to update the field with the details of the file after upload completes
  • callback(err, fileData) - is passed the object that will be stored in the field (see schema above)

Embedly

Object — Displayed as read-only data in the Admin UI

Automatically retrieves data from the Embedly API about the value of another field (specified with the from option).

It stores the retrieved data (which includes the provider, media type, full URL, HTML embed code, width, height, thumbnail picture and more).

The api call to retrieve the data is implemented as a pre-save hook, and is only triggered if the from path value has changed.

See the Embed.ly configuration documentation for details on how to set up Embed.ly in LandmarkJS.

{ type: Types.Embedly, from: 'path' }
Options

from String - the path of another field in the Schema that will be passed to the Embedly API. The other field must contain a String value.

options Object (optional) - passed as arguments to the embedly API along with the from field value

See Embedly's oEmbed API documentation for more information on options and returned data.

Schema

exists Boolean

type String

title String

url String

width Number

height Number

version String

description String

html String

authorName String

authorUrl String

providerName String

providerUrl String

thumbnailUrl String

thumbnailWidth Number

thumbnailHeight Number

More examples

See the Examples page for projects that demonstrate real-world usage of the various list options and field types.