Learning basics of keystone in order to find out whether it's an appropriate tool for future client projects.
Aims:
- Figure out how to set up a database with custom schema
- Set up basic site structure / logic
- Learn some pug
- Deploy to Heroku
Models represent lists. Lists are collections of data in the database. The content of lists can be managed via keystone's admin UI.
Example code for configuring a list:
const keystone = require('keystone');
const Category = new keystone.List('Category', {
autokey: { from: 'name', path: 'key', unique: true, },
label: 'Categories',
}); // config for admin UI
Category.add({
name: { type: String, required: true, },
}); // relates to DB schema
Category.track = true;
Category.register();
remember to include the new model in models/index.js
, i.e. require('./categories.js');
To define a relationship with an existing list, use type 'relationship'. E.g. for films we can set a category like this:
Film.add({
name: { type: String, required: true, },
year: { type: Number, required: false, },
category: { type: Types.Relationship, ref: 'Category', many: true, },
});
- Create a view under
routes/views
- Include the route in
routes/index.js
- this needs two arguments (the path and the view) - Any data that you need to access in your templates needs to be assigned to
res.locals
To display a variable from the server use ={var}
For inlining two types of HTML tag: li: a(href="#")
To escape custom HTML input p!=description
To get one matching result from DB (e.g. when search value is unique):
category.model.findOne({ key: req.params.cat}).exec
To get everything from a list:
films.model.find().exec
To match only certain values, specify as argument to find
:
films.model.find({category: { _id: cat.id } }).exec
In order for an admin to be able to upload custom images, we need to sign up for Cloudinary, which is free.
I've saved my API key and secret in a .env
file. Using the dotenv
module for env variables.
Cloudinary config is set like this:
keystone.set('cloudinary config', process.env.CLOUDINARY);
I've added the following the films
model:
image: { type: Types.CloudinaryImage, publicID: 'slug', autoCleanup: true, },
Images can now be uploaded in the admin panel. You can see the uploaded images immediately when you sign into Cloudinary.
Keystone sites can be deployed to heroku. I followed the instructions here:
https://gist.github.com/vitalbone/e49650000dcd005cac48
Additionally:
- Change the mongoDB url in
web.js
to come from process.env and put your local mongo url in.env
file - Add a start script to
package.json