import BlogPostUtil, { BlogPost, BlogPostHeader } from "../Utils/BlogPost"; import { BlogRootPath, ViewsPath } from "../Utils/Config"; import NotFoundUtil from "../Utils/NotFound"; import Text from "Common/Types/Text"; import Express, { ExpressApplication, ExpressRequest, ExpressResponse, NextFunction, } from "Common/Server/Utils/Express"; import logger from "Common/Server/Utils/Logger"; import Response from "Common/Server/Utils/Response"; import Route from "Common/Types/API/Route"; import { IsBillingEnabled } from "Common/Server/EnvironmentConfig"; const app: ExpressApplication = Express.getExpressApp(); // create redirect for old blog post urls. This is to handle old blog post urls that are indexed by search engines. app.get( "/blog/post/:file", async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const fileName: string = req.params["file"] as string; return Response.redirect( req, res, new Route(`/blog/post/${fileName}/view`), ); } catch (e) { logger.error(e); return next(e); } }, ); app.get( "/blog/post/:file/view", async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const fileName: string = req.params["file"] as string; const blogPost: BlogPost | null = await BlogPostUtil.getBlogPost(fileName); if (!blogPost) { return NotFoundUtil.renderNotFound(res); } res.render(`${ViewsPath}/Blog/Post`, { support: false, footerCards: true, cta: true, blackLogo: false, requestDemoCta: false, blogPost: blogPost, enableGoogleTagManager: IsBillingEnabled, }); } catch (e) { logger.error(e); return next(e); } }, ); app.get( "/blog/post/:postName/:fileName", async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { /* * return static files for blog post images * the static files are stored in the /usr/src/blog/post/:file/:imageName */ try { const fileName: string = req.params["fileName"] as string; const postName: string = req.params["postName"] as string; return Response.sendFileByPath( req, res, `${BlogRootPath}/posts/${postName}/${fileName}`, ); } catch (e) { logger.error(e); return next(e); } }, ); // List all blog posts with tag app.get( "/blog/tag/:tagName", async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const tagName: string = req.params["tagName"] as string; const tagSlug: string = tagName; // original slug // Pagination params const pageParam: string | undefined = req.query["page"] as | string | undefined; const pageSizeParam: string | undefined = req.query["pageSize"] as | string | undefined; let page: number = pageParam ? parseInt(pageParam, 10) : 1; let pageSize: number = pageSizeParam ? parseInt(pageSizeParam, 10) : 25; if (isNaN(page) || page < 1) { page = 1; } if (isNaN(pageSize) || pageSize < 1) { pageSize = 25; } if (pageSize > 100) { pageSize = 100; } const allPosts: Array = await BlogPostUtil.getBlogPostList(tagName); const totalPosts: number = allPosts.length; const totalPages: number = Math.ceil(totalPosts / pageSize) || 1; if (page > totalPages) { page = totalPages; } const start: number = (page - 1) * pageSize; const paginatedPosts: Array = allPosts.slice( start, start + pageSize, ); const allTags: Array = await BlogPostUtil.getTags(); res.render(`${ViewsPath}/Blog/ListByTag`, { support: false, footerCards: true, cta: true, blackLogo: false, requestDemoCta: false, blogPosts: paginatedPosts, tagName: Text.fromDashesToPascalCase(tagName), tagSlug: tagSlug, allTags: allTags, page: page, pageSize: pageSize, totalPages: totalPages, totalPosts: totalPosts, basePath: `/blog/tag/${tagSlug}`, enableGoogleTagManager: IsBillingEnabled, }); } catch (e) { logger.error(e); return next(e); } }, ); // main blog page app.get( "/blog", async (_req: ExpressRequest, res: ExpressResponse, next: NextFunction) => { try { const req: ExpressRequest = _req; // alias for clarity const pageParam: string | undefined = req.query["page"] as | string | undefined; const pageSizeParam: string | undefined = req.query["pageSize"] as | string | undefined; let page: number = pageParam ? parseInt(pageParam, 10) : 1; let pageSize: number = pageSizeParam ? parseInt(pageSizeParam, 10) : 25; if (isNaN(page) || page < 1) { page = 1; } if (isNaN(pageSize) || pageSize < 1) { pageSize = 25; } if (pageSize > 100) { pageSize = 100; } const allPosts: Array = await BlogPostUtil.getBlogPostList(); const totalPosts: number = allPosts.length; const totalPages: number = Math.ceil(totalPosts / pageSize) || 1; if (page > totalPages) { page = totalPages; } const start: number = (page - 1) * pageSize; const paginatedPosts: Array = allPosts.slice( start, start + pageSize, ); const allTags: Array = await BlogPostUtil.getTags(); res.render(`${ViewsPath}/Blog/List`, { support: false, footerCards: true, cta: true, blackLogo: false, requestDemoCta: false, blogPosts: paginatedPosts, page: page, pageSize: pageSize, totalPages: totalPages, totalPosts: totalPosts, basePath: `/blog`, allTags: allTags, enableGoogleTagManager: IsBillingEnabled, }); } catch (e) { logger.error(e); return next(e); } }, );