Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement/issue 881 favor content over configuration eg meta #892

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 1 addition & 15 deletions greenwood.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,11 @@ import { greenwoodPluginPostCss } from '@greenwood/plugin-postcss';
import rollupPluginAnalyzer from 'rollup-plugin-analyzer';
import { fileURLToPath, URL } from 'url';

const META_DESCRIPTION = 'Your workbench for the web. Focused on supporting modern web standards and development to help you create your next project.';
const FAVICON_HREF = '/favicon.ico';

export default {
workspace: fileURLToPath(new URL('./www', import.meta.url)),
optimization: 'inline',
staticRouter: true,
title: 'Greenwood',
meta: [
{ name: 'description', content: META_DESCRIPTION },
{ name: 'twitter:site', content: '@PrjEvergreen' },
{ property: 'og:title', content: 'Greenwood' },
{ property: 'og:type', content: 'website' },
{ property: 'og:url', content: 'https://www.greenwoodjs.io' },
{ property: 'og:image', content: 'https://www.greenwoodjs.io/assets/greenwood-logo-300w.png' },
{ property: 'og:description', content: META_DESCRIPTION },
{ rel: 'shortcut icon', href: FAVICON_HREF },
{ rel: 'icon', href: FAVICON_HREF }
],
interpolateFrontmatter: true,
plugins: [
...greenwoodPluginGraphQL(),
...greenwoodPluginPolyfills(),
Expand Down
17 changes: 2 additions & 15 deletions packages/cli/src/lifecycles/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ const defaultConfig = {
port: 8080,
optimization: optimizations[0],
interpolateFrontmatter: false,
title: 'My App',
meta: [],
plugins: greenwoodPlugins,
markdown: { plugins: [], settings: {} },
prerender: true,
Expand All @@ -60,7 +58,7 @@ const readAndMergeConfig = async() => {

if (fs.existsSync(path.join(process.cwd(), 'greenwood.config.js'))) {
const userCfgFile = (await import(pathToFileURL(path.join(process.cwd(), 'greenwood.config.js')))).default;
const { workspace, devServer, title, markdown, meta, optimization, plugins, port, prerender, staticRouter, pagesDirectory, templatesDirectory, interpolateFrontmatter } = userCfgFile;
const { workspace, devServer, markdown, optimization, plugins, port, prerender, staticRouter, pagesDirectory, templatesDirectory, interpolateFrontmatter } = userCfgFile;

// workspace validation
if (workspace) {
Expand All @@ -87,17 +85,6 @@ const readAndMergeConfig = async() => {
}
}

if (title) {
if (typeof title !== 'string') {
reject('Error: greenwood.config.js title must be a string');
}
customConfig.title = title;
}

if (meta && meta.length > 0) {
customConfig.meta = meta;
}

if (typeof optimization === 'string' && optimizations.indexOf(optimization.toLowerCase()) >= 0) {
customConfig.optimization = optimization;
} else if (optimization) {
Expand Down Expand Up @@ -219,7 +206,7 @@ const readAndMergeConfig = async() => {
}
}
} else {
// SPA should not prerender by default
// SPA should _not_ prerender unless if user has specified prerender should be true
if (fs.existsSync(path.join(customConfig.workspace, 'index.html'))) {
customConfig.prerender = false;
}
Expand Down
6 changes: 2 additions & 4 deletions packages/cli/src/lifecycles/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const generateGraph = async (compilation) => {
.replace(extension, '')
.replace(/\\/g, '/');
let template = 'page';
let title = '';
let title = null;
let imports = [];
let label = '';
let id;
Expand All @@ -51,7 +51,7 @@ const generateGraph = async (compilation) => {
const { attributes } = fm(fileContents);

template = attributes.template || 'page';
title = attributes.title || compilation.config.title || '';
title = attributes.title || title;
id = attributes.label || filename.split(path.sep)[filename.split(path.sep).length - 1].replace(extension, '');
imports = attributes.imports || [];
label = id.split('-')
Expand Down Expand Up @@ -133,7 +133,6 @@ const generateGraph = async (compilation) => {
.replace(extension, '')
.replace(/\\/g, '/')
.concat('/');
title = `${compilation.config.title} - ${label}`;
let ssrFrontmatter;

filePath = route;
Expand Down Expand Up @@ -243,7 +242,6 @@ const generateGraph = async (compilation) => {
filename: '404.html',
route: '/404/',
path: '404.html',
title: 'Not Found',
id: '404',
label: 'Not Found'
}
Expand Down
81 changes: 28 additions & 53 deletions packages/cli/src/plugins/resource/plugin-standard-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const getPageTemplate = (fullPath, templatesDir, template, contextPlugins = [],
return contents;
};

const getAppTemplate = (contents, templatesDir, customImports = [], contextPlugins, enableHud) => {
const getAppTemplate = (contents, templatesDir, customImports = [], contextPlugins, enableHud, frontmatterTitle) => {
const userAppTemplatePath = `${templatesDir}app.html`;
const customAppTemplates = getCustomPageTemplates(contextPlugins, 'app');

Expand Down Expand Up @@ -98,18 +98,35 @@ const getAppTemplate = (contents, templatesDir, customImports = [], contextPlugi

appTemplateContents = appTemplateContents.replace(/<page-outlet><\/page-outlet>/, '');
} else {
const appTitle = appRoot ? appRoot.querySelector('head title') : null;
const body = root.querySelector('body') ? root.querySelector('body').innerHTML : '';
const headScripts = root.querySelectorAll('head script');
const headLinks = root.querySelectorAll('head link');
const headMeta = root.querySelectorAll('head meta');
const headStyles = root.querySelectorAll('head style');
const headTitle = root.querySelector('head title');
const appTemplateHeadContents = appRoot.querySelector('head').innerHTML;

const hasInterpolatedFrontmatter = headTitle && headTitle.rawText.indexOf('${globalThis.page.title}') >= 0
|| appTitle && appTitle.rawText.indexOf('${globalThis.page.title}') >= 0;
const title = hasInterpolatedFrontmatter // favor frontmatter interpolation first
? headTitle && headTitle.rawText
? headTitle.rawText
: appTitle.rawText
: frontmatterTitle // otherwise, work in order of specificity from page -> page template -> app template
? frontmatterTitle
: headTitle && headTitle.rawText
? headTitle.rawText
: appTitle && appTitle.rawText
? appTitle.rawText
: 'My App';
appTemplateContents = appTemplateContents.replace(/<page-outlet><\/page-outlet>/, body);

if (headTitle) {
appTemplateContents = appTemplateContents.replace(/<title>(.*)<\/title>/, `<title>${headTitle.rawText}</title>`);
if (title) {
if (!appTitle) {
appTemplateContents = appTemplateContents.replace('<head>', '<head>\n <title></title>');
}

appTemplateContents = appTemplateContents.replace(/<title>(.*)<\/title>/, `<title>${title}</title>`);
}

// merge <script> tags
Expand Down Expand Up @@ -206,12 +223,12 @@ const getAppTemplate = (contents, templatesDir, customImports = [], contextPlugi
const appHeadMetaMatches = appTemplateHeadContents.match(matchNeedleMeta);
const lastMeta = appHeadMetaMatches && appHeadMetaMatches.length && appHeadMetaMatches.length > 0
? appHeadMetaMatches[appHeadMetaMatches.length - 1]
: '<head>';
: '</title>';
const pageMeta = headMeta.map((meta) => {
return `<meta ${meta.rawAttrs}/>`;
});

appTemplateContents = appTemplateContents.replace(lastMeta.replace('>', '/>'), `${lastMeta.replace('>', '/>')}\n
appTemplateContents = appTemplateContents.replace(lastMeta.replace('>', '/>'), `${lastMeta.replace('>', '/>')}
${pageMeta.join('\n')}
`);
}
Expand Down Expand Up @@ -268,48 +285,6 @@ const getUserScripts = (contents, context) => {
return contents;
};

const getMetaContent = (url, config, contents, ssrFrontmatter = {}) => {
const existingTitleMatch = contents.match(/<title>(.*)<\/title>/);
const existingTitleCheck = !!(existingTitleMatch && existingTitleMatch[1] && existingTitleMatch[1] !== '');

const title = existingTitleCheck
? existingTitleMatch[1]
: ssrFrontmatter.title
? ssrFrontmatter.title
: config.title
? config.title
: '';
const metaContent = [...config.meta || []].map(item => {
let metaHtml = '';

for (const [key, value] of Object.entries(item)) {
const isOgUrl = item.property === 'og:url' && key === 'content';
const hasTrailingSlash = isOgUrl && value[value.length - 1] === '/';
const contextualValue = isOgUrl
? hasTrailingSlash
? `${value}${url.replace('/', '')}`
: `${value}${url === '/' ? '' : url}`
: value;

metaHtml += ` ${key}="${contextualValue}"`;
}

return item.rel
? `<link${metaHtml}/>`
: `<meta${metaHtml}/>`;
}).join('\n');

// add an empty <title> if it's not already there
if (!existingTitleMatch) {
contents = contents.replace('<head>', '<head><title></title>');
}

contents = contents.replace(/<title>(.*)<\/title>/, `<title>${title}</title>`);
contents = contents.replace('<meta-outlet></meta-outlet>', metaContent);

return contents;
};

class StandardHtmlResource extends ResourceInterface {
constructor(compilation, options) {
super(compilation, options);
Expand Down Expand Up @@ -350,6 +325,7 @@ class StandardHtmlResource extends ResourceInterface {

let customImports = [];
let body = '';
let title = null;
let template = null;
let frontMatter = {};
let ssrBody;
Expand Down Expand Up @@ -394,7 +370,7 @@ class StandardHtmlResource extends ResourceInterface {
frontMatter = fm.attributes;

if (frontMatter.title) {
config.title = `${config.title} - ${frontMatter.title}`;
title = frontMatter.title;
}

if (frontMatter.template) {
Expand Down Expand Up @@ -430,7 +406,7 @@ class StandardHtmlResource extends ResourceInterface {
ssrFrontmatter = result.frontmatter;

if (ssrFrontmatter.title) {
config.title = `${config.title} - ${ssrFrontmatter.title}`;
title = ssrFrontmatter.title;
}

if (ssrFrontmatter.template) {
Expand Down Expand Up @@ -462,12 +438,11 @@ class StandardHtmlResource extends ResourceInterface {
if (isClientSideRoute) {
body = fs.readFileSync(fullPath, 'utf-8');
} else {
body = ssrTemplate ? ssrTemplate : getPageTemplate(fullPath, userTemplatesDir, template, contextPlugins, pagesDir, ssrTemplate);
body = ssrTemplate ? ssrTemplate : getPageTemplate(fullPath, userTemplatesDir, template, contextPlugins, pagesDir);
}

body = getAppTemplate(body, userTemplatesDir, customImports, contextPlugins, config.devServer.hud);
body = getAppTemplate(body, userTemplatesDir, customImports, contextPlugins, config.devServer.hud, title);
body = getUserScripts(body, this.compilation.context);
body = getMetaContent(matchingRoute.route.replace(/\\/g, '/'), config, body, ssrFrontmatter);

if (processedMarkdown) {
const wrappedCustomElementRegex = /<p><[a-zA-Z]*-[a-zA-Z](.*)>(.*)<\/[a-zA-Z]*-[a-zA-Z](.*)><\/p>/g;
Expand Down
3 changes: 1 addition & 2 deletions packages/cli/src/templates/app.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<!DOCTYPE html>
<html lang="en" prefix="og:http://ogp.me/ns#">
<head>
<title></title>
<title>My App</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<meta-outlet></meta-outlet>
</head>
<body>
<page-outlet></page-outlet>
Expand Down

This file was deleted.

This file was deleted.

10 changes: 0 additions & 10 deletions packages/cli/test/cases/build.config.meta/greenwood.config.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<!DOCTYPE html>
<html>
<head>
<meta-outlet></meta-outlet>
<script type="module" src="/components/header.js"></script>
</head>

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
* greenwood build
*
* User Config
* {
* title: 'a title to test correct title merging'
* }
* None
*
* User Workspace
* Greenwood default
Expand Down Expand Up @@ -53,13 +51,6 @@ describe('Build Greenwood With: ', function() {
before(async function() {
dom = await JSDOM.fromFile(path.resolve(this.context.publicDir, 'index.html'));
});

it('should have custom <title> tag in the <head>', function() {
const title = dom.window.document.querySelectorAll('head > title');

expect(title.length).to.be.equal(1);
expect(title[0].textContent).to.be.equal('this is the title from the config - this is a custom markdown title');
});

it('should correctly rendering an <h3> tag', function() {
const heading = dom.window.document.querySelectorAll('body h3');
Expand Down

This file was deleted.

Loading