Pages are the core of any content-driven site. They represent a single piece of content that can be requested through its url.
For example, you might have a about.md file that is rendered as a page at the /about url.
In jaspr_content pages are built based on the configuration provided to the ContentApp component. This configuration defines how the content is loaded, parsed, and rendered.
For a single page, the following steps are taken:
- The page is created by one of the provided
RouteLoaders. - The page's configuration is resolved by the provided
ConfigResolverbased on its route. - The page's frontmatter is parsed and additional data is loaded by the configured
DataLoaders. - The page's content is pre-processed by the configured
TemplateEngine. - The page's content is parsed by one of the configured
PageParsers. - The parsed content is further processed by the configured
PageExtensions. - The processed content is rendered using the configured
CustomComponents and wrapped in aContentcomponent. - The content component is wrapped in a
PageLayoutand gets applied the configuredContentTheme. - The result is rendered to HTML.
All of the different parts used to build a page are configurable. They can be switched out, extended, or replaced with custom implementations. This allows you to create a content-driven site that fits your needs perfectly.
The Page class is the main data object that holds all information about a single page.
Each part in the pipeline can modify the page's content or data by using the apply() method like this:
page.apply(
content: 'updated content',
data: {'key': 'value'},
);With this the content is overridden and the data is deeply merged with the existing data, unless mergeData is set to false.
For most parts of the pipeline, you will have access to the page object directly. E.g. a DataLoader will receive the current page as an argument in its loadData(Page page) method.
You can also access the current page from within any Jaspr component by using the context.page extension getter:
class MyComponent extends StatelessComponent {
@override
Component build(BuildContext context) {
return .text('Page URL: ${context.page.url}');
}
}In some cases you might want to access all, or a subset of all pages of your site at once, e.g. to build an overview page or a list of blog posts.
You can achieve this by using the context.pages extension getter on BuildContext. For this to work, you need to enable eager loading of all pages by setting eagerlyLoadAllPages: true in your ContentApp configuration.
// In main.server.dart:
ContentApp(
eagerlyLoadAllPages: true,
// ...
)
// In your component:
Component build(BuildContext context) {
final allPages = context.pages;
// Optionally filter pages by their path, frontmatter data or something else.
final blogPosts = allPages.where((page) => page.path.startsWith('blog/'));
return ...
}The PageConfig class is the main configuration object for a page. It holds all the settings for loading, parsing, and rendering the page.
There are two ways to create a PageConfig:
-
The
ContentApp()constructor creates a singlePageConfigthat is used for all pages. -
Alternatively the
ContentApp.custom()constructor takes aConfigResolverfunction that can return differentPageConfigs for different pages. This allows you to have different configurations for different parts of your site. In addition to writing a custom function, you can:- use
PageConfig.all(...)to create aConfigResolverthat resolves the samePageConfigfor all pages. - use
PageConfig.match(Map<Pattern, PageConfig>)to resolve aPageConfigbased on the page's path.
- use

