mirror of
https://github.com/ThatGuySam/doesitarm.git
synced 2026-05-15 06:35:20 -07:00
259 lines
7.3 KiB
JavaScript
259 lines
7.3 KiB
JavaScript
import fs from 'fs'
|
|
import { JSDOM } from 'jsdom'
|
|
|
|
import config from '../nuxt.config.js'
|
|
|
|
|
|
console.log('Running Default Layout file')
|
|
|
|
|
|
const year = new Date().getFullYear()
|
|
|
|
const makeTag = ( tag, tagName = 'meta') => {
|
|
|
|
const attributes = Object.entries(tag).map( ([ name, value ]) => `${name}="${value}"` ).join(' ')
|
|
|
|
return `<${tagName} ${attributes}>`
|
|
}
|
|
|
|
const mapMetaTag = ( tag ) => {
|
|
|
|
if ( tag.hasOwnProperty('property') ) {
|
|
return [
|
|
`property-${tag.property}`,
|
|
makeTag(tag)
|
|
]
|
|
}
|
|
|
|
if ( tag.hasOwnProperty('name') ) {
|
|
return [
|
|
`name-${tag.name}`,
|
|
makeTag(tag)
|
|
]
|
|
}
|
|
|
|
if ( tag.hasOwnProperty('charset') ) {
|
|
return [
|
|
'charset',
|
|
makeTag(tag)
|
|
]
|
|
}
|
|
}
|
|
|
|
const mapLinkTag = ( tag ) => {
|
|
return [
|
|
`type-${tag.type}`,
|
|
makeTag(tag, 'link')
|
|
]
|
|
}
|
|
|
|
|
|
const getNuxtDefaultLayoutHtml = () => {
|
|
const fileContents = fs.readFileSync('./dist/layout-template/index.html', { encoding: "UTF-8" })
|
|
|
|
return fileContents
|
|
}
|
|
|
|
const templateVar = string => `--- template-var ${string} ---`
|
|
|
|
const cleanNuxtLayout = ( layout ) => {
|
|
|
|
const document = layout.window.document
|
|
|
|
// Strip out existing meta
|
|
Array.from(document.querySelectorAll('head > meta')).forEach( domNode => {
|
|
domNode.remove()
|
|
})
|
|
|
|
// Strip out existing preloads
|
|
Array.from(document.querySelectorAll('link[rel="preload"]')).forEach( domNode => {
|
|
domNode.remove()
|
|
})
|
|
|
|
// Strip out existing scripts
|
|
Array.from(document.querySelectorAll('script[src*=".js"]')).forEach( domNode => {
|
|
domNode.remove()
|
|
})
|
|
|
|
// Convert subscribe to iframe embed
|
|
Array.from(document.querySelectorAll('form.all-updates-subscribe')).forEach( domNode => {
|
|
const subscribeEmbed = document.createElement('iframe')
|
|
subscribeEmbed.setAttribute('data-src', '/embed-subscribe')
|
|
// https://web.dev/iframe-lazy-loading/
|
|
subscribeEmbed.setAttribute('loading', 'lazy')
|
|
subscribeEmbed.setAttribute('title', 'Get email updates')
|
|
subscribeEmbed.classList.add('lazyload')
|
|
subscribeEmbed.style.width = '350px'
|
|
subscribeEmbed.style.height = '150px'
|
|
|
|
domNode.parentNode.replaceChild(subscribeEmbed, domNode)
|
|
})
|
|
|
|
|
|
// Set page title
|
|
document.title = templateVar('title')
|
|
|
|
// Set link tags
|
|
document.querySelector('title').insertAdjacentHTML('afterend', templateVar('link-tags') )
|
|
|
|
// Add meta tags after title node
|
|
document.querySelector('title').insertAdjacentHTML('afterend', templateVar('structured-data') )
|
|
|
|
// Add meta tags after title node
|
|
document.querySelector('title').insertAdjacentHTML('afterend', templateVar('meta-tags') )
|
|
|
|
// Set page css
|
|
// document.querySelector('head').insertAdjacentHTML('beforeend', this.getCss() )
|
|
|
|
// Set page content
|
|
document.querySelector('.app-main').innerHTML = templateVar('main-content')//content
|
|
|
|
// Set js before end of body
|
|
// `<script>${ this.getJs() }</script>`
|
|
document.querySelector('body').insertAdjacentHTML('beforeend', templateVar('scripts') )
|
|
|
|
return layout
|
|
}
|
|
|
|
let nuxtLayoutHtml = null
|
|
const parseDefaultLayoutDom = () => {
|
|
if ( nuxtLayoutHtml === null ) {
|
|
nuxtLayoutHtml = getNuxtDefaultLayoutHtml()
|
|
}
|
|
// const html = getNuxtDefaultLayoutHtml()
|
|
|
|
// Build initial dom from the Layout
|
|
const dom = new JSDOM( nuxtLayoutHtml )
|
|
|
|
const cleanedLayout = cleanNuxtLayout( dom )
|
|
|
|
return cleanedLayout
|
|
}
|
|
|
|
// 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().serialize()
|
|
|
|
class DefaultLayout {
|
|
|
|
generateMetaTags = function ( renderData ) {
|
|
|
|
const {
|
|
title = null,
|
|
description = null,
|
|
meta: pageMeta = []
|
|
} = renderData
|
|
|
|
// console.log('renderData', Object.keys(renderData))
|
|
|
|
const meta = {
|
|
...defaultMeta,
|
|
'property-twitter:url': `<meta property="twitter:url" content="${process.env.URL}${this.page.url}">`,
|
|
...Object.fromEntries( pageMeta.map(mapMetaTag) )
|
|
}
|
|
|
|
// console.log('renderData.description', renderData.description)
|
|
|
|
// if set
|
|
// get description from data
|
|
if ( description ) {
|
|
// Set meta description
|
|
meta['name-description'] = `<meta hid="description" name="description" content="${ description }">`
|
|
// Set twitter description
|
|
meta['property-twitter:description'] = `<meta hid="twitter:description" property="twitter:description" content="${ description }">`
|
|
}
|
|
|
|
// if set
|
|
// get title from data
|
|
if ( title ) {
|
|
// Set twitter title
|
|
meta['property-twitter:title'] = `<meta hid="twitter:title" property="twitter:title" content="${ title }">`
|
|
}
|
|
|
|
|
|
return Object.values(meta).join('')
|
|
}
|
|
|
|
generateStructuredData = function ( renderData ) {
|
|
|
|
const {
|
|
structuredData = null
|
|
} = renderData
|
|
|
|
// console.log('renderData', Object.keys(renderData))
|
|
|
|
if ( structuredData === null ) return ''
|
|
|
|
const structuredDataJson = JSON.stringify( structuredData )
|
|
|
|
return `<script type="application/ld+json">${ structuredDataJson }</script>`
|
|
}
|
|
|
|
generateLinkTags = ( renderData ) => {
|
|
|
|
const {
|
|
headLinkTags = []
|
|
} = renderData
|
|
|
|
const linkTags = {
|
|
...defaultLinkTags,
|
|
...Object.fromEntries( headLinkTags.map( mapLinkTag ) )
|
|
}
|
|
|
|
return Object.values( linkTags ).join('')
|
|
}
|
|
|
|
|
|
async render( data ) {
|
|
|
|
// return nuxtLayoutHtml
|
|
|
|
// console.log('Running DefaultLayout render')
|
|
|
|
const {
|
|
content,
|
|
title = null,
|
|
// description = null
|
|
} = data
|
|
|
|
const pageTitle = title || this.getNuxt().head.title
|
|
|
|
let workingLayoutString = masterLayoutDomString
|
|
|
|
// Set page title
|
|
// pageTitle
|
|
workingLayoutString = workingLayoutString.replace( templateVar('title'), pageTitle )
|
|
|
|
// Set link tags
|
|
// this.generateLinkTags()
|
|
workingLayoutString = workingLayoutString.replace( templateVar('link-tags'), this.generateLinkTags( data ) )
|
|
|
|
// Add meta tags after title node
|
|
// this.generateMetaTags( data )
|
|
workingLayoutString = workingLayoutString.replace( templateVar('meta-tags'), this.generateMetaTags( data ) )
|
|
|
|
// Add structured data
|
|
workingLayoutString = workingLayoutString.replace( templateVar('structured-data'), this.generateStructuredData( data ) )
|
|
|
|
// Set page css
|
|
// document.querySelector('head').insertAdjacentHTML('beforeend', this.getCss() )
|
|
|
|
// Set page content
|
|
// content
|
|
workingLayoutString = workingLayoutString.replace( templateVar('main-content'), content )
|
|
|
|
// Set js before end of body
|
|
// `<script>${ this.getJs() }</script>`
|
|
workingLayoutString = workingLayoutString.replace( templateVar('scripts'), `<script>${ this.getJs() }</script>` )
|
|
|
|
|
|
// Return stringified html for page
|
|
return workingLayoutString
|
|
|
|
}
|
|
}
|
|
|
|
module.exports = DefaultLayout
|