contentful-management.js
Javascript client for Contentful's Content Management API:
Supported browsers/environments:
- Chrome
- Firefox
- IE10
- node.js >= 0.8
Install
In node, using npm:
npm install contentful-management
Note: The next minor version release of dist/contentful-management.min.js
will
be much smaller. Please use a package manager to keep your JS
dependencies up to date and get the newest version right when it's
ready!
Examples
This library comes with a few example scripts
Cloning a Space
View Source
This clones a Space's complete content model & content.
It's intended to be used to create one-time clones of Spaces,
not for synchronization.
$ example/clone-space.js \
--access-token $CONTENTFUL_ACCESS_TOKEN \
--source-space-id $SOURCE_SPACE_ID \
--destination-space-id $DESTINATION_SPACE_ID
Omit the destination-space-id
parameter to make the script create a
Space. When doing that you might have to specify a
destination-organization-id
parameter if your user is in multiple
organizations.
Cloning a Space's Content Types Only
If you just want the content types for a space to be cloned, add the --only-content-types
flag.
$ example/clone-space.js \
--access-token $CONTENTFUL_ACCESS_TOKEN \
--source-space-id $SOURCE_SPACE_ID \
--destination-space-id $DESTINATION_SPACE_ID \
--only-content-types
Migrating Entry fields
Sometimes you need to migrate content from one field to another.
This is a script which migrates all values from one field to another
field, using a specific mapping function if it's provided.
It'll do this for each entry of a specific Content Type in a Space,
going through it slice by slice.
Currently this supports mapping from Text to Symbol.
But it would be very simple to convert e.g. numbers to symbols
or even location strings to locations by geocoding.
PRs are very welcome!
View Source
$ example/migrate-fields.js \
--access-token $CONTENTFUL_MANAGEMENT_API_ACCESS_TOKEN \
--space-id $SPACE_ID \
--content-type-id $CONTENT_TYPE_ID \
--source-field-id $SOURCE_FIELD_ID \
--destination-field-id $DESTINATION_FIELD_ID
API
createClient(opts) -> Client
To use the Content Management API you will need an access token. The easiest
way to get a token for local scripts/experimentation is by using the OAuth app
embedded in our Developer center documentation.
var contentful = require('contentful-management');
var client = contentful.createClient({
accessToken: 'b4c0n73n7fu1',
secure: true
});
Client#getSpace(id) -> SpacePromise
client.getSpace('foobar')
Returns a promise for a Space object.
Client#createSpace(opts) -> SpacePromise
Create a space with the name 'CMA Example Space'.
client.createSpace({name: 'CMA Example Space'})
Returns a promise for a Space object.
Client#deleteSpace -> Promise
Delete a space and all of its content. Warning: there is no undo!
client.deleteSpace(space);
Returns a promise for nothing, which should still be checked for errors.
Space API
A space is a top level container for all other resources. In addition to the
methods documented below, a space has the following data properties:
{
"name": "Example Space",
"sys": {
"type": "Space",
"id": "1vlwe1hnkhmk",
"version": 0,
"createdBy": {
"sys": {
"type": "Link",
"linkType": "User",
"id": "0lEP0wVJL8WSQSbRuVUdcJ"
}
},
"createdAt": "2013-09-22T17:34:53Z",
"updatedBy": {
"sys": {
"type": "Link",
"linkType": "User",
"id": "0lEP0wVJL8WSQSbRuVUdcJ"
}
},
"updatedAt": "2013-09-22T17:34:53Z"
}
}
Space#createContentType(data) -> ContentTypePromise
Create a new content type by providing a name, fields, optional description,
and an optional ID. If you do not provide the sys.id
property, an ID will be
generated for you.
space.createContentType({
sys: {id: 'blog-post'},
name: 'Blog Post',
description: 'For like, blogging',
fields: [
{id: 'title', name: 'Title', type: 'Text'},
{id: 'body', name: 'Body', type: 'Text'}
]
})
The easiest way to find out what field types are available and how to represent
them in JSON is to use the content type editor built into the [Contentful
app][cf-app]. (Note that you will need administrative privileges for a space to
edit content types).
Returns a promise for a ContentType.
Space#updateContentType(data) -> ContentTypePromise
Updates an existing content type. The provided data object needs to have
sys.id
and sys.version
properties. The version provided should be the version
of the content type retrieved from the server.
Read more about updating resources on the CMA documentation.
Space#getContentType(id) -> ContentTypePromise
Retrieve a content type by its ID (not its name). Returns a promise for a
ContentType.
Space#getContentTypes() -> ContentTypeCollectionPromise
Retrieve all content types for the space. Returns a promise for a collection
of ContentType objects.
Space#getPublishedContentTypes() -> ContentTypeCollectionPromise
Retrieve all published content types for the space. Returns a promise for a collection
of ContentType objects.
Space#publishContentType(contentType) -> ContentTypePromise
Publish a [content type][], making it available for use by [create-entry], as
well as visible to the [Content Delivery API][].
space.publishContentType(contentType)
Returns a promise for an updated version of the content type.
Space#unpublishContentType(contentType) -> ContentTypePromise
Unpublish a [content type][]. This operation is not allowed if there
are any entries of this content type (because entries may only be created for
published content types). If you wish to delete a content type and all of its
entries, you will need to iterate over the entries and delete them before
unpublishing and deleting the content type.
space.unpublishContentType(contentType)
Returns a promise for an updated version of the content type.
Space#deleteContentType(contentType) -> Promise
Delete a content type, note that the content type must be unpublished (and
therefore have no entries) before it can be deleted.
space.deleteContentType(contentType)
Space#createEntry(contentType, entry) -> EntryPromise
Create a new entry by providing field values and and an optional ID. If you do
not provide the sys.id
property, an ID will be generated for you.
space.createEntry(contentType, {
sys: {id: 'hello-world'},
fields: {
title: {'en-US': 'Hello, World!'},
body: {'en-US': 'Bacon is healthy!'}
}
})
For more information on what is allowed in the fields
property, see [Entry
fields][].
Returns a promise for an Entry.
Space#updateEntry(data) -> ContentTypePromise
Updates an existing entry. The provided data object needs to have
sys.id
and sys.version
properties. The version provided should be the version
of the entry retrieved from the server.
Read more about updating resources on the CMA documentation.
Space#getEntries(query) -> EntryCollectionPromise
Search & filter all of the entries in a space. The query
parameter should be
an object of querystring key-value pairs. The query examples
section containts more examples of the kinds of queries you can perform.
space.getEntries({content_type: 'blog-post'})
Returns a promise for a collection of Entry objects.
Space#getPublishedEntries(query) -> EntryCollectionPromise
Search & filter all of the published entries in a space. Works like getEntries.
Returns a promise for a collection of Entry objects.
Space#getEntry(id) -> EntryPromise
Retrieve an entry by its ID. Returns a promise for an Entry.
space.getEntry('hello-world')
Space#getEntries(query) -> EntryCollectionPromise
Search & filter all of the entries in a space. The query
parameter should be
an object of querystring key-value pairs. The query examples
section containts more examples of the kinds of queries you can perform.
space.getEntries({content_type: 'blog-post'})
Returns a promise for a collection of Entry objects.
Space#getPublishedEntries(query) -> EntryCollectionPromise
Search & filter all of the published entries in a space. Works like getEntries.
Returns a promise for a collection of Entry objects.
Space#publishEntry(entry) -> EntryPromise
Publish an Entry, making it visible to the [Content Delivery API][].
space.publishEntry(entry)
Returns a promise for an updated version of the entry.
Space#unpublishEntry(entry) -> EntryPromise
Unpublish an Entry, this appears to the [Content Delivery API][] as though
the entry was deleted.
space.unpublishEntry(entry)
Returns a promise for an updated version of the entry.
Space#archiveEntry(entry) -> EntryPromise
Archive an Entry. The Entry needs to be previously unpublished.
space.archiveEntry(entry)
Returns a promise for an updated version of the entry.
Space#unarchiveEntry(entry) -> EntryPromise
Unarchive an Entry.
space.unarchiveEntry(entry)
Returns a promise for an updated version of the entry.
Space#deleteEntry(entry) -> Promise
Delete an entry. Note that entries must be unpublished before deleting them.
space.deleteEntry(entry)
Returns a promise for nothing, which should still be checked for errors.
Space#createAsset(data) -> AssetPromise
Create a new asset by providing field values and and an optional ID. If you do
not provide the sys.id
property, an ID will be generated for you.
space.createAsset({
sys: {id: 'dinosaurs'},
fields: {
title: {'en-US': 'Dinosaur'},
file: {
'en-US': {
upload: 'http://www.qwantz.com/comics/comic2-2870.png'
}
}
}
})
Returns a promise for an Asset, which must be processed
before it can be published.
Space#updateAsset(data) -> ContentTypePromise
Updates an existing asset. The provided data object needs to have
sys.id
and sys.version
properties. The version provided should be the version
of the asset retrieved from the server.
Read more about updating resources on the CMA documentation.
Space#processAssetFile(asset, locale) -> Promise
Process the file for a particular asset & locale. Note that this operation is
asynchronous on the Contentful backend; you will receive a successful response
before the asset is fully processed.
space.processAssetFile(asset, 'en-US');
Returns a promise for nothing, which should still be checked for errors. In
order to detect when an asset has finished processing, retrieve the asset using
space.getAsset
and test for the presence of asset.fields.file[locale].url
.
Space#getAsset(id) -> AssetPromise
Retrieve an asset by its ID. Returns a promise for an Asset.
space.getAsset('dinosaurs')
Space#getAssets(query) -> AssetCollectionPromise
Search & filter all of the assets in a space. The query
parameter should be
an object of querystring key-value pairs. The query examples
section containts more examples of the kinds of queries you can perform.
space.getAssets({'fields.file.url[exists]': false})
Returns a promise for a collection of Asset objects.
Space#getPublishedAssets(query) -> AssetCollectionPromise
Search & filter all of the assets in a space. Works like getAssets.
Returns a promise for a collection of Asset objects.
Space#publishAsset(asset) -> AssetPromise
Publish an Asset, making it visible to the [Content Delivery API][].
space.publishAsset(asset)
Returns a promise for an updated version of the asset.
Space#unpublishAsset(asset) -> AssetPromise
Unpublish an Asset, this appears to the [Content Delivery API][] as though
the asset was deleted.
space.unpublishAsset(asset)
Returns a promise for an updated version of the asset.
Space#archiveAsset(asset) -> AssetPromise
Archive an Asset. The Asset needs to be previously unpublished.
space.archiveAsset(asset)
Returns a promise for an updated version of the asset.
Space#unarchiveAsset(asset) -> AssetPromise
Unarchive an Asset.
space.unarchiveAsset(asset)
Returns a promise for an updated version of the asset.
Space#createLocale(data) -> LocalePromise
Create a new locale by providing a name, and locale code. You can also specify
if the locale should be made available in the Content Management API and
Content Delivery API (both are enabled by default)
space.createLocale({
name: 'German',
code: 'de',
contentManagementApi: true,
contentDeliveryApi: true
})
Returns a promise for a [Locale][].
Space#updateLocale(data) -> LocalePromise
Updates an existing locale. The provided data object needs to have
sys.id
and sys.version
properties. The version provided should be the version
of the locale retrieved from the server.
Read more about updating resources on the CMA documentation.
Space#getLocale(id) -> LocalePromise
Retrieve a locale its ID (not its name or code). Returns a promise for a
[Locale][].
Space#deleteLocale(locale) -> Promise
Delete a locale. Any content for this locale in existing entries will be gone.
space.deleteLocale(locale)
ContentType properties
Each content type defines a schema for entries in its fields
array. Every
entry has a corresponding content type, and its own fields
property, which
is an object. The allowed keys and values in an entries fields
object
correspond to the field ids defined in that entries content type.
A complete content type (the one created in create-content-type) looks like:
{
"name": "Blog Post",
"fields": [
{ "id": "title", "name": "Title", "type": "Text" },
{ "id": "body", "name": "Body", "type": "Text" }
],
"sys": {
"id": "blog-post",
"type": "ContentType",
"space": {
"sys": { "type": "Link", "linkType": "Space", "id": "7daovfk1olns" }
},
"createdAt": "2013-09-22T21:42:00.184Z",
"createdBy": {
"sys": { "type": "Link", "linkType": "User", "id": "0lEP0wVJL8WSQSbRuVUdcJ" }
},
"version": 1,
"updatedAt": "2013-09-22T21:42:00.187Z",
"updatedBy": {
"sys": { "type": "Link", "linkType": "User", "id": "0lEP0wVJL8WSQSbRuVUdcJ" }
}
}
}
Entry properties
An entry is a piece of content containing fields and values. Every entry has a
corresponding content type (denoted by its sys.contentType
property) that
defines what keys are allowed in its fields
property, and what types those
keys can contain. Note that field values are always nested in an object whose
keys correspond to the locales available in a space.
{
"fields": {
"title": { "en-US": "Hello, World!" },
"body": { "en-US": "Bacon is healthy!" }
},
"sys": {
"id": "hello-world",
"type": "Entry",
"space": {
"sys": { "type": "Link", "linkType": "Space", "id": "7daovfk1olns" }
},
"createdAt": "2013-09-22T23:05:03.271Z",
"createdBy": {
"sys": { "type": "Link", "linkType": "User", "id": "0lEP0wVJL8WSQSbRuVUdcJ" }
},
"contentType": {
"sys": { "type": "Link", "linkType": "ContentType", "id": "blog-post" }
},
"version": 1,
"updatedAt": "2013-09-22T23:05:03.271Z",
"updatedBy": {
"sys": { "type": "Link", "linkType": "User", "id": "0lEP0wVJL8WSQSbRuVUdcJ" }
}
}
}
Asset properties
An asset is special kind of entry containing metadata for a binary file (e.g. an
image or video). Note that asset files have multiple states.
{
"fields": {
"title": { "en-US": "Dinosaurs" },
"file": { "en-US": { } }
},
"sys": {
"id": "dinosaurs",
"type": "Asset",
"space": {
"sys": { "type": "Link", "linkType": "Space", "id": "7daovfk1olns" }
},
"createdAt": "2013-09-22T23:05:03.271Z",
"createdBy": {
"sys": { "type": "Link", "linkType": "User", "id": "0lEP0wVJL8WSQSbRuVUdcJ" }
},
"version": 1,
"updatedAt": "2013-09-22T23:05:03.271Z",
"updatedBy": {
"sys": { "type": "Link", "linkType": "User", "id": "0lEP0wVJL8WSQSbRuVUdcJ" }
}
}
}
Asset file states
Assets may contain references to multiple files (one for each locale of their
space) and each one of those files may be in one of three states: "new",
"ready to process", or "processed".
To determine the state of an asset file, you can test for the presence of
fields.file[locale].upload
and fields.file[locale].url
. If the url
property is set, then the file has already been processed. If the url
property
is not set, but the upload
property is, you can attempt processing of the
file.
If neither property is present, the upload
property must be set to a valid
publically accessible URL before calling Space#processAssetFile.
Note that an asset with unprocessed files can not be published.
Query Examples
You can filter & search the entries and assets in your space by passing query
params to Space#getEntries
and Space#getAssets
. There are
a few predefined query parameter names (such as content_type
and order
), and
you can also query against document properties by using a dot-separated property
path (followed by an optional operator in square brackets) as a query parameter
name.
For example: fields.name[ne]
means "entries where fields.name
is not-equal
to ...". Full documentation of the allowed query parameters & field operators
can be found in our API Documentation, but below are some
examples of common queries to get you started:
Search entries that have been updated since the 1st of January, 2013:
space.getEntries({ 'sys.updatedAt[gte]': '2013-01-01T00:00:00Z' })
Retrieve a specific set of entries by their sys.id
:
space.getEntries({ 'sys.id[in]': [ 'finn', 'jake' ] })
Search for cat
entries that have less than three lives left:
space.getEntries({
'content_type': 'cat',
'fields.lives[lt]': 3
})
Specifying the content_type
query parameter is required when querying on
fields (such as fields.lives
above). Note that 'cat'
is the content type
ID and not its name.
Full-text search for entries with "bacon" anywhere in their textual content:
space.getEntries({ query: 'bacon' })
Full-text search for dogs with "bacon" specifically in the description
field:
space.getEntries({
'content_type': 'dog',
'fields.description[match]': 'bacon'
})
Get the 50 most recently created entries, and the next 50:
space.getEntries({
order: '-sys.createdAt',
limit: 50
})
space.getEntries({
order: '-sys.createdAt',
skip: 50,
limit: 50
})
See also: Collections and pagination.
Collections and pagination
Many methods return collections of resources. These collections are represented
as a JSON object containing items and pagination details:
{
"sys": {
"type": "Array"
},
"total": 1, // Total number of items matching the query
"skip": 0, // Offset into the result set represented by this response
"limit": 100, // Effective limit on # of items returned in this response
"items": [
// Full representations of each item
]
}
The getEntries
and getAssets
methods both accept limit
, skip
, and
order
as query parameters, allowing you to paginate through larger result
sets. Note that specifying a stable property (such as 'sys.createdAt'
) for
ordering results is recommended.
Unit Tests
Set the following environment variables to valid values:
CONTENTFUL_ACCESS_TOKEN
- a valid access token valueCONTENTFUL_MANAGEMENT_HOSTNAME
- the Contentful host name (without protocol)
Then execute the unit tests:
npm test
License
MIT