Add Latest Posts support
This commit is contained in:
@ -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.5.2",
|
"version": "0.5.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
|
9
src/components/blog/Grid.astro
Normal file
9
src/components/blog/Grid.astro
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
import Item from '~/components/blog/GridItem.astro';
|
||||||
|
|
||||||
|
const { posts } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="grid gap-6 row-gap-5 md:grid-cols-2 lg:grid-cols-4 -mb-6">
|
||||||
|
{posts.map((post) => <Item post={post} />)}
|
||||||
|
</div>
|
32
src/components/blog/GridItem.astro
Normal file
32
src/components/blog/GridItem.astro
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
import Picture from '~/components/core/Picture.astro';
|
||||||
|
|
||||||
|
import { findImage } from '~/utils/images';
|
||||||
|
import { getPermalink } from '~/utils/permalinks';
|
||||||
|
|
||||||
|
const { post } = Astro.props;
|
||||||
|
|
||||||
|
const image = await findImage(post.image);
|
||||||
|
---
|
||||||
|
|
||||||
|
<article class="mb-6 transition">
|
||||||
|
<div class="relative h-0 pb-[56.25%] lg:h-64 overflow-hidden bg-gray-400 dark:bg-slate-700 rounded shadow-lg mb-6">
|
||||||
|
<Picture
|
||||||
|
src={image}
|
||||||
|
class="object-cover w-full lg:h-64 rounded shadow-lg bg-gray-400 dark:bg-slate-700"
|
||||||
|
widths={[400, 900]}
|
||||||
|
sizes="(max-width: 900px) 400px, 900px"
|
||||||
|
alt={post.title}
|
||||||
|
aspectRatio="16:9"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<h3 class="mb-2 text-xl font-bold leading-snug sm:text-2xl font-heading">
|
||||||
|
<a
|
||||||
|
href={getPermalink(post.slug, 'post')}
|
||||||
|
class="hover:text-primary-600 underline underline-offset-4 decoration-1 decoration-dotted transition ease-in duration-200"
|
||||||
|
>
|
||||||
|
{post.title}
|
||||||
|
</a>
|
||||||
|
</h3>
|
||||||
|
<p class="text-gray-700 dark:text-gray-400">{post.excerpt || post.description}</p>
|
||||||
|
</article>
|
@ -1,9 +1,7 @@
|
|||||||
---
|
---
|
||||||
import Picture from '~/components/core/Picture.astro';
|
import Grid from '~/components/blog/Grid.astro';
|
||||||
|
|
||||||
import { findPostsByIds } from '~/utils/posts';
|
import { findPostsByIds } from '~/utils/posts';
|
||||||
import { findImage } from '~/utils/images';
|
|
||||||
import { getPermalink } from '~/utils/permalinks';
|
|
||||||
|
|
||||||
const ids = [
|
const ids = [
|
||||||
'get-started-website-with-astro-tailwind-css',
|
'get-started-website-with-astro-tailwind-css',
|
||||||
@ -11,10 +9,7 @@ const ids = [
|
|||||||
'useful-resources-to-create-websites',
|
'useful-resources-to-create-websites',
|
||||||
'astrowind-template-in-depth',
|
'astrowind-template-in-depth',
|
||||||
];
|
];
|
||||||
|
const posts = await findPostsByIds(ids);
|
||||||
const items = await Promise.all(
|
|
||||||
(await findPostsByIds(ids)).map(async (item) => ({ ...item, image: await findImage(item.image) }))
|
|
||||||
);
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<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">
|
||||||
@ -30,29 +25,5 @@ const items = await Promise.all(
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid gap-6 row-gap-5 md:grid-cols-2 lg:grid-cols-4 -mb-6">
|
<Grid posts={posts} />
|
||||||
{
|
|
||||||
items.map((post) => (
|
|
||||||
<article class="mb-6 transition">
|
|
||||||
<Picture
|
|
||||||
src={post.image}
|
|
||||||
class="object-cover w-full h-64 mb-6 rounded shadow-lg bg-gray-400 dark:bg-slate-700"
|
|
||||||
widths={[400, 900]}
|
|
||||||
sizes="(max-width: 900px) 400px, 900px"
|
|
||||||
alt={post.title}
|
|
||||||
aspectRatio="16:9"
|
|
||||||
/>
|
|
||||||
<h3 class="mb-2 text-xl font-bold leading-snug sm:text-2xl font-heading">
|
|
||||||
<a
|
|
||||||
href={getPermalink(post.slug, 'post')}
|
|
||||||
class="hover:text-primary-600 underline underline-offset-4 decoration-1 decoration-dotted transition ease-in duration-200"
|
|
||||||
>
|
|
||||||
{post.title}
|
|
||||||
</a>
|
|
||||||
</h3>
|
|
||||||
<p class="text-gray-700 dark:text-gray-400">{post.excerpt || post.description}</p>
|
|
||||||
</article>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
24
src/components/blog/LatestPosts.astro
Normal file
24
src/components/blog/LatestPosts.astro
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
import Grid from '~/components/blog/Grid.astro';
|
||||||
|
|
||||||
|
import { findLatestPosts } from '~/utils/posts';
|
||||||
|
|
||||||
|
const count = 4;
|
||||||
|
const posts = await findLatestPosts({ count });
|
||||||
|
---
|
||||||
|
|
||||||
|
<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">
|
||||||
|
<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>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p class="text-gray-700 dark:text-slate-400 lg:text-sm lg:max-w-md">
|
||||||
|
The blog will be used to display AstroWind documentation. Each new article will be an important step that you will
|
||||||
|
need to know to be an expert in creating a website using Astro + Tailwind CSS The blog does not exist yet, but
|
||||||
|
very soon. Astro is a very interesting technology. Thanks.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Grid posts={posts} />
|
||||||
|
</section>
|
@ -11,21 +11,23 @@ const { post } = Astro.props;
|
|||||||
const image = await findImage(post.image);
|
const image = await findImage(post.image);
|
||||||
---
|
---
|
||||||
|
|
||||||
<article class="max-w-md mx-auto md:max-w-none grid md:grid-cols-2 gap-6 md:gap-8">
|
<article class={`max-w-md mx-auto md:max-w-none grid gap-6 md:gap-8 ${image ? 'md:grid-cols-2' : ''}`}>
|
||||||
<a class="relative block group" href={getPermalink(post.slug, 'post')}>
|
{
|
||||||
<div
|
image && (
|
||||||
class="relative h-0 pb-[56.25%] md:pb-[75%] md:h-80 lg:pb-[56.25%] overflow-hidden bg-gray-400 dark:bg-slate-700 rounded shadow-lg"
|
<a class="relative block group" href={getPermalink(post.slug, 'post')}>
|
||||||
>
|
<div class="relative h-0 pb-[56.25%] md:pb-[75%] md:h-80 lg:pb-[56.25%] overflow-hidden bg-gray-400 dark:bg-slate-700 rounded shadow-lg">
|
||||||
<Picture
|
<Picture
|
||||||
src={image}
|
src={image}
|
||||||
class="absolute inset-0 object-cover w-full h-full mb-6 rounded shadow-lg bg-gray-400 dark:bg-slate-700"
|
class="absolute inset-0 object-cover w-full h-full mb-6 rounded shadow-lg bg-gray-400 dark:bg-slate-700"
|
||||||
widths={[400, 900]}
|
widths={[400, 900]}
|
||||||
sizes="(max-width: 900px) 400px, 900px"
|
sizes="(max-width: 900px) 400px, 900px"
|
||||||
alt={post.title}
|
alt={post.title}
|
||||||
aspectRatio="16:9"
|
aspectRatio="16:9"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
)
|
||||||
|
}
|
||||||
<div>
|
<div>
|
||||||
<header>
|
<header>
|
||||||
<h2 class="text-xl sm:text-2xl font-bold leading-snug mb-2 font-heading">
|
<h2 class="text-xl sm:text-2xl font-bold leading-snug mb-2 font-heading">
|
||||||
|
@ -9,18 +9,18 @@ const { post } = Astro.props;
|
|||||||
|
|
||||||
<section class="py-8 sm:py-16 lg:py-20 mx-auto">
|
<section class="py-8 sm:py-16 lg:py-20 mx-auto">
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header class={post.image ? 'text-center' : ''}>
|
||||||
<p class="max-w-3xl mx-auto text-center">
|
<p class="px-4 sm:px-6 max-w-3xl mx-auto">
|
||||||
<time datetime={post.publishDate}>{getFormattedDate(post.publishDate)}</time> ~ {Math.ceil(post.readingTime)} min
|
<time datetime={post.publishDate}>{getFormattedDate(post.publishDate)}</time> ~ {Math.ceil(post.readingTime)} min
|
||||||
read
|
read
|
||||||
</p>
|
</p>
|
||||||
<h1
|
<h1
|
||||||
class="px-4 sm:px-6 max-w-3xl mx-auto text-center text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-8 font-heading"
|
class="px-4 sm:px-6 max-w-3xl mx-auto text-4xl md:text-5xl font-bold leading-tighter tracking-tighter mb-8 font-heading"
|
||||||
>
|
>
|
||||||
{post.title}
|
{post.title}
|
||||||
</h1>
|
</h1>
|
||||||
{
|
{
|
||||||
post.image && (
|
post.image ? (
|
||||||
<Picture
|
<Picture
|
||||||
src={post.image}
|
src={post.image}
|
||||||
class="max-w-full lg:max-w-6xl mx-auto mt-4 mb-6 sm:rounded-md bg-gray-400 dark:bg-slate-700"
|
class="max-w-full lg:max-w-6xl mx-auto mt-4 mb-6 sm:rounded-md bg-gray-400 dark:bg-slate-700"
|
||||||
@ -29,6 +29,10 @@ const { post } = Astro.props;
|
|||||||
alt={post.description}
|
alt={post.description}
|
||||||
aspectRatio="16:9"
|
aspectRatio="16:9"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div class="max-w-3xl mx-auto px-4 sm:px-6">
|
||||||
|
<div class="border-t dark:border-slate-700" />
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</header>
|
</header>
|
||||||
|
@ -64,3 +64,11 @@ export const findPostsByIds = async (ids) => {
|
|||||||
return r;
|
return r;
|
||||||
}, []);
|
}, []);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** */
|
||||||
|
export const findLatestPosts = async ({ count }) => {
|
||||||
|
const _count = count || 4;
|
||||||
|
const posts = await fetchPosts();
|
||||||
|
|
||||||
|
return posts ? posts.slice(_count * -1) : [];
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user