contentful を触り始めてみました。
Content Delivery API を使ってエントリーを取得するクエリの記述を一部まとめてみました。
ブログによくある以下のような記事を取得できます。
- 記事一覧
- カテゴリアーカイブ
- 月別アーカイブ
- ページネーション
- 検索一覧
その他詳細は公式を参照してください。
準備
client には Contentful Delivery APIクライアント が入っています。
const contentful = require('contentful')
const client = contentful.createClient({
space: '<space_id>',
accessToken: '<content_delivery_api_key>'
});
getEntry('<entry_id>')
エントリーIDを指定して、単一のエントリーを取得します。
client.getEntry("31TNnjawUogHlfGUoMO0M2").then(entry => {
console.log(entry.fields.title);
console.log(entry.fields.body);
console.log(entry.sys.createdAt);
});
このとき fields
には Content type に自身で追加したフィールド(タイトル、本文など)が入っています。
sys
にはシステム管理のメタデータ(id, revision, createdAtなど)が入っています。
getEntries()
全てのエントリーを取得します。
引数にオプションを指定しない場合には、 entries.items
に、記事や人やカテゴリなど、Content type を元にした全てのエントリーが配列で入ります。
client.getEntries().then(entries => {
console.log(entries.items[0].fields.title);
console.log(entries.items[1].fields.title);
console.log(entries.items[2].fields.title);
});
この getEntries()
の引数に様々なオプションを含めることができます。
指定した Content type の全てのエントリーを取得
以下はブログ記事の一覧を取得します。
client.getEntries({
content_type: "blogPost"
}).then(entries => {
console.log(entries.items); // blogPostのエントリー配列
});
指定したフィールドと一致する全てのエントリーを取得
Memoフィールドに 'hoge'
という String を設定している全てのエントリーを取得します。
このように fields
を使用した検索をする場合は、 content_type
を指定する必要があります。
client.getEntries({
content_type: "blogPost",
"fields.memo": "hoge"
}).then(entries => {
console.log(entries.items);
});
指定したフィールドと一致しない全てのエントリーを取得
[ne]オペレーターを使うと、 'hoge'
という String を__設定していない__全てのエントリーを取得します。
client.getEntries({
content_type: "blogPost",
"fields.memo[ne]": "hoge"
}).then(entries => {
console.log(entries.items);
});
List形式のフィールドの検索
Likesフィールド(List形式)に 'banana'
が含まれている全てのエントリーを取得します。
client.getEntries({
content_type: "blogPost",
"fields.likes": "banana"
}).then(entries => {
console.log(entries.items);
});
その他のに使えるオペレータはこちら。
オペレータ | |
---|---|
[ne] | 指定した値が含まれない全てのエントリーを取得 |
[all] | 指定した複数のパラメータが全て含まれている全てのエントリーを取得 |
[in] | 指定した複数のパラメータのどれかが含まれている全てのエントリーを取得 |
[nin] | 指定した複数のパラメータのどれも含まれている全てのエントリーを取得 |
[exists] | フィールドに値が設定されている全てのエントリーを取得(パラメータがtrue の場合) |
[exists] | フィールドに値が設定されていない全てのエントリーを取得(パラメータがfalse の場合) |
日付形式, 数値形式の検索
以下のような範囲を指定するオペレータが使用できます。
オペレータ | |
---|---|
[lt] | より小さい |
[lte] | 以下 |
[gt] | より大きい |
[gte] | 以上 |
2019年10月のアーカイブスを表示したい場合、以下のようなクエリで取得します。
const year = 2019;
const month = 10;
// 年と月からその月の最終日を返す関数
const getLastDay = (year, month) => {
const lastDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const isLeap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
if (isLeap && month === 2) {
return 29;
} else {
return lastDays[month - 1];
}
};
client.getEntries({
content_type: "blogPost",
"fields.publishDate[gte]": `${year}-${month}-01`, // その月の初めの日以上
"fields.publishDate[lte]": `${year}-${month}-${getLastDay(year, month)}` // その月の最終日以内
}).then(entries => {
console.log(entries.items);
});
全文検索
指定した文字列を含む全てのエントリーを取得できます。
client.getEntries({
content_type: "blogPost",
query: "orange"
})
.then(entries => {
console.log(entries.items);
});
[match]オペレータでフィールドを指定した全文検索も可能です。
client.getEntries({
content_type: "blogPost",
"fields.description[match]": "Hello"
})
.then(entries => {
console.log(entries.items);
});
エントリーの並び替え
order
を使用して、順序を指定できます。
このとき指定パラメータの接頭に -
を付けると逆順になります。
client.getEntries({
content_type: "blogPost",
order: "-sys.createdAt"
})
.then(entries => {
console.log(entries.items);
});
指定できるパラメータは、日付や数値やブール値、256字以下の文字列のみです。
複数指定することも可能です。
client.getEntries({
order: '-sys.createdAt,sys.id'
})
ページネーション(取得数制限とオフセット機能)
limit
を使用して、取得数を制限できます。
skip
で取得位置のオフセットを指定できます。
ページネーションは以下のようなクエリで実装できます。
const MAX_ENTRY = 20;
const page = 3;
client.getEntries({
content_type: "blogPost",
order: "sys.createdAt",
limit: MAX_ENTRY,
skip: MAX_ENTRY * (page - 1)
})
.then(entries => {
console.log(entries.items);
});
Reference形式の検索
以下は、参照形式であるcategoryフィールドを指定した検索です。
指定する Reference の content type ID もクエリに含める必要があります。
client.getEntries({
content_type: "blogPost",
"fields.category.sys.contentType.sys.id": "tag", // ←これも必要
"fields.category.fields.name": "Game"
})
.then(entries => {
console.log(entries.items);
});
[追記]
sys.id を直接指定する場合は contentTypeIDの指定はいらないっぽい。
この場合、リスト形式のReference(= Many references)での取得が可能。
指定する sys.id は contentful CMSサイト の contentページ-> 各contentページ -> 右上のInfoボタン -> ENTRY ID で確認できるランダムな英数字。
client.getEntries({
content_type: "blogPost",
"fields.categories.sys.id": "<ENTRY ID>"
})
.then(entries => {
console.log(entries.items);
});
上記は複数カテゴリ(単カテゴリでも可)を持つ記事を、カテゴリ検索する場合。 事前にカテゴリを getEntries して fields の内容と一緒に sys.id を取得した上でカテゴリ検索する必要がある。
おわり
自分のサイトは何年もwordpressで運用してるので、 contentful に乗り換えてみようかと思います。