Simplify folders and more typescript migration
This commit is contained in:
@ -76,9 +76,8 @@ Inside AstroWind template, you'll see the following folders and files:
|
|||||||
| | └── styles/
|
| | └── styles/
|
||||||
| | └── base.css
|
| | └── base.css
|
||||||
│ ├── components/
|
│ ├── components/
|
||||||
│ │ ├── atoms/
|
|
||||||
│ │ ├── blog/
|
│ │ ├── blog/
|
||||||
│ │ ├── core/
|
│ │ ├── common/
|
||||||
| | └── widgets/
|
| | └── widgets/
|
||||||
| | ├── Header.astro
|
| | ├── Header.astro
|
||||||
| | ├── Footer.astro
|
| | ├── Footer.astro
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@onwidget/astrowind",
|
"name": "@onwidget/astrowind",
|
||||||
"description": "A template to make your website using Astro + Tailwind CSS.",
|
"description": "A template to make your website using Astro + Tailwind CSS.",
|
||||||
"version": "0.9.2",
|
"version": "0.9.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Item from '~/components/blog/GridItem.astro';
|
import Item from '~/components/blog/GridItem.astro';
|
||||||
import type { Post } from "~/types"
|
import type { Post } from '~/types';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
posts: Array<Post>;
|
posts: Array<Post>;
|
||||||
|
@ -4,7 +4,7 @@ import { Picture } from '@astrojs/image/components';
|
|||||||
import { findImage } from '~/utils/images';
|
import { findImage } from '~/utils/images';
|
||||||
import { getPermalink } from '~/utils/permalinks';
|
import { getPermalink } from '~/utils/permalinks';
|
||||||
|
|
||||||
import type { Post } from "~/types"
|
import type { Post } from '~/types';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
post: Post;
|
post: Post;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
import Grid from '~/components/blog/Grid.astro';
|
import Grid from '~/components/blog/Grid.astro';
|
||||||
|
|
||||||
|
import { getBlogPermalink } from '~/utils/permalinks';
|
||||||
import { findPostsByIds } from '~/utils/posts';
|
import { findPostsByIds } from '~/utils/posts';
|
||||||
|
|
||||||
const ids = [
|
const ids = [
|
||||||
@ -15,7 +16,12 @@ const posts = await findPostsByIds(ids);
|
|||||||
<section class="px-4 py-16 mx-auto max-w-6xl lg:py-20">
|
<section class="px-4 py-16 mx-auto max-w-6xl lg:py-20">
|
||||||
<div class="flex flex-col mb-6 lg:justify-between lg:flex-row md:mb-8">
|
<div class="flex flex-col mb-6 lg:justify-between lg:flex-row md:mb-8">
|
||||||
<h2 class="max-w-lg mb-2 text-3xl font-bold tracking-tight sm:text-4xl sm:leading-none lg:mb-5 group font-heading">
|
<h2 class="max-w-lg mb-2 text-3xl font-bold tracking-tight sm:text-4xl sm:leading-none lg:mb-5 group font-heading">
|
||||||
<span class="inline-block mb-1 sm:mb-4">Find out more content<br class="hidden md:block" /> in our Blog</span>
|
<span class="inline-block mb-1 sm:mb-4"
|
||||||
|
>Find out more content<br class="hidden md:block" /> in our <a
|
||||||
|
class="hover:text-primary-600 underline underline-offset-4 decoration-1 decoration-dotted transition ease-in duration-200"
|
||||||
|
href={getBlogPermalink()}>Blog</a
|
||||||
|
>
|
||||||
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="text-gray-700 dark:text-slate-400 lg:text-sm lg:max-w-md">
|
<p class="text-gray-700 dark:text-slate-400 lg:text-sm lg:max-w-md">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
import Grid from '~/components/blog/Grid.astro';
|
import Grid from '~/components/blog/Grid.astro';
|
||||||
|
|
||||||
|
import { getBlogPermalink } from '~/utils/permalinks';
|
||||||
import { findLatestPosts } from '~/utils/posts';
|
import { findLatestPosts } from '~/utils/posts';
|
||||||
|
|
||||||
const count = 4;
|
const count = 4;
|
||||||
@ -10,7 +11,12 @@ const posts = await findLatestPosts({ count });
|
|||||||
<section class="px-4 py-16 mx-auto max-w-6xl lg:py-20">
|
<section class="px-4 py-16 mx-auto max-w-6xl lg:py-20">
|
||||||
<div class="flex flex-col mb-6 lg:justify-between lg:flex-row md:mb-8">
|
<div class="flex flex-col mb-6 lg:justify-between lg:flex-row md:mb-8">
|
||||||
<h2 class="max-w-lg mb-2 text-3xl font-bold tracking-tight sm:text-4xl sm:leading-none lg:mb-5 group font-heading">
|
<h2 class="max-w-lg mb-2 text-3xl font-bold tracking-tight sm:text-4xl sm:leading-none lg:mb-5 group font-heading">
|
||||||
<span class="inline-block mb-1 sm:mb-4">Latest articles<br class="hidden md:block" /> in our Blog</span>
|
<span class="inline-block mb-1 sm:mb-4"
|
||||||
|
>Latest articles<br class="hidden md:block" /> in our <a
|
||||||
|
class="hover:text-primary-600 underline underline-offset-4 decoration-1 decoration-dotted transition ease-in duration-200"
|
||||||
|
href={getBlogPermalink()}>Blog</a
|
||||||
|
>
|
||||||
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="text-gray-700 dark:text-slate-400 lg:text-sm lg:max-w-md">
|
<p class="text-gray-700 dark:text-slate-400 lg:text-sm lg:max-w-md">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import Item from '~/components/blog/ListItem.astro';
|
import Item from '~/components/blog/ListItem.astro';
|
||||||
import type { Post } from "~/types"
|
import type { Post } from '~/types';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
posts: Array<Post>;
|
posts: Array<Post>;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
import { Picture } from '@astrojs/image/components';
|
import { Picture } from '@astrojs/image/components';
|
||||||
import PostTags from '~/components/atoms/Tags.astro';
|
import PostTags from '~/components/common/Tags.astro';
|
||||||
|
|
||||||
import { getPermalink } from '~/utils/permalinks';
|
import { getPermalink } from '~/utils/permalinks';
|
||||||
import { findImage } from '~/utils/images';
|
import { findImage } from '~/utils/images';
|
||||||
import { getFormattedDate } from '~/utils/utils';
|
import { getFormattedDate } from '~/utils/utils';
|
||||||
|
|
||||||
import type { Post } from "~/types"
|
import type { Post } from '~/types';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
post: Post;
|
post: Post;
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
---
|
---
|
||||||
import { Picture } from '@astrojs/image/components';
|
import { Picture } from '@astrojs/image/components';
|
||||||
import PostTags from '~/components/atoms/Tags.astro';
|
import PostTags from '~/components/common/Tags.astro';
|
||||||
import SocialShare from '~/components/atoms/SocialShare.astro';
|
import SocialShare from '~/components/common/SocialShare.astro';
|
||||||
|
|
||||||
import { getFormattedDate } from '~/utils/utils';
|
import { getFormattedDate } from '~/utils/utils';
|
||||||
|
|
||||||
import type { Post } from "~/types"
|
import type { Post } from '~/types';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
post: Post;
|
post: Post;
|
||||||
url: string;
|
url: string | URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { post, url } = Astro.props;
|
const { post, url } = Astro.props;
|
||||||
|
8
src/components/blog/Title.astro
Normal file
8
src/components/blog/Title.astro
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1 class="text-center text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-8 md:mb-16 font-heading">
|
||||||
|
<slot />
|
||||||
|
</h1>
|
||||||
|
</header>
|
10
src/components/blog/ToBlogLink.astro
Normal file
10
src/components/blog/ToBlogLink.astro
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
import { Icon } from 'astro-icon';
|
||||||
|
import { getBlogPermalink } from '~/utils/permalinks';
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="mx-auto px-6 sm:px-6 max-w-3xl pt-8 pb-12 md:pb-20 text-center md:text-left">
|
||||||
|
<a class="btn btn-ghost px-3" href={getBlogPermalink()}
|
||||||
|
><Icon name="tabler:chevron-left" class="w-5 h-5 mr-1" /> Back to Blog</a
|
||||||
|
>
|
||||||
|
</div>
|
@ -4,21 +4,23 @@ import { GoogleAnalytics } from '@astrolib/analytics';
|
|||||||
import { getImage } from '@astrojs/image';
|
import { getImage } from '@astrojs/image';
|
||||||
import { getRelativeUrlByFilePath } from '~/utils/directories';
|
import { getRelativeUrlByFilePath } from '~/utils/directories';
|
||||||
|
|
||||||
import defaultImageSrc from '~/assets/images/default.png';
|
|
||||||
|
|
||||||
import { SITE } from '~/config.mjs';
|
import { SITE } from '~/config.mjs';
|
||||||
import Fonts from '../atoms/Fonts.astro';
|
import Fonts from '~/components/common/Fonts.astro';
|
||||||
import ExtraMetaTags from '../atoms/ExtraMetaTags.astro';
|
import ExtraMetaTags from '~/components/common/ExtraMetaTags.astro';
|
||||||
import SplitbeeAnalytics from './SplitbeeAnalytics.astro';
|
import SplitbeeAnalytics from './SplitbeeAnalytics.astro';
|
||||||
|
|
||||||
import { MetaSEO } from '~/types';
|
import { MetaSEO } from '~/types';
|
||||||
|
|
||||||
const { src: defaultImage } = await getImage({
|
const defaultImage = SITE.defaultImage
|
||||||
src: defaultImageSrc,
|
? (
|
||||||
|
await getImage({
|
||||||
|
src: SITE.defaultImage,
|
||||||
alt: 'Default image',
|
alt: 'Default image',
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 628,
|
height: 628,
|
||||||
});
|
})
|
||||||
|
).src
|
||||||
|
: '';
|
||||||
|
|
||||||
export interface Props extends MetaSEO {}
|
export interface Props extends MetaSEO {}
|
||||||
|
|
||||||
@ -39,7 +41,8 @@ const image =
|
|||||||
typeof _image === 'string'
|
typeof _image === 'string'
|
||||||
? new URL(_image, Astro.site)
|
? new URL(_image, Astro.site)
|
||||||
: _image && typeof _image['src'] !== 'undefined'
|
: _image && typeof _image['src'] !== 'undefined'
|
||||||
? new URL(getRelativeUrlByFilePath(_image.src), Astro.site)
|
? // @ts-ignore
|
||||||
|
new URL(getRelativeUrlByFilePath(_image.src), Astro.site)
|
||||||
: null;
|
: null;
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -49,11 +52,11 @@ const image =
|
|||||||
<AstroSeo
|
<AstroSeo
|
||||||
title={title}
|
title={title}
|
||||||
description={description}
|
description={description}
|
||||||
canonical={canonical}
|
canonical={String(canonical)}
|
||||||
noindex={noindex}
|
noindex={noindex}
|
||||||
nofollow={nofollow}
|
nofollow={nofollow}
|
||||||
openGraph={{
|
openGraph={{
|
||||||
url: canonical,
|
url: String(canonical),
|
||||||
title: ogTitle,
|
title: ogTitle,
|
||||||
description: description,
|
description: description,
|
||||||
type: ogType,
|
type: ogType,
|
@ -18,14 +18,14 @@ const { prevUrl, nextUrl, prevText = 'Newer posts', nextText = 'Older posts' } =
|
|||||||
<div class="flex flex-row mx-auto container justify-between">
|
<div class="flex flex-row mx-auto container justify-between">
|
||||||
<a href={getRelativeLink(prevUrl)} class={`btn btn-ghost px-3 mr-2 ${!prevUrl ? 'invisible' : ''}`}>
|
<a href={getRelativeLink(prevUrl)} class={`btn btn-ghost px-3 mr-2 ${!prevUrl ? 'invisible' : ''}`}>
|
||||||
<div class="flex flex-row align-middle">
|
<div class="flex flex-row align-middle">
|
||||||
<Icon name="tabler:arrow-left" class="w-6 h-6" />
|
<Icon name="tabler:chevron-left" class="w-6 h-6" />
|
||||||
<p class="ml-2">{prevText}</p>
|
<p class="ml-2">{prevText}</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href={getRelativeLink(nextUrl)} class={`btn btn-ghost px-3 ${!nextUrl ? 'invisible' : ''}`}>
|
<a href={getRelativeLink(nextUrl)} class={`btn btn-ghost px-3 ${!nextUrl ? 'invisible' : ''}`}>
|
||||||
<div class="flex flex-row align-middle">
|
<div class="flex flex-row align-middle">
|
||||||
<span class="mr-2">{nextText}</span>
|
<span class="mr-2">{nextText}</span>
|
||||||
<Icon name="tabler:arrow-right" class="w-6 h-6" />
|
<Icon name="tabler:chevron-right" class="w-6 h-6" />
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
@ -3,7 +3,7 @@ import { Icon } from 'astro-icon';
|
|||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
text: string;
|
text: string;
|
||||||
url: string;
|
url: string | URL;
|
||||||
class?: string;
|
class?: string;
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import { getPermalink } from '~/utils/permalinks';
|
import { getPermalink } from '~/utils/permalinks';
|
||||||
|
|
||||||
import type { Post } from "~/types"
|
import type { Post } from '~/types';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
tags: Post['tags'];
|
tags: Post['tags'];
|
@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
import { Icon } from 'astro-icon';
|
import { Icon } from 'astro-icon';
|
||||||
import Logo from '~/components/atoms/Logo.astro';
|
import Logo from '~/components/common/Logo.astro';
|
||||||
import ToggleTheme from '~/components/core/ToggleTheme.astro';
|
import ToggleTheme from '~/components/common/ToggleTheme.astro';
|
||||||
import ToggleMenu from '~/components/core/ToggleMenu.astro';
|
import ToggleMenu from '~/components/common/ToggleMenu.astro';
|
||||||
|
|
||||||
import { getHomePermalink, getBlogPermalink, getPermalink, getRelativeLink } from '~/utils/permalinks';
|
import { getHomePermalink, getBlogPermalink, getPermalink, getRelativeLink } from '~/utils/permalinks';
|
||||||
---
|
---
|
||||||
@ -69,9 +69,8 @@ import { getHomePermalink, getBlogPermalink, getPermalink, getRelativeLink } fro
|
|||||||
<li class="md:hidden">
|
<li class="md:hidden">
|
||||||
<a
|
<a
|
||||||
class="font-bold hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
|
class="font-bold hover:text-gray-900 dark:hover:text-white px-4 py-3 flex items-center transition duration-150 ease-in-out"
|
||||||
href="https://github.com/onwidget/astrowind"
|
href="https://github.com/onwidget/astrowind">Github</a
|
||||||
>Github
|
>
|
||||||
</a>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="md:self-center flex items-center mb-4 md:mb-0 ml-2">
|
<div class="md:self-center flex items-center mb-4 md:mb-0 ml-2">
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import defaultImage from './assets/images/default.png';
|
||||||
|
|
||||||
export const SITE = {
|
export const SITE = {
|
||||||
name: 'AstroWind',
|
name: 'AstroWind',
|
||||||
|
|
||||||
@ -8,6 +10,8 @@ export const SITE = {
|
|||||||
title: 'AstroWind — Your website with Astro + Tailwind CSS',
|
title: 'AstroWind — Your website with Astro + Tailwind CSS',
|
||||||
description: '🚀 AstroWind is a free and ready to start template to make your website using Astro and Tailwind CSS.',
|
description: '🚀 AstroWind is a free and ready to start template to make your website using Astro and Tailwind CSS.',
|
||||||
|
|
||||||
|
defaultImage: defaultImage,
|
||||||
|
|
||||||
googleAnalyticsId: false, // or "G-XXXXXXXXXX",
|
googleAnalyticsId: false, // or "G-XXXXXXXXXX",
|
||||||
googleSiteVerificationId: 'orcPxI47GSa-cRvY11tUe6iGg2IO_RPvnA1q95iEM3M',
|
googleSiteVerificationId: 'orcPxI47GSa-cRvY11tUe6iGg2IO_RPvnA1q95iEM3M',
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,7 @@ image: '~/assets/images/astronaut.jpg'
|
|||||||
tags: [markdown, blog, Astro]
|
tags: [markdown, blog, Astro]
|
||||||
---
|
---
|
||||||
|
|
||||||
import Logo from '~/components/atoms/Logo.astro';
|
import Logo from '~/components/common/Logo.astro';
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
import '~/assets/styles/base.css';
|
import '~/assets/styles/base.css';
|
||||||
|
|
||||||
import MetaTags from '~/components/core/MetaTags.astro';
|
import MetaTags from '~/components/common/MetaTags.astro';
|
||||||
import BasicScripts from '~/components/core/BasicScripts.astro';
|
import BasicScripts from '~/components/common/BasicScripts.astro';
|
||||||
|
|
||||||
import { MetaSEO } from '~/types';
|
import { MetaSEO } from '~/types';
|
||||||
|
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
---
|
|
||||||
import Layout from '~/layouts/PageLayout.astro';
|
|
||||||
|
|
||||||
import { MetaSEO } from '~/types';
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
meta?: MetaSEO;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { meta } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<Layout {meta}>
|
|
||||||
<section class="px-6 sm:px-6 py-12 sm:py-16 lg:py-20 mx-auto max-w-3xl">
|
|
||||||
<header>
|
|
||||||
<h1
|
|
||||||
class="text-center text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-8 md:mb-16 font-heading"
|
|
||||||
>
|
|
||||||
<slot name="title" />
|
|
||||||
</h1>
|
|
||||||
</header>
|
|
||||||
<slot />
|
|
||||||
</section>
|
|
||||||
</Layout>
|
|
@ -1,18 +1,17 @@
|
|||||||
---
|
---
|
||||||
import { SITE, BLOG } from '~/config.mjs';
|
import { SITE, BLOG } from '~/config.mjs';
|
||||||
|
|
||||||
import Layout from '~/layouts/BlogLayout.astro';
|
import Layout from '~/layouts/PageLayout.astro';
|
||||||
import BlogList from '~/components/blog/List.astro';
|
import BlogList from '~/components/blog/List.astro';
|
||||||
import Pagination from '~/components/atoms/Pagination.astro';
|
import Pagination from '~/components/common/Pagination.astro';
|
||||||
|
|
||||||
import { fetchPosts } from '~/utils/posts';
|
import { fetchPosts } from '~/utils/posts';
|
||||||
import { getCanonical, getPermalink, BLOG_BASE } from '~/utils/permalinks';
|
import { getCanonical, getPermalink, BLOG_BASE } from '~/utils/permalinks';
|
||||||
|
import Title from '~/components/blog/Title.astro';
|
||||||
|
|
||||||
export async function getStaticPaths({ paginate }) {
|
export async function getStaticPaths({ paginate }) {
|
||||||
if (BLOG?.disabled || BLOG?.blog?.disabled) return [];
|
if (BLOG?.disabled || BLOG?.blog?.disabled) return [];
|
||||||
|
|
||||||
const posts = await fetchPosts();
|
const posts = await fetchPosts();
|
||||||
|
|
||||||
return paginate(posts, {
|
return paginate(posts, {
|
||||||
params: { blog: BLOG_BASE || undefined },
|
params: { blog: BLOG_BASE || undefined },
|
||||||
pageSize: BLOG.postsPerPage,
|
pageSize: BLOG.postsPerPage,
|
||||||
@ -32,10 +31,9 @@ const meta = {
|
|||||||
---
|
---
|
||||||
|
|
||||||
<Layout {meta}>
|
<Layout {meta}>
|
||||||
<Fragment slot="title">
|
<section class="px-6 sm:px-6 py-12 sm:py-16 lg:py-20 mx-auto max-w-3xl">
|
||||||
News and tutorials about
|
<Title>News and tutorials about AstroWind</Title>
|
||||||
<span>AstroWind</span>
|
|
||||||
</Fragment>
|
|
||||||
<BlogList posts={page.data} />
|
<BlogList posts={page.data} />
|
||||||
<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
|
<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
|
||||||
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
@ -3,6 +3,7 @@ import { SITE, BLOG } from '~/config.mjs';
|
|||||||
|
|
||||||
import Layout from '~/layouts/PageLayout.astro';
|
import Layout from '~/layouts/PageLayout.astro';
|
||||||
import SinglePost from '~/components/blog/SinglePost.astro';
|
import SinglePost from '~/components/blog/SinglePost.astro';
|
||||||
|
import ToBlogLink from '~/components/blog/ToBlogLink.astro';
|
||||||
|
|
||||||
import { getCanonical, getPermalink, cleanSlug, POST_BASE } from '~/utils/permalinks';
|
import { getCanonical, getPermalink, cleanSlug, POST_BASE } from '~/utils/permalinks';
|
||||||
import { fetchPosts } from '~/utils/posts';
|
import { fetchPosts } from '~/utils/posts';
|
||||||
@ -10,9 +11,7 @@ import { findImage } from '~/utils/images';
|
|||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
if (BLOG?.disabled || BLOG?.post?.disabled) return [];
|
if (BLOG?.disabled || BLOG?.post?.disabled) return [];
|
||||||
|
|
||||||
const posts = await fetchPosts();
|
const posts = await fetchPosts();
|
||||||
|
|
||||||
return posts.map((post) => ({
|
return posts.map((post) => ({
|
||||||
params: {
|
params: {
|
||||||
slug: cleanSlug(post.slug),
|
slug: cleanSlug(post.slug),
|
||||||
@ -37,4 +36,5 @@ const meta = {
|
|||||||
|
|
||||||
<Layout {meta}>
|
<Layout {meta}>
|
||||||
<SinglePost post={{ ...post, image: meta.image }} url={url} />
|
<SinglePost post={{ ...post, image: meta.image }} url={url} />
|
||||||
|
<ToBlogLink />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
---
|
---
|
||||||
import { SITE, BLOG } from '~/config.mjs';
|
import { SITE, BLOG } from '~/config.mjs';
|
||||||
|
|
||||||
import Layout from '~/layouts/BlogLayout.astro';
|
import Layout from '~/layouts/PageLayout.astro';
|
||||||
import BlogList from '~/components/blog/List.astro';
|
import BlogList from '~/components/blog/List.astro';
|
||||||
import Pagination from '~/components/atoms/Pagination.astro';
|
import Pagination from '~/components/common/Pagination.astro';
|
||||||
|
|
||||||
import { fetchPosts } from '~/utils/posts';
|
import { fetchPosts } from '~/utils/posts';
|
||||||
import { getCanonical, getPermalink, cleanSlug, CATEGORY_BASE } from '~/utils/permalinks';
|
import { getCanonical, getPermalink, cleanSlug, CATEGORY_BASE } from '~/utils/permalinks';
|
||||||
|
import Title from '~/components/blog/Title.astro';
|
||||||
|
|
||||||
export async function getStaticPaths({ paginate }) {
|
export async function getStaticPaths({ paginate }) {
|
||||||
if (BLOG?.disabled || BLOG?.category?.disabled) return [];
|
if (BLOG?.disabled || BLOG?.category?.disabled) return [];
|
||||||
|
|
||||||
const posts = await fetchPosts();
|
const posts = await fetchPosts();
|
||||||
|
|
||||||
const categories = new Set();
|
const categories = new Set();
|
||||||
posts.map((post) => {
|
posts.map((post) => {
|
||||||
typeof post.category === 'string' && categories.add(post.category.toLowerCase());
|
typeof post.category === 'string' && categories.add(post.category.toLowerCase());
|
||||||
@ -33,7 +33,6 @@ export async function getStaticPaths({ paginate }) {
|
|||||||
const { page, category } = Astro.props;
|
const { page, category } = Astro.props;
|
||||||
|
|
||||||
const currentPage = page.currentPage ?? 1;
|
const currentPage = page.currentPage ?? 1;
|
||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
title: `Category '${category}' ${currentPage > 1 ? `— Page ${currentPage} ` : ''}— ${SITE.name}`,
|
title: `Category '${category}' ${currentPage > 1 ? `— Page ${currentPage} ` : ''}— ${SITE.name}`,
|
||||||
description: SITE.description,
|
description: SITE.description,
|
||||||
@ -43,9 +42,9 @@ const meta = {
|
|||||||
---
|
---
|
||||||
|
|
||||||
<Layout meta={meta}>
|
<Layout meta={meta}>
|
||||||
<Fragment slot="title">
|
<section class="px-6 sm:px-6 py-12 sm:py-16 lg:py-20 mx-auto max-w-3xl">
|
||||||
Category: {category}
|
<Title>Category {category}</Title>
|
||||||
</Fragment>
|
|
||||||
<BlogList posts={page.data} />
|
<BlogList posts={page.data} />
|
||||||
<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
|
<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
|
||||||
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
---
|
---
|
||||||
import { SITE, BLOG } from '~/config.mjs';
|
import { SITE, BLOG } from '~/config.mjs';
|
||||||
|
|
||||||
import Layout from '~/layouts/BlogLayout.astro';
|
import Layout from '~/layouts/PageLayout.astro';
|
||||||
import BlogList from '~/components/blog/List.astro';
|
import BlogList from '~/components/blog/List.astro';
|
||||||
import Pagination from '~/components/atoms/Pagination.astro';
|
import Pagination from '~/components/common/Pagination.astro';
|
||||||
|
|
||||||
import { fetchPosts } from '~/utils/posts';
|
import { fetchPosts } from '~/utils/posts';
|
||||||
import { getCanonical, getPermalink, cleanSlug, TAG_BASE } from '~/utils/permalinks';
|
import { getCanonical, getPermalink, cleanSlug, TAG_BASE } from '~/utils/permalinks';
|
||||||
|
import Title from '~/components/blog/Title.astro';
|
||||||
|
|
||||||
export async function getStaticPaths({ paginate }) {
|
export async function getStaticPaths({ paginate }) {
|
||||||
if (BLOG?.disabled || BLOG?.tag?.disabled) return [];
|
if (BLOG?.disabled || BLOG?.tag?.disabled) return [];
|
||||||
|
|
||||||
const posts = await fetchPosts();
|
const posts = await fetchPosts();
|
||||||
|
|
||||||
const tags = new Set();
|
const tags = new Set();
|
||||||
posts.map((post) => {
|
posts.map((post) => {
|
||||||
Array.isArray(post.tags) && post.tags.map((tag) => tags.add(tag.toLowerCase()));
|
Array.isArray(post.tags) && post.tags.map((tag) => tags.add(tag.toLowerCase()));
|
||||||
@ -33,7 +33,6 @@ export async function getStaticPaths({ paginate }) {
|
|||||||
const { page, tag } = Astro.props;
|
const { page, tag } = Astro.props;
|
||||||
|
|
||||||
const currentPage = page.currentPage ?? 1;
|
const currentPage = page.currentPage ?? 1;
|
||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
title: `Posts by tag '${tag}' ${currentPage > 1 ? `— Page ${currentPage} ` : ''}— ${SITE.name}`,
|
title: `Posts by tag '${tag}' ${currentPage > 1 ? `— Page ${currentPage} ` : ''}— ${SITE.name}`,
|
||||||
description: SITE.description,
|
description: SITE.description,
|
||||||
@ -43,9 +42,9 @@ const meta = {
|
|||||||
---
|
---
|
||||||
|
|
||||||
<Layout meta={meta}>
|
<Layout meta={meta}>
|
||||||
<Fragment slot="title">
|
<section class="px-6 sm:px-6 py-12 sm:py-16 lg:py-20 mx-auto max-w-3xl">
|
||||||
Tag: {tag}
|
<Title>Tag: {tag}</Title>
|
||||||
</Fragment>
|
|
||||||
<BlogList posts={page.data} />
|
<BlogList posts={page.data} />
|
||||||
<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
|
<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
|
||||||
|
</section>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
16
src/types.ts
16
src/types.ts
@ -24,14 +24,14 @@ export interface Post {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface MetaSEO {
|
export interface MetaSEO {
|
||||||
title?: string,
|
title?: string;
|
||||||
description?: string,
|
description?: string;
|
||||||
image?: string,
|
image?: string;
|
||||||
|
|
||||||
canonical?: string,
|
canonical?: string | URL;
|
||||||
noindex?: boolean,
|
noindex?: boolean;
|
||||||
nofollow?: boolean,
|
nofollow?: boolean;
|
||||||
|
|
||||||
ogTitle?: string,
|
ogTitle?: string;
|
||||||
ogType?: string,
|
ogType?: string;
|
||||||
}
|
}
|
@ -13,6 +13,6 @@ export const getProjectRootDir = (): string => {
|
|||||||
const __srcFolder = path.join(getProjectRootDir(), '/src');
|
const __srcFolder = path.join(getProjectRootDir(), '/src');
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
export const getRelativeUrlByFilePath = (filepath: string): string | URL => {
|
export const getRelativeUrlByFilePath = (filepath: string): string => {
|
||||||
return filepath.replace(__srcFolder, '');
|
return filepath.replace(__srcFolder, '');
|
||||||
};
|
};
|
||||||
|
@ -26,7 +26,7 @@ export const CATEGORY_BASE = cleanSlug(BLOG?.category?.pathname);
|
|||||||
export const TAG_BASE = cleanSlug(BLOG?.tag?.pathname);
|
export const TAG_BASE = cleanSlug(BLOG?.tag?.pathname);
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
export const getCanonical = (path = '') => new URL(path, SITE.origin);
|
export const getCanonical = (path = ''): string | URL => new URL(path, SITE.origin);
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
export const getPermalink = (slug = '', type = 'page'): string => {
|
export const getPermalink = (slug = '', type = 'page'): string => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { getCollection, getEntry } from 'astro:content';
|
import { getCollection, getEntry } from 'astro:content';
|
||||||
import type { CollectionEntry } from 'astro:content';
|
import type { CollectionEntry } from 'astro:content';
|
||||||
import type { Post } from "~/types"
|
import type { Post } from '~/types';
|
||||||
|
|
||||||
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;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/base",
|
"extends": "astro/tsconfigs/base",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"types": ["astro/client"],
|
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
Reference in New Issue
Block a user