docs/guides/v0.3-to-v4.0-Upgrade-Guide.md
The mounting process has been rewritten for modularity and clarity. This
may introduce some breaking changes if your app has been attaching the
Keystone Admin UI to a nonstandard express app (i.e. not using
Keystone.start(), but should make things simpler going forward.
keystone.get('express session') has been replaced by
keystone.expressSessionkeystone.routes(fn) has been replaced by keystone.set('routes', fn)routes option supports both:
function (app) {} way of adding routes to the root
express appexpress.Router instancekeystone.set('pre:routes') now runs the hook as middleware before each
route is called, rather than running the function before Express starts up.keystone.static has been removed (replacement TBA, see
admin/server)keystone.mount has been removed (replaced by more granular methods,
see admin/server)keystone.bindEmailTestRoutes and keystone.set('email tests')
support (was this actually being used by anyone? let me know -
@jedwatson)keystone.set('email rules') option has been removed; you should just
use variables in your templates, rather than globally applied regular
expressions.Types.CloudinaryImage option publicID: 'slug' option has been
removed. It has been replaced by the generateFilename function.
Documentation for the new option can be found in
fields/types/cloudinaryimageThe UpdateHandler functionality has been completely rewritten to use the
new, generic List.updateItem method. While we have tried to preserve
backwards compatibility, there may be minor differences in functionality
and the format of messages returned.
The structure of error detail passed to the callback has changed, and now matches the new API error format (see the API Spec)
If you are using the UpdateHandler please test your application comprehensively when upgrading to 0.4 and report any problems you find in the issues.
Specific changes include:
callback function now receives a single error argument. To retreive the created/updated object use:// To create a new item
var model = new MyModel.model();
MyModel.model().updateItem(model, data, options, function (err) {
if (err) {
// Error handling
} else {
var savedItem = MyModel.getData(model);
}
});
options.validationMethods is no longer supported, please apply any custom validation before calling updateHandler.process()options.errorMessages is no longer supported, as fields may now return different error conditions and replacing specific error detail with a simple string has the potential to be misleading and frustrating for users. If you want to show custom messages, please handle this on a case-by-case basis in your application.The flashErrors option now supports the following values:
true send all error messages to req.flash"validation" only send validation error messages to req.flash"update" only send update errors to req.flashFile field typeThe new File field type, with the FS, S3 and Azure storage
adapters, replace the following field types (which are removed in 0.4) -
azureFilelocalFilelocalFiless3FileFor usage instructions, see:
For the full upgrade guide for File fields, see File-Fields-Upgrade-Guide in the KeystoneJS Wiki.
The _upload suffix is no longer required or supported when uploading
files from an html form. Now simply provide the cloudinary field path as
the name of file upload fields. For example:
<!-- old -->
<input type="file" name="picture_upload" />
<!-- new -->
<input type="file" name="picture" />
When the cloudinary folders Keystone option is set, in 0.3.x
CloudinaryImages fields would incorrectly use the cloudinary prefix
option's value as the first part of the folder path for fields that did
not specify the folder option. This has been fixed; the folder for
uploaded images now defaults to this.list.path + '/' + this.path
Explicit support for actions with paths.action (i.e. submitting a
fieldPath_action value) has been removed. To remove images from the
value, submit the new value for the field without the removed image
present.
The CloudinaryImages field no longer supports deleting removed images from Cloudinary, this may be restored in a subsequent version.
Reordering images with paths.order (i.e. submitting a
fieldPath_order value) has also been removed. To sort images, submit
the full array of values in the correct order.
field.updateItem(item, data)field.updateItem(item, data, function(err) {...})The geocodeGoogle option has been renamed to enableImprove.
The bundled version of Mongoose has been updated from 3.x to 4.x. Please review the Migration Guide and Release Notes for more information.
Keystone.EmailKeystone.Email was completely rewritten as the standalone, well-tested
keystone-email module, and requires it to be installed to work.
new Email now accepts a second argument as the options (e.g. to set the transport)new Email('templatepath.ext', { transport: 'mailgun' });
.sendnew Email('templatepath.ext', { transport: 'mailgun' })
.send(templateLocals, sendOptions, callback);
These options, APIs or behaviours were removed with the rewrite to an external module.
email.jade as the default filename, you now have
to pass an entire filename to or set the engine in the .Email callAll of these deprecations will continue to work throughout v4.x,
though warnings will be added in a future minor release. We highly
encourage moving to the new APIs as soon as possible, your apps will
break in v5 otherwise!
keystone.set('email') has been deprecated in favor of the root
option (passed to the .Email call)templateExt option was deprecated in favor of the engine
optionkeystone.set('transport') has been deprecated in favor of setting
transport in the new Email() optionskeystone.set('mailgun api key') and keystone.set('mailgun domain')
have been deprecated in favor of passing the apiKey and domain
option to the send options in .sendKeystone 0.3 had a feature where you could specify a custom toCSV
method on a list schema to control which values were included in the
CSV.
As the CSV Export has been completely rewritten and now supports the
same filter and fields options that the List view in the Admin UI does
(including being able to specify which fields are included in the CSV
from the Admin UI), the toCSV method has been replaced by a new
getCSVData method:
User.schema.methods.getCSVData = function (data, options) {
return {
password: undefined,
custom: { complex: true },
};
};
Values returned by this method will be added to the CSV regardless of
the fields specified to be included. You have access to the fields in
options.fields. Additionally, you can set values to undefined to
remove them from the csv if they were included.
The current User, if there is one, is provided in options.user.
You can now also specify a per-field toCSV transform. Provide a
function to return a custom value for the field if it is specified in
options.fields:
User.add({
email: { type: Types.Email, toCSV: function (field, options) {
return this.id === options.user.id ? 'Your email address' : this.email;
}}
})
The this scope will be the document being serialised to CSV format.
The field argument is the field definition, and the options argument
contains the options passed to getCSVData (see above).
For field types that store an object, you can instead provide a list or array of keys to include in the CSV data:
User.add({
address: { type: Types.Location, toCSV: 'suburb, postcode' }
})
Objects will be flattened to multiple columns, with each key being appended to the field path using camelCase.
So, for example, the following data from a File field with the path
attachment:
{
id: '56dd3f1a51cb31100cf08457',
attachment: {
filename: 'photo.jpg',
size: 83452
}
}
Will be added to the CSV in two columns:
id,attachmentFilename,attachmentFilesize
56dd3f1a51cb31100cf08457,photo.jpg,83452
The csv expanded Keystone option has been deprecated. Relationship
fields will always be expanded into fieldName, fieldId columns by
default.
Relationship fields had a bug in 0.3.x and 4.0.0 betas pre-beta.6 where undefined values passed to List.updateItem would be persisted to the database for { many: true } fields.
This has been fixed, so that incoming undefined values are ignored, which is consistent with all other field types except Boolean.
Keystone 3 included jade as a dependency; this meant your project may
have been able to use jade as the view engine without depending on it
explicitly. Jade has now been removed from Keystone, so if you're using
it you will need to explicitly add it to your package.json.
Keystone 3 included underscore as a dependency; this was utilised by
the generator, which should have added an explicit dependency when
generating package.json files. Unfortunately it didn't, which means
your project may expect underscore to be available and it won't be.
If you get the following error when starting a project with Keystone 4:
Error: Cannot find module 'underscore'
Run the following command in your project's root folder to resolve it:
npm install --save underscore