diff --git a/docs/Getting Started/Setting-Up/part-1.md b/docs/Getting Started/Setting-Up/part-1.md index b048f8146c..d57b21b742 100644 --- a/docs/Getting Started/Setting-Up/part-1.md +++ b/docs/Getting Started/Setting-Up/part-1.md @@ -2,39 +2,42 @@ ## Introduction -If you want to jump right in to a working Keystone codebase, check out our [quick start guide](/getting-started/yo-generator), which walks you through using our generator to get a Keystone codebase up and running quickly. This tutorial will walk you through setting up a project, looking at what the core parts of Keystone are and how to set them up. +If you want to jump right in to a working Keystone codebase, check out the [Quick Start](/getting-started/yo-generator) guide which walks you through using our generator to get a Keystone codebase up and running quickly. -This guide assumes you are familiar with using npm to install packages, and javascript as a language. +This Setting Up tutorial will walk you through setting up a project from scratch, including introducing and configuring the core parts of Keystone. -We're going to be tackling this in three parts. +This guide assumes you are familiar with [using `npm`](https://docs.npmjs.com/getting-started/what-is-npm) to install packages and JavaScript as a programming language. -Part 1 (this one here) will focus on installation and setting up our `keystone.js` file, which launch our app. +We're going to be tackling setting up from scratch in four parts: -[Part 2](/getting-started/setting-up/part-2) will detail building Keystone models and setting up your database. + - **Part 1: Initial Setup** (the page you are reading) starts with installation and setting up a `keystone.js` file to launch your application. -[Part 3](/getting-started/setting-up/part-3) will go through setting up routes with Keystone to serve both database information as well as website pages. + - [Part 2: Data Model Setup](/getting-started/setting-up/part-2) walks you through building your first data model. -[Part 4](/getting-started/setting-up/part-4) will get a us a `POST` endpoint which we can use to post data to. + - [Part 3: Routing](/getting-started/setting-up/part-3) introduces setting up routes with Keystone to serve website pages. -Before we start, make sure you have [node](nodejs.org) and [mongo](https://www.mongodb.com/download-center?jmp=nav#community) installed. + - [Part 4: Adding data from a form](/getting-started/setting-up/part-4) demonstrates how to create a `POST` endpoint for submitting data. + +Before getting started, make sure you have [Node.js](nodejs.org) and [MongoDB](https://www.mongodb.com/download-center?jmp=nav#community) installed. ## Installation -Start by creating a new directory and then from within it run `npm init`. This will set us up with a `package.json` for you with the ability to set up some default options. + +Start by creating a new directory and then from within it run `npm init`. Follow the prompts to create a default `package.json`. Next, install Keystone with `npm install --save keystone`. -At this point, we should have a `node_modules` directory and Keystone should have been added to the `package.json`. +At this point, you should have a `node_modules` directory and Keystone should have been added to the `package.json`. ## Initial Setup -Create a new file, `keystone.js` and we're ready to start configuring Keystone. +Create a new file, `keystone.js`, and you'll be ready to start configuring Keystone. -Your `keystone.js` file is the launch file for Keystone, which will connect Keystone to your database, start the database connection, and start your server running. This is where we will be adding configuration options to Keystone as well, which allow us to change how Keystone is running. +`keystone.js` file is the launch file for Keystone: it defines general configuration options, initialises Keystone, and starts your application server. The minimum file we need to start Keystone running is: ```javascript -var keystone = require('Keystone'); +var keystone = require('keystone'); keystone.init({ 'cookie secret': 'secure string goes here', @@ -43,29 +46,30 @@ keystone.init({ keystone.start(); ``` -First we require Keystone, then we run `keystone.init()`. This function sets up Keystone's initial starting values. Here we are only providing it a cookie secret, however as we build up our application we are going to come back and add more options here. If you want to check out the full list of options, you can find them [here](/documentation/configuration). +Your `keystone.js` needs to require `keystone` and then run the `keystone.init()` function to set up Keystone's initial values. -A `cookie secret` is the only option that is technically required to launch Keystone, however we'll be fleshing this out as we complete our setup. +In this example we are only providing a `cookie secret`. Technically this is the only non-default option that is required to launch Keystone, however as you complete this tutorial you will be adding more options. -Finally, we call `keystone.start()`, which kicks off our Keystone app. +Finally, we call `keystone.start()`, which kicks off the Keystone app. -We can now check this runs. Run `node keystone.js` and you should be greeted with: +You can now check this runs. Run `node keystone.js` and you should be greeted with: ```sh ------------------------------------------------ -KeystoneJS Started: +KeystoneJS v4.0.0 started: Keystone is ready on http://0.0.0.0:3000 ------------------------------------------------ ``` -You should get a 404 page. That's ok! That will be resolved in [part 3](/getting-started/setting-up/part-3) of this guide. In [Part 2](/getting-started/setting-up/part-2) we are going to focus on getting the database connected, and the admin UI up and running. You can do these two in either order. +You should get a 404 page. That's expected since there are no pages set up yet. ## Next Steps -Check out [part 2](/getting-started/setting-up/part-2) of this guide, which walks you through setting up your database, or if you want to read more about any of the parts we set up, you can check out these links: + +This tutorial continues in [Part 2: Data Model Setup](/getting-started/setting-up/part-2), which walks you through setting up your first data model. ## Learn more about: - [keystone.init](/api/methods/init) - [keystone.start](/api/methods/start) -- [keystone setup configuration](/documentation/configuration) +- [Keystone Setup Options](/documentation/configuration) diff --git a/docs/Getting Started/Setting-Up/part-2.md b/docs/Getting Started/Setting-Up/part-2.md index 1c3fee9c10..eff70ed84b 100644 --- a/docs/Getting Started/Setting-Up/part-2.md +++ b/docs/Getting Started/Setting-Up/part-2.md @@ -1,19 +1,19 @@ -# Part 2 - Database Setup +# Part 2: Data Model Setup -Keystone has an easy database integration with [mongodb](mongodb.com), and uses [mongoose](http://mongoosejs.com/) under the hood to help manage your data. In part 2, we are going to connect our app to mongo, and add a user model, so we can log in to and look at the admin UI. +Keystone has an easy database integration with [MongoDB](https://mongodb.com), and uses the [Mongoose ODM](http://mongoosejs.com/) under the hood to help manage your data. In this section of the tutorial you are going to connect your app to MongoDB and add a user model so you can log into the admin UI. ## Setup -From [Part 1](/getting-started/setting-up/part-1), we should have the following files: +From [Part 1: Initial Setup](/getting-started/setting-up/part-1), you should have the following files: ```sh -| our Project folder +| MyProject |--node_modules/ |--package.json |--keystone.js ``` -We should have installed keystone. We need at least the following in our `keystone.js` folder: +You should have installed Keystone with at least the following in your `keystone.js` file: ```javascript var keystone = require('keystone'); @@ -25,54 +25,54 @@ keystone.init({ keystone.start(); ``` -## Adding a `User` model +## Adding a User model -### Modifying our `keystone.js` file +### Modifying the `keystone.js` file -As we mentioned in part one, keystone.init allows us to define our initial options for keystone's startup. For configuring our database connection, we are going to add 4 new properties to our `keystone.init`. +As mentioned in Part 1, `keystone.init` defines initial options for Keystone's startup. For configuring a database connection, you are going to add four new properties to your `keystone.init`: -Firstly, we are going to add a `name`. This is used as the site name, and defaults to `KeystoneJS`. This will also be the name of our database in mongo. + 1. `name`: This is used as the site name and defaults to `KeystoneJS`. This will also be the name of your database in MongoDB. -Next, we want to define what our `'user model'` will be. Let's call it `'User'` to keep it simple. + 2. `'user model'`: The name of your user model. Let's use `'User'` to keep things simple. + + 3. `auth`: Set this to `true` so accessing the Keystone admin UI requires a user to log in. -We want to set `auth` to be `true` so accessing the Keystone admin UI requires a person to log in. + 4. `'auto update'`: Set this to `true` to enable Keystone's application update feature. This is will make it very easy to get seed data into your project. -Finally we want to set `'auto update'` to be `true`. This is going to make it very easy to get our seed data in to our project. - -Our init should now have at least the following properties: +Your `keystone.init` should now have at least the following properties: ```javascript keystone.init({ 'cookie secret': 'secure string goes here', - 'name': 'our-project', + 'name': 'my-project', 'user model': 'User', 'auto update': true, 'auth': true, }); ``` -If you want to read more about these options, you can find the documentation [here](/documentation/configuration). +> NOTE: If you want to read more about available configuration options, see [Keystone Setup Options](/documentation/configuration). -Finally, we are going to add a new line to the file, which is going to import our models. This should be placed after `keystone.init` but before `keystone.start` +Finally, add a new line to import your models. This should be placed after `keystone.init` but before `keystone.start`: ```javascript keystone.import('models'); ``` -The `import` method allows us to pull in an entire folder, in this case the entire models folder, and will allow us to add as many models as we want without having to come back and let Keystone know we've added something new. New models will be noticed each time Keystone starts. +The `import` method pulls in an entire folder (in this case the `models` folder) and allows you to add as many models as you want without having to come back and let Keystone know you've added something new. New models will be noticed each time Keystone starts. -If you want to know more about `keystone.import()` the documentation is [here](/api/methods/import). +> NOTE: If you want to learn more, see [`keystone.import()`](/api/methods/import). -### Adding our model file +### Adding a model file -Next up, we're going to add a file to hold the code which will define our `User` model for us. +Next up, you're going to add a file to hold the code which will define your `User` model. -First we need to create a directory called `models` and make a new file `User.js` in it. +First you need to create a directory called `models` and make a new file `User.js` in it. -Our folder should now look like: +Your project folder should now look like: ```sh -| our Project folder +| MyProject |--node_modules/ |--models | |--User.js @@ -80,7 +80,7 @@ Our folder should now look like: |--keystone.js ``` -In User.js, we are going to start by creating a new list. We'll need the following code: +In `User.js` you are going to start by creating a new list. You'll need the following code: ```javascript var keystone = require('keystone'); @@ -88,29 +88,29 @@ var keystone = require('keystone'); var User = new keystone.List('User'); ``` -We now have a User model from our constructor. This list doesn't have any properties yet, so isn't going to be very useful to us, so let's add some data fields below this code. +This constructor will create a User model which is a `keystone.List`. This list doesn't have any properties yet, so isn't going to be very useful. Let's add some data fields below this code: ```javascript User.add({ displayName: { type: String }, - email: { type: keystone.Field.Types.Email, unique: true }, password: { type: keystone.Field.Types.Password }, + email: { type: keystone.Field.Types.Email, unique: true }, }); ``` -This adds new fields to our model. Here we are adding a display name, as well as an email field and a password field. Let's break down the structure of these. +This adds three fields to your model: a display name, a password field, and an email field. Let's break down the structure of these. ```javascript displayName: { type: String } ``` -This is our most basic field here. Every field needs a `type` property defined, and here we are using one of the base types in javascript to define what our field is. +This demonstrates the most basic field definition. Every field needs a `type` property defined: `displayName` uses JavaScript's default `String` type. ```javascript password: { type: keystone.Field.Types.Password } ``` -Our email field is using a keystone-specific field type. This adds a defined shape to the data, as well as a collection of extra validation. For the password field, it will encrypt it for us. In addition, in the Keystone admin UI, it will not display the contents of the password field, and will require a password to be entered twice to change it. +The `password` field is using a Keystone-specific field type. This adds a defined shape to the data and some extra UI and data layer validation. Keystone's Password field types are automatically encrypted when saved. In addition, the Keystone admin UI will not display the contents of the `password` field and will require a password to be entered twice to change it. This takes care of a lot of our password security for us. @@ -118,17 +118,23 @@ This takes care of a lot of our password security for us. email: { type: keystone.Field.Types.Email, unique: true }, ``` -Email is similar to password in that it is using a keystone-specific field type, in this case to ensure that when this field is filled, it has the shape of an email. In addition, we have passed a second option of `unique: true`, which forces the field to be unique within the database. No doubling up on email addresses for accounts. +The `email` field is similar to `password` in that it is using another Keystone-specific field type. Keystone's Email type validates that field entries look like valid email addresses. In addition, we have passed a second option of `unique: true` which forces the field to be unique within the database. No doubling up on email addresses for accounts. + +If you want to know about all the field types Keystone offers, you can find the full list of options in the [Field API documentation](/api/field). Also, for options like `unique` which are available to all fields, you can read more about the [Field options API](/api/field/options). Understanding available field types and options will be very useful when you are making your own data models. -If you want to know about all the field types Keystone offers, you can find the full list of options in the [Field API documentation](/api/field) Also, for the options like `unique` which are available to all fields, you can read more about the [Field options API](/api/field/options), for when you are making your own models. +There are three more steps remaining to get your user model working. The first is to register the model so Keystone knows to include User in its list of models. -There are three more parts we are going to need to get our user model working. The first is to register it to keystone. This will tell Keystone to include it in its list of models. To do this, add the following line to the bottom of the file: +To do this, add the following line to the bottom of the `User.js` file: ```javascript User.register(); ``` -Next, as we want this to be our User model for logging in to the admin UI, we needs to add the property for `canAccessKeystone` to the model. We are going have a User model that allows all users to access to keystone, but you will likely want to implement more fine-grained control for your own apps. Add this above `User.register`: +### canAccessKeystone + +Next, since this User model will be used for logging into the admin UI you need to add the property `canAccessKeystone`. We are going have a User model that allows all users to access to Keystone, but you will likely want to implement more fine-grained control for your own apps. + +Add this above `User.register`: ```javascript User.schema.virtual('canAccessKeystone').get(function () { @@ -136,17 +142,23 @@ User.schema.virtual('canAccessKeystone').get(function () { }); ``` -If you want to know more about virtuals and other schema methods, you can find the [schema documentation](/api/list/schema). +> NOTE: If you want to know more about virtuals and other schema methods, you can find the [schema documentation](/api/list/schema). + +#### Default columns to display -The final part of setting up our user model is to define the default columns to be displayed in the admin UI. +The final part of setting up your user model is to define the default columns to be displayed in the admin UI. Add this line just above `User.register`: ```javascript -`User.defaultColumns = 'id, displayName, email';` +User.defaultColumns = 'id, displayName, email'; ``` -Alright, that's our user model complete. We should now have a file that looks like this: +#### A working User model + +Alright, that's your User model complete! + +You should now have a file that looks like this: ```javascript var keystone = require('keystone'); @@ -163,14 +175,17 @@ User.schema.virtual('canAccessKeystone').get(function () { return true; }); +User.defaultColumns = 'id, displayName, email'; User.register(); ``` ### Adding an update script -There's one more thing to do before we can launch our app. We need to have an initial user in our database. We can do this through an update script, which Keystone will run on startup. +There's one more thing to do before you can launch your app. You need to have an initial user in your database. You can do this through an update script, which Keystone will run on startup. + +Make a new directory called `updates` and make a file `0.0.1-first-user.js` in it. -Make a new directory called `updates` and make a file `0.0.1-first-user.js` in it. Next we can just drop in the following code: +Add the following code to `0.0.1-first-user.js`: ```javascript exports.create = { @@ -185,15 +200,19 @@ exports.create = { ``` -This will create a user with these details (though the password will be hashed before saving) when Keystone is started up. If you want to know more about update scripts, you can find the information [here](/documentation/configuration). +This will create a user with these details (though the password will be hashed before saving) when Keystone is started up. If you want to know more about update scripts, see [Application Updates](/documentation/database/application-updates). -An important note is that you will likely end up committing your update scripts to your project, so you should not include sensitive information in here. Any passwords added in an update script should be manually changed afterwards. +> NOTE: You will likely end up committing your update scripts to your project, so you should not include sensitive information. Any passwords added in an update script should be manually changed afterwards. ## Exploring the Admin UI -And now we're ready! We can run `node keystone.js` to start up our app. +Now you're ready! You should be able to run `node keystone.js` to start up your app. -We can now navigate to `localhost:3000/keystone` and be presented with a login page. Log in using the email address and password you just added, and have a bit of a play around. In fact, here are two more models to make this easier. Add these in and then restart your app. +If you point your favourite web browser at `http://localhost:3000/keystone` you should now be presented with a login page. Log in using the email address and password you just added, and have a bit of a play around. + +### Event model + +Below is a more interesting model to play with. Add this in and then restart your Keystone application. `models/Event.js` @@ -231,13 +250,14 @@ Event.register(); ``` ## Next Steps -Check out [Part 3 : Routing](/getting-started/setting-up/part-3) of our setting up Keystone guide, which walks you through adding your own pages to your site, or if you want to read more about any of the parts we set up, you can check out these links: + +This tutorial continues in [Part 3: Routing](/getting-started/setting-up/part-3), which walks you through adding static pages to your site. ## Learn more about: -- [configuring keystone](/documentation/configuration) -- [importing models](/api/methods/import) -- [list of Keystone fields](/api/field) -- [keystone field options](/api/field/options) -- [update scripts](/documentation/database/application-updates) -- [virtuals and schema methods](/api/list/schema) +- [Keystone Setup Options](/documentation/configuration) +- [Importing models](/api/methods/import) +- [Keystone Field Types](/api/field) +- [Keystone Field Options](/api/field/options) +- [Application Updates](/documentation/database/application-updates) +- [Virtuals and schema methods](/api/list/schema) diff --git a/docs/Getting Started/Setting-Up/part-3.md b/docs/Getting Started/Setting-Up/part-3.md index fb170c5960..8c3e62568c 100644 --- a/docs/Getting Started/Setting-Up/part-3.md +++ b/docs/Getting Started/Setting-Up/part-3.md @@ -1,25 +1,23 @@ # Part 3: Routing -Keystone is designed to do much of the setup of running an [ExpressJS](https://expressjs.com) application out of your hands as well as allowing an easy configuration of the options. +Keystone is designed to streamline running an [ExpressJS](https://expressjs.com) application including configuration of common options. -Here we are going to add a router to our Keystone application, and set up a basic webpage. This will not rely on what was done in part 2. +In this tutorial section we are going to add *routing* to your Keystone application. Routing is the process of directing client requests (from web browsers or API calls) to corresponding handling functions in your application. -After that, we are going to set up an API endpoint to retrieve information about the events model, which will be relying on setup we did in [Part 2](/getting-started/setting-up/part-2). - -For our routing, we are going to be using [pug](https://pugjs.org) to render our views, however the principles will remain the same for other view engines. +By the end of this tutorial section you will have created a basic web page rendered using the [Pug](https://pugjs.org) view engine. Pug is used as an example, but the principles of routing and rendering are the same for other view engines. ## Setup -From [part 1](/getting-started/setting-up/part-1), we should have the following files: +From [Part 1: Initial Setup](/getting-started/setting-up/part-1) you should have the following files: ```sh -| our Project folder +| MyProject |--node_modules/ |--package.json |--keystone.js ``` -We should have installed keystone. We need at least the following in our `keystone.js` folder: +Keystone should already be installed and at a minimum your `keystone.js` file should include the following: ```javascript var keystone = require('keystone'); @@ -31,24 +29,19 @@ keystone.init({ keystone.start(); ``` -If you did [part 2](/getting-started/setting-up/part-2), you will have more than this, however we will leave off that until we get to looking at our api route. +If you completed [Part 2: Data Model Setup](/getting-started/setting-up/part-2) your `keystone.js` will have additional database configuration options. The database configuration options aren't required for the basic routing and web page set up in this tutorial section, but you'll need to keep those details for the subsequent tutorial section ([Part 4: Adding data from a form](/getting-started/setting-up/part-4)). ## Adding a new page view -### Modifying our `keystone.js` file - -As we mentioned in part one, keystone.init allows us to define our initial options for keystone's startup. For configuring our database connection, we are going to add 2 new properties to our `keystone.init`, and then add a line that will import our routes. - -Our two properties are `views` and `view engine`. The first allows us to set a folder location relative to `keystone.js` to load our view files from. The second sets an engine for Keystone to try and render the files with. +### Modifying the `keystone.js` file -We are going to want to set them as: +As mentioned in Part 1, `keystone.init` defines initial options for Keystone's startup. For rendering application views we are going to add two new properties to `keystone.init`, and then add a line that will import our routes. -```javascript - views: 'templates/views', - 'view engine': 'pug', -``` +The two properties to add are: + 1. `views`: A folder location relative to `keystone.js` to load view files from. We're going to use `'templates/views'`. + 2. `view engine`: A template engine for Keystone to use to render view files. This will be `pug`. -which will give us an init looking something like: +Your `keystone.init` should now have at least the following properties: ```javascript keystone.init({ @@ -58,26 +51,28 @@ keystone.init({ }); ``` -Keystone will look for an installed npm package with the same name as the view engine, so we are going to have to install `pug` to get this working. +Keystone will look for an installed `npm` package with the same name as the view engine, so you are going to have to install `pug` to get this working. ```sh $ npm install --save pug ``` -Finally, we need to add a line to tell Keystone where we plan to write our routes. +Finally, add a line to tell Keystone where you plan to define your routes: ```javascript keystone.set('routes', require('./routes')); ``` -### Adding our routes file +### Adding routes + +Next, we need to add `routes` files. We are going to construct them using Keystone's recommended file and directory layout, however you can structure differently if you prefer. -Next, we need to add our `routes` files. We are going to construct them along keystone's [recommended file format](), however you can structure them differently. +First we are going to add a `routes` folder, and make an `index.js` file in it. Within the `routes` folder, add a `views` folder and then give that its own `index.js`. -First we are going to add a routes folder, and make an `index.js` file in it. Within our `routes` folder, add a `views` folder and then give that its own `index.js`. After this we should have a folder structure that looks like: +After this you should have a folder structure that looks like: ```sh -| Our Project +| MyProject |--node_modules/ |--routes | |--index.js @@ -90,11 +85,11 @@ The reason for this structure is that it is best to keep the individual routes i #### `routes/index.js` -Let's fill out our central file, our `routes/index.js`. +Let's start with the central routing file, `routes/index.js`. -This file is going to export a function, takes in the express app Keystone has built for us, and adds on our individual routes. +This file is going to export a function, take in the Express app Keystone has built for us, and add on our individual routes. -The most basic form of it would look like: +The most basic form would look like: ```javascript exports = module.exports = function (app) { @@ -102,9 +97,9 @@ exports = module.exports = function (app) { }; ``` -For each route we want, we add a new item. Each takes in its own function that it runs when a particular endpoint is hit, in this case `'/'`, the homepage. +For each route we want, we add a new path and route function. In the example above, the path `'/'` (the default homepage) will be handled by `routeFunction()`. -What we are going to add is going to be slightly more complicated. +What we are going to add will be slightly more complicated: ```javascript var keystone = require('keystone'); @@ -127,7 +122,9 @@ This is a bit heavyweight for a single route, but makes it easy to add new route #### `routes/views/index.js` -This is our first endpoint file, and is an important point for a lot of common patterns in setting up new routes. Let us jump right in to the code for this one. +This is our first endpoint file, and is an important point for a lot of common patterns in setting up new routes. + +Let us jump right in to the code for this one: ```javascript module.exports = function (req, res) { @@ -135,7 +132,7 @@ module.exports = function (req, res) { }; ``` -This is using express routing, which you can find out more about [at their website](http://expressjs.com/en/starter/basic-routing.html). +This is using Express routing, which you can learn more about in the Express documentation: [Basic routing](http://expressjs.com/en/starter/basic-routing.html). What we are going to want in this instance is to render our first view. For that, we want our file to read: @@ -145,14 +142,14 @@ module.exports = function (req, res) { }; ``` -### Adding our view +### Adding a view -Our final step to having a view rendered is the view file itself, which we can use to write the text to be rendered. +The final step to having a view rendered is the view file itself, which includes templated text contents. -First we will need a new templates folder at the top level, and a views folder within that. In this views folder create a file `index.pug`. After this, our file structure should look like: +First you will need a new templates folder at the top level, and a `views` folder within that. In this `views` folder create a file `index.pug`. After this, your file structure should look like: ```sh -| Our Project +| MyProject |--node_modules/ |--routes | |--index.js @@ -164,9 +161,9 @@ First we will need a new templates folder at the top level, and a views folder w |--keystone.js ``` -Note that the routes/views and templates/views are mirroring each other. It is a good idea to keep this as you add more routes, so the relationship between them is easy to determine. +Note that the routes/views and templates/views are mirroring each other. It is a good idea to follow this pattern as you add more routes so the relationship between them is easy to determine. -Our pug folder just needs a bit of content: +The `index.pug` file just needs a bit of content: ```jade doctype html @@ -177,21 +174,19 @@ html(lang="en") h1 Welcome to Keystone! #container.col p. - Hope you're enjoying learning about keystone. We're close to some very dynamic cool things + Hope you're enjoying learning about KeystoneJS. We're close to some very dynamic cool things. ``` -Check out [pugjs.org](https://pugjs.org) if you want to know more about pug. - -Now, if we start our Keystone app using `node keystone`, we should be able to visit the homepage and see it rendered! +Now, if you start your Keystone app using `node keystone` you should be able to visit the homepage and see it rendered! ## Next Steps -Check out [part 4](/getting-started/setting-up/part-4) of our setting up Keystone guide, which walks you through setting up an API endpoint so we can record data to our database from a form. +Continue this tutorial with [Part 4: Adding data from a form](/getting-started/setting-up/part-4), which walks you through setting up an API endpoint to save data from a form to a database. ## Learn more about: - [keystone.set](/api/methods/set) - [init options](/documentation/configuration) -- [pug](https://pugjs.org) -- [express](https://expressjs.com) - [keystone.importer](/api/methods/importer) +- [Express](https://expressjs.com) +- [Pug](https://pugjs.org) diff --git a/docs/Getting Started/Setting-Up/part-4.md b/docs/Getting Started/Setting-Up/part-4.md index c6c2cd2a69..9fc1c87c96 100644 --- a/docs/Getting Started/Setting-Up/part-4.md +++ b/docs/Getting Started/Setting-Up/part-4.md @@ -1,10 +1,10 @@ -# Part 4 - Adding data to the database from a form +# Part 4: Adding data from a form -For the final part of this guide, we're going to set up an api endpoint, bringing together our routing configuration and database configuration, so we can see both working together. +For the final part of this Setting Up guide, we're going to set up an API endpoint to connect together the routing configuration and database configuration. ## Setup -For part 4, we are going to use a second model, the Event model that was looked at briefly in part 2. Here it is again if you skipped it. +We are going to use a second model, the Event model that was looked at briefly in [Part 2: Data Model Setup](/getting-started/setting-up/part-2): ```javascript var keystone = require('keystone'); @@ -40,12 +40,12 @@ Event.defaultColumns = 'displayName, email'; Event.register(); ``` -We are going to be drawing together everything we added in both [part 2](/getting-started/setting-up/part-2) and [part 3](/getting-started/setting-up/part-3), so we recommend completing both of those. +We are going to be using everything added in [Part 2: Data Model Setup](/getting-started/setting-up/part-2) and [Part 3: Routing](/getting-started/setting-up/part-3), so we recommend completing both of those sections before continuing. Your source tree should look like the following: ```sh -| Our Project +| MyProject |--node_modules/ |--models | |--User.js @@ -60,11 +60,11 @@ Your source tree should look like the following: |--keystone.js ``` -## Adding an `addEvent` view +## Creating an addEvent view -First we want our pair of new files to make up the route and the view. These should be `routes/views/addEvent` and `templates/views/addEvent.pug`. +First, we want to create a pair of new files to make up the route and the view. These should be `routes/views/addEvent` and `templates/views/addEvent.pug`. -As this is not a pug tutorial, here's a page we prepared earlier: +As this is not a Pug tutorial, here's a page we prepared earlier for the `addEvent.pug` template: ```jade doctype html @@ -103,15 +103,15 @@ module.exports = function (req, res) { }; ``` -Finally, we want to add our new route to our `routes/index.js` and add our new path to our app. +Finally, we want to add this new route to `routes/index.js` and add a new path to our Keystone application. -The new lines is: +The new route to add is: ```javascript app.get('/add-event', routes.views.addEvent) ``` -so we should now have in our index: +... so `/routes/index.js` should now contain: ```javascript exports = module.exports = function (app) { @@ -120,16 +120,15 @@ exports = module.exports = function (app) { }; ``` -With all this, we can start keystone, and go to our new route, and fill out the form. Our next step is to receive and process the data. - +With this routing configured you should be able to start Keystone, go to the new route, and fill out the Event form. The next step will be to receive and process the data. ## Creating an `event/post.js` endpoint -We are going to create a new addition to our app, a handler for a post request, and then a request handler that can save the event information back to our database. +We are now going to add a handler for a post request and a request handler that can save the event information back to our database. -As this endpoint is not a view, we are going to have to modify our routes object. We are going to create a new folder to importRoutes from, called `api`. Before this though, let us set up our `routes/index` for it. +As this endpoint is not a view, we are going to have to modify our routes object. We are going to create a new folder to importRoutes from, called `api`. -First, we want to add a second property to our routes object to read in our api folder. Our routes object should end up looking like: +First we need to add a property to our `routes` object to read the `api` folder. The `routes` object should end up looking like: ```javascript var routes = { @@ -138,26 +137,26 @@ var routes = { }; ``` -Second we are going to add our new route to our app. As this is not a get request, we need to let the app know. We use this by changing the verb. +Second we are going to add a new route to the application. As this is not a get request, we need to let the app know by changing the verb to `post`: ```javascript app.post('/api/event', routes.api.event.post); ``` -Next we can create our `routes/api/event/post` route. It's alright that the api folder only contains another folder. This structure helps us get the very readable route definition above. +Next, we can create our `routes/api/event/post` route. It is alright that the api folder only contains another folder. This structure helps us get the very readable route definition above. -We start out the route much as we have before in the express style for a route: +We start out the route much as we have before in the Express style for a route: ```javascript module.exports = function (req, res) { } ``` -This time however, we're going to be doing some more complex things. First, we are going to be reading the form data, and second we are going to be saving this to the database. +This time, however, we're going to be doing some more complex things. First we are going to be reading the form data, and then we are going to be saving this data to the database. ### Reading the form data -The form data is located on the request object that is passed in, more specifically as the `req.body`. As we have constructed the `req.body` to consist only of fields that we will use, we are going to be able to pass it in directly, however to ensure there are no errors, we want to check our data now. +The form data is located on the request object that is passed in -- more specifically as the `req.body`. As we have constructed `req.body` to consist only of fields that we will use, we are going to be able to pass it in directly. However, to ensure there are no errors it is best to check for the expected values. We can assign these to their own variables in our function to give us: @@ -171,7 +170,9 @@ module.exports = function (req, res) { ### Adding the event to the database -Once we have checked the data, we can move to looking at how data is saved back to the database. We are going to need to require a few things before we come back to our route function. +Once the form data has been validated, we can move to looking at how data is saved back to the database. + +We will require a few packages before we come back to our route function: ```javascript var keystone = require('keystone'); @@ -180,13 +181,13 @@ var Event = keystone.list('Event'); With these set up, we can start looking at how to save the data. -First, we can create a new item, passing in values we want to use as our initial values. +First, we can create a new Event item including passing initial values: ```javascript var newEvent = new Event(req.body); ``` -This will return us an object with the properties of an Event from our schema however it has not yet been saved. You can use `newEvent.save()`, which implements mongoose's save method, however Keystone provides an `updateItem` function that runs keystone's validators, to make sure the data in the fields complies with keystone's full schema. Yes, updateItem will create an item if it does not exist. +This code will return an object with the properties of an Event from our schema, however the object has not yet been saved to the database. You can use `newEvent.save()` which implements Mongoose's `save()` method, however Keystone provides an `updateItem()` function that runs Keystone's validators (which can include additional validation). If an item does not already exist, `updateItem()` will create the item. We can call this like so: @@ -194,7 +195,7 @@ We can call this like so: Event.updateItem(newEvent) ``` -`updateItem` has a lot of other great features for helping you ensure your data integrity, and we recommend reading the full documentation [here](/api/list/update-item) when you have time. +> NOTE: [`updateItem()`](/api/list/update-item) has a lot of other great features for helping you ensure data integrity, and we recommend reading the full documentation when you have time. This leaves us with a file looking like: @@ -215,7 +216,7 @@ module.exports = function (req, res) { ### Don't leave me hanging -The one flaw here is we never give a response to our waiting website to tell it when we have successfully added an event. We are going to do this in the callback to updateItem. We can also add in some more error checking. +The one flaw here is we never give a response to our waiting website to tell it when we have successfully added an event. We are going to do this in the callback to `updateItem`. We can also add in some more error checking. ```javascript Event.updateItem(newEvent, req.body, function (error) { @@ -226,14 +227,14 @@ Event.updateItem(newEvent, req.body, function (error) { ``` ## Congratulations -Well done! You have finished this four-step guide to getting started with Keystone, and you now have a basic Keystone app, complete with an API for form handling that adds data to our database. For more information on list options and the field types Keystone supports, browse the [database guide](/documentation/database/). +Well done! You have finished this four-step guide to getting started with Keystone, and you now have a basic Keystone app complete with an API for form handling that adds data to a database. For more information on list options and the field types Keystone supports, browse the [Database Configuration](/documentation/database/) documentation. -You should also [Follow @KeystoneJS on Twitter](https://twitter.com/keystonejs) for news and updates, [Star KeystoneJS on GitHub](https://github.com/keystonejs/keystone), and discuss this guide (or anything KeystoneJS related) on the [KeystoneJS Google Group](https://groups.google.com/d/forum/keystonejs). +You should also [Follow @KeystoneJS on Twitter](https://twitter.com/keystonejs) for news and updates, [Star KeystoneJS on GitHub](https://github.com/keystonejs/keystone), and discuss this guide (or anything KeystoneJS related) on the [KeystoneJS Community Slack](https://launchpass.com/keystonejs). Enjoy using KeystoneJS! ## Next Steps - [Guides](/guides) - [Documentation](/documentation) -- [api](/api) -- [updateItem](/api/list/update-item) \ No newline at end of file +- [API](/api) +- [updateItem()](/api/list/update-item) \ No newline at end of file diff --git a/docs/Getting Started/yo-generator.md b/docs/Getting Started/yo-generator.md index b6617a7c39..c70ec8c7fc 100644 --- a/docs/Getting Started/yo-generator.md +++ b/docs/Getting Started/yo-generator.md @@ -1,32 +1,36 @@ -# Keystone Yeoman Generator +# Quick Start: Yeoman Generator -The easiest way to get started with KeystoneJS is to use our Yeoman Generator. The rest of this guide will walk you through what the generator has done for you, however this should also give you the context to start a project from scratch if you do not wish to use the generator. +The easiest way to get started is to use our Keystone Yeoman Generator. [Yeoman](http://yeoman.io) is a scaffolding tool that helps you kickstart new projects using plugins called generators. The [Keystone Yeoman Generator](https://github.com/keystonejs/generator-keystone) includes prompts to create a new Keystone app based on a few questions such as template formats (Pug, Nunjucks, Twig, or HBS), CSS pre-processor (LESS, Sass, or Stylus), and site features (blog, image gallery, and contact form). The intent is to demonstrate some of the flexibility of Keystone including example code & templates (with optional comments) that you can use as the basis for a new application. -To use the generator, you will need to install [Yeoman](http://yeoman.io/) (yo) if you have not. +The rest of this guide will walk you through what the generator has created for you, however this should also give you the context to [start a project from scratch](/getting-started/setting-up/part-1) if you do not wish to use the generator for future projects. + +To use the generator, you need to install [Yeoman](http://yeoman.io) (`yo`): ```sh $ npm install -g yo ``` - -Once you have yo, you will need to install the Keystone generator. +Once you have `yo`, you will then need to install the Keystone generator: ```sh $ npm install -g generator-keystone ``` -Run `yo keystone` to create a new project. The generator will ask you questions about your project setup, and then generate the base files for you, before doing an npm install. -Running `yo keystone` will create most of the parts in guide below, which explains the purpose of the parts you have created. +## yo keystone + +Run `yo keystone` to create a new project. The generator will ask you questions about your project setup and then generate the base files for you before doing an `npm install`. + +Running `yo keystone` will create most of the parts described below, depending on the options you select. You can also create a starter project using all default options (with no prompting) using `yo keystone auto`. -If you want more information about the generator, it can be found at [KeystoneJS Yeoman Generator](https://github.com/keystonejs/generator-keystone). +If you want more information about the generator, see the [Keystone Yeoman Generator](https://github.com/keystonejs/generator-keystone) project. -In the guide we'll also be using [Pug](https://pugjs.org/) for our view templates and [LESS](http://lesscss.org/) for our CSS templates. In your own project you can use any template language you like; see [using other template languages](#using-other-template-languages) (below) for more information. +In the guide we'll be using the default options of [Pug](https://pugjs.org) for our view templates and [LESS](http://lesscss.org) for our CSS templates. In your own project you can use any template language you like; see [using other template languages](#using-other-template-languages) (below) for more information. ## Our Setup: ### keystone.js start script -The first place to look is the `keystone.js` file. This is the script that will run our Keystone website, and is the file we use to set most of the Keystone configuration options. +The first place to look is the `keystone.js` file. This is the script that will run your Keystone website, and is the file used to set most of the Keystone configuration options. ```javascript var keystone = require('keystone'); @@ -61,7 +65,9 @@ keystone.start(); ## Project Structure -The yeoman generator comes with our suggested structure for Keystone, designed to make it easy to begin development. Below is the folder structure laid out with explanations of each part. +The Keystone generator creates a recommended project structure designed to make it easy to begin development. + +Below is the folder structure laid out with explanations of the expected contents: ```sh |--lib @@ -96,15 +102,15 @@ The yeoman generator comes with our suggested structure for Keystone, designed t | Main script that starts your application ``` -We also recommend that your application will be simpler to build and maintain if you mirror the internal structure of your `routes/views` and `templates/views` directories as much as possible. +Your application will be simpler to build and maintain if you mirror the internal structure of your `routes/views` and `templates/views` directories as much as possible. -This guide assumes you follow the recommendations above, however Keystone doesn't actually enforce any structure, so you're free to make changes to suit your application better. +> NOTE: This guide assumes you follow the recommendations above. However, Keystone doesn't actually enforce any structure so you're free to make changes to better suit your application or preferences. ## Models Before you can start your Keystone app, you'll need some data models. -We're going to start with the `User` model, which is special - we need it so that Keystone can do authentication and session management. +We're going to start with the `User` model, which is special -- this is required for Keystone's authentication and session management. **models/users.js** @@ -130,21 +136,21 @@ User.register(); For Keystone to provide authentication and session management to your application, it needs to know a few things: -- The option `user model` must be the name of the Model that Keystone should look in to find your users. If you use a different model name, be sure to set the option correctly. -- If you want your application to support session management, set the `session` option to true. Loading sessions incurs a small overhead, so if your application doesn't need sessions you can turn this off. -- Keystone has built-in views for signing in and out. To enable them, set the `auth` option to true. You can also implement custom signin and signout screens in your applications' views. +- The option `user model` must be the name of the Model that Keystone should look in to find your users. If you use a different model name, be sure to set this option correctly. +- If you want your application to support session management, set the `session` option to `true`. Loading sessions incurs a small overhead, so if your application doesn't need sessions you can turn this off. +- Keystone has built-in views for signing in and out. To enable them, set the `auth` option to `true`. You can also implement custom signin and signout screens in your applications' views. - Sessions are persisted using an encrypted cookie storing the user's ID. Make sure you set the `cookie secret` option to a long, random string. -- The user model must have a `canAccessKeystone` property (which can be a virtual method or a stored boolean) that says whether a user can access Keystone's Admin UI or not. \*Note\* If you choose to use a virtual method setting the value in mongodb directly will not authenticate correctly. A virtual method is useful when the criteria for access is more complex. See [Mongoose virtuals](http://mongoosejs.com/docs/4.x/docs/guide.html#virtuals). +- The user model must have a `canAccessKeystone` property that says whether a user can access Keystone's Admin UI or not. This property can be a virtual method or a stored boolean. **Note:** If you choose to use a virtual method, setting the value in MongoDB directly will not authenticate correctly. A virtual method is useful when the criteria for access is more complex. See [Mongoose virtuals](http://mongoosejs.com/docs/4.x/docs/guide.html#virtuals). ### More on Data Models -For more information on how to set up your application's models, and the full documentation for lists and fields, see the [database guide](/documentation/database/). +For more information on how to set up your application's models and the full documentation for lists and fields, see [Database Configuration](/documentation/database/). ## Routes & Views -Usually, the easiest and clearest way to configure the logic for different routes (or views) in your application is to set up all the bindings in a single file, then put any common logic (or middleware) in another file. +The easiest and clearest way to configure the logic for different routes (or views) in your application is usually to set up all the bindings in a single file, then put any common logic (or middleware) in another file. -Then, the controller for each route you bind goes in its own file, organised similarly to the template that renders the view. +Then, the controller for each route you bind goes in its own file and can be organised similarly to the template that renders the view. Keystone's [importer](/api/methods/importer) and Express's middleware support makes this easy to set up. @@ -152,7 +158,7 @@ Keystone's [importer](/api/methods/importer) and Express's middleware support ma **routes/index.js** -This script imports your route controllers and binds them to URLs. +This script imports your route controllers and binds them to URLs: ```javascript var keystone = require('keystone'); @@ -202,7 +208,7 @@ exports = module.exports = function(app) { - Tell Keystone how to handle `404` and `500` errors - Use the importer to load all the route controllers in the `/routes/views` directory - Export a method that binds the index route controller to `GET` requests on the root url `/` - - The `app` argument to this method comes from our express app, so anything you can do binding routes in express, you can do here. + - The `app` argument to this method comes from our Express app, so anything you can do binding routes in Express, you can do here. - Additional route controllers that you add to your app should be added using `app.get`, `app.post` or `app.all` under your root controller. ### Common Route Middleware @@ -210,7 +216,8 @@ exports = module.exports = function(app) { Putting your common middleware in a separate `routes/middleware.js` file keeps your route index nice and clean. If your middleware file gets too big, it's a good idea to restructure any significant functionality into custom modules in your projects `/lib` folder. **routes/middleware.js** -This script includes common middleware for your application routes + +This script includes common middleware for your application routes: ```javascript var _ = require('lodash'); @@ -278,8 +285,8 @@ exports.flashMessages = function(req, res, next) { Keystone expects middleware functions to accept the following arguments: -- req - an express request object -- res - an express response object +- req - an Express request object +- res - an Express response object - next - the method to call when the middleware has finished running (including any internal callbacks) #### Flash message support (no, not that flash) @@ -297,20 +304,21 @@ To use flash messages in your route controllers, do this: `req.flash('info', 'Some information!');` -Messages use session so they survive redirects, and will only be displayed to the user once, making them perfect for status messages (e.g. "Your changes have been saved") or form validation (e.g. "Please enter a valid email address"). +Messages use sessions so they survive redirects and will only be displayed to the user once, making them perfect for status messages (e.g. "Your changes have been saved") or form validation (e.g. "Please enter a valid email address"). -Some Keystone features (such as the Update Handler) can automatically generate flash messages for you, and expect the categories above to be available. +Some Keystone features (such as the [Update Handler](/api/methods/update-handler/)) can automatically generate flash messages for you and expect the categories above to be available. ## Templates -Now, for the template our route will `render`. The render method looks in the `views` directory specified in our `keystone.js`, which we set to `/templates/views`. +Now, for the template our route will `render`. The render method looks in the `views` directory specified in `keystone.js`, which we set to `/templates/views`. -The generator has several options, however we are going to use pug. To learn more about Pug, visit [pugjs.org](https://pugjs.org). +The generator has several options, however we are going to use Pug. To learn more about Pug, visit [pugjs.org](https://pugjs.org). Pug comes with some great features to simplify templates - including using layouts that define regions. We're going to use a layout called `../templates/layouts/base.pug`, which is included on the first line of the file above: **templates/layouts/base.pug** -The base layout for our view templates + +The base layout for our view templates: ```jade include ../mixins/flash-messages @@ -343,10 +351,11 @@ html block js ``` -We're also have a mixin file `templates/mixins/flash-messages.pug` which we can add to include the `flash-messages`. Including mixins in your layout or view templates is a great way to keep your layout and view files clean, and re-use mixins across multiple views. +We also have a mixin file `templates/mixins/flash-messages.pug` which we can add to include the `flash-messages`. Including mixins in your layout or view templates is a great way to keep your layout and view files clean, and re-use mixins across multiple views. **templates/mixins/flash-messages.pug** -Our flash-messages mixin + +Our flash-messages mixin: ```jade mixin flash-messages(messages) @@ -378,11 +387,11 @@ mixin flash-message(message, type) ### Using other template languages -KeystoneJS supports any [template language supported by express](https://expressjs.com/en/api.html). +KeystoneJS supports any [template language supported by Express](https://expressjs.com/en/api.html). Use the `view engine` option to specify the template language you want to use. -If you want to use a custom template engine, set the `custom engine` option as well. For instance, [EJS](http://ejs.co) is supported by express by default, but you might want to use [ejs.locals](https://github.com/RandomEtc/ejs-locals) as a template engine in order to benefit from get extensions. +If you want to use a custom template engine, set the `custom engine` option as well. For instance, [EJS](http://ejs.co) is supported by Express by default, but you might want to use [ejs.locals](https://github.com/RandomEtc/ejs-locals) as a template engine in order to benefit from get extensions. ```javascript // Modified web.js to use the ejs-locals custom template engine. @@ -398,15 +407,15 @@ keystone.init({ ## Public Assets -You'll want to add your own css, javascript, images and other files to your project. In the examples above, we're including `/styles/site.min.css`. If you are using less, add `public/styles/site.less` to your project. We can leave it blank for now, but note Keystone will generate a site.min.css on run time. +You'll want to add your own CSS, JavaScript, images and other files to your project. In the examples above, we're including `/styles/site.min.css`. If you are using LESS, add `public/styles/site.less` to your project. We can leave this blank for now, but note Keystone will generate a `site.min.css` on run time. Keystone will serve any static assets you place in the public directory. This path is specified in `keystone.js` by the `static` option. Keystone will also automatically generate `.css` or compressed `.min.css` files when a corresponding `.less` file is found in the public folder, as specified in `keystone.js` by the `less` option. For more information on LESS, see [lesscss.org](http://lesscss.org). -## Writing Updates +## Writing Application Updates -To do this, we're going to create an update script, which Keystone will automatically run before starting the web server. +Keystone includes an [Application Updates](/documentation/database/application-updates/) framework which can be used to apply one-off data changes against your database. Application update scripts can be convenient for seeding your database, transitioning existing data when models change, or running transformation scripts against your database. Since update scripts only run once per database, they are also very useful to ensure consistency across multiple deployments or environments. Keystone's automatic update functionality is enabled in `keystone.js` by the auto `update option`. @@ -418,7 +427,7 @@ Updates are ordered using [Semantic Versioning](https://semver.org), and Keyston Update file names should match the pattern `x.x.x-description.js` - anything after the first hyphen is ignored, so you can describe the update in the filename. -So to automatically add a new Admin User when your app first launches, you have a `updates/0.0.1-admin.js` file: +To automatically add a new Admin User when your app first launches, create an `updates/0.0.1-admin.js` file: **updates/0.0.1-admin.js** Update script to add the first admin (change to your own name, email and password) @@ -438,8 +447,7 @@ exports = module.exports = function(done) { }; ``` -> NOTE -> You probably don't want to store your real password in the code, so it's a good idea to set the default password to something simple, then sign in and change it using Keystone's Admin UI after you start your app for the first time. +> NOTE: You probably don't want to store your real password in the code, so it's a good idea to set the default password to something simple, then sign in and change it using Keystone's Admin UI after you start your app for the first time. ## Starting Keystone @@ -447,7 +455,7 @@ Now you're ready to run your application, so execute the following in your proje `npm start` -Keystone will automatically apply the update, and then start a web server on the default port, 3000. +Keystone will automatically apply any pending application updates and then start a web server on the default port, 3000. To see your home page, point your browser at [localhost:3000](http://localhost:3000). You should see a **Hello World!** message. @@ -455,8 +463,8 @@ To sign in to Keystone's Admin UI, go to [localhost:3000/keystone](http://localh ## Next Steps -... you're done! Well, not really. It's time to start building your app now. For more information on list options and the field types Keystone supports, browse the [database guide](/documentation/database/). +... you're done! Well, not really. It's time to start building your app now. For more information on list options and the field types Keystone supports, browse the [Database Configuration](/documentation/database/) documentation. -You should also [Follow @KeystoneJS on Twitter](https://twitter.com/keystonejs) for news and updates, [Star KeystoneJS on GitHub](https://github.com/keystonejs/keystone), and discuss this guide (or anything KeystoneJS related) on the [KeystoneJS Google Group](https://groups.google.com/d/forum/keystonejs). +You should also [Follow @KeystoneJS on Twitter](https://twitter.com/keystonejs) for news and updates, [Star KeystoneJS on GitHub](https://github.com/keystonejs/keystone), and discuss this guide (or anything KeystoneJS related) on the [KeystoneJS Community Slack](https://launchpass.com/keystonejs). Enjoy using KeystoneJS! diff --git a/docs/documentation/Configuration/Project-Options.md b/docs/documentation/Configuration/Project-Options.md index b706426f42..974c28967f 100644 --- a/docs/documentation/Configuration/Project-Options.md +++ b/docs/documentation/Configuration/Project-Options.md @@ -7,7 +7,7 @@ The following options control the branding, navigation and default export settin The name of the KeystoneJS application -
name
brand