From e7175d2b76d2d2da3a000b46e250085ac4f4aa4f Mon Sep 17 00:00:00 2001 From: Sam Carlton Date: Sat, 20 Mar 2021 16:21:22 -0500 Subject: [PATCH] Pull base story layout from layout file --- layouts-eleventy/default.11ty.js | 62 ++++- layouts-eleventy/story.11ty.js | 184 +++++++++++++ pages-eleventy/story.11ty.js | 457 +++++++------------------------ 3 files changed, 331 insertions(+), 372 deletions(-) create mode 100644 layouts-eleventy/story.11ty.js diff --git a/layouts-eleventy/default.11ty.js b/layouts-eleventy/default.11ty.js index 3a32b14..9d7e71a 100644 --- a/layouts-eleventy/default.11ty.js +++ b/layouts-eleventy/default.11ty.js @@ -9,14 +9,18 @@ console.log('Running Default Layout file') const year = new Date().getFullYear() -const makeTag = ( tag, tagName = 'meta') => { +export function makeFullUrlFromPath ( path ) { + return `${process.env.URL}${path}` +} + +export const makeTag = ( tag, tagName = 'meta') => { const attributes = Object.entries(tag).map( ([ name, value ]) => `${name}="${value}"` ).join(' ') return `<${tagName} ${attributes}>` } -const mapMetaTag = ( tag ) => { +export const mapMetaTag = ( tag ) => { if ( tag.hasOwnProperty('property') ) { return [ @@ -40,7 +44,7 @@ const mapMetaTag = ( tag ) => { } } -const mapLinkTag = ( tag ) => { +export const mapLinkTag = ( tag ) => { return [ `type-${tag.type}`, makeTag(tag, 'link') @@ -54,12 +58,29 @@ const getNuxtDefaultLayoutHtml = () => { return fileContents } -const templateVar = string => `--- template-var ${string} ---` +export const templateVar = ( string, asComment = true ) => { + if ( asComment === false ) { + return `-- template-var ${string} --` + } -const cleanNuxtLayout = ( layout ) => { + return `` +} + +const cleanNuxtLayout = ( layout, options ) => { + + const { + excludedElements = [], + replaceElements = {} + } = options const document = layout.window.document + excludedElements.forEach( selector => { + Array.from( document.querySelectorAll(selector) ).forEach( domNode => { + domNode.remove() + }) + }) + // Strip out existing meta Array.from(document.querySelectorAll('head > meta')).forEach( domNode => { domNode.remove() @@ -89,7 +110,7 @@ const cleanNuxtLayout = ( layout ) => { // Set page title - document.title = templateVar('title') + document.title = templateVar('title', false) // Set link tags document.querySelector('title').insertAdjacentHTML('afterend', templateVar('link-tags') ) @@ -100,6 +121,12 @@ const cleanNuxtLayout = ( layout ) => { // Set page css // document.querySelector('head').insertAdjacentHTML('beforeend', this.getCss() ) + // Set header-scripts placeholder + document.querySelector('title').insertAdjacentHTML('afterend', templateVar('header-scripts') ) + + // Set header-styles placeholder + document.querySelector('title').insertAdjacentHTML('afterend', templateVar('header-styles') ) + // Set page content document.querySelector('.app-main').innerHTML = templateVar('main-content')//content @@ -107,11 +134,28 @@ const cleanNuxtLayout = ( layout ) => { // `` document.querySelector('body').insertAdjacentHTML('beforeend', templateVar('scripts') ) + + // Run additional replacements + for ( const selector in replaceElements ) { + // console.log('domNode', selector, document.querySelector( selector ), replaceElements[ selector ]) + + Array.from( document.querySelectorAll( selector ) ).forEach( domNode => { + // console.log('domNode', domNode, replaceElements[ selector ]) + domNode.outerHTML = replaceElements[ selector ] + }) + } + return layout } let nuxtLayoutHtml = null -const parseDefaultLayoutDom = () => { +export const parseDefaultLayoutDom = ( options = {} ) => { + + // const { + // excludedElements = [], + // replaceElements = {} + // } = options + if ( nuxtLayoutHtml === null ) { nuxtLayoutHtml = getNuxtDefaultLayoutHtml() } @@ -120,7 +164,7 @@ const parseDefaultLayoutDom = () => { // Build initial dom from the Layout const dom = new JSDOM( nuxtLayoutHtml ) - const cleanedLayout = cleanNuxtLayout( dom ) + const cleanedLayout = cleanNuxtLayout( dom, options ) return cleanedLayout } @@ -201,7 +245,7 @@ class DefaultLayout { // Set page title // pageTitle - workingLayoutString = workingLayoutString.replace( templateVar('title'), pageTitle ) + workingLayoutString = workingLayoutString.replace( templateVar('title', false), pageTitle ) // Set link tags // this.generateLinkTags() diff --git a/layouts-eleventy/story.11ty.js b/layouts-eleventy/story.11ty.js new file mode 100644 index 0000000..0b9925c --- /dev/null +++ b/layouts-eleventy/story.11ty.js @@ -0,0 +1,184 @@ +import config from '../nuxt.config' +import { + makeFullUrlFromPath, + + mapMetaTag, + mapLinkTag, + parseDefaultLayoutDom, + templateVar +} from './default.11ty.js' + + +console.log('Running Story Layout file') + + +// Buld data that only needs to run once +const defaultMeta = Object.fromEntries(config.head.meta.map( mapMetaTag )) + +const defaultLinkTags = Object.fromEntries(config.head.link.map( mapLinkTag )) + +const masterLayoutDomString = parseDefaultLayoutDom({ + replaceElements: { + // Replace root nuxt element + // and get rid of normal layout + '#__nuxt': templateVar('main-content') + } +}).serialize() + +class StoryLayout { + + generateMetaTags = function ( renderData ) { + + const { + title = null, + description = null, + pageMeta = [] + } = renderData + + // https://amp.dev/documentation/components/amp-story/#metadata-guidelines + const meta = { + ...defaultMeta, + 'property-twitter:url': /* html */``, + 'amp-story-generator-name': /* html */``, + 'amp-story-generator-version': /* html */``, + + 'og:url': /* html */``, + 'twitter:creator': /* html */``, + 'title': /* html */``, + 'og:title': /* html */``, + // 'twitter:title': /* html */``, // Already included + + // Example: + 'og:modified_time': /* html */``, + + 'og:type': /* html */``, + + ...Object.fromEntries( pageMeta.map(mapMetaTag) ) + } + + // if set + // get description from data + if ( description ) { + // Set meta description + meta['name-description'] = `` + // Set twitter description + meta['property-twitter:description'] = `` + } + + // if set + // get title from data + if ( title ) { + // Set twitter title + meta['property-twitter:title'] = `` + } + + + return Object.values(meta).join('') + } + + generateLinkTags = ( pageLinkTags = [] ) => { + + const layoutLinkTags = { + ampCorePreload: /* html */``, + + icon: /* html */``, + canonical: /* html */``, + + ampYoutubeStylesheet: /* html */``, + } + + const linkTags = { + ...defaultLinkTags, + ...layoutLinkTags, + ...Object.fromEntries(pageLinkTags.map( mapLinkTag )) + } + + return Object.values( linkTags ).join('') + } + + defaultHeaderScripts = () => { + return { + ampCore: /* html */``, + ampStoryElement: /* html */``, + ampYoutubeElement: /* html */``, + } + } + + defaultHeaderStyleTags = () => { + return { + ampBoilerplate: /* html */``, + // ampCore: /* html */``, + } + } + + async render( data ) { + + // return nuxtLayoutHtml + + // console.log('Running StoryLayout render') + + const { + content, + title = null, + headerScripts = {}, + jsonLd + // description = null + } = data + + const pageTitle = title || this.getNuxt().head.title + + const headerScriptsHtml = Object.values( { + ...this.defaultHeaderScripts(), + jsonLd: /* html */`` + } ).join('') + + const headerStylesHtml = Object.values( { + ...this.defaultHeaderStyleTags() + } ).join('') + + let workingLayoutString = masterLayoutDomString + + // Set as an amp html document + workingLayoutString = workingLayoutString.replace( '${ this.getJs() }` + workingLayoutString = workingLayoutString.replace( templateVar('scripts'), `` ) + + + // Return stringified html for page + return workingLayoutString + + } +} + +module.exports = StoryLayout diff --git a/pages-eleventy/story.11ty.js b/pages-eleventy/story.11ty.js index 2b34840..fa7ba14 100644 --- a/pages-eleventy/story.11ty.js +++ b/pages-eleventy/story.11ty.js @@ -5,7 +5,12 @@ import config from '../nuxt.config.js' import { hasStory, getStoryEndpoint } from '../helpers/app-derived.js' import { makeLastUpdatedFriendly } from '../helpers/parse-date' +import { + makeFullUrlFromPath +} from '../layouts-eleventy/default.11ty.js' + import CoverPage from '../components-eleventy/story/cover.js' +import YoutubePage from '../components-eleventy/story/youtube.js' // import VideoRow from '../components-eleventy/video/row.js' @@ -24,10 +29,6 @@ export const makeDescription = function ( app ) { return `Reported status of ${ app.name } on Apple Silicon and the new Apple Macs. ` } -function makeFullUrlFromPath ( path ) { - return `${process.env.URL}${path}` -} - // https://stackoverflow.com/a/34015511/1397641 function makeJsonLdDate ( dateObject ) { return dateObject.toLocaleDateString('en-US') @@ -106,7 +107,7 @@ export class Story { // or `get data() {` data () { return { - // layout: 'default.11ty.js', + layout: 'story.11ty.js', pagination: { data: 'eleventy-endpoints', @@ -117,7 +118,9 @@ export class Story { return data.filter( entry => { // const appType = getAppType( entry.payload.app ) - return hasStory ( entry.payload.app ) && entry.route === getStoryEndpoint( entry.payload.app ) + // return hasStory ( entry.payload.app ) && entry.route === getStoryEndpoint( entry.payload.app ) + + return entry.route.includes('/photoshop/story/') }) } }, @@ -134,6 +137,8 @@ export class Story { mainHeading: ({ app: { payload: { app } } }) => { return `Does ${ app.name } work on Apple Silicon?` }, + jsonLd: data => makeJsonLdObject( data ), + lastUpdatedDate: data => new Date( data.app.payload.app.lastUpdated.raw ) }, permalink: ({ app }) => { @@ -164,11 +169,21 @@ export class Story { // Build cover page pages.push({ template: CoverPage, - heading: `${ app.name } has been reported to support Apple Silicon nativelty as of ${lastUpdatedFriendly}!`, + heading: `${ app.name } has been reported to support Apple Silicon natively as of ${lastUpdatedFriendly}!`, headingUrl: '', imageUrl: '/images/backgrounds/liquid-cheese.svg' }) + // console.log('app', app) + + if (Array.isArray( app.relatedVideos ) && app.relatedVideos.length > 0 ) { + app.relatedVideos.forEach( video => { + pages.push({ + template: YoutubePage, + videoId: 'dQw4w9WgXcQ' + }) + }) + } return pages } @@ -193,7 +208,7 @@ export class Story { // console.log('video.payload', Object.keys(video.payload)) const lastUpdatedFriendly = makeLastUpdatedFriendly( app.lastUpdated ) - const jsonLd = JSON.stringify( makeJsonLdObject( data ) ) + // const jsonLd = JSON.stringify( makeJsonLdObject( data ) ) const pages = this.buildPages( data ) @@ -202,373 +217,89 @@ export class Story { } ).join('') return /* html */` - - - - - - - - - - - - - - ${ pageTitle } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${ pagesHtml } + ${ pagesHtml } - - - - - - - -
- -

Ack has  been reported to support Apple Silicon nativelty as of ${lastUpdatedFriendly}!

- -
+ + + + + + + +
+ +

Ack has  been reported to support Apple Silicon natively as of ${lastUpdatedFriendly}!

+ +
-
- +
+ - - - - - - - -
- -

ack has will support Apple Silicon and take full advantage of new higher perfomance Macs. 

- -
+ + + + + + + +
+ +

ack has will support Apple Silicon and take full advantage of new higher perfomance Macs. 

+ +
-
- +
+ - - - - - - - -
- -

This will apply to ack version 3.0.2 and newer 

- -
+ + + + + + + +
+ +

This will apply to ack version 3.0.2 and newer 

+ +
-
- +
+ - - - - - - - -
- -

The best therapist has fur and four legs

- - + + + + + + + +
+ +

The best therapist has fur and four legs

+ + - -
- -
- Find More -
-
+ +
+ +
+ Find More +
+
-
- + + - - - - -
- - - + + + + + ` } }