Files
next-static-site/lib/data.js
Brandon Lee Kitajchuk db94b17829 Latest news + banner, cypress tests, open source copy, general style tweaks (#13)
* Adding latest news and banners

* Adding first draft of cypress specs and github actions workflow

* Adding sticky position for top banner

* Tweak styles for new latest news section

* Tweak styles for text__layout innerHTML

* Fix Cypress homepage test spec

* Fix mobile navi z-index with sticky top banner

* Fix sticky banner z-index bug with mobile navi

* Refactor markdown tools to support pages beyond developer docs

* Adjust TADHACK text max-widths for small mobile

* initial changes for open source copy

* more copy

* more copy

* updated open source structure

* minor

* typo

* more copy

* Adjust styles for Open Source markdown small text

* Update readme and remove floats from docs webhooks markdown

* Add readme notes on Cypress and flesh out navi spec tests

* Fix main navi highlight when on sub-sections of markdown pages

Co-authored-by: Dave Horton <daveh@beachdognet.com>
2021-07-22 12:34:01 -04:00

180 lines
4.6 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const yamljs = require('yamljs');
const matter = require('gray-matter');
const remark = require('remark');
const remarkHtml = require('remark-html');
const remarkGfm = require('remark-gfm');
const dataDir = path.join(process.cwd(), 'data');
const markdownDir = path.join(process.cwd(), 'markdown');
/**
* Parse YAML data to generate the static props for Next.js page components
* @param {string} key The fileName without extension to load from ./data
* @returns {Object}
*/
function _getData(key) {
const fullPath = path.join(dataDir, `${key}.yml`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
return yamljs.parse(fileContents);
}
/**
* Load YAML data to generate the static props for Next.js page components
* @param {string} key The fileName without extension to load from ./data
* @returns {Object}
*/
export function getData(key) {
return {
[key]: _getData(key),
site: _getData('site'),
};
}
/**
* Get a cleaned slug for Next.js static paths pattern
* @param {string} scope The subdirectory of ./markdown
* @param {string} slug The fileName of a found markdown file
* @returns {Array}
*/
function _getCleanSlug(scope, slug) {
return slug
.replace(path.join(markdownDir, scope), '')
.replace(/^\/+|\/+$/, '')
.split('/');
}
/**
* Load Markdown and YAML front-matter to generate the static props for Next.js docs component
* @param {string} filePath The full path to a markdown file
* @returns {Object}
*/
export async function getParsedMarkdown(filePath) {
const fileContents = fs.readFileSync(filePath, 'utf8');
const fileMatter = matter(fileContents);
const frontMatter = fileMatter.data;
// Use remark to convert markdown into HTML string
const processedContent = await remark()
.use(remarkGfm)
.use(remarkHtml)
.process(fileMatter.content);
const contentHtml = processedContent.toString();
// Combine the data with the slug and contentHtml
return {
contentHtml,
frontMatter,
};
}
/**
* Walk the markdown file tree to generate the static paths for Next.js components
* @param {string} dirPath The full path to markdown subdirectory
* @param {string} scope The subdirectory of ./markdown
* @param {Array} arrayOfFiles The static paths array formatted for Next.js
* @returns {Array}
*/
function _getMarkdownPaths(dirPath, scope, arrayOfFiles = [{params:{slug:[]}}]) {
const files = fs.readdirSync(dirPath);
files.forEach((file) => {
const filePath = `${dirPath}/${file}`;
const isDirectory = fs.statSync(filePath).isDirectory();
const isMarkdown = /\.md$/.test(file);
let slug;
if (isDirectory) {
const indexFile = path.join(filePath, 'index.md');
const isIndexFile = fs.existsSync(indexFile);
if (isIndexFile) {
slug = _getCleanSlug(scope, path.join(
__dirname,
dirPath,
'/',
file
));
arrayOfFiles.push({
params: {
slug,
},
});
}
arrayOfFiles = _getMarkdownPaths(filePath, scope, arrayOfFiles);
} else if (isMarkdown) {
slug = _getCleanSlug(scope, path.join(
__dirname,
dirPath,
'/',
file.replace(/\.md$/, '')
));
arrayOfFiles.push({
params: {
slug,
},
});
}
});
return arrayOfFiles;
}
/**
* Public method to return static props for Next.js components
* @param {string} scope The subdirectory of ./markdown
* @param {string} slug The markdown fileName
* @returns {Object|null}
*/
export async function getMarkdown(scope, slug) {
let filePath = slug ? path.join(
markdownDir,
scope,
slug.join('/')
) : path.join(
markdownDir,
scope,
'index.md'
);
const isDirectory = (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory());
let isMarkdown = /\.md$/.test(filePath);
if (isDirectory) {
filePath = path.join(
markdownDir,
scope,
slug.join('/'),
'index.md'
);
isMarkdown = true;
} else if (!isMarkdown) {
filePath = path.join(
markdownDir,
scope,
`${slug.join('/')}.md`
);
isMarkdown = true;
}
if (isMarkdown && fs.existsSync(filePath)) {
return getParsedMarkdown(filePath);
}
return null;
}
/**
* Public proxy for _getMarkdownPaths() to return static paths for Next.js components
* @param {string} scope The subdirectory of ./markdown
* @returns {Array}
*/
export function getMarkdownPaths(scope) {
const paths = _getMarkdownPaths(path.join(markdownDir, scope), scope);
return paths;
}