Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
contentful-management
Advanced tools
The contentful-management npm package is a JavaScript client for the Contentful Content Management API. It allows developers to manage content, assets, and other resources within a Contentful space programmatically.
Create an Entry
This code sample demonstrates how to create a new entry in a Contentful space. You need to provide your access token and space ID, and specify the content type and fields for the new entry.
const contentfulManagement = require('contentful-management');
contentfulManagement.createClient({
accessToken: 'your-access-token'
}).then(client => {
return client.getSpace('your-space-id')
.then(space => space.createEntry('contentType', {
fields: {
title: {
'en-US': 'Hello, World!'
}
}
}))
.then(entry => console.log(entry))
.catch(console.error);
});
Update an Entry
This code sample shows how to update an existing entry in a Contentful space. You need to provide your access token, space ID, and the ID of the entry you want to update. The example updates the title field of the entry.
const contentfulManagement = require('contentful-management');
contentfulManagement.createClient({
accessToken: 'your-access-token'
}).then(client => {
return client.getSpace('your-space-id')
.then(space => space.getEntry('entry-id'))
.then(entry => {
entry.fields.title['en-US'] = 'Updated Title';
return entry.update();
})
.then(entry => console.log(entry))
.catch(console.error);
});
Delete an Entry
This code sample demonstrates how to delete an entry from a Contentful space. You need to provide your access token, space ID, and the ID of the entry you want to delete.
const contentfulManagement = require('contentful-management');
contentfulManagement.createClient({
accessToken: 'your-access-token'
}).then(client => {
return client.getSpace('your-space-id')
.then(space => space.getEntry('entry-id'))
.then(entry => entry.delete())
.then(() => console.log('Entry deleted'))
.catch(console.error);
});
Upload an Asset
This code sample shows how to upload an asset to a Contentful space. You need to provide your access token, space ID, and the path to the file you want to upload. The example also processes and publishes the asset.
const contentfulManagement = require('contentful-management');
const fs = require('fs');
contentfulManagement.createClient({
accessToken: 'your-access-token'
}).then(client => {
return client.getSpace('your-space-id')
.then(space => space.createAssetFromFiles({
fields: {
title: {
'en-US': 'My Asset'
},
file: {
'en-US': {
contentType: 'image/jpeg',
fileName: 'my-asset.jpg',
file: fs.createReadStream('path/to/your/file.jpg')
}
}
}
}))
.then(asset => asset.processForAllLocales())
.then(asset => asset.publish())
.then(asset => console.log(asset))
.catch(console.error);
});
Strapi is an open-source headless CMS that provides a robust API and a user-friendly admin panel. Unlike Contentful, which is a SaaS product, Strapi can be self-hosted, giving you more control over your data and infrastructure.
Prismic is another headless CMS that offers a content management API. The prismic-javascript package allows you to query and manage content in Prismic. It is similar to Contentful in terms of functionality but offers different pricing and features.
Javascript client for Contentful's Content Management API:
Supported browsers/environments:
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!
contentful-management.js uses axios under the hood, which depends on a native ES6 Promise implementation to be supported. If your environment doesn't support ES6 Promises, you can polyfill it.
This library comes with a few example scripts
If you're looking for the old clone-space.js script, check out our new tool, contentful-space-sync
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!
$ 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
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({
// A valid access token for your user (see above on how to create a valid access token)
accessToken: 'b4c0n73n7fu1',
// Enable or disable SSL. Enabled by default.
secure: true
});
If you'd like to use contentful.js with an http proxy, look into https-proxy-agent. If you pass down an agent through the relevant initialization option it gets passed down to axios and subsequently to Node's http module.
client.getSpace('foobar')
Returns a promise for a Space object.
Create a space with the name 'CMA Example Space'.
client.createSpace({name: 'CMA Example Space'})
Returns a promise for a Space object.
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.
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"
}
}
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.
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.
Retrieve a content type by its ID (not its name). Returns a promise for a ContentType.
Retrieve all content types for the space. Returns a promise for a collection of ContentType objects.
Retrieve all published content types for the space. Returns a promise for a collection of ContentType objects.
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.
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.
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)
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.
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.
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.
Retrieve an entry by its ID. Returns a promise for an Entry.
space.getEntry('hello-world')
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.
Search & filter all of the published entries in a space. Works like getEntries.
Returns a promise for a collection of Entry objects.
Publish an Entry, making it visible to the [Content Delivery API][].
space.publishEntry(entry)
Returns a promise for an updated version of the entry.
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.
Archive an Entry. The Entry needs to be previously unpublished.
space.archiveEntry(entry)
Returns a promise for an updated version of the entry.
Unarchive an Entry.
space.unarchiveEntry(entry)
Returns a promise for an updated version of the entry.
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.
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.
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.
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
.
Retrieve an asset by its ID. Returns a promise for an Asset.
space.getAsset('dinosaurs')
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.
Search & filter all of the assets in a space. Works like getAssets.
Returns a promise for a collection of Asset objects.
Publish an Asset, making it visible to the [Content Delivery API][].
space.publishAsset(asset)
Returns a promise for an updated version of the asset.
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.
Archive an Asset. The Asset needs to be previously unpublished.
space.archiveAsset(asset)
Returns a promise for an updated version of the asset.
Unarchive an Asset.
space.unarchiveAsset(asset)
Returns a promise for an updated version of the asset.
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][].
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.
Retrieve a locale its ID (not its name or code). Returns a promise for a [Locale][].
Delete a locale. Any content for this locale in existing entries will be gone.
space.deleteLocale(locale)
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" }
}
}
}
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" }
}
}
}
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": { /* See comments regarding asset file states below */ } }
},
"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" }
}
}
}
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.
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 asfields.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.
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.
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
MIT
FAQs
Client for Contentful's Content Management API
The npm package contentful-management receives a total of 269,850 weekly downloads. As such, contentful-management popularity was classified as popular.
We found that contentful-management demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.