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' })
|
||||
const express = require('express')
|
||||
const url = require('url')
|
||||
const querystring = require('querystring')
|
||||
const path = require('path')
|
||||
const helpers = require('./helpers')
|
||||
// const favicon = require('serve-favicon')
|
||||
@@ -34,21 +34,34 @@ app.use(breadcrumb())
|
||||
|
||||
// Pass our application state and custom helpers to all our templates
|
||||
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
|
||||
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
|
||||
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 })
|
||||
}
|
||||
|
||||
@@ -86,6 +99,15 @@ app.use(async function (req, res, next) {
|
||||
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()
|
||||
})
|
||||
|
||||
|
||||
@@ -25,13 +25,7 @@ async function renderSettings (res, opts) {
|
||||
|
||||
/* GET settings page. */
|
||||
router.get('/', catchErrors(async function (req, res, next) {
|
||||
const cookie = req.cookies.theExampleAppSettings
|
||||
const settings = cookie || {
|
||||
space: process.env.CF_SPACE,
|
||||
cda: process.env.CF_ACCESS_TOKEN,
|
||||
cpa: process.env.CF_PREVIEW_ACCESS_TOKEN
|
||||
}
|
||||
|
||||
const { settings } = res.locals
|
||||
await renderSettings(res, {
|
||||
settings
|
||||
})
|
||||
@@ -40,8 +34,13 @@ router.get('/', catchErrors(async function (req, res, next) {
|
||||
/* POST settings page. */
|
||||
router.post('/', catchErrors(async function (req, res, next) {
|
||||
const errorList = []
|
||||
const { space, cda, cpa } = req.body
|
||||
const settings = {space, cda, cpa}
|
||||
const { space, cda, cpa, editorialFeatures } = req.body
|
||||
const settings = {
|
||||
space,
|
||||
cda,
|
||||
cpa,
|
||||
editorialFeatures: !!editorialFeatures
|
||||
}
|
||||
|
||||
// Validate required fields.
|
||||
if (!space) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
extends layout
|
||||
|
||||
include mixins/_breadcrumb
|
||||
include mixins/_editorialFeatures
|
||||
include mixins/_lesson
|
||||
|
||||
block content
|
||||
@@ -25,6 +26,7 @@ block content
|
||||
else
|
||||
.course
|
||||
h1.course__title= course.fields.title
|
||||
+editorialFeatures(course)
|
||||
.course__overview
|
||||
h3.course__overview-title Overview
|
||||
if course.fields.duration
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
extends layout
|
||||
|
||||
include mixins/_breadcrumb
|
||||
include mixins/_editorialFeatures
|
||||
include mixins/_moduleCopy
|
||||
include mixins/_moduleHeroImage
|
||||
include mixins/_moduleHighlightedCourse
|
||||
|
||||
block content
|
||||
if currentPath !== '/'
|
||||
.layout-centered
|
||||
+breadcrumb
|
||||
.layout-centered
|
||||
+editorialFeatures(landingPage)
|
||||
.modules-container
|
||||
if currentPath !== '/'
|
||||
.layout-centered
|
||||
+breadcrumb
|
||||
each module in landingPage.fields.contentModules
|
||||
case module.sys.contentType.sys.id
|
||||
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 _lessonModuleCopy
|
||||
include _lessonModuleImage
|
||||
@@ -5,23 +6,24 @@ include _lessonModuleImage
|
||||
mixin lesson(lesson, course, nextLesson)
|
||||
.lesson
|
||||
h1.lesson__title #{lesson.fields.title}
|
||||
div.lesson__short-description !{helpers.markdown(lesson.fields.description)}
|
||||
+editorialFeatures(lesson)
|
||||
if lesson.fields.image
|
||||
img.lesson__image(src=`${lesson.fields.image.fields.file.url}` alt=`${lesson.fields.image.fields.title}`)
|
||||
each module in lesson.fields.modules
|
||||
if module.sys.contentType
|
||||
case module.sys.contentType.sys.id
|
||||
when 'lessonCodeSnippets'
|
||||
+lessonModuleCodeSnippet(module)
|
||||
when 'lessonCopy'
|
||||
+lessonModuleCopy(module)
|
||||
when 'lessonModuleImage'
|
||||
+lessonImage(module)
|
||||
else
|
||||
h2 ️️⚠️ Invalid lesson module
|
||||
p
|
||||
span Could not determine type of
|
||||
strong #{module.sys.id}
|
||||
.lesson__modules
|
||||
each module in lesson.fields.modules
|
||||
if module.sys.contentType
|
||||
case module.sys.contentType.sys.id
|
||||
when 'lessonCodeSnippets'
|
||||
+lessonModuleCodeSnippet(module)
|
||||
when 'lessonCopy'
|
||||
+lessonModuleCopy(module)
|
||||
when 'lessonModuleImage'
|
||||
+lessonImage(module)
|
||||
else
|
||||
h2 ️️⚠️ Invalid lesson module
|
||||
p
|
||||
span Could not determine type of
|
||||
strong #{module.sys.id}
|
||||
if nextLesson
|
||||
a.lesson__cta.cta(href=`/courses/${course.fields.slug}/lessons/${nextLesson.fields.slug}${queryString}`) View next lesson
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ mixin moduleCopy(module)
|
||||
.module
|
||||
div(class=`module-copy${style}`)
|
||||
div(class=`module-copy__first${style}`)
|
||||
h1(class=`module-copy__headline${style}`) #{module.fields.headline}
|
||||
if 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__second${style}`)
|
||||
if module.fields.ctaTitle && module.fields.ctaLink
|
||||
|
||||
@@ -39,23 +39,24 @@ block content
|
||||
|
||||
form(action=`/settings` method="POST" class="form")
|
||||
.form-item
|
||||
label(for="space") Space ID
|
||||
input(type="text" name="space" value=settings.space)
|
||||
label(for="input-space") Space ID
|
||||
input(type="text" name="space" id="input-space" value=settings.space)
|
||||
if 'space' in errors
|
||||
+renderErrors(errors.space)
|
||||
.form-item__help-text The Space ID is a unique identifier for your space.
|
||||
|
||||
.form-item
|
||||
label(for="cda") Content Delivery API - access token
|
||||
input(type="text" name="cda" value=settings.cda)
|
||||
label(for="input-cda") Content Delivery API - access token
|
||||
input(type="text" name="cda" id="input-cda" value=settings.cda)
|
||||
if 'cda' in errors
|
||||
+renderErrors(errors.cda)
|
||||
.form-item__help-text
|
||||
| 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.
|
||||
|
||||
.form-item
|
||||
label(for="cpa") Content Preview API - access token
|
||||
input(type="text" name="cpa" value=settings.cpa)
|
||||
label(for="input-cpa") Content Preview API - access token
|
||||
input(type="text" name="cpa" id="input-cpa" value=settings.cpa)
|
||||
if 'cpa' in errors
|
||||
+renderErrors(errors.cpa)
|
||||
.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.
|
||||
|
||||
.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