Once content has been saved in the CMS you'll want a way to retrieve it. Your CMS instance has methods to fetch specific Entries or search through all content.
Content can be queried within React server components (and functions that run on the server such as generateStaticParams).
import {cms} from '@/cms'
import {Query} from 'alinea'
export default async function HomePage() {
const homePage = await cms.get({type: HomePage})
return <h1>{homePage.title}</h1>
}
A single Entry can be fetched using the get method.
const entry = await cms.get({
type: HomePage,
id: homePageId
})
Multiple Entries can be fetched using the find method.
const blogPosts = await cms.find({
type: BlogPost,
parentId: blogId
})
A result set can be limited using skip and take.
// Skip the first 10 entries and return a maximum of 10
const posts = await cms.find({
type: BlogPost,
skip: 10,
take: 10
})
A result set can be ordered by passing one or multiple fields.
const ordered = await cms.find({
type: NewsItem,
orderBy: {desc: NewsItem.publishDate}
})
Results can be grouped by one or more fields.
const grouped = await cms.find({
type: NewsItem,
orderBy: NewsItem.category
})
To search Entries by specific Fields use the filter option.
// If filtered by Type first it's possible to match fields
// on equality directly by passing an object. This does not
// work for any other comparison operator.
const withPath = await cms.get({
type: BlogPost,
filter: {path: 'why-you-should-get-a-cat'}
})
// Comparisons can be made by using the conditional methods
// of the field you're comparing to.
const recent = await cms.find({
type: BlogPost,
filter: {publishedDate: {gte: `2024-01-01`}}
})
// Multiple conditions result in matching on both (AND).
const postsOf2023 = await cms.find({
type: BlogPost,
filter: {
publishedDate: {
lt: '2024-01-01',
gte: '2023-01-01'
}
}
})
Entries can be queried with search terms. Any (Rich) Text Field with the searchable option set to true is indexed.
// Search can be used in combination with conditions
const containsDogs = await cms.find({
type: BlogPost,
search: 'dog'
})
// Multiple search terms can be used
const containsBothDogsAndCats = await cms.find({
type: BlogPost,
search: ['dog', 'cat']
})
Resulting rows can be narrowed to contain only specific fields.
import {Query} from 'alinea'
// Returns a select set of fields
const rows = await cms.find({
type: BlogPost,
select: {
// Entry fields are available on Query
id: Query.id,
url: Query.url,
title: BlogPost.title,
description: BlogPost.shortDescription
}
})
Entries in Alinea are part of a content tree. This means they'll often have a parent Entry or contain children Entries. To query content from the parent(s) or children you can request it within the selection.
import {Query} from 'alinea'
// Select a few fields from the parent Entries to render
// a breadcrumb navigation.
const breadcrumbs = Query.parents({
select: {
url: Query.url,
title: Query.title
}
})
// Use it directly in another select
const blogPosts = await cms.find({
type: BlogPost,
select: {
// Select the fields you want from this blog post
title: BlogPost.title,
body: BlogPost.body,
// ... and include the data of the parents
breadcrumbs
}
})
// You can use the spread operator to make the above more readable
const blogPosts = await cms.find({
type: BlogPost,
select: {
...BlogPost,
breadcrumbs
}
})
// Similarly you can fetch parent and children in one query
const blog = await cms.get({
type: Blog,
select: {
...Blog,
posts: Query.children({type: blogPost})
}
})