mirror of
https://github.com/jimeh/commonflow.org.git
synced 2026-02-19 05:46:40 +00:00
Merge pull request #20 from jimeh/feat/llms-txt-and-spec-url-pattern
This commit is contained in:
@@ -11,7 +11,9 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { title, description = config.description } = Astro.props;
|
const { title, description = config.description } = Astro.props;
|
||||||
const fullTitle = title.includes(config.title) ? title : `${title} | ${config.title}`;
|
const fullTitle = title.includes(config.title)
|
||||||
|
? title
|
||||||
|
: `${title} | ${config.title}`;
|
||||||
const canonicalUrl = Astro.url.href;
|
const canonicalUrl = Astro.url.href;
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -42,12 +44,15 @@ const canonicalUrl = Astro.url.href;
|
|||||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||||
|
|
||||||
|
<!-- Slot for page-specific head content -->
|
||||||
|
<slot name="head" />
|
||||||
|
|
||||||
<!-- Prevent flash of wrong theme -->
|
<!-- Prevent flash of wrong theme -->
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
(function () {
|
(function () {
|
||||||
const mode = localStorage.getItem("theme");
|
const mode = localStorage.getItem("theme");
|
||||||
const prefersDark = window.matchMedia(
|
const prefersDark = window.matchMedia(
|
||||||
"(prefers-color-scheme: dark)",
|
"(prefers-color-scheme: dark)"
|
||||||
).matches;
|
).matches;
|
||||||
if (mode === "dark" || (mode !== "light" && prefersDark)) {
|
if (mode === "dark" || (mode !== "light" && prefersDark)) {
|
||||||
document.documentElement.classList.add("dark");
|
document.documentElement.classList.add("dark");
|
||||||
@@ -63,7 +68,7 @@ const canonicalUrl = Astro.url.href;
|
|||||||
document.addEventListener("astro:after-swap", () => {
|
document.addEventListener("astro:after-swap", () => {
|
||||||
const mode = localStorage.getItem("theme");
|
const mode = localStorage.getItem("theme");
|
||||||
const prefersDark = window.matchMedia(
|
const prefersDark = window.matchMedia(
|
||||||
"(prefers-color-scheme: dark)",
|
"(prefers-color-scheme: dark)"
|
||||||
).matches;
|
).matches;
|
||||||
if (mode === "dark" || (mode !== "light" && prefersDark)) {
|
if (mode === "dark" || (mode !== "light" && prefersDark)) {
|
||||||
document.documentElement.classList.add("dark");
|
document.documentElement.classList.add("dark");
|
||||||
|
|||||||
@@ -31,7 +31,11 @@ const markdown = content.replace(/^---[\s\S]*?---\n/, "");
|
|||||||
const parsed = await parseSpecContent(markdown);
|
const parsed = await parseSpecContent(markdown);
|
||||||
|
|
||||||
// Read SVG content for inline embedding
|
// Read SVG content for inline embedding
|
||||||
const svgFilePath = path.join(process.cwd(), "src/content/spec", `${version}.svg`);
|
const svgFilePath = path.join(
|
||||||
|
process.cwd(),
|
||||||
|
"src/content/spec",
|
||||||
|
`${version}.svg`
|
||||||
|
);
|
||||||
let svgContent: string | null = null;
|
let svgContent: string | null = null;
|
||||||
if (fs.existsSync(svgFilePath)) {
|
if (fs.existsSync(svgFilePath)) {
|
||||||
svgContent = fs.readFileSync(svgFilePath, "utf-8");
|
svgContent = fs.readFileSync(svgFilePath, "utf-8");
|
||||||
@@ -39,14 +43,19 @@ if (fs.existsSync(svgFilePath)) {
|
|||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={spec.data.title}>
|
<BaseLayout title={spec.data.title}>
|
||||||
|
<Fragment slot="head">
|
||||||
|
<link
|
||||||
|
rel="alternate"
|
||||||
|
type="text/markdown"
|
||||||
|
href={`/spec/git-common-flow-v${version}.md`}
|
||||||
|
title="Raw Markdown"
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
|
||||||
<Header version={version} versions={versions} />
|
<Header version={version} versions={versions} />
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<Hero
|
<Hero version={version} versions={versions} svgContent={svgContent} />
|
||||||
version={version}
|
|
||||||
versions={versions}
|
|
||||||
svgContent={svgContent}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<AboutSection
|
<AboutSection
|
||||||
introduction={parsed.introduction}
|
introduction={parsed.introduction}
|
||||||
|
|||||||
25
src/pages/llms.txt.ts
Normal file
25
src/pages/llms.txt.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import type { APIRoute } from "astro";
|
||||||
|
import { getVersionInfo } from "../utils/versions";
|
||||||
|
|
||||||
|
export const GET: APIRoute = async () => {
|
||||||
|
const { currentVersion } = await getVersionInfo();
|
||||||
|
|
||||||
|
const content = `# Common-Flow
|
||||||
|
|
||||||
|
> A Git workflow specification combining GitHub Flow with versioned releases.
|
||||||
|
|
||||||
|
Common-Flow is a sensible git workflow based on GitHub Flow, with the addition
|
||||||
|
of versioned releases, optional release branches, and without the requirement
|
||||||
|
to deploy to production all the time.
|
||||||
|
|
||||||
|
## Docs
|
||||||
|
|
||||||
|
- [Git Common-Flow Specification](/spec/git-common-flow-v${currentVersion}.md): The complete Git Common-Flow v${currentVersion} specification in Markdown format
|
||||||
|
`;
|
||||||
|
|
||||||
|
return new Response(content, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "text/plain; charset=utf-8",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -116,6 +116,15 @@ const previewHtml = await unified()
|
|||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={`${spec.data.title} - Markdown`}>
|
<BaseLayout title={`${spec.data.title} - Markdown`}>
|
||||||
|
<Fragment slot="head">
|
||||||
|
<link
|
||||||
|
rel="alternate"
|
||||||
|
type="text/markdown"
|
||||||
|
href={`/spec/git-common-flow-v${version}.md`}
|
||||||
|
title="Raw Markdown"
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<header
|
<header
|
||||||
class="sticky top-0 z-50 border-b
|
class="sticky top-0 z-50 border-b
|
||||||
@@ -227,6 +236,19 @@ const previewHtml = await unified()
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Raw button -->
|
||||||
|
<a
|
||||||
|
href={`/spec/git-common-flow-v${version}.md`}
|
||||||
|
class="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm
|
||||||
|
font-medium rounded-lg transition-colors
|
||||||
|
text-gray-600 dark:text-neutral-400
|
||||||
|
hover:bg-gray-100 hover:text-gray-950
|
||||||
|
dark:hover:bg-neutral-800 dark:hover:text-neutral-50"
|
||||||
|
>
|
||||||
|
<Icon name="heroicons:document-text" class="w-4 h-4" />
|
||||||
|
<span>Raw</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
<!-- Download button -->
|
<!-- Download button -->
|
||||||
<button
|
<button
|
||||||
id="download-btn"
|
id="download-btn"
|
||||||
|
|||||||
30
src/pages/spec/git-common-flow-v[version].md.ts
Normal file
30
src/pages/spec/git-common-flow-v[version].md.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import type { APIRoute, GetStaticPaths } from "astro";
|
||||||
|
import { getCollection } from "astro:content";
|
||||||
|
import * as fs from "node:fs";
|
||||||
|
import * as path from "node:path";
|
||||||
|
|
||||||
|
export const getStaticPaths: GetStaticPaths = async () => {
|
||||||
|
const specs = await getCollection("spec");
|
||||||
|
return specs.map((spec) => ({
|
||||||
|
params: { version: spec.data.version },
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GET: APIRoute = ({ params }) => {
|
||||||
|
const version = params.version;
|
||||||
|
const filePath = path.join(
|
||||||
|
process.cwd(),
|
||||||
|
"src/content/spec",
|
||||||
|
`${version}.md`
|
||||||
|
);
|
||||||
|
const content = fs.readFileSync(filePath, "utf-8");
|
||||||
|
const markdown = content.replace(/^---[\s\S]*?---\n/, "");
|
||||||
|
const filename = `git-common-flow-v${version}.md`;
|
||||||
|
|
||||||
|
return new Response(markdown, {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "text/markdown; charset=utf-8",
|
||||||
|
"Content-Disposition": `inline; filename="${filename}"`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user