From fcc2f4704e39b0e69b377cc138f75027721dac22 Mon Sep 17 00:00:00 2001 From: Dawid Rycerz Date: Tue, 22 Jul 2025 15:08:37 +0300 Subject: Initial template --- src/utils/permalinks.ts | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 src/utils/permalinks.ts (limited to 'src/utils/permalinks.ts') diff --git a/src/utils/permalinks.ts b/src/utils/permalinks.ts new file mode 100644 index 0000000..4e3078d --- /dev/null +++ b/src/utils/permalinks.ts @@ -0,0 +1,134 @@ +import slugify from 'limax'; + +import { SITE, APP_BLOG } from 'astrowind:config'; + +import { trim } from '~/utils/utils'; + +export const trimSlash = (s: string) => trim(trim(s, '/')); +const createPath = (...params: string[]) => { + const paths = params + .map((el) => trimSlash(el)) + .filter((el) => !!el) + .join('/'); + return '/' + paths + (SITE.trailingSlash && paths ? '/' : ''); +}; + +const BASE_PATHNAME = SITE.base || '/'; + +export const cleanSlug = (text = '') => + trimSlash(text) + .split('/') + .map((slug) => slugify(slug)) + .join('/'); + +export const BLOG_BASE = cleanSlug(APP_BLOG?.list?.pathname); +export const CATEGORY_BASE = cleanSlug(APP_BLOG?.category?.pathname); +export const TAG_BASE = cleanSlug(APP_BLOG?.tag?.pathname) || 'tag'; + +export const POST_PERMALINK_PATTERN = trimSlash(APP_BLOG?.post?.permalink || `${BLOG_BASE}/%slug%`); + +/** */ +export const getCanonical = (path = ''): string | URL => { + const url = String(new URL(path, SITE.site)); + if (SITE.trailingSlash == false && path && url.endsWith('/')) { + return url.slice(0, -1); + } else if (SITE.trailingSlash == true && path && !url.endsWith('/')) { + return url + '/'; + } + return url; +}; + +/** */ +export const getPermalink = (slug = '', type = 'page'): string => { + let permalink: string; + + if ( + slug.startsWith('https://') || + slug.startsWith('http://') || + slug.startsWith('://') || + slug.startsWith('#') || + slug.startsWith('javascript:') + ) { + return slug; + } + + switch (type) { + case 'home': + permalink = getHomePermalink(); + break; + + case 'blog': + permalink = getBlogPermalink(); + break; + + case 'asset': + permalink = getAsset(slug); + break; + + case 'category': + permalink = createPath(CATEGORY_BASE, trimSlash(slug)); + break; + + case 'tag': + permalink = createPath(TAG_BASE, trimSlash(slug)); + break; + + case 'post': + permalink = createPath(trimSlash(slug)); + break; + + case 'page': + default: + permalink = createPath(slug); + break; + } + + return definitivePermalink(permalink); +}; + +/** */ +export const getHomePermalink = (): string => getPermalink('/'); + +/** */ +export const getBlogPermalink = (): string => getPermalink(BLOG_BASE); + +/** */ +export const getAsset = (path: string): string => + '/' + + [BASE_PATHNAME, path] + .map((el) => trimSlash(el)) + .filter((el) => !!el) + .join('/'); + +/** */ +const definitivePermalink = (permalink: string): string => createPath(BASE_PATHNAME, permalink); + +/** */ +export const applyGetPermalinks = (menu: object = {}) => { + if (Array.isArray(menu)) { + return menu.map((item) => applyGetPermalinks(item)); + } else if (typeof menu === 'object' && menu !== null) { + const obj = {}; + for (const key in menu) { + if (key === 'href') { + if (typeof menu[key] === 'string') { + obj[key] = getPermalink(menu[key]); + } else if (typeof menu[key] === 'object') { + if (menu[key].type === 'home') { + obj[key] = getHomePermalink(); + } else if (menu[key].type === 'blog') { + obj[key] = getBlogPermalink(); + } else if (menu[key].type === 'asset') { + obj[key] = getAsset(menu[key].url); + } else if (menu[key].url) { + obj[key] = getPermalink(menu[key].url, menu[key].type); + } + } + } else { + obj[key] = applyGetPermalinks(menu[key]); + } + } + return obj; + } + return menu; +}; -- cgit v1.2.3