#Pages and Layouts
Unlike Assets, Media, Components, and other things your Addon provides, you generally should not directly create Pages and Layouts. Instead, you should create Repository Pages and Repository Layouts (RepoPages and RepoLayouts for short). These are Page and Layout definitions that are added to the Page Library and Layout Library that act as examples the user can import and modify to suit their Site.
There are certain, rare instances where you will need to directly create Pages and Layouts. For these use-cases see Pages and Layouts Direct Access.
#RepoPage Schema
{
// uneditable properties
_id: '63a0db9dd37c3735b468e1f8',
managedByAddonId: '639b8f837f5fb8a39404280a',
updatedAt: 1671486365027,
createdAt: 1671486531695,
// basic properties
title: '',
type: '',
path: '',
description: '',
layoutName: '',
isEnabled: true,
// body properties
lang: 'pug',
body: '',
// style properties
styleLang: 'stylus',
style: '',
// tags
tags: [],
// scripts
script: '',
usesDataScript: false,
dataScript: '',
// seo
favicon: '',
noindex: false,
nofollow: false,
canonicalUrl: '',
ogType: '',
ogTitle: '',
ogImages: '',
ogDescription: '',
ogArticleAuthors: '',
ogArticlePublishedTime: '',
ogArticleModifiedTime: '',
ogArticleExpirationTime: '',
ogArticleSection: '',
ogArticleTags: '',
schemas: [],
}
#Uneditable Properties
Name | Description |
---|---|
_id | Assigned by MercuryCMS when the RepoPage is created |
managedByAddonId | All of your created RepoPages have this automatically added so they can be removed when the Addon is uninstalled |
createdAt | JavaScript Date the RepoPage was created |
updatedAt | JavaScript Date the RepoPage was last modified |
#Basic Properties
Name | Description |
---|---|
title | The RepoPage's Title used in the <title> tag in the generated page's <head> |
type | The RepoPage's Type. This can be '' for normal Pages, '404' for 404s, or '500' for 500 pages. Default is '' |
path | The path of the RepoPage. The user will likely change this path. Example: /path/to/page . For 404 and 500 pages, this will be a regex to match against the path |
description | Optional, but you should always provide a description of what the RepoPage does |
layoutName | If provided, the created Page will use the RepoLayout provided by your Addon with this name |
isEnabled | Set to false to disable the Page |
#Body Properties
Name | Description |
---|---|
lang | Language to use for the body. Either "html" or "pug" . Default is "pug" |
body | Body HTML/Pug. This is meant to be further edited by the user after they create a Page from this RepoPage, so don't use minification |
#Style Properties
Name | Description |
---|---|
styleLang | Language to use for the style. Either "css" or "stylus" . Default is "stylus" |
style | Style CSS/Stylus. This is meant to be further edited by the user after they create a Page from this RepoPage, so don't use minification |
#Tags
This is a list of Tags in the order they should be added to the Page. See Tags for more information.
Name | Description |
---|---|
name | The name of the Tag. For example: "Google Analytics" |
location | One of "head" , "bodyStart" , or "bodyEnd" . Default is "head" |
lang | The language of the tag body. Either "pug" or "html" . Default is "html" |
body | The HTML/Pug body of the Tag |
#Scripts
Name | Description |
---|---|
script | The script to be used on the Page |
usesDataScript | When true , the Build system will use the RepoPage's dataScript to determine dynamic data and paths. Otherwise dataScript is ignored |
dataScript | The script used to create determine the data for use in the Page's markup |
#SEO Properties
Many of a RepoPage's SEO properties relate to Open Graph.
Name | Description |
---|---|
favicon | A Media ID to use for the Page's favicon |
noindex | When true , tell robots not to index the Page |
nofollow | When true , tell robots not to follow links on the Page |
canonicalUrl | The RepoPage's canonical URL |
ogType | The RepoPage's Open Graph type. Either article , book , music.album , music.playlist , profile , music.radio_station , music.song , video.episode , video.movie , video.other , video.tv_show , or website . Default is website |
ogTitle | The RepoPage's Open Graph title |
ogImages | A list of paths or URLs for the RepoPage's Open Graph images as a comma-separated string |
ogDescription | The RepoPage's Open Graph description |
ogArticleAuthors | The RepoPage's Open Graph authors. Only applies if ogType is article |
ogArticlePublishedTime | The RepoPage's Open Graph published time. This will generally be a generated value using Templating. Only applies if ogType is article |
ogArticleModifiedTime | The RepoPage's Open Graph modified time. This will generally be a generated value using Templating. Only applies if ogType is article |
ogArticleExpirationTime | The RepoPage's Open Graph expiration time. This will generally be a generated value using Templating. Only applies if ogType is article |
ogArticleSection | The RepoPage's Open Graph article section (article category like "Technology"). Only applies if ogType is article |
ogArticleTags | The RepoPage's Open Graph tags (keywords) as a comma-separated string. Only applies if ogType is article |
schemas | An array of Rich Snippets to add to the page. See Rich Snippets |
#Authoring Addon RepoPages
Trying to write body
, style
, and script
within your code is very difficult. It is recommended you first write and test the Page in MercuryCMS, then export it as a zip. You can then include the exported page.zip
file in your Addon Package as a RepoPage.
#Creating RepoPages
You can create RepoPages using cms.upsertRepoPage()
.
let repoPageDef = {
title: 'My Page',
path: '/my-page',
description: 'A Demo Page',
layoutName: 'My Layout',
body: '.my-page\n This is my demo page!',
style: ".my-page\n color {{ addons['demo-addon'].mainColor }}",
}
// use static-cms-addon
import cms from 'static-cms-addon'
let repoPage = await cms.upsertRepoPage({title: 'My Page'}, repoPageDef)
console.log(repoPage._id) // "63a0db9dd37c3735b468e1f8"
// use axios
let response = await axios.post(`http://localhost:${cmsPort}/api/addon/${addonId}/repopage`, {match: {title: 'My Page'}, repoPage: repoPageDef})
console.log(response.data.repoPage._id) // "63a0db9dd37c3735b468e1f8"
You can also load the RepoPage from a zip using cms.loadRepoPagePackage()
.
let repoPageDef = cms.loadRepoPagePackage('repoPages/myPage.page.zip').page
let repoPage = await cms.upsertRepoPage({title: repoPageDef.title}, repoPageDef)
#Listing RepoPages
You can use cms.getRepoPages()
to get a list of the RepoPages your Addon has created.
// use static-cms-addon
import cms from 'static-cms-addon'
let repoPages = await cms.getRepoPages()
console.log(repoPages.map(repoPage => repoPage.title)) // ['My Page', 'Another Page']
// use axios
let response = await axios.get(`http://localhost:${cmsPort}/api/addon/${addonId}/repopage`)
console.log(response.data.repoPages.map(repoPage => repoPage.title)) // ['My Page', 'Another Page']
#Deleting RepoPages
You can use cms.deleteRepoPages()
to delete RepoPages your Addon has created.
// use static-cms-addon
import cms from 'static-cms-addon'
let repoPages = await cms.getRepoPages()
let repoPage = repoPages.find(repoPage => repoPage.title == 'My Page')
await cms.deleteRepoPages([repoPage._id])
// use axios
let response = await axios.get(`http://localhost:${cmsPort}/api/addon/${addonId}/repopage`)
let repoPage = response.data.repoPages.find(repoPage => repoPage.title == 'My Page')
await axios.post(`http://localhost:${cmsPort}/api/addon/${addonId}/repopage/delete`, {repoPageIds: [repoPage._id]})
#RepoLayout Schema
{
// uneditable properties
_id: '63a0db9dd37c3735b468e1f8',
managedByAddonId: '639b8f837f5fb8a39404280a',
updatedAt: 1671486365027,
createdAt: 1671486531695,
// basic properties
name: '',
description: '',
// body properties
lang: 'pug',
body: '',
// style properties
styleLang: 'stylus',
style: '',
// tags
tags: [],
// scripts
script: '',
// seo
favicon: '',
schemas: [],
}
#Uneditable Properties
Name | Description |
---|---|
_id | Assigned by MercuryCMS when the RepoLayout is created |
managedByAddonId | All of your created RepoLayouts have this automatically added so they can be removed when the Addon is uninstalled |
createdAt | JavaScript Date the RepoLayout was created |
updatedAt | JavaScript Date the RepoLayout was last modified |
#Basic Properties
Name | Description |
---|---|
name | The RepoLayout's name |
description | Optional, but you should always provide a description of what the RepoLayout does |
#Body Properties
Name | Description |
---|---|
lang | Language to use for the body. Either "html" or "pug" . Default is "pug" |
body | Body HTML/Pug. This is meant to be further edited by the user after they create a Layout from this RepoLayout, so don't use minification |
#Style Properties
Name | Description |
---|---|
styleLang | Language to use for the style. Either "css" or "stylus" . Default is "stylus" |
style | Style CSS/Stylus. This is meant to be further edited by the user after they create a Layout from this RepoLayout, so don't use minification |
#Tags
This is a list of Tags in the order they should be added to any Page that uses this RepoLayout. See Tags for more information.
Name | Description |
---|---|
name | The name of the Tag. For example: "Google Analytics" |
location | One of "head" , "bodyStart" , or "bodyEnd" . Default is "head" |
lang | The language of the tag body. Either "pug" or "html" . Default is "html" |
body | The HTML/Pug body of the Tag |
#Scripts
Name | Description |
---|---|
script | The script to be used on any Page that uses this RepoLayout |
#SEO
Name | Description |
---|---|
favicon | A Media ID to use as a favicon for any Page that uses this Layout |
schemas | An array of Rich Snippets to add to Pages that use this Layout. See Rich Snippets |
#Authoring Addon RepoLayouts
Trying to write body
, style
, and script
within your code is very difficult. It is recommended you first write and test the Layout in MercuryCMS, then export it as a zip. You can then include the exported layout.zip
file in your Addon Package as a RepoLayout.
#Creating RepoLayouts
You can create RepoLayouts using cms.upsertRepoLayout()
.
let repoLayoutDef = {
name: 'My Layout',
description: 'A Demo Layout',
body: 'doctype html\nhtml\n head\n meta(charset="utf-8")\n title #{ page.title }\n body\n .my-layout !{ page.body }',
style: ".my-layout\n color {{ addons['demo-addon'].mainColor }}",
}
// use static-cms-addon
import cms from 'static-cms-addon'
let repoLayout = await cms.upsertRepoLayout({name: 'My Layout'}, repoLayoutDef)
console.log(repoLayout._id) // "63a0db9dd37c3735b468e1f8"
// use axios
let response = await axios.post(`http://localhost:${cmsPort}/api/addon/${addonId}/repolayout`, {match: {name: 'My Layout'}, repoLayout: repoLayoutDef})
console.log(response.data.repoLayout._id) // "63a0db9dd37c3735b468e1f8"
You can also load the RepoLayout from a zip using cms.loadRepoLayoutPackage()
.
let repoLayoutDef = cms.loadRepoLayoutPackage('repoPages/myLayout.layout.zip').layout
let repoLayout = await cms.createRepoLayout({name: repoLayoutDef.name}, repoLayoutDef)
#Listing RepoLayouts
You can use cms.getRepoLayouts()
to get a list of the RepoLayouts your Addon has created.
// use static-cms-addon
import cms from 'static-cms-addon'
let repoLayouts = await cms.getRepoLayouts()
console.log(repoLayouts.map(repoLayout => repoLayout.name)) // ['My Layout', 'Another Layout']
// use axios
let response = await axios.get(`http://localhost:${cmsPort}/api/addon/${addonId}/repolayout`)
console.log(response.data.repoLayouts.map(repoLayout => repoLayout.name)) // ['My Layout', 'Another Layout']
#Deleting RepoLayouts
You can use cms.deleteRepoLayouts()
to delete RepoLayouts your Addon has created.
// use static-cms-addon
import cms from 'static-cms-addon'
let repoLayouts = await cms.getRepoLayouts()
let repoLayout = repoLayouts.find(repoLayout => repoLayout.name == 'My Layout')
await cms.deleteRepoLayouts([repoLayout._id])
// use axios
let response = await axios.get(`http://localhost:${cmsPort}/api/addon/${addonId}/repolayout`)
let repoLayout = response.data.repoLayouts.find(repoLayout => repoLayout.name == 'My Layout')
await axios.post(`http://localhost:${cmsPort}/api/addon/${addonId}/repolayout/delete`, {repoLayoutIds: [repoLayout._id]})
#User Modification
Unlike Components and other things your Addon manages. With RepoPages and RepoLayouts, you are not managing Pages and Layouts. You are managing RepoPages and RepoLayouts, which the user may or may not choose to use as examples to build their own Pages and Layouts.
The user may choose not to use your RepoPages and RepoLayouts at all, or they may decide to use some of your RepoPages as starting points for building their own Pages. Many times, they will incorporate your RepoPages into their own Layouts to match the rest of their Site. Because of this, it's important not to design RepoPages that are dependent on specific Layouts.
#Rich Snippets
For details about adding Rich Snippets to Pages and Layouts, see Rich Snippets.