feat(editors): add editorial features aka the configurable edit link
This commit is contained in:
committed by
Benedikt Rötsch
parent
bf50c66df4
commit
240e008a87
46
app.js
46
app.js
@@ -1,6 +1,6 @@
|
|||||||
require('dotenv').config({ path: 'variables.env' })
|
require('dotenv').config({ path: 'variables.env' })
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const url = require('url')
|
const querystring = require('querystring')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const helpers = require('./helpers')
|
const helpers = require('./helpers')
|
||||||
// const favicon = require('serve-favicon')
|
// const favicon = require('serve-favicon')
|
||||||
@@ -34,21 +34,34 @@ app.use(breadcrumb())
|
|||||||
|
|
||||||
// Pass our application state and custom helpers to all our templates
|
// Pass our application state and custom helpers to all our templates
|
||||||
app.use(async function (req, res, next) {
|
app.use(async function (req, res, next) {
|
||||||
// Inject custom helpers
|
|
||||||
res.locals.helpers = helpers
|
|
||||||
|
|
||||||
// Express query string
|
|
||||||
const qs = url.parse(req.url).query
|
|
||||||
res.locals.queryString = qs ? `?${qs}` : ''
|
|
||||||
res.locals.query = req.query
|
|
||||||
res.locals.currentPath = req.path
|
|
||||||
|
|
||||||
// Allow setting of API credentials via query parameters
|
// Allow setting of API credentials via query parameters
|
||||||
let settings = req.cookies.theExampleAppSettings
|
let settings = {
|
||||||
|
space: process.env.CF_SPACE,
|
||||||
|
cda: process.env.CF_ACCESS_TOKEN,
|
||||||
|
cpa: process.env.CF_PREVIEW_ACCESS_TOKEN,
|
||||||
|
editorialFeatures: false,
|
||||||
|
...req.cookies.theExampleAppSettings
|
||||||
|
}
|
||||||
|
|
||||||
const { space_id, preview_access_token, delivery_access_token } = req.query
|
const { space_id, preview_access_token, delivery_access_token } = req.query
|
||||||
if (space_id && preview_access_token && delivery_access_token) { // eslint-disable-line camelcase
|
if (space_id && preview_access_token && delivery_access_token) { // eslint-disable-line camelcase
|
||||||
settings = {space: space_id, cda: delivery_access_token, cpa: preview_access_token}
|
settings = {
|
||||||
|
...settings,
|
||||||
|
space: space_id,
|
||||||
|
cda: delivery_access_token,
|
||||||
|
cpa: preview_access_token
|
||||||
|
}
|
||||||
|
res.cookie('theExampleAppSettings', settings, { maxAge: 900000, httpOnly: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow enabling of editorial features via query parameters
|
||||||
|
const { enable_editorial_features } = req.query
|
||||||
|
if (enable_editorial_features !== undefined) { // eslint-disable-line camelcase
|
||||||
|
delete req.query.enable_editorial_features
|
||||||
|
settings = {
|
||||||
|
...settings,
|
||||||
|
editorialFeatures: true
|
||||||
|
}
|
||||||
res.cookie('theExampleAppSettings', settings, { maxAge: 900000, httpOnly: true })
|
res.cookie('theExampleAppSettings', settings, { maxAge: 900000, httpOnly: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +99,15 @@ app.use(async function (req, res, next) {
|
|||||||
res.locals.currentLocale = defaultLocale
|
res.locals.currentLocale = defaultLocale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inject custom helpers
|
||||||
|
res.locals.helpers = helpers
|
||||||
|
|
||||||
|
// Make query string available in templates
|
||||||
|
const qs = querystring.stringify(req.query)
|
||||||
|
res.locals.queryString = qs ? `?${qs}` : ''
|
||||||
|
res.locals.query = req.query
|
||||||
|
res.locals.currentPath = req.path
|
||||||
|
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,7 @@ async function renderSettings (res, opts) {
|
|||||||
|
|
||||||
/* GET settings page. */
|
/* GET settings page. */
|
||||||
router.get('/', catchErrors(async function (req, res, next) {
|
router.get('/', catchErrors(async function (req, res, next) {
|
||||||
const cookie = req.cookies.theExampleAppSettings
|
const { settings } = res.locals
|
||||||
const settings = cookie || {
|
|
||||||
space: process.env.CF_SPACE,
|
|
||||||
cda: process.env.CF_ACCESS_TOKEN,
|
|
||||||
cpa: process.env.CF_PREVIEW_ACCESS_TOKEN
|
|
||||||
}
|
|
||||||
|
|
||||||
await renderSettings(res, {
|
await renderSettings(res, {
|
||||||
settings
|
settings
|
||||||
})
|
})
|
||||||
@@ -40,8 +34,13 @@ router.get('/', catchErrors(async function (req, res, next) {
|
|||||||
/* POST settings page. */
|
/* POST settings page. */
|
||||||
router.post('/', catchErrors(async function (req, res, next) {
|
router.post('/', catchErrors(async function (req, res, next) {
|
||||||
const errorList = []
|
const errorList = []
|
||||||
const { space, cda, cpa } = req.body
|
const { space, cda, cpa, editorialFeatures } = req.body
|
||||||
const settings = {space, cda, cpa}
|
const settings = {
|
||||||
|
space,
|
||||||
|
cda,
|
||||||
|
cpa,
|
||||||
|
editorialFeatures: !!editorialFeatures
|
||||||
|
}
|
||||||
|
|
||||||
// Validate required fields.
|
// Validate required fields.
|
||||||
if (!space) {
|
if (!space) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
extends layout
|
extends layout
|
||||||
|
|
||||||
include mixins/_breadcrumb
|
include mixins/_breadcrumb
|
||||||
|
include mixins/_editorialFeatures
|
||||||
include mixins/_lesson
|
include mixins/_lesson
|
||||||
|
|
||||||
block content
|
block content
|
||||||
@@ -25,6 +26,7 @@ block content
|
|||||||
else
|
else
|
||||||
.course
|
.course
|
||||||
h1.course__title= course.fields.title
|
h1.course__title= course.fields.title
|
||||||
|
+editorialFeatures(course)
|
||||||
.course__overview
|
.course__overview
|
||||||
h3.course__overview-title Overview
|
h3.course__overview-title Overview
|
||||||
if course.fields.duration
|
if course.fields.duration
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
extends layout
|
extends layout
|
||||||
|
|
||||||
include mixins/_breadcrumb
|
include mixins/_breadcrumb
|
||||||
|
include mixins/_editorialFeatures
|
||||||
include mixins/_moduleCopy
|
include mixins/_moduleCopy
|
||||||
include mixins/_moduleHeroImage
|
include mixins/_moduleHeroImage
|
||||||
include mixins/_moduleHighlightedCourse
|
include mixins/_moduleHighlightedCourse
|
||||||
|
|
||||||
block content
|
block content
|
||||||
.modules-container
|
|
||||||
if currentPath !== '/'
|
if currentPath !== '/'
|
||||||
.layout-centered
|
.layout-centered
|
||||||
+breadcrumb
|
+breadcrumb
|
||||||
|
.layout-centered
|
||||||
|
+editorialFeatures(landingPage)
|
||||||
|
.modules-container
|
||||||
each module in landingPage.fields.contentModules
|
each module in landingPage.fields.contentModules
|
||||||
case module.sys.contentType.sys.id
|
case module.sys.contentType.sys.id
|
||||||
when 'layoutCopy'
|
when 'layoutCopy'
|
||||||
|
|||||||
13
views/mixins/_editorialFeatures.pug
Normal file
13
views/mixins/_editorialFeatures.pug
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
mixin editorialFeatures(entry)
|
||||||
|
if settings.editorialFeatures
|
||||||
|
.editorial-features
|
||||||
|
.editorial-features__item
|
||||||
|
a.editorial-features__text(
|
||||||
|
href=`https://app.contentful.com/spaces/${settings.space}/entries/${entry.sys.id}`
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener'
|
||||||
|
) Edit in the web app
|
||||||
|
.editorial-features__hint-wrapper
|
||||||
|
svg.editorial-features__hint-icon
|
||||||
|
use(xlink:href='/icons/icons.svg#info')
|
||||||
|
.editorial-features__hint-message Edit this entry in our web app. You have to be logged in and have access to the connected space to use this feature.
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
include _editorialFeatures
|
||||||
include _lessonModuleCodeSnippet
|
include _lessonModuleCodeSnippet
|
||||||
include _lessonModuleCopy
|
include _lessonModuleCopy
|
||||||
include _lessonModuleImage
|
include _lessonModuleImage
|
||||||
@@ -5,9 +6,10 @@ include _lessonModuleImage
|
|||||||
mixin lesson(lesson, course, nextLesson)
|
mixin lesson(lesson, course, nextLesson)
|
||||||
.lesson
|
.lesson
|
||||||
h1.lesson__title #{lesson.fields.title}
|
h1.lesson__title #{lesson.fields.title}
|
||||||
div.lesson__short-description !{helpers.markdown(lesson.fields.description)}
|
+editorialFeatures(lesson)
|
||||||
if lesson.fields.image
|
if lesson.fields.image
|
||||||
img.lesson__image(src=`${lesson.fields.image.fields.file.url}` alt=`${lesson.fields.image.fields.title}`)
|
img.lesson__image(src=`${lesson.fields.image.fields.file.url}` alt=`${lesson.fields.image.fields.title}`)
|
||||||
|
.lesson__modules
|
||||||
each module in lesson.fields.modules
|
each module in lesson.fields.modules
|
||||||
if module.sys.contentType
|
if module.sys.contentType
|
||||||
case module.sys.contentType.sys.id
|
case module.sys.contentType.sys.id
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ mixin moduleCopy(module)
|
|||||||
.module
|
.module
|
||||||
div(class=`module-copy${style}`)
|
div(class=`module-copy${style}`)
|
||||||
div(class=`module-copy__first${style}`)
|
div(class=`module-copy__first${style}`)
|
||||||
|
if module.fields.headline
|
||||||
h1(class=`module-copy__headline${style}`) #{module.fields.headline}
|
h1(class=`module-copy__headline${style}`) #{module.fields.headline}
|
||||||
div(class=`module-copy__copy${style}`) !{helpers.markdown(module.fields.copy)}
|
div(class=`module-copy__copy${style}`) !{helpers.markdown(module.fields.copy)}
|
||||||
div(class=`module-copy__second${style}`)
|
div(class=`module-copy__second${style}`)
|
||||||
|
|||||||
@@ -39,23 +39,24 @@ block content
|
|||||||
|
|
||||||
form(action=`/settings` method="POST" class="form")
|
form(action=`/settings` method="POST" class="form")
|
||||||
.form-item
|
.form-item
|
||||||
label(for="space") Space ID
|
label(for="input-space") Space ID
|
||||||
input(type="text" name="space" value=settings.space)
|
input(type="text" name="space" id="input-space" value=settings.space)
|
||||||
if 'space' in errors
|
if 'space' in errors
|
||||||
+renderErrors(errors.space)
|
+renderErrors(errors.space)
|
||||||
.form-item__help-text The Space ID is a unique identifier for your space.
|
.form-item__help-text The Space ID is a unique identifier for your space.
|
||||||
|
|
||||||
.form-item
|
.form-item
|
||||||
label(for="cda") Content Delivery API - access token
|
label(for="input-cda") Content Delivery API - access token
|
||||||
input(type="text" name="cda" value=settings.cda)
|
input(type="text" name="cda" id="input-cda" value=settings.cda)
|
||||||
if 'cda' in errors
|
if 'cda' in errors
|
||||||
+renderErrors(errors.cda)
|
+renderErrors(errors.cda)
|
||||||
.form-item__help-text
|
.form-item__help-text
|
||||||
| View published content using this API.
|
| View published content using this API.
|
||||||
a(href='https://www.contentful.com/developers/docs/references/content-delivery-api/' target='_blank' rel='noopener') Content Delivery API.
|
a(href='https://www.contentful.com/developers/docs/references/content-delivery-api/' target='_blank' rel='noopener') Content Delivery API.
|
||||||
|
|
||||||
.form-item
|
.form-item
|
||||||
label(for="cpa") Content Preview API - access token
|
label(for="input-cpa") Content Preview API - access token
|
||||||
input(type="text" name="cpa" value=settings.cpa)
|
input(type="text" name="cpa" id="input-cpa" value=settings.cpa)
|
||||||
if 'cpa' in errors
|
if 'cpa' in errors
|
||||||
+renderErrors(errors.cpa)
|
+renderErrors(errors.cpa)
|
||||||
.form-item__help-text
|
.form-item__help-text
|
||||||
@@ -63,4 +64,11 @@ block content
|
|||||||
a(href='https://www.contentful.com/developers/docs/references/content-preview-api/' target='_blank' rel='noopener') Content Preview API.
|
a(href='https://www.contentful.com/developers/docs/references/content-preview-api/' target='_blank' rel='noopener') Content Preview API.
|
||||||
|
|
||||||
.form-item
|
.form-item
|
||||||
input.cta(type="submit" value="Load settings")
|
input(type="checkbox" name="editorialFeatures" id="input-editorial-features" checked=settings.editorialFeatures)
|
||||||
|
label(for="input-editorial-features") Enable editorial features
|
||||||
|
if 'cpa' in errors
|
||||||
|
+renderErrors(errors.cpa)
|
||||||
|
.form-item__help-text Enable to display an edit link and other contextual helpers for authors. You need to have access to the connected space to make this work.
|
||||||
|
|
||||||
|
.form-item
|
||||||
|
input.cta(type="submit" value="Save settings")
|
||||||
|
|||||||
Reference in New Issue
Block a user