Add date formatter, language and text direction settings

This commit is contained in:
prototypa
2023-01-08 12:28:59 -05:00
parent a210c72431
commit 8ce8421334
12 changed files with 121 additions and 65 deletions

View File

@ -149,11 +149,21 @@ const CONFIG = {
trailingSlash: false, // Generate permalinks with or without "/" at the end trailingSlash: false, // Generate permalinks with or without "/" at the end
title: 'Example - This is the homepage title of Example', // default seo title title: 'Example - This is the homepage title of Example', // default seo title
description: 'This is the homepage description of Example', // default seo descriptio description: 'This is the homepage description of Example', // default seo description
defaultImage: 'image.jpg', // default seo image defaultImage: 'image.jpg', // default seo image
defaultTheme: 'system', // Values: "system" | "light" | "dark" | "light:only" | "dark:only" defaultTheme: 'system', // Values: "system" | "light" | "dark" | "light:only" | "dark:only"
language: 'en', // default language
textDirection: 'ltr', // default html text direction
dateFormatter: new Intl.DateTimeFormat('en', { // date format
year: 'numeric',
month: 'short',
day: 'numeric',
timeZone: 'UTC',
}),
googleAnalyticsId: false, // or "G-XXXXXXXXXX", googleAnalyticsId: false, // or "G-XXXXXXXXXX",
googleSiteVerificationId: false, // or some value, googleSiteVerificationId: false, // or some value,

View File

@ -13,6 +13,16 @@ const CONFIG = {
defaultTheme: 'system', // Values: "system" | "light" | "dark" | "light:only" | "dark:only" defaultTheme: 'system', // Values: "system" | "light" | "dark" | "light:only" | "dark:only"
language: 'en',
textDirection: 'ltr',
dateFormatter: new Intl.DateTimeFormat('en', {
year: 'numeric',
month: 'short',
day: 'numeric',
timeZone: 'UTC',
}),
googleAnalyticsId: false, // or "G-XXXXXXXXXX", googleAnalyticsId: false, // or "G-XXXXXXXXXX",
googleSiteVerificationId: 'orcPxI47GSa-cRvY11tUe6iGg2IO_RPvnA1q95iEM3M', googleSiteVerificationId: 'orcPxI47GSa-cRvY11tUe6iGg2IO_RPvnA1q95iEM3M',
@ -48,3 +58,4 @@ const CONFIG = {
export const SITE = { ...CONFIG, blog: undefined }; export const SITE = { ...CONFIG, blog: undefined };
export const BLOG = CONFIG.blog; export const BLOG = CONFIG.blog;
export const DATE_FORMATTER = CONFIG.dateFormatter;

View File

@ -1,11 +1,14 @@
--- ---
publishDate: 'Aug 08 2022' publishDate: 2023-01-08T00:00:00Z
title: 'AstroWind template in depth' title: AstroWind template in depth
description: 'Ornare cum cursus laoreet sagittis nunc fusce posuere per euismod dis vehicula a, semper fames lacus maecenas dictumst pulvinar neque enim non potenti. Torquent hac sociosqu eleifend potenti.' description: Ornare cum cursus laoreet sagittis nunc fusce posuere per euismod dis vehicula a, semper fames lacus maecenas dictumst pulvinar neque enim non potenti. Torquent hac sociosqu eleifend potenti.
image: '~/assets/images/old.jpg' image: ~/assets/images/old.jpg
category: 'Tutorials' category: Tutorials
tags: [astro, tailwind css, front-end] tags:
canonical: https://astrowind.vercel.app/astrowind-template-in-depth # When posting content to multiple platforms at the same time (such as this website and Medium) and want to specify the ultimate authority. Remove it to automatically generate canonical - astro
- tailwind css
- front-end
canonical: https://astrowind.vercel.app/astrowind-template-in-depth
--- ---
## Dictum integer fusce ac ridiculus et odio sollicitudin diam at ## Dictum integer fusce ac ridiculus et odio sollicitudin diam at

View File

@ -1,12 +1,14 @@
--- ---
publishDate: 'Aug 12 2022' publishDate: 2023-01-12T00:00:00Z
title: 'Get started with AstroWind to create a website using Astro and Tailwind CSS' title: Get started with AstroWind to create a website using Astro and Tailwind CSS
description: 'Lorem ipsum dolor sit amet' description: Lorem ipsum dolor sit amet
excerpt: 'Sint sit cillum pariatur eiusmod nulla pariatur ipsum. Sit laborum anim qui mollit tempor pariatur nisi minim dolor. Aliquip et adipisicing sit sit fugiat' excerpt: Sint sit cillum pariatur eiusmod nulla pariatur ipsum. Sit laborum anim qui mollit tempor pariatur nisi minim dolor. Aliquip et adipisicing sit sit fugiat
image: '~/assets/images/steps.jpg' image: ~/assets/images/steps.jpg
category: 'Tutorials' category: Tutorials
tags: [astro, tailwind css] tags:
canonical: https://astrowind.vercel.app/get-started-website-with-astro-tailwind-css # When posting content to multiple platforms at the same time (such as this website and Medium) and want to specify the ultimate authority. Remove it to automatically generate canonical - astro
- tailwind css
canonical: https://astrowind.vercel.app/get-started-website-with-astro-tailwind-css
--- ---
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

View File

@ -1,10 +1,13 @@
--- ---
publishDate: 'Aug 10 2022' publishDate: 2023-01-06T00:00:00Z
title: 'How to customize AstroWind template to suit your branding' title: How to customize AstroWind template to suit your branding
description: 'Sint sit cillum pariatur eiusmod nulla pariatur ipsum. Sit laborum anim qui mollit tempor pariatur nisi minim dolor. Aliquip et adipisicing sit sit fugiat' description: Sint sit cillum pariatur eiusmod nulla pariatur ipsum. Sit laborum anim qui mollit tempor pariatur nisi minim dolor. Aliquip et adipisicing sit sit fugiat
image: '~/assets/images/colors.jpg' image: ~/assets/images/colors.jpg
tags: [astro, tailwind css, theme] tags:
canonical: https://astrowind.vercel.app/how-to-customize-astrowind-to-your-brand # When posting content to multiple platforms at the same time (such as this website and Medium) and want to specify the ultimate authority. Remove it to automatically generate canonical - astro
- tailwind css
- theme
canonical: https://astrowind.vercel.app/how-to-customize-astrowind-to-your-brand
--- ---
## Congue justo vulputate nascetur convallis varius orci fringilla nulla pharetr ## Congue justo vulputate nascetur convallis varius orci fringilla nulla pharetr

View File

@ -1,9 +1,12 @@
--- ---
publishDate: 'Aug 02 2022' publishDate: 2023-01-02T00:00:00Z
title: 'Markdown elements demo post' title: Markdown elements demo post
description: 'Lorem ipsum dolor sit amet' description: Lorem ipsum dolor sit amet
excerpt: 'Sint sit cillum pariatur eiusmod nulla pariatur ipsum. Sit laborum anim qui mollit tempor pariatur nisi minim dolor. Aliquip et adipisicing sit sit fugiat' excerpt: Sint sit cillum pariatur eiusmod nulla pariatur ipsum. Sit laborum anim qui mollit tempor pariatur nisi minim dolor. Aliquip et adipisicing sit sit fugiat
tags: [markdown, blog, Astro] tags:
- markdown
- blog
- Astro
--- ---
import Logo from '~/components/common/Logo.astro'; import Logo from '~/components/common/Logo.astro';

View File

@ -1,9 +1,12 @@
--- ---
publishDate: 'Aug 09 2022' publishDate: 2023-01-09T00:00:00Z
title: 'Useful tools and resources to create a professional website' title: Useful tools and resources to create a professional website
description: 'Nibh senectus lacinia volutpat nostra taciti ac posuere, dictum ultricies dictumst luctus in vehicula, mus molestie venenatis penatibus ridiculus elementum. Phasellus sollicitudin dignissim parturient.' description: Nibh senectus lacinia volutpat nostra taciti ac posuere, dictum ultricies dictumst luctus in vehicula, mus molestie venenatis penatibus ridiculus elementum. Phasellus sollicitudin dignissim parturient.
image: '~/assets/images/tools.jpg' image: ~/assets/images/tools.jpg
tags: [front-end, tools, resources] tags:
- front-end
- tools
- resources
--- ---
## Magna nunc senectus torquent per fusce sapien ligula tempus cra ## Magna nunc senectus torquent per fusce sapien ligula tempus cra

View File

@ -1,5 +1,4 @@
import { z, defineCollection } from 'astro:content'; import { z, defineCollection } from 'astro:content';
import { cleanSlug } from '~/utils/permalinks';
const blog = defineCollection({ const blog = defineCollection({
schema: { schema: {
@ -10,7 +9,9 @@ const blog = defineCollection({
canonical: z.string().url().optional(), canonical: z.string().url().optional(),
permalink: z.string().optional(), permalink: z.string().optional(),
publishDate: z.date().optional(), publishDate: z
.date().or(z.string())
.optional(),
draft: z.boolean().optional(), draft: z.boolean().optional(),
excerpt: z.string().optional(), excerpt: z.string().optional(),
@ -19,7 +20,7 @@ const blog = defineCollection({
author: z.string().optional(), author: z.string().optional(),
}, },
slug: ({ defaultSlug, data }) => { slug: ({ defaultSlug, data }) => {
return cleanSlug(data.permalink || defaultSlug); return data.permalink || defaultSlug;
}, },
}); });

View File

@ -5,16 +5,18 @@ import MetaTags from '~/components/common/MetaTags.astro';
import BasicScripts from '~/components/common/BasicScripts.astro'; import BasicScripts from '~/components/common/BasicScripts.astro';
import { MetaSEO } from '~/types'; import { MetaSEO } from '~/types';
import { SITE } from '~/config.mjs';
export interface Props { export interface Props {
meta?: MetaSEO; meta?: MetaSEO;
} }
const { meta = {} } = Astro.props; const { meta = {} } = Astro.props;
const { language = 'en', textDirection = 'ltr' } = SITE;
--- ---
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" class="motion-safe:scroll-smooth 2xl:text-[20px]"> <html lang={language} dir={textDirection} class="motion-safe:scroll-smooth 2xl:text-[20px]">
<head> <head>
<MetaTags {...meta} /> <MetaTags {...meta} />
</head> </head>

View File

@ -4,14 +4,14 @@ import type { Post } from '~/types';
import { cleanSlug } from './permalinks'; import { cleanSlug } from './permalinks';
const getNormalizedPost = async (post: CollectionEntry<'blog'>): Promise<Post> => { const getNormalizedPost = async (post: CollectionEntry<'blog'>): Promise<Post> => {
const { id, slug, data } = post; const { id, slug = '', data } = post;
const { Content, injectedFrontmatter } = await post.render(); const { Content, injectedFrontmatter } = await post.render();
const { tags = [], category = 'default', author = 'Anonymous', publishDate, ...rest } = data; const { tags = [], category = 'default', author = 'Anonymous', publishDate = new Date(), ...rest } = data;
return { return {
id: id, id: id,
slug: slug, slug: cleanSlug(slug.split('/').pop() ?? ''),
publishDate: new Date(publishDate), publishDate: new Date(publishDate),
category: cleanSlug(category), category: cleanSlug(category),

View File

@ -1,22 +1,18 @@
import slugify from 'limax'; import slugify from 'limax';
import { SITE, BLOG } from '~/config.mjs'; import { SITE, BLOG } from '~/config.mjs';
import { trim } from '~/utils/utils';
const trim = (str = '', ch?: string) => {
let start = 0,
end = str.length || 0;
while (start < end && str[start] === ch) ++start;
while (end > start && str[end - 1] === ch) --end;
return start > 0 || end < str.length ? str.substring(start, end) : str;
};
const trimSlash = (s: string) => trim(trim(s, '/')); const trimSlash = (s: string) => trim(trim(s, '/'));
const createPath = (...params: string[]) => { const createPath = (...params: string[]) => {
const paths = params.filter((el) => !!el).join('/'); const paths = params
.map((el) => trimSlash(el))
.filter((el) => !!el)
.join('/');
return '/' + paths + (SITE.trailingSlash && paths ? '/' : ''); return '/' + paths + (SITE.trailingSlash && paths ? '/' : '');
}; };
const basePathname = trimSlash(SITE.basePathname); const BASE_PATHNAME = SITE.basePathname;
export const cleanSlug = (text: string) => export const cleanSlug = (text: string) =>
trimSlash(text) trimSlash(text)
@ -34,25 +30,35 @@ export const getCanonical = (path = ''): string | URL => new URL(path, SITE.orig
/** */ /** */
export const getPermalink = (slug = '', type = 'page'): string => { export const getPermalink = (slug = '', type = 'page'): string => {
let permalink: string;
switch (type) { switch (type) {
case 'category': case 'category':
return createPath(basePathname, CATEGORY_BASE, cleanSlug(slug)); permalink = createPath(CATEGORY_BASE, cleanSlug(slug));
break;
case 'tag': case 'tag':
return createPath(basePathname, TAG_BASE, cleanSlug(slug)); permalink = createPath(TAG_BASE, cleanSlug(slug));
break;
case 'post': case 'post':
return createPath(basePathname, POST_BASE, cleanSlug(slug)); permalink = createPath(POST_BASE, cleanSlug(slug));
break;
case 'page':
default:
permalink = createPath(slug);
break;
} }
return createPath(basePathname, trimSlash(slug)); return definitivePermalink(permalink);
}; };
/** */ /** */
export const getHomePermalink = (): string => { export const getHomePermalink = (): string => getPermalink('/');
const permalink = getPermalink();
return !permalink.startsWith('/') ? '/' + permalink : permalink;
};
/** */ /** */
export const getBlogPermalink = (): string => getPermalink(BLOG_BASE); export const getBlogPermalink = (): string => getPermalink(BLOG_BASE);
/** */
const definitivePermalink = (permalink: string): string => createPath(BASE_PATHNAME, permalink);

View File

@ -1,9 +1,21 @@
import { DATE_FORMATTER } from '~/config.mjs';
const formatter =
DATE_FORMATTER ||
new Intl.DateTimeFormat('en', {
year: 'numeric',
month: 'short',
day: 'numeric',
timeZone: 'UTC'
});
/* eslint-disable no-mixed-spaces-and-tabs */ /* eslint-disable no-mixed-spaces-and-tabs */
export const getFormattedDate = (date: Date) => export const getFormattedDate = (date: Date) => (date ? formatter.format(date) : '');
date
? new Date(date).toLocaleDateString('en-us', { export const trim = (str = '', ch?: string) => {
year: 'numeric', let start = 0,
month: 'short', end = str.length || 0;
day: 'numeric', while (start < end && str[start] === ch) ++start;
}) while (end > start && str[end - 1] === ch) --end;
: ''; return start > 0 || end < str.length ? str.substring(start, end) : str;
};