<commit_before>extends ../layout/base

block content
	.container: .alerts
		.alert.alert-success The KeystoneJS docs are in beta. For updates, please follow @keystonejs on twitter!
	
	.container: .row
		
		.col-sm-3: #docs-sidebar
			ul.sidebar-nav
				li.nav-label Database
				li: a(href='#concepts') Concepts
				li.nav-label Lists
				li: a(href='#lists_usage') Usage
				li: a(href='#lists_example') Example
				li: a(href='#lists_options') List Options
				li: a(href='#lists_plugins') Schema Plugins
				li: a(href='#lists_querying') Querying Data
				li.nav-label Fields
				li: a(href='#fields_overview') Overview
				li: a(href='#fields_options') Field Options
				li: a(href='#fields_underscoremethods') Underscore Methods
				li.nav-label Field Types
				li: a(href='#field_boolean') Boolean
				li: a(href='#field_text') Text
				li: a(href='#field_textarea') Textarea
				li: a(href='#field_email') Email
				li: a(href='#field_url') Url
				li: a(href='#field_html') Html
				li: a(href='#field_date') Date
				li: a(href='#field_datetime') Datetime
				li: a(href='#field_key') Key
				li: a(href='#field_number') Number
				li: a(href='#field_money') Money
				li: a(href='#field_select') Select
				li: a(href='#field_markdown') Markdown
				li: a(href='#field_name') Name
				li: a(href='#field_password') Password
				li: a(href='#field_location') Location
				li: a(href='#field_cloudinaryimage') CloudinaryImage
				li: a(href='#field_cloudinaryimages') CloudinaryImages
				li: a(href='#field_embedly') Embedly
		
		.col-sm-9: #docs-content
			
			a(name='concepts')
			h1 Setting up &amp; Using Data Models
			
			p In KeystoneJS, your data schema and models are controlled by <strong>Lists</strong>, and documents in your database are often called <strong>Items</strong>.
			
			p To define a data model, you create a <code>new keystone.List</code>, and pass it <a href="#lists_options">list options</a>. 
			
			p You then <code>add</code> fields to the list. Behind the scenes, a Keystone List will create a <a href="http://mongoosejs.com/docs/guide.html" target="_blank">mongoose schema</a>, and add the appropriate paths to it for the fields you define.
			
			p The <code>schema</code> is accessible, allowing you to plug in other mongoose functionality like virtuals, methods and pre / post hooks.
			
			p When you have finished setting up your List, call <code>list.register()</code> to initialise it and register it with Keystone.
			
			p To query your data, you use the <code>list.model</code> (which is a <a href="http://mongoosejs.com/docs/models.html" target="_blank">mongoose model</a>).
			
			p List Items are <a href="http://mongoosejs.com/docs/documents.html" target"_blank">mongoose documents</a>. To create new items, use <code>new list.model()</code> and when you're ready to save it (or to save changes to an existing Item), call <code>item.save()</code>.
			
			a(name='lists_usage')
			h2 Lists
			
			h3 Usage
			
			p The syntax for creating a <strong>Keystone List</strong> is very similar to the syntax for creating a Mongoose Schema, with the exception of the constructor, which is <code>var MyList = new keystone.List(key, options)</code>.
			p Once you have created a new List, add fields to it using <code>MyList.add(fields)</code>, where fields is an object of keys (for field paths) and values (for field types, or options).
			p Fields are defined by an object with a <code>type</code> 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.
			p When all the fields and options have been set on the list, call <code>MyList.register()</code> to register the list with Keystone and finalise its configuration.
			
			a(name='lists_example')
			p <strong>For example: </strong> a simple Post model for a blog might look like this:
			
			.code-header: h4 Post.js
			pre
				| var keystone = require('keystone'),
				|     Types = keystone.Field.Types;
				| var Post = new keystone.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();
			
			p.note This example implements the optional <code>map</code>, <code>autokey</code> and <code>defaultSort</code> options, described below.
			p.note It also specifies <code>title</code>, <code>state</code>, <code>author</code> and <code>publishedAt</code> as the default columns to display in the Admin UI, with state and publishedAt being given column widths.
			p.note The <code>author</code> field is a relationship with the <code>User</code> model, as described in the <a href="/guide#models_users">getting started guide</a>.
			
			a(name='lists_options')
			h3 Options
			
			p Lists support the following options:
			
			table.table
				col(width=200)
				col
				tr
					td <code>drilldown</code> <code class="data-type">String</code>
					td A space-delimited list of relationships to display as drilldown in the Admin UI
				tr
					td <code>sortable</code> <code class="data-type">Boolean</code>
					td Adds a hidden field <code>sortOrder</code> to the schema, and enables drag and drop sorting in the Admin UI
				tr
					td <code>sortContext</code> <code class="data-type">String</code>
					td A <code>List:relationship</code> pair to control when drag and drop sorting is available in the Admin UI
				tr
					td <code>searchFields</code> <code class="data-type">String</code>
					td A space-delimited list of paths to use for searching in Admin UI
				tr
					td <code>defaultSort</code> <code class="data-type">String</code>
					td The default column or path to sort on in the Admin UI
				tr
					td <code>defaultColumns</code> <code class="data-type">String</code>
					td 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 <code>|</code> pipe character.
				tr
					td <code>map</code> <code class="data-type">Object</code>
					td An object that maps fields to special <strong>list</strong> paths. Each path defaults to its key if a field with that key is added. Mappable paths include
						ul.options
							li <code>name</code> - the field that contains the name of the item, for display in the Admin UI
				tr
					td <code>autokey</code> <code class="data-type">Object</code>
					td 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:
						ul.options
							li <code>from</code> <code class="data-type">String</code> - the field or path to generate the key from, can be a space-delimited list of fields
							li <code>path</code> <code class="data-type">String</code> - the path to store the key at
							li <code>unique</code> <code class="data-type">Boolean</code> - whether the key should be unique or not
						| <em>Autokey paths are automatically be indexed; you may also want to include them in compound indexes.</em>
				tr
					td <code>noedit</code> <code class="data-type">Boolean</code>
					td Prevents editing of items in the list through the Keystone Admin UI
				tr
					td <code>nocreate</code> <code class="data-type">Boolean</code>
					td Prevents creation of new items in the list through the Keystone Admin UI
				tr
					td <code>nodelete</code> <code class="data-type">Boolean</code>
					td Prevents deletion of items from the list through the Keystone Admin UI
			
			a(name='lists_plugins')
			h3 Schema Plugins
			
			p You can specify <a href="http://mongoosejs.com/docs/guide.html" target="_blank"><strong>virtuals</strong>, <strong>methods</strong>, <strong>statics</strong></a> as well as <a href="http://mongoosejs.com/docs/middleware.html" target="_blank"><strong>pre</strong> and <strong>post</strong> hooks</a> for your <strong>Lists</strong> using the <code>schema</code>. You can also use <a href="http://mongoosejs.com/docs/plugins.html" target="_blank">mongoose plugins</a> from the <a href="http://plugins.mongoosejs.com" target="_blank">plugins website</a>.
			
			p For example, in our <strong>Post</strong> list above, we might want to automatically set the <code>publishedAt</code> value when the <code>state</code> is changed to <code>published</code> (but only if it hasn't already been set).
			
			p We might also want to add a method to check whether the post is published, rather than checking the <code>state</code> field value directly.
			
			p Before calling <code>Post.register()</code>, we would add the following code:
			
			pre
				| Post.schema.methods.isPublished = function() {
				|     return (this.state == 'published') ? true : false;
				| }
				| 
				| Post.schema.pre('save', function(next) {
				|     if (this.isChanged('state') &amp;&amp; this.isPublished() &amp;&amp; !this.publishedAt) {
				|         this.publishedAt = new Date();
				|     }
				| });
			
			
			a(name='lists_querying')
			h3 Querying Data
			
			p To query data, you can use any of the <a href="http://mongoosejs.com/docs/queries.html" target="_blank">mongoose query</a> methods on the <code>list.model</code>.
			
			p <strong>For example:</strong> to load the last 5 <code>posts</code> with the state <code>published</code>, populating the linked <code>author</code>, sorted by reverse published date:
			
			.code-header: h4 Loading Posts
			pre
				| var keystone = require('keystone'),
				|     Post = keystone.list('Post');
				| 
				| Post.model.find()
				|     .where('state', 'published')
				|     .populate('author')
				|     .sort('-publishedAt')
				|     .limit(5)
				|     .exec(function(err, posts) {
				|         // do something with posts
				|     });
			
			h3 Creating Items
			
			p To create new items, again use the <a href="http://mongoosejs.com/docs/models.html" target"_blank">mongoose model</a>:
			
			.code-header: h4 Creating Posts
			pre
				| var keystone = require('keystone'),
				|     Post = keystone.list('Post');
				| 
				| var newPost = new Post.model({
				|     title: 'New Post'
				| });
				| 
				| if (shouldBePublished) {
				|     newPost.state = 'published';
				| }
				| 
				| newPost.save(function(err) {
				|     // post has been saved	
				| });
			
			.contextual-note
				h4 Automatic keys
				p Because we set the <code>autokey</code> option on our <code>Post</code> list, it will have generated a unique key based on the <code>title</code> before it was saved to the database.
				pre
					| newPost.slug == 'new-post';
			
			h3 Deleting Items
			
			p To delete items, first load the data, then use the <code>remove</code> method:
			
			.code-header: h4 Deleting a Post
			pre
				| var keystone = require('keystone'),
				|     Post = keystone.list('Post');
				| 
				| Post.model.findById(postId)
				|     .remove(function(err) {
				|         // post has been deleted
				|     });
			
			// TODO: Documentation for Schema features (virtuals, methods, statics and hooks)
			
			// TODO: Documentation for Update Handler
			
			a(name='fields_overview')
			h2 Fields
			
			p When adding <strong>fields</strong> to <strong>Lists</strong>, you can either specify basic data types or Keystone Field Types.
			
			p <strong>Keystone Fields</strong> allow you to easily add rich, functional fields to your application's models. They are designed to describe not just the <em>structure</em> of your data, but also the <em>intention</em> of your data. They provide:
			ul
				li Rich controls in Keystone's Admin UI
				li Complex data types; e.g. the <code>location</code> field stores several strings and an GeoJSON lng/lat point
				li Formatting and validation methods
				li Additional virtual properties; e.g. the <code>name</code> field provides a <code>name.full</code> virtual which concatenates the stored <code>name.first</code> and <code>name.last</code>
				li Underscore methods; e.g. the <code>password</code> field provides a <code>password.compare</code> method for testing against the encrypted hash
				li Metadata about how fields relate to each other; e.g. which fields depend on certain values in other fields
			
			p Basic data types are mapped to their corresponding Keystone field types:
			
			table.table(style="width:200px")
				col
				col
				thead
					th Data type
					th Field type
				tr
					td: code.data-type String
					td: code.data-type Text
				tr
					td: code.data-type Number
					td: code.data-type Number
				tr
					td: code.data-type Date
					td: code.data-type DateTime
				tr
					td: code.data-type Boolean
					td: code.data-type Boolean
			
			a(name='fields_options')
			h3 Field Options
			
			p All field types support several common options, which can specify database settings (such as <code>index</code> and <code>default</code>), or can provide information for Keystone's Admin UI (such as <code>label</code>).
			
			p.note Fields can be nested inside objects, as in mongoose schemas.
			
			p.note All <a href="http://mongoosejs.com/docs/schematypes.html" target="_blank">mongoose schema type options</a> are passed to the <a href="http://mongoosejs.com/docs/guide.html" target="_blank">mongoose schema</a>, so you can also use any options mongoose supports.
			
			p Common field options include:
			
			table.table
				col(width="200")
				col
				tr
					td <code>label</code> <code class="data-type">String</code>
					td The label of each field is generated from the field path; set this option to override the default.
				tr
					td <code>required</code> <code class="data-type">Boolean</code>
					td Validates that the field has a value before an item can be saved (<em>also passed to mongoose and enforced using a database index</em>).
				tr
					td <code>initial</code> <code class="data-type">Boolean</code>
					td Causes the field to be displayed in the <strong>Create Item</strong> form, in the Admin UI.
				tr
					td <code>noedit</code> <code class="data-type">Boolean</code>
					td Renders the field as read-only in the admin UI.
				tr
					td <code>note</code> <code class="data-type">String</code>
					td Is displayed with the field in the admin UI.
				tr
					td <code>collapse</code> <code class="data-type">Boolean</code>
					td Displays an <strong>+ <u>add</u></strong> link in the admin UI when the field has no value. Will completely hide field UI when <code>noedit</code> is also set to true, when the field has no value.
				tr
					td <code>dependsOn</code> <code class="data-type">Object</code>
					td Hides the field in the admin UI unless the specified conditions (other field values) are met.
			
			// TODO: Documentation for field methods
			
			a(name="fields_underscoremethods")
			h3 Underscore Methods
			
			p Some field types include helpful <strong>underscore methods</strong>, which are available on the item at the field's path preceded by an underscore.
			p <strong>For example</strong>: use the <code>format</code> underscore method of the <code>createdAt</code> <code class="data-type">DateTime</code> field of the Posts List (above) like this
			
			pre
				| var keystone = require('keystone'),
				|     Post = keystone.list('Post');
				| 
				| Post.model.findById(postId).exec(function(err, post) {
				|    console.log(post._.createdAt.format('Do MMMM YYYY')); // 25th August 2013
				| });
			
			
			a(name="field_types")
			h2 Field Types
			
			
			a(name="field_boolean")
			h3 <code>Boolean</code>
			h4 <code class="data-type">Boolean</code> &mdash; Displayed as a checkbox in the Admin UI
			pre { type: Types.Boolean }
			
			
			a(name="field_text")
			h3 <code>Text</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a text field in the Admin UI
			pre { type: Types.Text }
			
			
			a(name="field_textarea")
			h3 <code>Textarea</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a textarea field in the Admin UI
			pre { type: Types.Textarea }
			.options
				
				h5 Options
				p <code>height</code> <code class="data-type">Number</code> - the height of the field (in pixels)
			
			
			a(name="field_email")
			h3 <code>Email</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a text field in the Admin UI
			p.note Input must look like a valid email address (can be blank unless field is required)
			pre { type: Types.Email }
			
			
			a(name="field_url")
			h3 <code>Url</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a text field in the Admin UI.
			pre { type: Types.Text }
			.options
				
				h5 Underscore methods:
				p <code>format()</code> - formats the stored value by stripping the leading protocol (if any)
				pre
					| item.url = "http://keystonejs.com";
					| item._.url.format(); // "keystonejs.com"
			
			
			a(name="field_html")
			h3 <code>Html</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a text field or WYSIWYG Editor in the Admin UI.
			pre { type: Types.Html, wysiwyg: true }
			.options
				
				h5 Options
				p <code>wysiwyg</code> <code class="data-type">Boolean</code> - whether to display a WYSIWYG editor in the Admin UI
				p <code>height</code> <code class="data-type">Number</code> - the height of the field (in pixels)
			
			
			a(name="field_date")
			h3 <code>Date</code>
			h4 <code class="data-type">Date</code> &mdash; Displayed as a date picker in the Admin UI
			p.note Input should either be a valid <strong>Date</strong>, or a string in the format <strong>YYYY-MM-DD</strong> (can be blank unless field is required)
			p.note To default Date fields to the current time, set the <code>default</code> option to <code class="default-value">Date.now</code>
			pre { type: Types.Date }
			.options
				
				h5 Underscore methods:
				p <code>format(string)</code> - formats the stored value using <a href="http://momentjs.com" target="_blank">momentjs</a>.
				p Format string defaults to <code class="default-value">Do MMM YYYY</code>
			
			
			a(name="field_datetime")
			h3 <code>Datetime</code>
			h4 <code class="data-type">Date</code> &mdash; Displayed as a date and time picker in the Admin UI
			p.note Input should either be a valid <strong>Date</strong>, or a string in the format <code class="default-value">YYYY-MM-DD</code> (can be blank unless field is required)
			p.note To default Date fields to the current time, set the <code>default</code> option to <code>Date.now</code>
			pre { type: Types.Date, default: Date.now }
			.options
				
				h5 Underscore methods:
				p <code>format(string)</code> - formats the stored value using <a href="http://momentjs.com" target="_blank">momentjs</a>.
				p Format string defaults to <code class="default-value">Do MMM YYYY hh:mm:ss a</code>
			
			
			a(name="field_key")
			h3 <code>Key</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a text field in the Admin UI
			p Automatically converts input to a valid key (no spaces or special characters). White space is replaced with a separator.
			pre { type: Types.Key }
			.options
				
				h5 Options
				p <code>separator</code> <code class="data-type">String</code> - the separator to use when replace white space in the input; defaults to <code class="default-value">-</code>
			
			
			a(name="field_number")
			h3 <code>Number</code>
			h4 <code class="data-type">Number</code> &mdash; Displayed as a number field in the Admin UI
			p Input should either be a valid <strong>Number</strong>, or a string that can be converted to a number (can be blank unless field is required)
			pre { type: Types.Number }
			.options
				
				h5 Underscore methods:
				p <code>format(string)</code> - formats the stored value using <a href="http://numeraljs.com" target="_blank">numeraljs</a>.
				p Format string defaults to <code class="default-value">0,0[.][000000000000]</code>
			
			
			a(name="field_money")
			h3 <code>Money</code>
			h4 <code class="data-type">Number</code> &mdash; Displayed as a number field in the Admin UI
			p Input should either be a valid <strong>Number</strong>, 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.
			pre { type: Types.Money }
			.options
				
				h5 Underscore methods:
				p <code>format(string)</code> - formats the stored value using <a href="http://numeraljs.<EMAIL>" target="_blank">numeraljs</a>.
				p Format string defaults to <code class="default-value">$0,0.00</code>
			
			
			a(name="field_select")
			h3 <code>Select</code>
			h4 <code class="data-type">String</code> or <code class="data-type">Number</code> &mdash; Displayed as a select field in the Admin UI
			pre { type: Types.Select, options: 'first, second, third' }
			.options
				
				h5 Options:
				p <code>numeric</code> <code class="data-type">Boolean</code> when <code class="default-value">true</code>, causes the value of the field to be stored as a <code class="data-type">Number</code> instead of a <code class="data-type">String</code>
				pre { type: Types.Select, numeric: true, options: [{ value: 1, label: 'One' }, { value: 2, label: 'Two' }] }
				p <code>options</code> <code class="data-type">String</code> or <code class="data-type">Array</code> - the options for the select field
				p Option values can be provided as a comma-delimited list <code class="data-type">String</code> of values, in which the string is split into an <code class="data-type">Array</code>.
				p For an <code class="data-type">Array</code> of options, each option should be either a
				ul
					li <code class="data-type">String</code> representing the <code>value</code> of the option; the <code>label</code> is automatically generated
					li <code class="data-type">Object</code> with <code>value</code> and <code>label</code> <code class="data-type">String</code> properties
				p You can mix <code class="data-type">String</code> and <code class="data-type">Object</code> items in the <code>options</code> <code class="data-type">Array</code>:
				pre { type: Types.Select, options: ['first', 'second', { value: 'third', label: 'The third one' }] }
				p <code class="data-type">Object</code> options can have additional properties which are accessible when the current options data, or fields options are retrieved.
				pre
					| { type: Types.Select, options: [
					|     { value: 'first', label: 'The first option', custom: 'value' },
					|     { value: 'second', label: 'Second' }
					| ]}
				
				h5 Properties:
				p <code>ops</code> <code class="data-type">Array</code> - the field <strong>options</strong> array
				p <code>values</code> <code class="data-type">Array</code> - all <code>option.value</code> properties
				p <code>labels</code> <code class="data-type">Object</code> - app <code>option.label</code> properties, keyed by <code>option.value</code>
				p <code>map</code> <code class="data-type">Object</code> - map of options, keyed by <code>option.value</code>
				
				h5 Schema:
				p The value of the current option will be stored at <code>{path}</code>. In addition, these virtuals are provided:
				p <code>pathLabel</code> <code class="data-type">String</code> - the label of the currently selected <strong>option</strong>
				p <code>pathData</code> <code class="data-type">Object</code> - the currently selected <strong>option</strong>, including any custom properties
				p <code>pathOptions</code> <code class="data-type">Array</code> - the field <strong>options</strong> array
				p <code>pathOptionsMap</code> <code class="data-type">Object</code> - map of options, keyed by <code>option.value</code>
				
				h5 Underscore methods:
				p <code>pluck(property, default)</code> - returns <code>property</code> value of the currently selected <strong>option</strong>, or <code>default</code>. Useful in conjunction with custom properties for options.
				
				pre
					| 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;
			
			
			a(name="field_markdown")
			h3 <code>Markdown</code>
			h4 <code class="data-type">Object</code> &mdash; Displayed as a textarea field in the Admin UI
			pre { type: Types.Markdown }
			.options
				
				h5 Schema:
				p The markdown field will automatically convert markdown to html when the <code>md</code> property is changed, via a setter on the <code>md</code> path.
				p <code>md</code> <code class="data-type">String</code> - source markdown text
				p <code>html</code> <code class="data-type">String</code> - generated html code
				pre
					| Page.add({ content: Types.Markdown });
					| 
					| var page = new Page.model();
					| page.content.md = "# Hello World";
					| page.content.html == "&lt;h1&gt;Hello World&lt;/h1&gt;";
					| 
					| // or...
					| 
					| Page.fields.content.updateItem(page, "* list item");
					| page.fields.content.format(page) == "&lt;ul&gt;&lt;li&gt;list item&lt;/ul&gt;&lt;/li&gt;";
			
			a(name="field_name")
			h3 <code>Name</code>
			h4 <code class="data-type">Object</code> &mdash; Displayed as <strong>firstname</strong> <strong>lastname</strong> fields in the Admin UI
			pre { type: Types.Name }
			.options
				
				h5 Schema:
				p The name field adds <code>first</code> and <code>last</code> <code class="data-type">String</code> paths to the schema, as well as a <code>full</code> virtual getter and setter.
				p <code>first</code> <code class="data-type">String</code> - first name
				p <code>last</code> <code class="data-type">String</code> - last name
				
				h5 Virtuals:
				p <code>full</code> <code class="data-type">String</code> - first and last name, concatenated with a space (if both have a value)
				p The <code>name.full</code> setter splits input at the first space.
			
			
			a(name="field_password")
			h3 <code>Password</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a password field in the Admin UI, with a 'change' button.
			
			p Passwords are automatically encrypted with bcrypt, and expose a method to compare a string to the encrypted hash.
			p.note The encryption happens with a <strong>pre-save hook</strong> added to the <strong>schema</strong>, so passwords set will not be encrypted until an item has been saved to the database.
			pre { type: Types.Password }
			.options
				
				h5 Options:
				p <code>workFactor</code> <code class="data-type">Number</code> - the bcrypt workfactor to use when generating the hash, higher numbers are slower but more secure (defaults to <code class="default-value">10</code>)
				
				h5 Underscore methods:
				p <code>compare(input String)</code> <code class="data-type">Boolean</code> - compares the input against the encrypted hash, returns <code class="default-value">true</code> if they match or <code class="default-value">false</code> if they don't
				
				h5 Special paths:
				p <code>{path}_compare</code> - when provided to the <strong>updateHandler</strong>, it will be checked against <code>{path}</code> and validation will fail if they don't match.
			
			
			a(name="field_location")
			h3 <code>Location</code>
			h4 <code class="data-type">Object</code> &mdash; Displayed as a combination of fields in the Admin UI
			p Contains a standard set of strings for storing an address, and a longitude / latitude point with a <code class="data-type">2dsphere</code> index.
			p 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).
			pre { type: Types.Location }
			p.note 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.
			.options
				
				h5 Schema
				p <code>name</code> <code class="data-type">String</code> - building name
				p <code>number</code> <code class="data-type">String</code> - unit or shop number
				p <code>street1</code> <code class="data-type">String</code> - street address
				p <code>street2</code> <code class="data-type">String</code> - street address line 2
				p <code>suburb</code> <code class="data-type">String</code>
				p <code>state</code> <code class="data-type">String</code>
				p <code>postcode</code> <code class="data-type">String</code>
				p <code>country</code> <code class="data-type">String</code>
				p <code>geo</code> <code class="data-type">Array</code> <code class="default-value">longitude, latitude</code>
				p.note <strong>Important</strong>: as per the MongoDB convention, the order for the <strong>geo</strong> array must be <code class="default-value">lng, lat</code> which is the opposite of the order used by Google's API.
				
				h5 Underscore methods:
				p <code>googleLookup(region, update, callback)</code> - autodetect the full address and lng, lat from the stored value.
				ul
					li <code>region</code> <code class="data-type">String</code> is passed to the Places API for regional biasing and filtering.
					li <code>update</code> <code class="data-type">String</code> passing <code class="default-value">"overwrite"</code> will completely overwrite existing data with the result. <code class="default-value">true</code> will set blank properties on the field with the result.
					li <code>callback(err, location, result)</code> - is passed the parsed <strong>location</strong> object, and the raw <strong>result</strong> from Google.
				
				p Internal status codes mimic the Google API status codes. See <a href="https://developers.google.com/maps/documentation/geocoding/" target="_blank">https://developers.google.com/maps/documentation/geocoding/</a> for more information.
				p Use of the Google Geocoding API is subject to a query limit of 2,500 geolocation requests per day, except with an enterprise license.
				p 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 Keystone app complies with the Google Maps API License.
			
			a(name="field_cloudinaryimage")
			h3 <code>CloudinaryImage</code>
			h4 <code class="data-type">Object</code> &mdash; Displayed as an image upload field in the Admin UI
			p Automatically manages images stored in <a href="http://cloudinary.com" target="_blank">Cloudinary</a>, including uploading, resizing and deleting.
			pre { type: Types.CloudinaryImage }
			.options
				
				h5 Schema
				p <code>public_id</code> <code class="data-type">String</code>
				p <code>version</code> <code class="data-type">Number</code>
				p <code>signature</code> <code class="data-type">String</code>
				p <code>format</code> <code class="data-type">String</code>
				p <code>resource_type</code> <code class="data-type">String</code>
				p <code>url</code> <code class="data-type">String</code>
				p <code>width</code> <code class="data-type">Number</code>
				p <code>height</code> <code class="data-type">Number</code>
				p <code>secure_url</code> <code class="data-type">String</code>
				
				h5 Virtuals
				<code>exists</code> <code class="data-type">Boolean</code> - whether there is a stored image
				
				h5 Special paths
				p <code>{path}_upload</code> - when a <code class="data-type">file</code> is provided to the <strong>updateHandler</strong>, it will be uploaded to cloudinary and the details will be stored in the field.
				//- TODO: Document {path}_action
				
				h5 Underscore methods
				p <code>src(options)</code> <code class="data-type">String</code> - returns the url of the image, accepts all options cloudinary supports
				p <code>tag(options)</code> <code class="data-type">String</code> - returns an `<img>` tag
				p <code>scale(width, height, options)</code> <code class="data-type">String</code> - scales the image to fit the exact width and height, retaining aspect ratio
				p <code>fit(width, height, options)</code> <code class="data-type">String</code> - scales the image to fit within the specified width and height, retaining aspect ratio
				p <code>lfit(width, height, options)</code> <code class="data-type">String</code> - scales the image to fit within the specified width and height, retaining aspect ratio (without exceeding the original dimensions)
				p <code>limit(width, height, options)</code> <code class="data-type">String</code> - scales the image (down only) to fit within the specified width and height, retaining aspect ratio
				p <code>fill(width, height, options)</code> <code class="data-type">String</code> - scales the image to fill the specified width and height
				p <code>crop(width, height, options)</code> <code class="data-type">String</code> - crops the image to fill the specified width and height
				p <code>pad(width, height, options)</code> <code class="data-type">String</code> - pads the image to fill the specified width and height
				p <code>lpad(width, height, options)</code> <code class="data-type">String</code> - pads the image to fill the specified width and height (without exceeding the original dimensions)
				p <code>thumbnail(width, height, options)</code> <code class="data-type">String</code> - crops the image to fill the specified width and height
				p In all methods, <code class="default-value">options</code> is an optional <code class="data-type">Object</code>. See <a href="http://cloudinary.com/documentation/image_transformations" target="_blank">Cloudinary's Transformation Documentation</a> for more information on the supported options and transformations.
				//- TODO: Usage Examples
			
			a(name="field_cloudinaryimages")
			h3 <code>CloudinaryImages</code>
			h4 <code class="data-type">Array</code> &mdash; Displayed as a series of images, and an upload field in the Admin UI
			p Stores multiple images in a array as a nested <code class="data-type">Schema</code>, each of which expose the same methods as the <code class="data-type">cloudinaryimage</code> field.
			pre { type: Types.CloudinaryImages }
			//- TODO: Usage Examples
			
			
			a(name="field_embedly")
			h3 <code>Embedly</code>
			h4 <code class="data-type">Object</code> &mdash; Displayed as read-only data in the Admin UI
			p Stores data retrieved from the <a href="http://embed.ly" target="_blank">Embedly</a> API about the value of another field (specified with the <code>from</code> option).
			p Includes useful information like provider, type, full URL, HTML embed code, width, height, thumbnail picture and more.
			p The api call is implemented as a pre-save hook, and only triggered if the <strong>from path</strong> value has changed.
			pre { type: Types.Embedly, from: 'path' }
			.options
				
				h5 Options
				<code>from</code> <code class="data-type">String</code> - another path in the Schema that will be passed to the Embedly API.
				
				h5 Schema
				<code>exists</code> <code class="data-type">Boolean</code>
				<code>type</code> <code class="data-type">String</code>
				<code>title</code> <code class="data-type">String</code>
				<code>url</code> <code class="data-type">String</code>
				<code>width</code> <code class="data-type">Number</code>
				<code>height</code> <code class="data-type">Number</code>
				<code>version</code> <code class="data-type">String</code>
				<code>description</code> <code class="data-type">String</code>
				<code>html</code> <code class="data-type">String</code>
				<code>authorName</code> <code class="data-type">String</code>
				<code>authorUrl</code> <code class="data-type">String</code>
				<code>providerName</code> <code class="data-type">String</code>
				<code>providerUrl</code> <code class="data-type">String</code>
				<code>thumbnailUrl</code> <code class="data-type">String</code>
				<code>thumbnailWidth</code> <code class="data-type">Number</code>
				<code>thumbnailHeight</code> <code class="data-type">Number</code>
			
			//- TODO: Documentation for Relationships
			
<commit_msg>Wrapping up the database docs<commit_after>extends ../layout/base

block content
	.container: .alerts
		.alert.alert-success The KeystoneJS docs are in beta. For updates, please follow @keystonejs on twitter!
	
	.container: .row
		
		.col-sm-3: #docs-sidebar
			ul.sidebar-nav
				li.nav-label Database
				li: a(href='#concepts') Concepts
				li.nav-label Lists
				li: a(href='#lists_usage') Usage
				li: a(href='#lists_example') Example
				li: a(href='#lists_options') List Options
				li: a(href='#lists_plugins') Schema Plugins
				li: a(href='#lists_querying') Querying Data
				li.nav-label Fields
				li: a(href='#fields_overview') Overview
				li: a(href='#fields_options') Field Options
				li: a(href='#fields_underscoremethods') Underscore Methods
				li.nav-label Field Types
				li: a(href='#field_boolean') Boolean
				li: a(href='#field_text') Text
				li: a(href='#field_textarea') Textarea
				li: a(href='#field_email') Email
				li: a(href='#field_url') Url
				li: a(href='#field_html') Html
				li: a(href='#field_date') Date
				li: a(href='#field_datetime') Datetime
				li: a(href='#field_key') Key
				li: a(href='#field_number') Number
				li: a(href='#field_money') Money
				li: a(href='#field_select') Select
				li: a(href='#field_markdown') Markdown
				li: a(href='#field_name') Name
				li: a(href='#field_password') Password
				li: a(href='#field_location') Location
				li: a(href='#field_cloudinaryimage') CloudinaryImage
				li: a(href='#field_cloudinaryimages') CloudinaryImages
				li: a(href='#field_embedly') Embedly
		
		.col-sm-9: #docs-content
			
			a(name='concepts')
			h1 Setting up &amp; Using Data Models
			
			p In KeystoneJS, your data schema and models are controlled by <strong>Lists</strong>, and documents in your database are often called <strong>Items</strong>.
			
			p To define a data model, you create a <code>new keystone.List</code>, and pass it <a href="#lists_options">list options</a>. 
			
			p You then <code>add</code> fields to the list. Behind the scenes, a Keystone List will create a <a href="http://mongoosejs.com/docs/guide.html" target="_blank">mongoose schema</a>, and add the appropriate paths to it for the fields you define.
			
			p The <code>schema</code> is accessible, allowing you to plug in other mongoose functionality like virtuals, methods and pre / post hooks.
			
			p When you have finished setting up your List, call <code>list.register()</code> to initialise it and register it with Keystone.
			
			p To query your data, you use the <code>list.model</code> (which is a <a href="http://mongoosejs.com/docs/models.html" target="_blank">mongoose model</a>).
			
			p List Items are <a href="http://mongoosejs.com/docs/documents.html" target"_blank">mongoose documents</a>. To create new items, use <code>new list.model()</code> and when you're ready to save it (or to save changes to an existing Item), call <code>item.save()</code>.
			
			a(name='lists_usage')
			h2 Lists
			
			h3 Usage
			
			p The syntax for creating a <strong>Keystone List</strong> is very similar to the syntax for creating a Mongoose Schema, with the exception of the constructor, which is <code>var MyList = new keystone.List(key, options)</code>.
			p Once you have created a new List, add fields to it using <code>MyList.add(fields)</code>, where fields is an object of keys (for field paths) and values (for field types, or options).
			p Fields are defined by an object with a <code>type</code> 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.
			p When all the fields and options have been set on the list, call <code>MyList.register()</code> to register the list with Keystone and finalise its configuration.
			
			a(name='lists_example')
			p <strong>For example: </strong> a simple Post model for a blog might look like this:
			
			.code-header: h4 Post.js
			pre
				| var keystone = require('keystone'),
				|     Types = keystone.Field.Types;
				| var Post = new keystone.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();
			
			p.note This example implements the optional <code>map</code>, <code>autokey</code> and <code>defaultSort</code> options, described below.
			p.note It also specifies <code>title</code>, <code>state</code>, <code>author</code> and <code>publishedAt</code> as the default columns to display in the Admin UI, with state and publishedAt being given column widths.
			p.note The <code>author</code> field is a relationship with the <code>User</code> model, as described in the <a href="/guide#models_users">getting started guide</a>.
			
			a(name='lists_options')
			h3 Options
			
			p Lists support the following options:
			
			table.table
				col(width=200)
				col
				tr
					td <code>drilldown</code> <code class="data-type">String</code>
					td A space-delimited list of relationships to display as drilldown in the Admin UI
				tr
					td <code>sortable</code> <code class="data-type">Boolean</code>
					td Adds a hidden field <code>sortOrder</code> to the schema, and enables drag and drop sorting in the Admin UI
				tr
					td <code>sortContext</code> <code class="data-type">String</code>
					td A <code>List:relationship</code> pair to control when drag and drop sorting is available in the Admin UI
				tr
					td <code>searchFields</code> <code class="data-type">String</code>
					td A space-delimited list of paths to use for searching in Admin UI
				tr
					td <code>defaultSort</code> <code class="data-type">String</code>
					td The default column or path to sort on in the Admin UI
				tr
					td <code>defaultColumns</code> <code class="data-type">String</code>
					td 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 <code>|</code> pipe character.
				tr
					td <code>map</code> <code class="data-type">Object</code>
					td An object that maps fields to special <strong>list</strong> paths. Each path defaults to its key if a field with that key is added. Mappable paths include
						ul.options
							li <code>name</code> - the field that contains the name of the item, for display in the Admin UI
				tr
					td <code>autokey</code> <code class="data-type">Object</code>
					td 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:
						ul.options
							li <code>from</code> <code class="data-type">String</code> - the field or path to generate the key from, can be a space-delimited list of fields
							li <code>path</code> <code class="data-type">String</code> - the path to store the key at
							li <code>unique</code> <code class="data-type">Boolean</code> - whether the key should be unique or not
						| <em>Autokey paths are automatically be indexed; you may also want to include them in compound indexes.</em>
				tr
					td <code>noedit</code> <code class="data-type">Boolean</code>
					td Prevents editing of items in the list through the Keystone Admin UI
				tr
					td <code>nocreate</code> <code class="data-type">Boolean</code>
					td Prevents creation of new items in the list through the Keystone Admin UI
				tr
					td <code>nodelete</code> <code class="data-type">Boolean</code>
					td Prevents deletion of items from the list through the Keystone Admin UI
			
			a(name='lists_plugins')
			h3 Schema Plugins
			
			p You can specify <a href="http://mongoosejs.com/docs/guide.html" target="_blank"><strong>virtuals</strong>, <strong>methods</strong>, <strong>statics</strong></a> as well as <a href="http://mongoosejs.com/docs/middleware.html" target="_blank"><strong>pre</strong> and <strong>post</strong> hooks</a> for your <strong>Lists</strong> using the <code>schema</code>. You can also use <a href="http://mongoosejs.com/docs/plugins.html" target="_blank">mongoose plugins</a> from the <a href="http://plugins.mongoosejs.com" target="_blank">plugins website</a>.
			
			p For example, in our <strong>Post</strong> list above, we might want to automatically set the <code>publishedAt</code> value when the <code>state</code> is changed to <code>published</code> (but only if it hasn't already been set).
			
			p We might also want to add a method to check whether the post is published, rather than checking the <code>state</code> field value directly.
			
			p Before calling <code>Post.register()</code>, we would add the following code:
			
			pre
				| Post.schema.methods.isPublished = function() {
				|     return (this.state == 'published') ? true : false;
				| }
				| 
				| Post.schema.pre('save', function(next) {
				|     if (this.isChanged('state') &amp;&amp; this.isPublished() &amp;&amp; !this.publishedAt) {
				|         this.publishedAt = new Date();
				|     }
				| });
			
			
			a(name='lists_querying')
			h3 Querying Data
			
			p To query data, you can use any of the <a href="http://mongoosejs.com/docs/queries.html" target="_blank">mongoose query</a> methods on the <code>list.model</code>.
			
			p <strong>For example:</strong> to load the last 5 <code>posts</code> with the state <code>published</code>, populating the linked <code>author</code>, sorted by reverse published date:
			
			.code-header: h4 Loading Posts
			pre
				| var keystone = require('keystone'),
				|     Post = keystone.list('Post');
				| 
				| Post.model.find()
				|     .where('state', 'published')
				|     .populate('author')
				|     .sort('-publishedAt')
				|     .limit(5)
				|     .exec(function(err, posts) {
				|         // do something with posts
				|     });
			
			h3 Creating Items
			
			p To create new items, again use the <a href="http://mongoosejs.com/docs/models.html" target"_blank">mongoose model</a>:
			
			.code-header: h4 Creating Posts
			pre
				| var keystone = require('keystone'),
				|     Post = keystone.list('Post');
				| 
				| var newPost = new Post.model({
				|     title: 'New Post'
				| });
				| 
				| if (shouldBePublished) {
				|     newPost.state = 'published';
				| }
				| 
				| newPost.save(function(err) {
				|     // post has been saved	
				| });
			
			.contextual-note
				h4 Automatic keys
				p Because we set the <code>autokey</code> option on our <code>Post</code> list, it will have generated a unique key based on the <code>title</code> before it was saved to the database.
				pre
					| newPost.slug == 'new-post';
			
			h3 Deleting Items
			
			p To delete items, first load the data, then use the <code>remove</code> method:
			
			.code-header: h4 Deleting a Post
			pre
				| var keystone = require('keystone'),
				|     Post = keystone.list('Post');
				| 
				| Post.model.findById(postId)
				|     .remove(function(err) {
				|         // post has been deleted
				|     });
			
			// TODO: Documentation for Schema features (virtuals, methods, statics and hooks)
			
			// TODO: Documentation for Update Handler
			
			a(name='fields_overview')
			h2 Fields
			
			p When adding <strong>fields</strong> to <strong>Lists</strong>, you can either specify basic data types or Keystone Field Types.
			
			p <strong>Keystone Fields</strong> allow you to easily add rich, functional fields to your application's models. They are designed to describe not just the <em>structure</em> of your data, but also the <em>intention</em> of your data. They provide:
			ul
				li Rich controls in Keystone's Admin UI
				li Complex data types; e.g. the <code>location</code> field stores several strings and an GeoJSON lng/lat point
				li Formatting and validation methods
				li Additional virtual properties; e.g. the <code>name</code> field provides a <code>name.full</code> virtual which concatenates the stored <code>name.first</code> and <code>name.last</code>
				li Underscore methods; e.g. the <code>password</code> field provides a <code>password.compare</code> method for testing against the encrypted hash
				li Metadata about how fields relate to each other; e.g. which fields depend on certain values in other fields
			
			p Basic data types are mapped to their corresponding Keystone field types:
			
			table.table(style="width:200px")
				col
				col
				thead
					th Data type
					th Field type
				tr
					td: code.data-type String
					td: code.data-type Text
				tr
					td: code.data-type Number
					td: code.data-type Number
				tr
					td: code.data-type Date
					td: code.data-type DateTime
				tr
					td: code.data-type Boolean
					td: code.data-type Boolean
			
			a(name='fields_options')
			h3 Field Options
			
			p All field types support several common options, which can specify database settings (such as <code>index</code> and <code>default</code>), or can provide information for Keystone's Admin UI (such as <code>label</code>).
			
			p.note Fields can be nested inside objects, as in mongoose schemas.
			
			p.note All <a href="http://mongoosejs.com/docs/schematypes.html" target="_blank">mongoose schema type options</a> are passed to the <a href="http://mongoosejs.com/docs/guide.html" target="_blank">mongoose schema</a>, so you can also use any options mongoose supports.
			
			p Common field options include:
			
			table.table
				col(width="200")
				col
				tr
					td <code>label</code> <code class="data-type">String</code>
					td The label of each field is generated from the field path; set this option to override the default.
				tr
					td <code>required</code> <code class="data-type">Boolean</code>
					td Validates that the field has a value before an item can be saved (<em>also passed to mongoose and enforced using a database index</em>).
				tr
					td <code>initial</code> <code class="data-type">Boolean</code>
					td Causes the field to be displayed in the <strong>Create Item</strong> form, in the Admin UI.
				tr
					td <code>noedit</code> <code class="data-type">Boolean</code>
					td Renders the field as read-only in the admin UI.
				tr
					td <code>note</code> <code class="data-type">String</code>
					td Is displayed with the field in the admin UI.
				tr
					td <code>collapse</code> <code class="data-type">Boolean</code>
					td Displays an <strong>+ <u>add</u></strong> link in the admin UI when the field has no value. Will completely hide field UI when <code>noedit</code> is also set to true, when the field has no value.
				tr
					td <code>dependsOn</code> <code class="data-type">Object</code>
					td Hides the field in the admin UI unless the specified conditions (other field values) are met.
			
			// TODO: Documentation for field methods
			
			a(name="fields_underscoremethods")
			h3 Underscore Methods
			
			p Some field types include helpful <strong>underscore methods</strong>, which are available on the item at the field's path preceded by an underscore.
			p <strong>For example</strong>: use the <code>format</code> underscore method of the <code>createdAt</code> <code class="data-type">DateTime</code> field of the Posts List (above) like this
			
			pre
				| var keystone = require('keystone'),
				|     Post = keystone.list('Post');
				| 
				| Post.model.findById(postId).exec(function(err, post) {
				|    console.log(post._.createdAt.format('Do MMMM YYYY')); // 25th August 2013
				| });
			
			
			a(name="field_types")
			h2 Field Types
			
			
			a(name="field_boolean")
			h3 <code>Boolean</code>
			h4 <code class="data-type">Boolean</code> &mdash; Displayed as a checkbox in the Admin UI
			pre { type: Types.Boolean }
			
			
			a(name="field_text")
			h3 <code>Text</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a text field in the Admin UI
			pre { type: Types.Text }
			
			
			a(name="field_textarea")
			h3 <code>Textarea</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a textarea field in the Admin UI
			pre { type: Types.Textarea }
			.options
				
				h5 Options
				p <code>height</code> <code class="data-type">Number</code> - the height of the field (in pixels)
			
			
			a(name="field_email")
			h3 <code>Email</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a text field in the Admin UI
			p.note Input must look like a valid email address (can be blank unless field is required)
			pre { type: Types.Email }
			
			
			a(name="field_url")
			h3 <code>Url</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a text field in the Admin UI.
			pre { type: Types.Text }
			.options
				
				h5 Underscore methods:
				p <code>format()</code> - formats the stored value by stripping the leading protocol (if any)
				pre
					| item.url = "http://keystonejs.com";
					| item._.url.format(); // "keystonejs.com"
			
			
			a(name="field_html")
			h3 <code>Html</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a text field or WYSIWYG Editor in the Admin UI.
			pre { type: Types.Html, wysiwyg: true }
			.options
				
				h5 Options
				p <code>wysiwyg</code> <code class="data-type">Boolean</code> - whether to display a WYSIWYG editor in the Admin UI
				p <code>height</code> <code class="data-type">Number</code> - the height of the field (in pixels)
			
			
			a(name="field_date")
			h3 <code>Date</code>
			h4 <code class="data-type">Date</code> &mdash; Displayed as a date picker in the Admin UI
			p.note Input should either be a valid <strong>Date</strong>, or a string in the format <strong>YYYY-MM-DD</strong> (can be blank unless field is required)
			p.note To default Date fields to the current time, set the <code>default</code> option to <code class="default-value">Date.now</code>
			pre { type: Types.Date }
			.options
				
				h5 Underscore methods:
				p <code>format(string)</code> - formats the stored value using <a href="http://momentjs.com" target="_blank">momentjs</a>.
				p Format string defaults to <code class="default-value">Do MMM YYYY</code>
			
			
			a(name="field_datetime")
			h3 <code>Datetime</code>
			h4 <code class="data-type">Date</code> &mdash; Displayed as a date and time picker in the Admin UI
			p.note Input should either be a valid <strong>Date</strong>, or a string in the format <code class="default-value">YYYY-MM-DD</code> (can be blank unless field is required)
			p.note To default Date fields to the current time, set the <code>default</code> option to <code>Date.now</code>
			pre { type: Types.Date, default: Date.now }
			.options
				
				h5 Underscore methods:
				p <code>format(string)</code> - formats the stored value using <a href="http://momentjs.com" target="_blank">momentjs</a>.
				p Format string defaults to <code class="default-value">Do MMM YYYY hh:mm:ss a</code>
			
			
			a(name="field_key")
			h3 <code>Key</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a text field in the Admin UI
			p Automatically converts input to a valid key (no spaces or special characters). White space is replaced with a separator.
			pre { type: Types.Key }
			.options
				
				h5 Options
				p <code>separator</code> <code class="data-type">String</code> - the separator to use when replace white space in the input; defaults to <code class="default-value">-</code>
			
			
			a(name="field_number")
			h3 <code>Number</code>
			h4 <code class="data-type">Number</code> &mdash; Displayed as a number field in the Admin UI
			p Input should either be a valid <strong>Number</strong>, or a string that can be converted to a number (can be blank unless field is required)
			pre { type: Types.Number }
			.options
				
				h5 Underscore methods:
				p <code>format(string)</code> - formats the stored value using <a href="http://numeraljs.com" target="_blank">numeraljs</a>.
				p Format string defaults to <code class="default-value">0,0[.][000000000000]</code>
			
			
			a(name="field_money")
			h3 <code>Money</code>
			h4 <code class="data-type">Number</code> &mdash; Displayed as a number field in the Admin UI
			p Input should either be a valid <strong>Number</strong>, 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.
			pre { type: Types.Money }
			.options
				
				h5 Underscore methods:
				p <code>format(string)</code> - formats the stored value using <a href="http://numeraljs.com" target="_blank">numeraljs</a>.
				p Format string defaults to <code class="default-value">$0,0.00</code>
			
			
			a(name="field_select")
			h3 <code>Select</code>
			h4 <code class="data-type">String</code> or <code class="data-type">Number</code> &mdash; Displayed as a select field in the Admin UI
			pre { type: Types.Select, options: 'first, second, third' }
			.options
				
				h5 Options:
				p <code>numeric</code> <code class="data-type">Boolean</code> when <code class="default-value">true</code>, causes the value of the field to be stored as a <code class="data-type">Number</code> instead of a <code class="data-type">String</code>
				pre { type: Types.Select, numeric: true, options: [{ value: 1, label: 'One' }, { value: 2, label: 'Two' }] }
				p <code>options</code> <code class="data-type">String</code> or <code class="data-type">Array</code> - the options for the select field
				p Option values can be provided as a comma-delimited list <code class="data-type">String</code> of values, in which the string is split into an <code class="data-type">Array</code>.
				p For an <code class="data-type">Array</code> of options, each option should be either a
				ul
					li <code class="data-type">String</code> representing the <code>value</code> of the option; the <code>label</code> is automatically generated
					li <code class="data-type">Object</code> with <code>value</code> and <code>label</code> <code class="data-type">String</code> properties
				p You can mix <code class="data-type">String</code> and <code class="data-type">Object</code> items in the <code>options</code> <code class="data-type">Array</code>:
				pre { type: Types.Select, options: ['first', 'second', { value: 'third', label: 'The third one' }] }
				p <code class="data-type">Object</code> options can have additional properties which are accessible when the current options data, or fields options are retrieved.
				pre
					| { type: Types.Select, options: [
					|     { value: 'first', label: 'The first option', custom: 'value' },
					|     { value: 'second', label: 'Second' }
					| ]}
				
				h5 Properties:
				p <code>ops</code> <code class="data-type">Array</code> - the field <strong>options</strong> array
				p <code>values</code> <code class="data-type">Array</code> - all <code>option.value</code> properties
				p <code>labels</code> <code class="data-type">Object</code> - app <code>option.label</code> properties, keyed by <code>option.value</code>
				p <code>map</code> <code class="data-type">Object</code> - map of options, keyed by <code>option.value</code>
				
				h5 Schema:
				p The value of the current option will be stored at <code>{path}</code>. In addition, these virtuals are provided:
				p <code>pathLabel</code> <code class="data-type">String</code> - the label of the currently selected <strong>option</strong>
				p <code>pathData</code> <code class="data-type">Object</code> - the currently selected <strong>option</strong>, including any custom properties
				p <code>pathOptions</code> <code class="data-type">Array</code> - the field <strong>options</strong> array
				p <code>pathOptionsMap</code> <code class="data-type">Object</code> - map of options, keyed by <code>option.value</code>
				
				h5 Underscore methods:
				p <code>pluck(property, default)</code> - returns <code>property</code> value of the currently selected <strong>option</strong>, or <code>default</code>. Useful in conjunction with custom properties for options.
				
				pre
					| 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;
			
			
			a(name="field_markdown")
			h3 <code>Markdown</code>
			h4 <code class="data-type">Object</code> &mdash; Displayed as a textarea field in the Admin UI
			pre { type: Types.Markdown }
			.options
				
				h5 Schema:
				p The markdown field will automatically convert markdown to html when the <code>md</code> property is changed, via a setter on the <code>md</code> path.
				p <code>md</code> <code class="data-type">String</code> - source markdown text
				p <code>html</code> <code class="data-type">String</code> - generated html code
				pre
					| Page.add({ content: Types.Markdown });
					| 
					| var page = new Page.model();
					| page.content.md = "# Hello World";
					| page.content.html == "&lt;h1&gt;Hello World&lt;/h1&gt;";
					| 
					| // or...
					| 
					| Page.fields.content.updateItem(page, "* list item");
					| page.fields.content.format(page) == "&lt;ul&gt;&lt;li&gt;list item&lt;/ul&gt;&lt;/li&gt;";
			
			a(name="field_name")
			h3 <code>Name</code>
			h4 <code class="data-type">Object</code> &mdash; Displayed as <strong>firstname</strong> <strong>lastname</strong> fields in the Admin UI
			pre { type: Types.Name }
			.options
				
				h5 Schema:
				p The name field adds <code>first</code> and <code>last</code> <code class="data-type">String</code> paths to the schema, as well as a <code>full</code> virtual getter and setter.
				p <code>first</code> <code class="data-type">String</code> - first name
				p <code>last</code> <code class="data-type">String</code> - last name
				
				h5 Virtuals:
				p <code>full</code> <code class="data-type">String</code> - first and last name, concatenated with a space (if both have a value)
				p The <code>name.full</code> setter splits input at the first space.
			
			
			a(name="field_password")
			h3 <code>Password</code>
			h4 <code class="data-type">String</code> &mdash; Displayed as a password field in the Admin UI, with a 'change' button.
			
			p Passwords are automatically encrypted with bcrypt, and expose a method to compare a string to the encrypted hash.
			p.note The encryption happens with a <strong>pre-save hook</strong> added to the <strong>schema</strong>, so passwords set will not be encrypted until an item has been saved to the database.
			pre { type: Types.Password }
			.options
				
				h5 Options:
				p <code>workFactor</code> <code class="data-type">Number</code> - the bcrypt workfactor to use when generating the hash, higher numbers are slower but more secure (defaults to <code class="default-value">10</code>)
				
				h5 Underscore methods:
				p <code>compare(input String)</code> <code class="data-type">Boolean</code> - compares the input against the encrypted hash, returns <code class="default-value">true</code> if they match or <code class="default-value">false</code> if they don't
				
				h5 Special paths:
				p <code>{path}_compare</code> - when provided to the <strong>updateHandler</strong>, it will be checked against <code>{path}</code> and validation will fail if they don't match.
			
			
			a(name="field_location")
			h3 <code>Location</code>
			h4 <code class="data-type">Object</code> &mdash; Displayed as a combination of fields in the Admin UI
			p Contains a standard set of strings for storing an address, and a longitude / latitude point with a <code class="data-type">2dsphere</code> index.
			p 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).
			pre { type: Types.Location }
			p.note 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.
			.options
				
				h5 Schema
				p <code>name</code> <code class="data-type">String</code> - building name
				p <code>number</code> <code class="data-type">String</code> - unit or shop number
				p <code>street1</code> <code class="data-type">String</code> - street address
				p <code>street2</code> <code class="data-type">String</code> - street address line 2
				p <code>suburb</code> <code class="data-type">String</code>
				p <code>state</code> <code class="data-type">String</code>
				p <code>postcode</code> <code class="data-type">String</code>
				p <code>country</code> <code class="data-type">String</code>
				p <code>geo</code> <code class="data-type">Array</code> <code class="default-value">longitude, latitude</code>
				p.note <strong>Important</strong>: as per the MongoDB convention, the order for the <strong>geo</strong> array must be <code class="default-value">lng, lat</code> which is the opposite of the order used by Google's API.
				
				h5 Underscore methods:
				p <code>googleLookup(region, update, callback)</code> - autodetect the full address and lng, lat from the stored value.
				ul
					li <code>region</code> <code class="data-type">String</code> is passed to the Places API for regional biasing and filtering.
					li <code>update</code> <code class="data-type">String</code> passing <code class="default-value">"overwrite"</code> will completely overwrite existing data with the result. <code class="default-value">true</code> will set blank properties on the field with the result.
					li <code>callback(err, location, result)</code> - is passed the parsed <strong>location</strong> object, and the raw <strong>result</strong> from Google.
				
				p Internal status codes mimic the Google API status codes. See <a href="https://developers.google.com/maps/documentation/geocoding/" target="_blank">https://developers.google.com/maps/documentation/geocoding/</a> for more information.
				p Use of the Google Geocoding API is subject to a query limit of 2,500 geolocation requests per day, except with an enterprise license.
				p 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 Keystone app complies with the Google Maps API License.
			
			a(name="field_cloudinaryimage")
			h3 <code>CloudinaryImage</code>
			h4 <code class="data-type">Object</code> &mdash; Displayed as an image upload field in the Admin UI
			p Automatically manages images stored in <a href="http://cloudinary.com" target="_blank">Cloudinary</a>, including uploading, resizing and deleting.
			pre { type: Types.CloudinaryImage }
			.options
				
				h5 Schema
				p <code>public_id</code> <code class="data-type">String</code>
				p <code>version</code> <code class="data-type">Number</code>
				p <code>signature</code> <code class="data-type">String</code>
				p <code>format</code> <code class="data-type">String</code>
				p <code>resource_type</code> <code class="data-type">String</code>
				p <code>url</code> <code class="data-type">String</code>
				p <code>width</code> <code class="data-type">Number</code>
				p <code>height</code> <code class="data-type">Number</code>
				p <code>secure_url</code> <code class="data-type">String</code>
				
				h5 Virtuals
				<code>exists</code> <code class="data-type">Boolean</code> - whether there is a stored image
				
				h5 Special paths
				p <code>{path}_upload</code> - when a <code class="data-type">file</code> is provided to the <strong>updateHandler</strong>, it will be uploaded to cloudinary and the details will be stored in the field.
				//- TODO: Document {path}_action
				
				h5 Underscore methods
				p <code>src(options)</code> <code class="data-type">String</code> - returns the url of the image, accepts all options cloudinary supports
				p <code>tag(options)</code> <code class="data-type">String</code> - returns an `<img>` tag
				p <code>scale(width, height, options)</code> <code class="data-type">String</code> - scales the image to fit the exact width and height, retaining aspect ratio
				p <code>fit(width, height, options)</code> <code class="data-type">String</code> - scales the image to fit within the specified width and height, retaining aspect ratio
				p <code>lfit(width, height, options)</code> <code class="data-type">String</code> - scales the image to fit within the specified width and height, retaining aspect ratio (without exceeding the original dimensions)
				p <code>limit(width, height, options)</code> <code class="data-type">String</code> - scales the image (down only) to fit within the specified width and height, retaining aspect ratio
				p <code>fill(width, height, options)</code> <code class="data-type">String</code> - scales the image to fill the specified width and height
				p <code>crop(width, height, options)</code> <code class="data-type">String</code> - crops the image to fill the specified width and height
				p <code>pad(width, height, options)</code> <code class="data-type">String</code> - pads the image to fill the specified width and height
				p <code>lpad(width, height, options)</code> <code class="data-type">String</code> - pads the image to fill the specified width and height (without exceeding the original dimensions)
				p <code>thumbnail(width, height, options)</code> <code class="data-type">String</code> - crops the image to fill the specified width and height
				p In all methods, <code class="default-value">options</code> is an optional <code class="data-type">Object</code>. See <a href="http://cloudinary.com/documentation/image_transformations" target="_blank">Cloudinary's Transformation Documentation</a> for more information on the supported options and transformations.
				//- TODO: Usage Examples
			
			a(name="field_cloudinaryimages")
			h3 <code>CloudinaryImages</code>
			h4 <code class="data-type">Array</code> &mdash; Displayed as a series of images, and an upload field in the Admin UI
			p Stores multiple images in a array as a nested <code class="data-type">Schema</code>, each of which expose the same methods as the <code class="data-type">cloudinaryimage</code> field.
			pre { type: Types.CloudinaryImages }
			//- TODO: Usage Examples
			
			
			a(name="field_embedly")
			h3 <code>Embedly</code>
			h4 <code class="data-type">Object</code> &mdash; Displayed as read-only data in the Admin UI
			p Stores data retrieved from the <a href="http://embed.ly" target="_blank">Embedly</a> API about the value of another field (specified with the <code>from</code> option).
			p Includes useful information like provider, type, full URL, HTML embed code, width, height, thumbnail picture and more.
			p The api call is implemented as a pre-save hook, and only triggered if the <strong>from path</strong> value has changed.
			pre { type: Types.Embedly, from: 'path' }
			.options
				
				h5 Options
				p <code>from</code> <code class="data-type">String</code> - another path in the Schema (must contin a <code class="data-type">String</code> value) that will be passed to the Embedly API.
				p <code>options</code> <code class="data-type">Object</code> (optional) - passed as arguments to the embedly API along with the <code>from</code> field value
				p See <a href="http://embed.ly/docs/embed/api/endpoints/1/oembed" target="_blank">Embedly's oEmbed API documentation</a> for more information on options and returned data.
				
				h5 Schema
				p <code>exists</code> <code class="data-type">Boolean</code>
				p <code>type</code> <code class="data-type">String</code>
				p <code>title</code> <code class="data-type">String</code>
				p <code>url</code> <code class="data-type">String</code>
				p <code>width</code> <code class="data-type">Number</code>
				p <code>height</code> <code class="data-type">Number</code>
				p <code>version</code> <code class="data-type">String</code>
				p <code>description</code> <code class="data-type">String</code>
				p <code>html</code> <code class="data-type">String</code>
				p <code>authorName</code> <code class="data-type">String</code>
				p <code>authorUrl</code> <code class="data-type">String</code>
				p <code>providerName</code> <code class="data-type">String</code>
				p <code>providerUrl</code> <code class="data-type">String</code>
				p <code>thumbnailUrl</code> <code class="data-type">String</code>
				p <code>thumbnailWidth</code> <code class="data-type">Number</code>
				p <code>thumbnailHeight</code> <code class="data-type">Number</code>
			
			h2 More examples
			p See the <a href="/examples">Examples</a> page for projects that demonstrate real-world usage of the various list options and field types.
			//- TODO: Documentation for Relationships
			

{'fraction_non_alphanumeric': 0.1282814578695715, 'fraction_numerical': 0.0037671729079677024, 'mean_word_length': 3.588420161972682, 'pattern_counts': {'":': 0, '<': 1654, '<?xml version=': 0, '>': 1654, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7546566', 'n_tokens_mistral': 26981, 'n_tokens_neox': 22592, 'n_words': 7932}