@parameter1/base-cms-marko-web 4.8.0 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/browser-component.marko.js +2 -2
- package/components/document/components/body-wrapper.marko.js +2 -2
- package/components/document/components/error.marko.js +2 -2
- package/components/document/components/live-reload.marko.js +2 -2
- package/components/document/components/polyfill.marko.js +2 -2
- package/components/document/components/styles.marko +23 -0
- package/components/document/components/styles.marko.js +57 -0
- package/components/document/container.marko.js +2 -2
- package/components/document/index.marko +8 -19
- package/components/document/index.marko.js +15 -38
- package/components/element/array.marko.js +2 -2
- package/components/element/audio.marko.js +2 -2
- package/components/element/block.marko.js +2 -2
- package/components/element/clear.marko.js +2 -2
- package/components/element/components/image.marko.js +2 -2
- package/components/element/components/text.marko.js +2 -2
- package/components/element/content/address1.marko.js +2 -2
- package/components/element/content/address2.marko.js +2 -2
- package/components/element/content/audio.marko.js +2 -2
- package/components/element/content/authors.marko.js +2 -2
- package/components/element/content/body.marko.js +2 -2
- package/components/element/content/byline.marko.js +2 -2
- package/components/element/content/city-state-zip.marko.js +2 -2
- package/components/element/content/contributors.marko.js +2 -2
- package/components/element/content/country.marko.js +2 -2
- package/components/element/content/embed-code.marko.js +2 -2
- package/components/element/content/end-date.marko.js +2 -2
- package/components/element/content/ends.marko.js +2 -2
- package/components/element/content/fax.marko.js +2 -2
- package/components/element/content/images.marko.js +2 -2
- package/components/element/content/mobile.marko.js +2 -2
- package/components/element/content/name.marko.js +2 -2
- package/components/element/content/phone.marko.js +2 -2
- package/components/element/content/photographers.marko.js +2 -2
- package/components/element/content/public-email.marko.js +2 -2
- package/components/element/content/published.marko.js +2 -2
- package/components/element/content/short-name.marko.js +2 -2
- package/components/element/content/sidebar-stubs.marko.js +2 -2
- package/components/element/content/sidebars.marko.js +2 -2
- package/components/element/content/source.marko.js +2 -2
- package/components/element/content/sponsors.marko.js +2 -2
- package/components/element/content/start-date.marko.js +2 -2
- package/components/element/content/starts.marko.js +2 -2
- package/components/element/content/teaser.marko.js +2 -2
- package/components/element/content/title.marko.js +2 -2
- package/components/element/content/tollfree.marko.js +2 -2
- package/components/element/content/transcript.marko.js +2 -2
- package/components/element/content/website.marko.js +2 -2
- package/components/element/date.marko.js +2 -2
- package/components/element/image/caption.marko.js +2 -2
- package/components/element/image/credit.marko.js +2 -2
- package/components/element/image/display-name.marko.js +2 -2
- package/components/element/image/slider.marko.js +2 -2
- package/components/element/img.marko.js +2 -2
- package/components/element/index.marko.js +2 -2
- package/components/element/link.marko.js +2 -2
- package/components/element/magazine-issue/description.marko.js +2 -2
- package/components/element/magazine-issue/digital-edition-url.marko.js +2 -2
- package/components/element/magazine-issue/name.marko.js +2 -2
- package/components/element/magazine-issue/pdf-url.marko.js +2 -2
- package/components/element/magazine-publication/cancel-url.marko.js +2 -2
- package/components/element/magazine-publication/change-address-url.marko.js +2 -2
- package/components/element/magazine-publication/description.marko.js +2 -2
- package/components/element/magazine-publication/einquiry-url.marko.js +2 -2
- package/components/element/magazine-publication/name.marko.js +2 -2
- package/components/element/magazine-publication/renewal-url.marko.js +2 -2
- package/components/element/magazine-publication/reprints-url.marko.js +2 -2
- package/components/element/magazine-publication/subscribe-url.marko.js +2 -2
- package/components/element/obj-array.marko.js +2 -2
- package/components/element/obj-audio.marko.js +2 -2
- package/components/element/obj-date.marko.js +2 -2
- package/components/element/obj-nodes.marko.js +2 -2
- package/components/element/obj-text.marko.js +2 -2
- package/components/element/obj.marko.js +2 -2
- package/components/element/picture.marko.js +2 -2
- package/components/element/text.marko.js +2 -2
- package/components/element/website-section/description.marko.js +2 -2
- package/components/element/website-section/hierarchy.marko.js +2 -2
- package/components/element/website-section/name.marko.js +2 -2
- package/components/font/google.marko.js +2 -2
- package/components/font/link.marko.js +2 -2
- package/components/font/typekit.marko.js +2 -2
- package/components/load-more/index.marko.js +2 -2
- package/components/load-more/trigger.marko.js +2 -2
- package/components/node/body.marko.js +2 -2
- package/components/node/element.marko.js +2 -2
- package/components/node/footer.marko.js +2 -2
- package/components/node/header.marko.js +2 -2
- package/components/node/image-inner-wrapper.marko.js +2 -2
- package/components/node/image-wrapper.marko.js +2 -2
- package/components/node/image.marko.js +2 -2
- package/components/node/index.marko.js +2 -2
- package/components/node-list/body.marko.js +2 -2
- package/components/node-list/element.marko.js +2 -2
- package/components/node-list/footer.marko.js +2 -2
- package/components/node-list/header.marko.js +2 -2
- package/components/node-list/index.marko.js +2 -2
- package/components/node-list/node.marko.js +2 -2
- package/components/node-list/nodes.marko.js +2 -2
- package/components/page/container.marko.js +2 -2
- package/components/page/description.marko.js +2 -2
- package/components/page/image.marko.js +2 -2
- package/components/page/layouts/content.marko.js +2 -2
- package/components/page/layouts/default.marko.js +2 -2
- package/components/page/layouts/dynamic-page.marko.js +2 -2
- package/components/page/layouts/magazine-issue.marko.js +2 -2
- package/components/page/layouts/magazine-publication.marko.js +2 -2
- package/components/page/layouts/website-section.marko.js +2 -2
- package/components/page/metadata/components/common.marko.js +2 -2
- package/components/page/metadata/content.marko.js +2 -2
- package/components/page/metadata/default.marko.js +2 -2
- package/components/page/metadata/dynamic-page.marko.js +2 -2
- package/components/page/metadata/magazine-issue.marko.js +2 -2
- package/components/page/metadata/magazine-publication.marko.js +2 -2
- package/components/page/metadata/website-section.marko.js +2 -2
- package/components/page/rel-canonical.marko.js +2 -2
- package/components/page/title.marko.js +2 -2
- package/components/page/wrapper.marko.js +2 -2
- package/components/resolve/page.marko.js +2 -2
- package/components/rss/website-section.marko.js +2 -2
- package/config/core.js +0 -41
- package/eslint.log +3 -0
- package/express/asset-loader.js +55 -0
- package/express/cdn.js +27 -0
- package/express/css-loader.js +117 -0
- package/express/error-handlers.js +2 -0
- package/express/index.js +12 -3
- package/middleware/with-content.js +4 -0
- package/middleware/with-dynamic-page.js +4 -0
- package/middleware/with-magazine-issue.js +4 -0
- package/middleware/with-magazine-publication.js +4 -0
- package/middleware/with-website-section.js +4 -0
- package/package.json +3 -3
- package/scss/fonts/alata-fallback.scss +7 -0
- package/scss/fonts/arimo-fallback.scss +7 -0
- package/scss/fonts/fira-sans-fallback.scss +1 -0
- package/scss/fonts/ibm-plex-sans-fallback.scss +7 -0
- package/scss/fonts/informapro-fallback.scss +6 -0
- package/scss/fonts/lato-fallback.scss +7 -0
- package/scss/fonts/montserrat-fallback.scss +1 -0
- package/scss/fonts/open-sans-condensed-fallback.scss +1 -0
- package/scss/fonts/open-sans-fallback.scss +1 -0
- package/scss/fonts/oswold-fallback.scss +1 -0
- package/scss/fonts/roboto-condensed-fallback.scss +7 -0
- package/scss/fonts/roboto-fallback.scss +7 -0
- package/scss/fonts/roboto-slab-fallback.scss +7 -0
- package/scss/fonts/solitaire-mvb-pro-fallback.scss +6 -0
- package/scss/fonts/source-sans-4-fallback.scss +1 -0
- package/scss/fonts/source-serif-pro-fallback.scss +7 -0
- package/base-cms-marko-web-0.7.4.tgz +0 -0
- package/base-cms-marko-web-0.9.37.tgz +0 -0
- package/base-cms-marko-web-0.9.55.tgz +0 -0
- package/config/dist-loader.js +0 -42
- package/express/purged-css.js +0 -11
- package/public/lazysizes/v5.3.2.js +0 -2
@@ -0,0 +1,55 @@
|
|
1
|
+
const path = require('path');
|
2
|
+
const { readFile } = require('fs').promises;
|
3
|
+
const { asyncRoute } = require('@parameter1/base-cms-utils');
|
4
|
+
|
5
|
+
const readManifest = async (loc) => {
|
6
|
+
try {
|
7
|
+
const contents = await readFile(loc, 'utf8');
|
8
|
+
return JSON.parse(contents);
|
9
|
+
} catch (e) {
|
10
|
+
if (e.code === 'ENOENT') return null;
|
11
|
+
throw e;
|
12
|
+
}
|
13
|
+
};
|
14
|
+
|
15
|
+
const getRelPathFromManifest = async ({ distDir, type, entry }) => {
|
16
|
+
const file = path.resolve(distDir, type, 'manifest.json');
|
17
|
+
const manifest = await readManifest(file);
|
18
|
+
if (!manifest) throw new Error(`Unable to load the asset manifest for type ${type}`);
|
19
|
+
|
20
|
+
const asset = manifest[entry];
|
21
|
+
if (!asset) throw new Error(`Unable to extract an asset for type ${type} using manifest entry ${entry}`);
|
22
|
+
return `${type}/${asset.file}`;
|
23
|
+
};
|
24
|
+
|
25
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
26
|
+
const types = [
|
27
|
+
{ type: 'js', entry: 'browser/index.js' },
|
28
|
+
];
|
29
|
+
|
30
|
+
module.exports = ({ distDir }) => asyncRoute(async (req, res, next) => {
|
31
|
+
const { cdn } = res.locals;
|
32
|
+
const { app } = req;
|
33
|
+
|
34
|
+
if (!app.locals.assets) app.locals.assets = {};
|
35
|
+
const { assets } = app.locals;
|
36
|
+
|
37
|
+
// when on production, only load the file paths from the manifest once
|
38
|
+
// as long as the cdn configs are the same (allows for changing the cdn env var in prod)
|
39
|
+
if (isProduction && assets.files && assets.cdn === cdn.enabled) return next();
|
40
|
+
|
41
|
+
// get file paths from manifests
|
42
|
+
const rels = await Promise.all(types.map(async ({ type, entry }) => {
|
43
|
+
const rel = await getRelPathFromManifest({ distDir, type, entry });
|
44
|
+
return { type, rel };
|
45
|
+
}));
|
46
|
+
|
47
|
+
assets.files = rels.reduce((map, { type, rel }) => {
|
48
|
+
const href = cdn.dist(rel);
|
49
|
+
map.set(type, [href]);
|
50
|
+
return map;
|
51
|
+
}, new Map());
|
52
|
+
assets.cdn = cdn.enabled;
|
53
|
+
|
54
|
+
return next();
|
55
|
+
});
|
package/express/cdn.js
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
const { cleanPath } = require('@parameter1/base-cms-utils');
|
2
|
+
|
3
|
+
module.exports = ({ enabled = false, origin, siteVersion } = {}) => (req, res, next) => {
|
4
|
+
const { config, tenantKey } = req.app.locals;
|
5
|
+
const url = `${cleanPath(origin)}/web-assets/${tenantKey}/${config.website('id')}/v${siteVersion}`;
|
6
|
+
|
7
|
+
const key = '__cdn';
|
8
|
+
const values = new Set(['true', '1']);
|
9
|
+
let isEnabled = enabled;
|
10
|
+
if (values.has(req.query[key])) isEnabled = true;
|
11
|
+
if (values.has(req.cookies[key])) isEnabled = true;
|
12
|
+
|
13
|
+
res.locals.cdn = {
|
14
|
+
enabled: isEnabled,
|
15
|
+
origin,
|
16
|
+
url,
|
17
|
+
dist: (path) => {
|
18
|
+
const cleaned = `dist/${cleanPath(path)}`;
|
19
|
+
return isEnabled ? `${url}/${cleaned}` : `/${cleaned}`;
|
20
|
+
},
|
21
|
+
public: (path) => {
|
22
|
+
const cleaned = cleanPath(path);
|
23
|
+
return isEnabled ? `${url}/public/${cleaned}` : `/${cleaned}`;
|
24
|
+
},
|
25
|
+
};
|
26
|
+
next();
|
27
|
+
};
|
@@ -0,0 +1,117 @@
|
|
1
|
+
const path = require('path');
|
2
|
+
const { readFile } = require('fs').promises;
|
3
|
+
const { readFileSync } = require('fs');
|
4
|
+
const { asyncRoute } = require('@parameter1/base-cms-utils');
|
5
|
+
|
6
|
+
const modes = new Set(['main', 'purged', 'optimized', 'critical']);
|
7
|
+
|
8
|
+
const readManifest = async (loc) => {
|
9
|
+
try {
|
10
|
+
const contents = await readFile(loc, 'utf8');
|
11
|
+
return JSON.parse(contents);
|
12
|
+
} catch (e) {
|
13
|
+
if (e.code === 'ENOENT') return null;
|
14
|
+
throw e;
|
15
|
+
}
|
16
|
+
};
|
17
|
+
|
18
|
+
/**
|
19
|
+
* @typedef {import("@parameter1/base-cms-web-cli/build/utils/css.js")
|
20
|
+
* .WrittenCSSOutputAsset} WrittenCSSOutputAsset
|
21
|
+
*
|
22
|
+
* @param {object} params
|
23
|
+
* @param {string} params.distDir
|
24
|
+
* @returns {Promise<WrittenCSSOutputAsset[]>}
|
25
|
+
*/
|
26
|
+
const loadManifestEntries = async ({ distDir }) => {
|
27
|
+
const file = path.resolve(distDir, 'css', 'manifest.json');
|
28
|
+
const manifest = await readManifest(file);
|
29
|
+
if (!manifest) throw new Error('Unable to load the CSS asset manifest');
|
30
|
+
return Object.keys(manifest).map((key) => {
|
31
|
+
const asset = { key, ...manifest[key] };
|
32
|
+
return asset;
|
33
|
+
});
|
34
|
+
};
|
35
|
+
|
36
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
37
|
+
|
38
|
+
module.exports = ({ distDir }) => asyncRoute(async (req, res, next) => {
|
39
|
+
const { cdn } = res.locals;
|
40
|
+
const { app } = req;
|
41
|
+
if (!app.locals.css) app.locals.css = {};
|
42
|
+
const { css } = app.locals;
|
43
|
+
|
44
|
+
// determine the current CSS mode
|
45
|
+
// use the env first and fallback to main (all).
|
46
|
+
let mode = process.env.CSS_MODE || 'main';
|
47
|
+
if (!modes.has(mode)) mode = 'main';
|
48
|
+
|
49
|
+
// then allow the request query or a cookie to override this.
|
50
|
+
const key = '__css';
|
51
|
+
if (modes.has(req.query[key])) {
|
52
|
+
mode = req.query[key];
|
53
|
+
} else if (modes.has(req.cookies[key])) {
|
54
|
+
mode = req.cookie[key];
|
55
|
+
}
|
56
|
+
|
57
|
+
// always set the mode to the app on every request.
|
58
|
+
css.mode = mode;
|
59
|
+
|
60
|
+
// when on production, only load the file paths and/or contents from the manifest once
|
61
|
+
// as long as the cdn configs are the same (allows for changing the cdn env var in prod)
|
62
|
+
if (isProduction && css.ready && css.cdn === cdn.enabled) return next();
|
63
|
+
|
64
|
+
css.cdn = cdn.enabled;
|
65
|
+
|
66
|
+
const items = await loadManifestEntries({ distDir });
|
67
|
+
const files = items.reduce((map, asset) => {
|
68
|
+
if (asset.embedded) return map;
|
69
|
+
map.set(asset.key, cdn.dist(`css/${asset.file}`));
|
70
|
+
return map;
|
71
|
+
}, new Map());
|
72
|
+
css.files = files;
|
73
|
+
|
74
|
+
const embeddable = items.reduce((map, asset) => {
|
75
|
+
if (!asset.embedded) return map;
|
76
|
+
map.set(asset.key, path.resolve(distDir, 'css', asset.file));
|
77
|
+
return map;
|
78
|
+
}, new Map());
|
79
|
+
css.embeddable = embeddable;
|
80
|
+
|
81
|
+
css.main = () => files.get('main');
|
82
|
+
css.purged = () => files.get('purged');
|
83
|
+
|
84
|
+
css.optimized = ({ kind, type } = {}) => {
|
85
|
+
// attempt to load the optimized file from most to least specific.
|
86
|
+
const keys = [];
|
87
|
+
if (kind && type) keys.push(`optimized-${kind}.${type}`);
|
88
|
+
if (kind) keys.push(`optimized-${kind}`);
|
89
|
+
keys.push('optimized');
|
90
|
+
|
91
|
+
return keys.reduce((file, k) => {
|
92
|
+
if (file) return file;
|
93
|
+
return files.get(k) || null;
|
94
|
+
}, null);
|
95
|
+
};
|
96
|
+
|
97
|
+
css.critical = ({ kind, type } = {}) => {
|
98
|
+
// attempt to load the critical file from most to least specific.
|
99
|
+
const keys = [];
|
100
|
+
if (kind && type) keys.push(`critical-${kind}.${type}`);
|
101
|
+
if (kind) keys.push(`critical-${kind}`);
|
102
|
+
keys.push('critical');
|
103
|
+
|
104
|
+
const critical = keys.reduce((file, k) => {
|
105
|
+
if (file) return file;
|
106
|
+
return embeddable.get(k) || null;
|
107
|
+
}, null);
|
108
|
+
if (!critical) return null;
|
109
|
+
// @todo determine if this should read contents all the time or store in memory?
|
110
|
+
const contents = readFileSync(critical, 'utf8');
|
111
|
+
return `/* ${critical.split('/').pop()} */ ${contents}`;
|
112
|
+
};
|
113
|
+
|
114
|
+
css.ready = true;
|
115
|
+
|
116
|
+
return next();
|
117
|
+
});
|
@@ -1,5 +1,6 @@
|
|
1
1
|
const { STATUS_CODES } = require('http');
|
2
2
|
const createError = require('http-errors');
|
3
|
+
const setRouteKind = require('@parameter1/base-cms-marko-express/utils/set-route-kind');
|
3
4
|
const errorTemplate = require('../components/document/components/error');
|
4
5
|
const getRedirect = require('./get-redirect');
|
5
6
|
const findContentAlias = require('./find-content-alias');
|
@@ -16,6 +17,7 @@ const noCache = (res) => {
|
|
16
17
|
};
|
17
18
|
|
18
19
|
const renderError = (res, { statusCode, err, template }) => {
|
20
|
+
setRouteKind(res, { kind: 'error', type: statusCode });
|
19
21
|
res.status(statusCode);
|
20
22
|
res.marko(template || errorTemplate, {
|
21
23
|
statusCode,
|
package/express/index.js
CHANGED
@@ -12,7 +12,9 @@ const embeddedMedia = require('./embedded-media');
|
|
12
12
|
const loadObject = require('./load-object');
|
13
13
|
const loadDocument = require('./load-document');
|
14
14
|
const oembed = require('./oembed');
|
15
|
-
const
|
15
|
+
const cdn = require('./cdn');
|
16
|
+
const assetLoader = require('./asset-loader');
|
17
|
+
const cssLoader = require('./css-loader');
|
16
18
|
const rss = require('./rss');
|
17
19
|
const sitemaps = require('./sitemaps');
|
18
20
|
const { version } = require('../package.json');
|
@@ -117,14 +119,21 @@ module.exports = (config = {}) => {
|
|
117
119
|
// Set website context.
|
118
120
|
app.use(websiteContext(app.locals.config));
|
119
121
|
|
122
|
+
// Load CDN info before dist and CSS loading (but after the website context).
|
123
|
+
app.use(cdn({
|
124
|
+
enabled: ['true', '1'].includes(process.env.USE_ASSET_CDN),
|
125
|
+
origin: process.env.ASSET_CDN_ORIGIN || 'https://cdn.parameter1.com',
|
126
|
+
siteVersion: sitePackage.version,
|
127
|
+
}));
|
128
|
+
app.use(cssLoader({ distDir }));
|
129
|
+
app.use(assetLoader({ distDir }));
|
130
|
+
|
120
131
|
// Register the Marko middleware.
|
121
132
|
app.use(markoMiddleware());
|
122
|
-
app.use(purgedCSS());
|
123
133
|
app.use(cleanMarkoResponse());
|
124
134
|
|
125
135
|
// Serve static assets
|
126
136
|
app.use('/dist/css', express.static(`${distDir}/css`, { maxAge: '2y', immutable: true }));
|
127
|
-
app.use('/dist/js/lazysizes', express.static(path.resolve(__dirname, '../public/lazysizes'), { maxAge: '2y', immutable: true }));
|
128
137
|
app.use('/dist/js', express.static(`${distDir}/js`, { maxAge: '2y', immutable: true }));
|
129
138
|
app.use('/dist', express.static(distDir));
|
130
139
|
|
@@ -2,6 +2,7 @@ const { get } = require('@parameter1/base-cms-object-path');
|
|
2
2
|
const { asyncRoute, isFunction: isFn } = require('@parameter1/base-cms-utils');
|
3
3
|
const { content: loader } = require('@parameter1/base-cms-web-common/page-loaders');
|
4
4
|
const { blockContent: queryFactory } = require('@parameter1/base-cms-web-common/query-factories');
|
5
|
+
const setRouteKind = require('@parameter1/base-cms-marko-express/utils/set-route-kind');
|
5
6
|
const PageNode = require('./page-node');
|
6
7
|
const buildContentInput = require('../utils/build-content-input');
|
7
8
|
const applyQueryParams = require('../utils/apply-query-params');
|
@@ -22,6 +23,9 @@ module.exports = ({
|
|
22
23
|
|
23
24
|
const additionalInput = buildContentInput({ req });
|
24
25
|
const content = await loader(apollo, { id, additionalInput, queryFragment: loaderQueryFragment });
|
26
|
+
|
27
|
+
// set the route kind
|
28
|
+
setRouteKind(res, { kind: 'content', type: content.type });
|
25
29
|
const redirectTo = isFn(redirectToFn) ? redirectToFn({ content }) : content.redirectTo;
|
26
30
|
const path = isFn(pathFn) ? pathFn({ content }) : get(content, 'siteContext.path');
|
27
31
|
|
@@ -2,6 +2,7 @@ const { get } = require('@parameter1/base-cms-object-path');
|
|
2
2
|
const { asyncRoute, isFunction: isFn } = require('@parameter1/base-cms-utils');
|
3
3
|
const { dynamicPage: loader } = require('@parameter1/base-cms-web-common/page-loaders');
|
4
4
|
const { blockDynamicPage: queryFactory } = require('@parameter1/base-cms-web-common/query-factories');
|
5
|
+
const setRouteKind = require('@parameter1/base-cms-marko-express/utils/set-route-kind');
|
5
6
|
const PageNode = require('./page-node');
|
6
7
|
const applyQueryParams = require('../utils/apply-query-params');
|
7
8
|
|
@@ -15,6 +16,9 @@ module.exports = ({
|
|
15
16
|
const { apollo, query } = req;
|
16
17
|
|
17
18
|
const page = await loader(apollo, { alias });
|
19
|
+
|
20
|
+
setRouteKind(res, { kind: 'dynamic-page', type: alias });
|
21
|
+
|
18
22
|
const { redirectTo } = page;
|
19
23
|
const path = get(page, 'siteContext.path');
|
20
24
|
if (redirectTo) {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
const { asyncRoute } = require('@parameter1/base-cms-utils');
|
2
2
|
const { magazineIssue: loader } = require('@parameter1/base-cms-web-common/page-loaders');
|
3
3
|
const { blockMagazineIssue: queryFactory } = require('@parameter1/base-cms-web-common/query-factories');
|
4
|
+
const setRouteKind = require('@parameter1/base-cms-marko-express/utils/set-route-kind');
|
4
5
|
const PageNode = require('./page-node');
|
5
6
|
|
6
7
|
module.exports = ({
|
@@ -10,6 +11,9 @@ module.exports = ({
|
|
10
11
|
const { apollo } = req;
|
11
12
|
const id = Number(req.params.id);
|
12
13
|
const issue = await loader(apollo, { id });
|
14
|
+
|
15
|
+
// set the route kind
|
16
|
+
setRouteKind(res, { kind: 'magazine-issue', type: '' });
|
13
17
|
const pageNode = new PageNode(apollo, {
|
14
18
|
queryFactory,
|
15
19
|
queryFragment,
|
@@ -1,6 +1,7 @@
|
|
1
1
|
const { asyncRoute } = require('@parameter1/base-cms-utils');
|
2
2
|
const { magazinePublication: loader } = require('@parameter1/base-cms-web-common/page-loaders');
|
3
3
|
const { blockMagazinePublication: queryFactory } = require('@parameter1/base-cms-web-common/query-factories');
|
4
|
+
const setRouteKind = require('@parameter1/base-cms-marko-express/utils/set-route-kind');
|
4
5
|
const PageNode = require('./page-node');
|
5
6
|
|
6
7
|
module.exports = ({
|
@@ -10,6 +11,9 @@ module.exports = ({
|
|
10
11
|
const { apollo } = req;
|
11
12
|
const { id } = req.params;
|
12
13
|
const publication = await loader(apollo, { id });
|
14
|
+
|
15
|
+
// set the route kind
|
16
|
+
setRouteKind(res, { kind: 'magazine-publication', type: '' });
|
13
17
|
const pageNode = new PageNode(apollo, {
|
14
18
|
queryFactory,
|
15
19
|
queryFragment,
|
@@ -1,6 +1,7 @@
|
|
1
1
|
const { asyncRoute, isFunction: isFn } = require('@parameter1/base-cms-utils');
|
2
2
|
const { websiteSection: loader } = require('@parameter1/base-cms-web-common/page-loaders');
|
3
3
|
const { blockWebsiteSection: queryFactory } = require('@parameter1/base-cms-web-common/query-factories');
|
4
|
+
const setRouteKind = require('@parameter1/base-cms-marko-express/utils/set-route-kind');
|
4
5
|
const PageNode = require('./page-node');
|
5
6
|
const applyQueryParams = require('../utils/apply-query-params');
|
6
7
|
|
@@ -16,6 +17,9 @@ module.exports = ({
|
|
16
17
|
const cleanedAlias = alias.replace(/\/+$/, '').replace(/^\/+/, '');
|
17
18
|
|
18
19
|
const section = await loader(apollo, { alias: cleanedAlias });
|
20
|
+
|
21
|
+
// set the route kind
|
22
|
+
setRouteKind(res, { kind: 'website-section', type: section.alias });
|
19
23
|
const { redirectTo, canonicalPath } = section;
|
20
24
|
if (redirectTo) {
|
21
25
|
return res.redirect(301, applyQueryParams({ path: redirectTo, query }));
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@parameter1/base-cms-marko-web",
|
3
|
-
"version": "4.
|
3
|
+
"version": "4.9.0",
|
4
4
|
"description": "Core Marko+Express components for BaseCMS websites",
|
5
5
|
"author": "Jacob Bare <jacob@parameter1.com>",
|
6
6
|
"main": "index.js",
|
@@ -31,7 +31,7 @@
|
|
31
31
|
"@parameter1/base-cms-html": "^4.5.12",
|
32
32
|
"@parameter1/base-cms-image": "^4.6.0",
|
33
33
|
"@parameter1/base-cms-inflector": "^4.5.12",
|
34
|
-
"@parameter1/base-cms-marko-express": "^4.
|
34
|
+
"@parameter1/base-cms-marko-express": "^4.9.0",
|
35
35
|
"@parameter1/base-cms-marko-node-require": "^4.5.12",
|
36
36
|
"@parameter1/base-cms-marko-web-deferred-script-loader": "^4.5.12",
|
37
37
|
"@parameter1/base-cms-object-path": "^4.5.12",
|
@@ -60,5 +60,5 @@
|
|
60
60
|
"publishConfig": {
|
61
61
|
"access": "public"
|
62
62
|
},
|
63
|
-
"gitHead": "
|
63
|
+
"gitHead": "4e879581f5dea1692abd1b2942c1be27c1910bf4"
|
64
64
|
}
|
Binary file
|
Binary file
|
Binary file
|
package/config/dist-loader.js
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
const path = require('path');
|
2
|
-
const { readFileSync } = require('fs');
|
3
|
-
|
4
|
-
const read = (file) => {
|
5
|
-
try {
|
6
|
-
return JSON.parse(readFileSync(file, 'utf8'));
|
7
|
-
} catch (e) {
|
8
|
-
if (e.code === 'ENOENT') return null;
|
9
|
-
throw e;
|
10
|
-
}
|
11
|
-
};
|
12
|
-
|
13
|
-
const loadFromManifest = ({ distDir, type, entry }) => {
|
14
|
-
const file = path.resolve(distDir, type, 'manifest.json');
|
15
|
-
const manifest = read(file);
|
16
|
-
if (!manifest) throw new Error(`Unable to load the asset manifest for type ${type}`);
|
17
|
-
const asset = manifest[entry];
|
18
|
-
if (!asset) throw new Error(`Unable to extract an asset for type ${type} using manifest entry ${entry}`);
|
19
|
-
return `/dist/${type}/${asset.file}`;
|
20
|
-
};
|
21
|
-
|
22
|
-
const load = ({ distDir, file }) => readFileSync(path.resolve(distDir, `.${file.replace('/dist/', '/')}`), 'utf8');
|
23
|
-
|
24
|
-
module.exports = ({ distDir, type, entry }) => {
|
25
|
-
let file;
|
26
|
-
let contents;
|
27
|
-
return ({ embedded } = {}) => {
|
28
|
-
const isDevelopment = process.env.NODE_ENV !== 'production';
|
29
|
-
// when on dev, always return the file from the manifest
|
30
|
-
// as it may have changed during build.
|
31
|
-
if (isDevelopment) {
|
32
|
-
const f = loadFromManifest({ distDir, type, entry });
|
33
|
-
if (!embedded) return f;
|
34
|
-
return load({ distDir, file: f });
|
35
|
-
}
|
36
|
-
// otherwise, only retrieve it once
|
37
|
-
if (!file) file = loadFromManifest({ distDir, type, entry });
|
38
|
-
if (!embedded) return file;
|
39
|
-
if (!contents) contents = load({ distDir, file });
|
40
|
-
return contents;
|
41
|
-
};
|
42
|
-
};
|
package/express/purged-css.js
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
module.exports = () => (req, res, next) => {
|
2
|
-
res.locals.usePurgedCSS = ['cookies', 'query'].some((key) => {
|
3
|
-
const { __purgecss: purge } = req[key];
|
4
|
-
return purge && !['false', '0', 'null'].includes(purge);
|
5
|
-
});
|
6
|
-
res.locals.embedCSS = ['cookies', 'query'].some((key) => {
|
7
|
-
const { __embedcss: embed } = req[key];
|
8
|
-
return embed && !['false', '0', 'null'].includes(embed);
|
9
|
-
});
|
10
|
-
next();
|
11
|
-
};
|
@@ -1,2 +0,0 @@
|
|
1
|
-
/*! lazysizes - v5.3.2 */
|
2
|
-
!function(e){var t=function(u,D,f){"use strict";var k,H;if(function(){var e;var t={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",fastLoadedClass:"ls-is-cached",iframeLoadMode:0,srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:true,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:true,ricTimeout:0,throttleDelay:125};H=u.lazySizesConfig||u.lazysizesConfig||{};for(e in t){if(!(e in H)){H[e]=t[e]}}}(),!D||!D.getElementsByClassName){return{init:function(){},cfg:H,noSupport:true}}var O=D.documentElement,i=u.HTMLPictureElement,P="addEventListener",$="getAttribute",q=u[P].bind(u),I=u.setTimeout,U=u.requestAnimationFrame||I,o=u.requestIdleCallback,j=/^picture$/i,r=["load","error","lazyincluded","_lazyloaded"],a={},G=Array.prototype.forEach,J=function(e,t){if(!a[t]){a[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")}return a[t].test(e[$]("class")||"")&&a[t]},K=function(e,t){if(!J(e,t)){e.setAttribute("class",(e[$]("class")||"").trim()+" "+t)}},Q=function(e,t){var a;if(a=J(e,t)){e.setAttribute("class",(e[$]("class")||"").replace(a," "))}},V=function(t,a,e){var i=e?P:"removeEventListener";if(e){V(t,a)}r.forEach(function(e){t[i](e,a)})},X=function(e,t,a,i,r){var n=D.createEvent("Event");if(!a){a={}}a.instance=k;n.initEvent(t,!i,!r);n.detail=a;e.dispatchEvent(n);return n},Y=function(e,t){var a;if(!i&&(a=u.picturefill||H.pf)){if(t&&t.src&&!e[$]("srcset")){e.setAttribute("srcset",t.src)}a({reevaluate:true,elements:[e]})}else if(t&&t.src){e.src=t.src}},Z=function(e,t){return(getComputedStyle(e,null)||{})[t]},s=function(e,t,a){a=a||e.offsetWidth;while(a<H.minSize&&t&&!e._lazysizesWidth){a=t.offsetWidth;t=t.parentNode}return a},ee=function(){var a,i;var t=[];var r=[];var n=t;var s=function(){var e=n;n=t.length?r:t;a=true;i=false;while(e.length){e.shift()()}a=false};var e=function(e,t){if(a&&!t){e.apply(this,arguments)}else{n.push(e);if(!i){i=true;(D.hidden?I:U)(s)}}};e._lsFlush=s;return e}(),te=function(a,e){return e?function(){ee(a)}:function(){var e=this;var t=arguments;ee(function(){a.apply(e,t)})}},ae=function(e){var a;var i=0;var r=H.throttleDelay;var n=H.ricTimeout;var t=function(){a=false;i=f.now();e()};var s=o&&n>49?function(){o(t,{timeout:n});if(n!==H.ricTimeout){n=H.ricTimeout}}:te(function(){I(t)},true);return function(e){var t;if(e=e===true){n=33}if(a){return}a=true;t=r-(f.now()-i);if(t<0){t=0}if(e||t<9){s()}else{I(s,t)}}},ie=function(e){var t,a;var i=99;var r=function(){t=null;e()};var n=function(){var e=f.now()-a;if(e<i){I(n,i-e)}else{(o||r)(r)}};return function(){a=f.now();if(!t){t=I(n,i)}}},e=function(){var v,m,c,h,e;var y,z,g,p,C,b,A;var n=/^img$/i;var d=/^iframe$/i;var E="onscroll"in u&&!/(gle|ing)bot/.test(navigator.userAgent);var _=0;var w=0;var M=0;var N=-1;var L=function(e){M--;if(!e||M<0||!e.target){M=0}};var x=function(e){if(A==null){A=Z(D.body,"visibility")=="hidden"}return A||!(Z(e.parentNode,"visibility")=="hidden"&&Z(e,"visibility")=="hidden")};var W=function(e,t){var a;var i=e;var r=x(e);g-=t;b+=t;p-=t;C+=t;while(r&&(i=i.offsetParent)&&i!=D.body&&i!=O){r=(Z(i,"opacity")||1)>0;if(r&&Z(i,"overflow")!="visible"){a=i.getBoundingClientRect();r=C>a.left&&p<a.right&&b>a.top-1&&g<a.bottom+1}}return r};var t=function(){var e,t,a,i,r,n,s,o,l,u,f,c;var d=k.elements;if((h=H.loadMode)&&M<8&&(e=d.length)){t=0;N++;for(;t<e;t++){if(!d[t]||d[t]._lazyRace){continue}if(!E||k.prematureUnveil&&k.prematureUnveil(d[t])){R(d[t]);continue}if(!(o=d[t][$]("data-expand"))||!(n=o*1)){n=w}if(!u){u=!H.expand||H.expand<1?O.clientHeight>500&&O.clientWidth>500?500:370:H.expand;k._defEx=u;f=u*H.expFactor;c=H.hFac;A=null;if(w<f&&M<1&&N>2&&h>2&&!D.hidden){w=f;N=0}else if(h>1&&N>1&&M<6){w=u}else{w=_}}if(l!==n){y=innerWidth+n*c;z=innerHeight+n;s=n*-1;l=n}a=d[t].getBoundingClientRect();if((b=a.bottom)>=s&&(g=a.top)<=z&&(C=a.right)>=s*c&&(p=a.left)<=y&&(b||C||p||g)&&(H.loadHidden||x(d[t]))&&(m&&M<3&&!o&&(h<3||N<4)||W(d[t],n))){R(d[t]);r=true;if(M>9){break}}else if(!r&&m&&!i&&M<4&&N<4&&h>2&&(v[0]||H.preloadAfterLoad)&&(v[0]||!o&&(b||C||p||g||d[t][$](H.sizesAttr)!="auto"))){i=v[0]||d[t]}}if(i&&!r){R(i)}}};var a=ae(t);var S=function(e){var t=e.target;if(t._lazyCache){delete t._lazyCache;return}L(e);K(t,H.loadedClass);Q(t,H.loadingClass);V(t,B);X(t,"lazyloaded")};var i=te(S);var B=function(e){i({target:e.target})};var T=function(e,t){var a=e.getAttribute("data-load-mode")||H.iframeLoadMode;if(a==0){e.contentWindow.location.replace(t)}else if(a==1){e.src=t}};var F=function(e){var t;var a=e[$](H.srcsetAttr);if(t=H.customMedia[e[$]("data-media")||e[$]("media")]){e.setAttribute("media",t)}if(a){e.setAttribute("srcset",a)}};var s=te(function(t,e,a,i,r){var n,s,o,l,u,f;if(!(u=X(t,"lazybeforeunveil",e)).defaultPrevented){if(i){if(a){K(t,H.autosizesClass)}else{t.setAttribute("sizes",i)}}s=t[$](H.srcsetAttr);n=t[$](H.srcAttr);if(r){o=t.parentNode;l=o&&j.test(o.nodeName||"")}f=e.firesLoad||"src"in t&&(s||n||l);u={target:t};K(t,H.loadingClass);if(f){clearTimeout(c);c=I(L,2500);V(t,B,true)}if(l){G.call(o.getElementsByTagName("source"),F)}if(s){t.setAttribute("srcset",s)}else if(n&&!l){if(d.test(t.nodeName)){T(t,n)}else{t.src=n}}if(r&&(s||l)){Y(t,{src:n})}}if(t._lazyRace){delete t._lazyRace}Q(t,H.lazyClass);ee(function(){var e=t.complete&&t.naturalWidth>1;if(!f||e){if(e){K(t,H.fastLoadedClass)}S(u);t._lazyCache=true;I(function(){if("_lazyCache"in t){delete t._lazyCache}},9)}if(t.loading=="lazy"){M--}},true)});var R=function(e){if(e._lazyRace){return}var t;var a=n.test(e.nodeName);var i=a&&(e[$](H.sizesAttr)||e[$]("sizes"));var r=i=="auto";if((r||!m)&&a&&(e[$]("src")||e.srcset)&&!e.complete&&!J(e,H.errorClass)&&J(e,H.lazyClass)){return}t=X(e,"lazyunveilread").detail;if(r){re.updateElem(e,true,e.offsetWidth)}e._lazyRace=true;M++;s(e,t,r,i,a)};var r=ie(function(){H.loadMode=3;a()});var o=function(){if(H.loadMode==3){H.loadMode=2}r()};var l=function(){if(m){return}if(f.now()-e<999){I(l,999);return}m=true;H.loadMode=3;a();q("scroll",o,true)};return{_:function(){e=f.now();k.elements=D.getElementsByClassName(H.lazyClass);v=D.getElementsByClassName(H.lazyClass+" "+H.preloadClass);q("scroll",a,true);q("resize",a,true);q("pageshow",function(e){if(e.persisted){var t=D.querySelectorAll("."+H.loadingClass);if(t.length&&t.forEach){U(function(){t.forEach(function(e){if(e.complete){R(e)}})})}}});if(u.MutationObserver){new MutationObserver(a).observe(O,{childList:true,subtree:true,attributes:true})}else{O[P]("DOMNodeInserted",a,true);O[P]("DOMAttrModified",a,true);setInterval(a,999)}q("hashchange",a,true);["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){D[P](e,a,true)});if(/d$|^c/.test(D.readyState)){l()}else{q("load",l);D[P]("DOMContentLoaded",a);I(l,2e4)}if(k.elements.length){t();ee._lsFlush()}else{a()}},checkElems:a,unveil:R,_aLSL:o}}(),re=function(){var a;var n=te(function(e,t,a,i){var r,n,s;e._lazysizesWidth=i;i+="px";e.setAttribute("sizes",i);if(j.test(t.nodeName||"")){r=t.getElementsByTagName("source");for(n=0,s=r.length;n<s;n++){r[n].setAttribute("sizes",i)}}if(!a.detail.dataAttr){Y(e,a.detail)}});var i=function(e,t,a){var i;var r=e.parentNode;if(r){a=s(e,r,a);i=X(e,"lazybeforesizes",{width:a,dataAttr:!!t});if(!i.defaultPrevented){a=i.detail.width;if(a&&a!==e._lazysizesWidth){n(e,r,i,a)}}}};var e=function(){var e;var t=a.length;if(t){e=0;for(;e<t;e++){i(a[e])}}};var t=ie(e);return{_:function(){a=D.getElementsByClassName(H.autosizesClass);q("resize",t)},checkElems:t,updateElem:i}}(),t=function(){if(!t.i&&D.getElementsByClassName){t.i=true;re._();e._()}};return I(function(){H.init&&t()}),k={cfg:H,autoSizer:re,loader:e,init:t,uP:Y,aC:K,rC:Q,hC:J,fire:X,gW:s,rAF:ee}}(e,e.document,Date);e.lazySizes=t,"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:{});
|