1
0
Fork 0
mirror of https://github.com/codex-team/codex.docs.git synced 2025-07-18 20:59:42 +02:00

Static generation fixes (#292)
Some checks are pending
Build and push Docker image / build (push) Waiting to run
Release Drafter / update_release_draft (push) Waiting to run

* add error handler for creating dist folder

* fix favicon in generated files

* add option for generating pages inside separate folders

* fix favicon problem

---------

Co-authored-by: Peter Savchenko <specc.dev@gmail.com>
This commit is contained in:
Nikita Melnikov 2024-04-26 22:57:49 +01:00 committed by GitHub
parent a6391a3da0
commit f8ba8abf19
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 60 additions and 25 deletions

View file

@ -13,6 +13,7 @@ import fse from 'fs-extra';
import appConfig from './utils/appConfig.js'; import appConfig from './utils/appConfig.js';
import Aliases from './controllers/aliases.js'; import Aliases from './controllers/aliases.js';
import Pages from './controllers/pages.js'; import Pages from './controllers/pages.js';
import { downloadFavicon } from './utils/downloadFavicon.js';
/** /**
* Build static pages from database * Build static pages from database
@ -54,7 +55,33 @@ export default async function buildStatic(): Promise<void> {
const pagesOrder = await PagesOrder.getAll(); const pagesOrder = await PagesOrder.getAll();
const allPages = await Page.getAll(); const allPages = await Page.getAll();
await mkdirp(distPath); try {
console.log('Create dist folder');
await mkdirp(distPath);
} catch (e) {
console.log('Error while creating dist folder', e);
return;
}
console.log('Copy public directory');
const publicDir = path.resolve(dirname, '../../public');
console.log(`Copy from ${publicDir} to ${distPath}`);
try {
await fse.copy(publicDir, distPath);
console.log('Public directory copied');
} catch (e) {
console.log('Error while copying public directory');
console.error(e);
}
const favicon = appConfig.favicon ? await downloadFavicon(appConfig.favicon, distPath, '') : {
destination: '/favicon.png',
type: 'image/png',
};
/** /**
* Renders single page * Renders single page
@ -64,6 +91,11 @@ export default async function buildStatic(): Promise<void> {
*/ */
async function renderPage(page: Page, isIndex?: boolean): Promise<void> { async function renderPage(page: Page, isIndex?: boolean): Promise<void> {
console.log(`Rendering page ${page.uri}`); console.log(`Rendering page ${page.uri}`);
const pageUri = page.uri;
if (!pageUri) {
throw new Error('Page uri is not defined');
}
const pageParent = await page.getParent(); const pageParent = await page.getParent();
const pageId = page._id; const pageId = page._id;
@ -74,16 +106,30 @@ export default async function buildStatic(): Promise<void> {
const previousPage = await PagesFlatArray.getPageBefore(pageId); const previousPage = await PagesFlatArray.getPageBefore(pageId);
const nextPage = await PagesFlatArray.getPageAfter(pageId); const nextPage = await PagesFlatArray.getPageAfter(pageId);
const menu = createMenuTree(parentIdOfRootPages, allPages, pagesOrder, 2); const menu = createMenuTree(parentIdOfRootPages, allPages, pagesOrder, 2);
const result = await renderTemplate('./views/pages/page.twig', { const result = await renderTemplate('./views/pages/page.twig', {
page, page,
pageParent, pageParent,
previousPage, previousPage,
nextPage, nextPage,
menu, menu,
favicon,
config: appConfig.frontend, config: appConfig.frontend,
}); });
const filename = (isIndex || page.uri === '') ? 'index.html' : `${page.uri}.html`; let filename: string;
if (isIndex) {
filename = 'index.html';
} else if (config?.pagesInsideFolders) { // create folder for each page if pagesInsideFolders is true
const pagePath = path.resolve(distPath, pageUri);
await mkdirp(pagePath);
filename = path.resolve(pagePath, 'index.html');
} else {
filename = `${page.uri}.html`;
}
await fs.writeFile(path.resolve(distPath, filename), result); await fs.writeFile(path.resolve(distPath, filename), result);
console.log(`Page ${page.uri} rendered`); console.log(`Page ${page.uri} rendered`);
@ -119,19 +165,6 @@ export default async function buildStatic(): Promise<void> {
} }
console.log('Static files built'); console.log('Static files built');
console.log('Copy public directory');
const publicDir = path.resolve(dirname, '../../public');
console.log(`Copy from ${publicDir} to ${distPath}`);
try {
await fse.copy(publicDir, distPath);
console.log('Public directory copied');
} catch (e) {
console.log('Error while copying public directory');
console.error(e);
}
if (appConfig.uploads.driver === 'local') { if (appConfig.uploads.driver === 'local') {
console.log('Copy uploads directory'); console.log('Copy uploads directory');
await fse.copy(path.resolve(cwd, appConfig.uploads.local.path), path.resolve(distPath, 'uploads')); await fse.copy(path.resolve(cwd, appConfig.uploads.local.path), path.resolve(distPath, 'uploads'));

View file

@ -90,7 +90,10 @@ const FrontendConfig = z.object({
*/ */
const StaticBuildConfig = z.object({ const StaticBuildConfig = z.object({
outputDir: z.string(), // Output directory for static build outputDir: z.string(), // Output directory for static build
overwrite: z.boolean().optional().default(true), overwrite: z.boolean().optional() // Overwrite output directory
.default(true),
pagesInsideFolders: z.boolean().optional() // Create separate folder for each page
.default(true),
indexPage: z.object({ indexPage: z.object({
enabled: z.boolean(), // Is index page enabled enabled: z.boolean(), // Is index page enabled
uri: z.string(), // Index page uri uri: z.string(), // Index page uri

View file

@ -1,5 +1,5 @@
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs/promises';
import fetch, { RequestInit } from 'node-fetch'; import fetch, { RequestInit } from 'node-fetch';
/** /**
@ -32,9 +32,10 @@ function checkIsUrl(str: string): boolean {
* *
* @param destination - url or path of favicon * @param destination - url or path of favicon
* @param faviconFolder - folder to save favicon * @param faviconFolder - folder to save favicon
* @param subRoute - subroute from which the favicon will be served
* @returns { Promise<FaviconData> } - Promise with data about favicon * @returns { Promise<FaviconData> } - Promise with data about favicon
*/ */
export async function downloadFavicon(destination: string, faviconFolder: string): Promise<FaviconData> { export async function downloadFavicon(destination: string, faviconFolder: string, subRoute = '/favicon'): Promise<FaviconData> {
// Check of destination is empty // Check of destination is empty
if (!destination) { if (!destination) {
throw Error('Favicon destination is empty'); throw Error('Favicon destination is empty');
@ -48,8 +49,10 @@ export async function downloadFavicon(destination: string, faviconFolder: string
// Check if string is url // Check if string is url
if (!checkIsUrl(destination)) { if (!checkIsUrl(destination)) {
await fs.copyFile(destination, path.join(faviconFolder, filename));
return { return {
destination: `/${filename}`, destination: `${subRoute}/${filename}`,
type: `image/${format}`, type: `image/${format}`,
} as FaviconData; } as FaviconData;
} }
@ -72,14 +75,10 @@ export async function downloadFavicon(destination: string, faviconFolder: string
const filePath = path.join(faviconFolder, `favicon.${format}`); const filePath = path.join(faviconFolder, `favicon.${format}`);
// Save file // Save file
await fs.writeFile(filePath, fileData, (err) => { await fs.writeFile(filePath, fileData);
if (err) {
console.log(err);
}
});
return { return {
destination: `/favicon/favicon.${format}`, destination: `${subRoute}/favicon.${format}`,
type: `image/${format}`, type: `image/${format}`,
} as FaviconData; } as FaviconData;
} }