Add blog back to astro (#4797)
This commit is contained in:
Родитель
642a1d3e33
Коммит
bb7d035c56
|
@ -2,6 +2,8 @@
|
|||
slug: 2024-04-25-introducing
|
||||
title: "Introducing TypeSpec: A New Language for API-Centric Development"
|
||||
image: ./intro.png
|
||||
description: Over last few years, we've been hard at work on https://typespec.io/, a modern API definition language. This language is designed to meet the evolving needs of API developers, architects, and managers in an environment where the delivery of consistently high-quality APIs and related experiences is becoming increasingly complex and critical.
|
||||
publishDate: 2024-04-25
|
||||
---
|
||||
|
||||
Over last few years, we've been hard at work on https://typespec.io/, a modern API definition language. This language is designed to meet the evolving needs of API developers, architects, and managers in an environment where the delivery of consistently high-quality APIs and related experiences is becoming increasingly complex and critical.
|
||||
|
|
|
@ -101,6 +101,7 @@ words:
|
|||
- keyer
|
||||
- killpg
|
||||
- kwargs
|
||||
- labelledby
|
||||
- lifecyle
|
||||
- LINUXNEXTVMIMAGE
|
||||
- LINUXOS
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Temporary to help with migration
|
||||
src/content/docs/docs/
|
||||
src/content/docs/docs/next/
|
||||
src/content/blog/
|
||||
src/assets/
|
||||
public/
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"copy": "cp -r ../../docs/. ./src/content/docs/docs && cp -r ../website/static/. ./src/assets && cp -r ../website/static/img/. ./public/img && cp ../website/static/1ds-init.js ./public/1ds-init.js",
|
||||
"copy": "cp -r ../../docs/. ./src/content/docs/docs && cp -r ../website/static/. ./src/assets && cp -r ../website/static/img/. ./public/img && cp ../website/static/1ds-init.js ./public/1ds-init.js && cp -r ../../blog/. ./src/content/blog",
|
||||
"clean": "rimraf ./dist ./temp ./.astro",
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "tsx ./.scripts/build.ts",
|
||||
"build:web": "pnpm copy && astro check && astro build",
|
||||
"build:web": "pnpm copy && astro check --minimumFailingSeverity warning && astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
|
@ -29,6 +29,7 @@
|
|||
"@typespec/playground": "workspace:~",
|
||||
"astro": "^4.16.1",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"es-module-shims": "~1.10.0",
|
||||
"prism-react-renderer": "^2.4.0",
|
||||
"react": "~18.3.1",
|
||||
|
|
|
@ -106,8 +106,7 @@ import Search from "./search.astro";
|
|||
>
|
||||
<Link class="item link" href="/docs">Docs</Link>
|
||||
<Link class="item link" href="/playground">Playground</Link>
|
||||
<!-- TODO: add blog -->
|
||||
<!-- <Link class="item link" href="/blog">Blog</Link> -->
|
||||
<Link class="item link" href="/blog">Blog</Link>
|
||||
<Link class="item link" href="/community">Community</Link>
|
||||
</div>
|
||||
<div class="items right">
|
||||
|
|
|
@ -3,7 +3,6 @@ import { Links } from "@site/src/constants";
|
|||
import Button from "../button.astro";
|
||||
import { DescriptionText } from "../text/text";
|
||||
import HeroIllustration from "./hero-illustration.astro";
|
||||
import { link } from "@site/src/utils/link";
|
||||
---
|
||||
|
||||
<style>
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
import { docsSchema } from "@astrojs/starlight/schema";
|
||||
import { defineCollection } from "astro:content";
|
||||
import { defineCollection, z } from "astro:content";
|
||||
|
||||
export const collections = {
|
||||
docs: defineCollection({ schema: docsSchema() }),
|
||||
blog: defineCollection({
|
||||
type: "content",
|
||||
// Type-check frontmatter using a schema
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
image: z.string().optional(),
|
||||
publishDate: z.coerce
|
||||
.date()
|
||||
.describe(
|
||||
"A date string or YAML date that is compatible with JavaScript's `new Date()` constructor.",
|
||||
),
|
||||
}),
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
img {
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
a {
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
---
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import BaseLayout from "./base-layout.astro";
|
||||
import { resolveBlogImagePath } from "../pages/blog/resolve-image";
|
||||
import { format } from "date-fns/format";
|
||||
import { Image } from "astro:assets";
|
||||
|
||||
type Props = CollectionEntry<"blog">["data"];
|
||||
|
||||
const { title, image: relativeImage, publishDate } = Astro.props;
|
||||
const image = relativeImage && (await resolveBlogImagePath(Astro.params.slug ?? "", relativeImage));
|
||||
---
|
||||
|
||||
<style>
|
||||
.content {
|
||||
min-height: 100%;
|
||||
box-sizing: border-box;
|
||||
font-size: var(--fontSizeBase400);
|
||||
}
|
||||
@media only screen and (min-width: 1024px) {
|
||||
.content {
|
||||
padding: 3rem;
|
||||
}
|
||||
}
|
||||
.hero-image {
|
||||
width: 100%;
|
||||
}
|
||||
.hero-image img {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
box-shadow: var(--shadow2);
|
||||
}
|
||||
.prose {
|
||||
width: 720px;
|
||||
max-width: calc(100% - 2em);
|
||||
margin: auto;
|
||||
}
|
||||
.title {
|
||||
margin-bottom: 1em;
|
||||
padding: 1em 0;
|
||||
text-align: center;
|
||||
line-height: 1;
|
||||
}
|
||||
.title h1 {
|
||||
margin: 0 0 0.5em 0;
|
||||
}
|
||||
.date {
|
||||
display: block;
|
||||
padding: 1rem;
|
||||
font-size: var(--fontSizeBase400);
|
||||
color: var(--colorNeutralForeground1);
|
||||
}
|
||||
.last-updated-on {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
hr {
|
||||
display: block;
|
||||
margin-top: 2rem;
|
||||
border-top: 0;
|
||||
border-color: var(--colorNeutralStroke3);
|
||||
}
|
||||
</style>
|
||||
<BaseLayout>
|
||||
<article class="content">
|
||||
<div class="hero-image">
|
||||
{image && <Image src={image} alt="" />}
|
||||
</div>
|
||||
<div class="prose">
|
||||
<div class="title">
|
||||
<time class="date" datetime={publishDate.toISOString()}>
|
||||
{format(publishDate, "MMMM d, yyyy")}
|
||||
</time>
|
||||
<h1>{title}</h1>
|
||||
<hr />
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
</article>
|
||||
</BaseLayout>
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
import { FluentLayout } from "../components/layouts/fluent-layout";
|
||||
import BaseLayout from "./base-layout.astro";
|
||||
---
|
||||
|
||||
<BaseLayout>
|
||||
<FluentLayout client:only="react">
|
||||
<slot />
|
||||
</FluentLayout>
|
||||
</BaseLayout>
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
import { type CollectionEntry, getCollection } from "astro:content";
|
||||
import BlogPost from "../../layouts/blog-post.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection("blog");
|
||||
return posts.map((post) => ({
|
||||
params: { slug: post.slug },
|
||||
props: post,
|
||||
}));
|
||||
}
|
||||
type Props = CollectionEntry<"blog">;
|
||||
|
||||
const post = Astro.props;
|
||||
const { Content } = await post.render();
|
||||
---
|
||||
|
||||
<BlogPost {...post.data}>
|
||||
<Content />
|
||||
</BlogPost>
|
|
@ -0,0 +1,119 @@
|
|||
---
|
||||
import Card from "@site/src/components/card.astro";
|
||||
import { resolveBlogImagePath } from "@site/src/pages/blog/resolve-image";
|
||||
import { format } from "date-fns";
|
||||
import { Image } from "astro:assets";
|
||||
import Link from "@site/src/components/link.astro";
|
||||
|
||||
export type Props = {
|
||||
post: {
|
||||
slug: string;
|
||||
data: {
|
||||
title: string;
|
||||
description: string;
|
||||
publishDate: Date;
|
||||
image?: string;
|
||||
};
|
||||
};
|
||||
imageLoading: "lazy" | "eager";
|
||||
};
|
||||
|
||||
const { post, imageLoading } = Astro.props;
|
||||
|
||||
const image = post.data.image && (await resolveBlogImagePath(post.slug, post.data.image));
|
||||
---
|
||||
|
||||
<style>
|
||||
.card > :global(.bg) {
|
||||
border: 1px solid var(--colorNeutralStroke3);
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
.card {
|
||||
border-radius: 0;
|
||||
color: var(--colorNeutralForeground1);
|
||||
|
||||
}
|
||||
.card:hover {
|
||||
outline: solid var(--colorBrandForeground1)
|
||||
}
|
||||
.date {
|
||||
display: block;
|
||||
padding: 1rem;
|
||||
text-align: left;
|
||||
font-size: var(--fontSizeBase500);
|
||||
border-bottom: 1px solid var(--colorNeutralStroke3);
|
||||
}
|
||||
|
||||
.image {
|
||||
margin: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
:global([data-theme="light"]) .image-container {
|
||||
background: radial-gradient(
|
||||
46.56% 45.08% at 56.04% 55.33%,
|
||||
rgba(0, 50, 255, 0.1) 0%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
),
|
||||
radial-gradient(
|
||||
46.69% 41.74% at 69.64% 60.81%,
|
||||
rgba(192, 59, 196, 0.1) 0%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
),
|
||||
radial-gradient(
|
||||
59.78% 45.73% at 30.42% 58.68%,
|
||||
rgba(0, 120, 212, 0.1) 0%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
),
|
||||
radial-gradient(32.53% 31.57% at 50% 66.82%, rgba(70, 54, 104, 0.1) 0%, rgba(0, 0, 0, 0) 100%);
|
||||
}
|
||||
|
||||
:global([data-theme="dark"]) .image-container {
|
||||
background: radial-gradient(
|
||||
46.56% 45.08% at 56.04% 55.33%,
|
||||
rgba(0, 50, 255, 0.2) 0%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
),
|
||||
radial-gradient(
|
||||
46.69% 41.74% at 69.64% 60.81%,
|
||||
rgba(192, 59, 196, 0.2) 0%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
),
|
||||
radial-gradient(
|
||||
59.78% 45.73% at 30.42% 58.68%,
|
||||
rgba(0, 120, 212, 0.2) 0%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
),
|
||||
radial-gradient(32.53% 31.57% at 50% 66.82%, rgba(70, 54, 104, 0.2) 0%, rgba(0, 0, 0, 0) 100%);
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 1rem;
|
||||
background: var(--colorNeutralBackground2);
|
||||
}
|
||||
</style>
|
||||
<article aria-labelledby={post.slug}>
|
||||
<Link
|
||||
href={`/blog/${post.slug}/`}
|
||||
data-astro-prefetch
|
||||
class="outline-none after:absolute after:inset-0"
|
||||
>
|
||||
<Card noPadding class="card">
|
||||
<header>
|
||||
<time class="date" datetime={post.data.publishDate.toISOString()}>
|
||||
{format(post.data.publishDate, "MMMM d, yyyy")}
|
||||
</time>
|
||||
</header>
|
||||
<div class="image-container">
|
||||
{image && <Image class="image" src={image} alt="" loading={imageLoading} />}
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<h3 class="heading-4 md:heading-3" id={post.slug}>
|
||||
{post.data.title}
|
||||
</h3>
|
||||
<p class="text-astro-gray-200">{post.data.description}</p>
|
||||
</div>
|
||||
</Card>
|
||||
</Link>
|
||||
</article>
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import BaseLayout from "@site/src/layouts/base-layout.astro";
|
||||
import BlogPostPreview from "./_BlogPostPreview.astro";
|
||||
|
||||
const posts = await getCollection("blog");
|
||||
---
|
||||
|
||||
<style>
|
||||
.content {
|
||||
background-color: var(--colorNeutralBackground3);
|
||||
min-height: 100%;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.list {
|
||||
max-width: 960px;
|
||||
margin: auto;
|
||||
}
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 2rem;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
<BaseLayout>
|
||||
<div class="content">
|
||||
<section class="list">
|
||||
<ul>
|
||||
{
|
||||
posts.map((post, index) => (
|
||||
<li>
|
||||
<BlogPostPreview post={post} imageLoading={index === 0 ? "eager" : "lazy"} />
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</BaseLayout>
|
|
@ -0,0 +1,11 @@
|
|||
import { join } from "path/posix";
|
||||
const allImages = import.meta.glob<{ default: ImageMetadata }>(
|
||||
"../..//content/blog/**/*.{png,jpg,jpeg,webp}",
|
||||
);
|
||||
|
||||
export async function resolveBlogImagePath(slug: string, relativeImage: string) {
|
||||
const path = join("../../content/blog/", slug, relativeImage);
|
||||
const { default: image } = await allImages[path]();
|
||||
|
||||
return image;
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
import { AsyncPlayground } from "../components/react-pages/playground";
|
||||
import FluentUILayout from "@site/src/layouts/fluentui.astro";
|
||||
import packageJson from "../../../compiler/package.json";
|
||||
import { LoadingSpinner } from "../components/playground-component/loading-spinner";
|
||||
import BaseLayout from "../layouts/base-layout.astro";
|
||||
|
|
|
@ -2058,6 +2058,9 @@ importers:
|
|||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
date-fns:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0
|
||||
es-module-shims:
|
||||
specifier: ~1.10.0
|
||||
version: 1.10.0
|
||||
|
@ -7766,6 +7769,9 @@ packages:
|
|||
resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
date-fns@4.1.0:
|
||||
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
|
||||
|
||||
dayjs@1.11.10:
|
||||
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
|
||||
|
||||
|
@ -21762,6 +21768,8 @@ snapshots:
|
|||
es-errors: 1.3.0
|
||||
is-data-view: 1.0.1
|
||||
|
||||
date-fns@4.1.0: {}
|
||||
|
||||
dayjs@1.11.10: {}
|
||||
|
||||
de-indent@1.0.2: {}
|
||||
|
|
Загрузка…
Ссылка в новой задаче