feat: complete the blog list and blog content pages

This commit is contained in:
Guoqi Sun 2024-11-27 03:21:25 +08:00
parent e5b8bd7ab0
commit 3ab8839462
30 changed files with 581 additions and 103 deletions

View file

@ -1,48 +1,2 @@
# Astro Starter Kit: Basics
```sh inspired by [wordpress-dear](https://github.com/imjeff/wordpress-dear)
npm create astro@latest -- --template basics
```
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/basics/devcontainer.json)
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
![just-the-basics](https://github.com/withastro/astro/assets/2244813/a0a5533c-a856-4198-8470-2d67b1d7c554)
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:
```text
/
├── public/
│ └── favicon.svg
├── src/
│ ├── layouts/
│ │ └── Layout.astro
│ └── pages/
│ └── index.astro
└── package.json
```
To learn more about the folder structure of an Astro project, refer to [our guide on project structure](https://docs.astro.build/en/basics/project-structure/).
## 🧞 Commands
All commands are run from the root of the project, from a terminal:
| Command | Action |
| :------------------------ | :----------------------------------------------- |
| `npm install` | Installs dependencies |
| `npm run dev` | Starts local dev server at `localhost:4321` |
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI |
## 👀 Want to learn more?
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).

View file

@ -24,6 +24,7 @@
"typescript": "^5.7.2" "typescript": "^5.7.2"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/typography": "^0.5.15",
"@typescript-eslint/parser": "^8.16.0", "@typescript-eslint/parser": "^8.16.0",
"eslint": "^9.15.0", "eslint": "^9.15.0",
"eslint-plugin-astro": "^1.3.1", "eslint-plugin-astro": "^1.3.1",

35
pnpm-lock.yaml generated
View file

@ -42,6 +42,9 @@ importers:
specifier: ^5.7.2 specifier: ^5.7.2
version: 5.7.2 version: 5.7.2
devDependencies: devDependencies:
'@tailwindcss/typography':
specifier: ^0.5.15
version: 0.5.15(tailwindcss@3.4.15)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: ^8.16.0 specifier: ^8.16.0
version: 8.16.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.7.2) version: 8.16.0(eslint@9.15.0(jiti@1.21.6))(typescript@5.7.2)
@ -857,6 +860,11 @@ packages:
'@shikijs/vscode-textmate@9.3.0': '@shikijs/vscode-textmate@9.3.0':
resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==} resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==}
'@tailwindcss/typography@0.5.15':
resolution: {integrity: sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==}
peerDependencies:
tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20'
'@types/babel__core@7.20.5': '@types/babel__core@7.20.5':
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
@ -1971,6 +1979,12 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'} engines: {node: '>=10'}
lodash.castarray@4.4.0:
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
lodash.merge@4.6.2: lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
@ -2384,6 +2398,10 @@ packages:
peerDependencies: peerDependencies:
postcss: ^8.2.14 postcss: ^8.2.14
postcss-selector-parser@6.0.10:
resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
engines: {node: '>=4'}
postcss-selector-parser@6.1.2: postcss-selector-parser@6.1.2:
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -3883,6 +3901,14 @@ snapshots:
'@shikijs/vscode-textmate@9.3.0': {} '@shikijs/vscode-textmate@9.3.0': {}
'@tailwindcss/typography@0.5.15(tailwindcss@3.4.15)':
dependencies:
lodash.castarray: 4.4.0
lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2
postcss-selector-parser: 6.0.10
tailwindcss: 3.4.15
'@types/babel__core@7.20.5': '@types/babel__core@7.20.5':
dependencies: dependencies:
'@babel/parser': 7.26.2 '@babel/parser': 7.26.2
@ -5281,6 +5307,10 @@ snapshots:
dependencies: dependencies:
p-locate: 5.0.0 p-locate: 5.0.0
lodash.castarray@4.4.0: {}
lodash.isplainobject@4.0.6: {}
lodash.merge@4.6.2: {} lodash.merge@4.6.2: {}
lodash@4.17.21: {} lodash@4.17.21: {}
@ -5847,6 +5877,11 @@ snapshots:
postcss: 8.4.49 postcss: 8.4.49
postcss-selector-parser: 6.1.2 postcss-selector-parser: 6.1.2
postcss-selector-parser@6.0.10:
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
postcss-selector-parser@6.1.2: postcss-selector-parser@6.1.2:
dependencies: dependencies:
cssesc: 3.0.0 cssesc: 3.0.0

View file

@ -0,0 +1,28 @@
---
import { config } from "~/config"
import { formatDate, getPosts } from "~/utils"
interface PostProps {
slug: string
data: {
title: string
pubDate: Date
}
}
const posts = (await getPosts()).slice(0, config.latestPosts ?? 8)
---
<div class="mb-4 text-xl font-medium md:my-8">近期文章</div>
{
posts.map((post: PostProps) => (
<a href={`/posts/${post.slug}/`}>
<div class="my-2 flex text-lg">
<p class="flex w-36 flex-shrink-0 truncate text-gray-500 dark:text-gray-400">
<time>{formatDate(post.data.pubDate)}</time>
</p>
<p class="line-clamp-3">{post.data.title}</p>
</div>
</a>
))
}

View file

@ -1,22 +1,18 @@
--- <footer class="my-10 flex flex-wrap items-center gap-1">
---
<div class="my-10 flex flex-col md:flex-row">
<p> <p>
&copy; {new Date().getFullYear()} &copy; {new Date().getFullYear()}
</p> </p>
<p class="mx-1 hidden md:block">|</p> <p class="mx-1">|</p>
<p class="mr-1">Designed By</p> <p>Designed By</p>
<a href="https://sunguoqi.com" class="text-blue-500 hover:underline"> <a href="https://sunguoqi.com" class="text-blue-500 hover:underline">
Guoqi Sun Guoqi Sun
</a> </a>
<p class="mx-1 hidden md:block">|</p> <p class="mx-1">|</p>
<p class="mr-1">Powered By</p> <p>Powered By</p>
<a <a
href="https://github.com/sun0225SUN/astro-air" href="https://github.com/sun0225SUN/astro-air"
class="text-blue-500 hover:underline" class="text-blue-500 hover:underline"
> >
Astro Air Astro Air
</a> </a>
</div> </footer>

View file

@ -1,17 +1,28 @@
--- ---
import { Rss } from "lucide-react" import { Rss } from "lucide-react"
import ThemeToggle from "~/components/astro/theme-toggle.astro" import ThemeToggle from "~/components/astro/theme-toggle.astro"
import { site } from "~/config" import { config } from "~/config"
--- ---
<header class="flex h-20 w-full items-center justify-between"> <header class="flex h-24 w-full items-center justify-between">
<a href="/"> <a href="/">
<div class="text-xl font-semibold">{site.name}</div> <div class="text-2xl font-semibold">{config.siteName}</div>
</a> </a>
<div class="flex items-center gap-4"> <div class="flex items-center gap-6">
{
config.social.map((social) => (
<a href={social.link} target="_blank">
<social.icon />
</a>
))
}
{
config.rss && (
<a href="/atom.xml" target="_blank"> <a href="/atom.xml" target="_blank">
<Rss /> <Rss />
</a> </a>
)
}
<ThemeToggle /> <ThemeToggle />
</div> </div>
</header> </header>

View file

@ -0,0 +1,5 @@
---
import { config } from "~/config"
---
<div class="prose my-10 dark:prose-invert">{config.intro}</div>

View file

@ -0,0 +1,54 @@
---
import { config } from "~/config"
const { home, archive, category, tags, custom, about } = config.navigation
---
<div class="flex gap-4 text-lg">
{
home && (
<a href="/" class="hover:underline hover:underline-offset-4">
<p>首页</p>
</a>
)
}
{
archive && (
<a href="/archive" class="hover:underline hover:underline-offset-4">
<p>归档</p>
</a>
)
}
{
category && (
<a href="/category" class="hover:underline hover:underline-offset-4">
<p>分类</p>
</a>
)
}
{
tags && (
<a href="/tags" class="hover:underline hover:underline-offset-4">
<p>标签</p>
</a>
)
}
{
custom?.map((tab) => (
<a
href={tab.link}
class="hover:underline hover:underline-offset-4"
target="_blank"
>
<p>{tab.label}</p>
</a>
))
}
{
about && (
<a href="/about" class="hover:underline hover:underline-offset-4">
<p>关于</p>
</a>
)
}
</div>

View file

@ -1,28 +1,40 @@
export const site = { import { Github, Twitter } from "lucide-react"
name: "小孙同学",
favicon: "/avatar.png", export const config = {
meta: {
favicon: "",
title: "小孙同学", title: "小孙同学",
url: "https://blog.sunguoqi.com", url: "https://blog.sunguoqi.com",
slogan: "一个浪漫的理性主义者", slogan: "一个浪漫的理性主义者",
description: description: "读书、摄影、编程、旅行",
"🖥️ 前端小学生(React)|📸 摄影爱好者(Nikon Zfc)|🛸 旅行探索家(体验派)|🚴 骑行蹭风选手( Java 鱼雷 6-top )|🍎 科技产品发烧友(苹果&小米)<br/><br/> ✨ 路虽远行则将至,事虽难做则必成。热爱可抵岁月漫长。山高路远,独善其身,看世界,也找自己。希望能成为一个有趣的人~", },
} siteName: "小孙同学",
social: [
export const tabs = [ {
// { icon: Twitter,
// label: "归档", label: "X",
// link: "./archive", link: "https://x.com/sun0225SUN",
// }, },
// { {
// label: "标签", icon: Github,
// link: "./tags", label: "GitHub",
// }, link: "https://github.com/sun0225SUN",
},
],
rss: true,
navigation: {
home: true,
archive: true,
category: false,
tags: false,
about: true,
custom: [
{ {
label: "影集", label: "影集",
link: "https://camlife.cn", link: "https://camlife.cn",
}, },
{ ],
label: "关于",
link: "https://sunguoqi.com",
}, },
] intro: `🖥️ 前端小学生|📸 摄影爱好者|🛸 旅行探索家|🚴 骑行蹭风选手|🍎 科技产品发烧友`,
latestPosts: 8,
}

14
src/content.config.ts Normal file
View file

@ -0,0 +1,14 @@
import { defineCollection, z } from "astro:content"
const posts = defineCollection({
type: "content",
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
heroImage: z.string().optional(),
}),
})
export const collections = { posts }

View file

@ -0,0 +1,28 @@
---
title: "我的第一篇博客文章"
pubDate: 2024-07-01
description: "这是我 Astro 博客的第一篇文章。"
author: "Astro 学习者"
image:
url: "https://docs.astro.build/assets/rose.webp"
alt: "The Astro logo on a dark background with a pink glow."
tags: ["astro", "blogging", "learning in public"]
---
# 我的第一篇博客文章
发表于2022-07-01
欢迎来到我学习关于 Astro 的新博客!在这里,我将分享我建立新网站的学习历程。
## 我做了什么
1. **安装 Astro**:首先,我创建了一个新的 Astro 项目并设置好了我的在线账号。
2. **制作页面**:然后我学习了如何通过创建新的 `.astro` 文件并将它们保存在 `src/pages/` 文件夹里来制作页面。
3. **发表博客文章**:这是我的第一篇博客文章!我现在有用 Astro 编写的页面和用 Markdown 写的文章了!
## 下一步计划
我将完成 Astro 教程,然后继续编写更多内容。关注我以获取更多信息。

View file

@ -0,0 +1,12 @@
---
title: 我的第二篇博客文章
author: Astro 学习者
description: "学习了一些 Astro 后,我根本停不下来!"
image:
url: "https://docs.astro.build/assets/arc.webp"
alt: "The Astro logo on a dark background with a purple gradient arc."
pubDate: 2024-07-08
tags: ["astro", "blogging", "learning in public", "successes"]
---
在学习 Astro 大约一周后,我决定尝试些新的东西。我编写并导入了一个小组件!

View file

@ -0,0 +1,12 @@
---
title: 我的第三篇博客文章
author: Astro 学习者
description: "我遇到了一些问题,但是在社区里面提问真的很有帮助!"
image:
url: "https://docs.astro.build/assets/rays.webp"
alt: "The Astro logo on a dark background with rainbow rays."
pubDate: 2024-07-15
tags: ["astro", "learning in public", "setbacks", "community"]
---
尽管这并不总是一帆风顺,但我很享受使用 Astro 进行搭建。并且,[Discord 社区](https://astro.build/chat)真的很友好而且乐于助人!

View file

@ -0,0 +1,12 @@
---
title: "我的第四篇博客文章"
author: "Astro 学习者"
description: "这篇文章会自己出现在列表中!"
image:
url: "https://docs.astro.build/default-og-image.png"
alt: "The word astro against an illustration of planets and stars."
pubDate: 2024-08-08
tags: ["astro", "successes"]
---
这篇文章应该会与其他的博客文章一起显示,因为 `Astro.glob()` 会返回一个包含所有文章的列表,以创建这个文章列表。

View file

@ -0,0 +1,29 @@
---
title: "探索前端新技术"
author: "Guoqi Sun"
description: "记录一下最近学习的一些前端新技术和心得体会"
image:
url: "https://docs.astro.build/assets/rays.webp"
alt: "Colorful abstract background"
pubDate: 2024-08-15
tags: ["前端", "技术", "学习笔记"]
---
最近在学习和探索一些前端新技术,感觉收获颇丰。前端技术栈的发展真是日新月异,每天都有新的工具和框架出现。
## 新技术探索
1. Astro 框架
- 零 JS 优先
- 出色的性能表现
- 灵活的组件集成
2. Tailwind CSS
- 原子化 CSS
- 快速开发
- 暗黑模式支持
## 学习心得
持续学习是前端工程师的必修课。在技术快速迭代的今天,保持对新技术的热情和学习的动力很重要。同时也要注意技术选型要符合实际需求,不要盲目追求新技术。

View file

@ -0,0 +1,42 @@
---
title: "我的摄影之旅"
author: "Guoqi Sun"
description: "分享一些摄影经验和心得体会"
image:
url: "https://docs.astro.build/assets/arc.webp"
alt: "A beautiful landscape photo"
pubDate: 2024-09-01
tags: ["摄影", "旅行", "生活"]
---
作为一个摄影爱好者,总是希望能够用镜头记录下生活中的美好瞬间。今天想和大家分享一些摄影心得。
## 器材选择
虽然说器材不是最重要的,但合适的器材确实能帮助我们更好地表达:
1. 相机选择
- 轻便为主
- 操控要顺手
- 画质适中即可
2. 镜头搭配
- 35mm 街拍定焦
- 85mm 人像利器
- 16-35mm 风光广角
## 拍摄技巧
1. 构图要点
- 三分法则
- 引导线条
- 框架构图
2. 光线运用
- 黄金时间
- 顺光逆光
- 自然光影
摄影最重要的不是技术,而是发现美的眼睛。希望通过不断练习,能够拍出更多打动人心的照片。

View file

@ -0,0 +1,42 @@
---
title: "骑行的乐趣"
author: "Guoqi Sun"
description: "分享骑行运动的快乐和一些个人经验"
image:
url: "https://docs.astro.build/assets/rose.webp"
alt: "A scenic cycling route"
pubDate: 2024-09-15
tags: ["骑行", "运动", "生活"]
---
骑行是一项既能锻炼身体又充满乐趣的运动。今天想和大家分享一下我的骑行经历和心得。
## 装备选择
合适的装备能让骑行更加安全和舒适:
1. 自行车
- 车架材质:铝合金/碳纤维
- 变速系统:禧玛诺套件
- 轮胎选择:防扎耐磨
2. 骑行装备
- 头盔(安全第一)
- 骑行服(速干透气)
- 手套和眼镜
## 骑行技巧
1. 基础要点
- 正确的骑行姿势
- 变速时机的把握
- 体力分配
2. 安全建议
- 路况观察
- 夜骑装备
- 天气考虑
骑行不仅是一项运动,更是一种生活方式。在路上,你可以感受风的轻抚,欣赏沿途的风景,让身心都得到放松。希望更多的人能够加入骑行的行列,体验这项运动的魅力。

View file

@ -0,0 +1,53 @@
---
title: "科技产品使用体验"
author: "Guoqi Sun"
description: "分享一些常用科技产品的使用体验和选购建议"
image:
url: "https://docs.astro.build/assets/arc.webp"
alt: "Modern tech devices"
pubDate: 2024-10-01
tags: ["科技", "数码", "生活"]
---
作为一个科技产品爱好者,经常会尝试各种新的数码产品。今天想和大家分享一下我的使用体验。
## 苹果生态
1. iPhone 体验
- Face ID的便捷
- 相机系统的提升
- iOS生态的流畅
2. MacBook 使用感受
- M系列芯片的性能
- 续航能力
- 系统集成度
## 小米产品
1. 智能家居
- 米家自动化
- 设备互联
- 语音控制
2. 周边配件
- 充电设备
- 智能手环
- 蓝牙耳机
## 选购建议
1. 需求为先
- 实际使用场景
- 预算考虑
- 长期价值
2. 生态集成
- 设备互通
- 数据同步
- 使用便利性
科技产品应该服务于生活,而不是成为负担。在选择产品时,要考虑实际需求,不要盲目追求新品。好的产品应该能够提升生活品质,带来便利和愉悦的体验。

View file

@ -1,6 +1,6 @@
--- ---
import "~/styles/globals.css" import "~/styles/globals.css"
import { site } from "~/config" import { config } from "~/config"
--- ---
<!doctype html> <!doctype html>
@ -8,10 +8,10 @@ import { site } from "~/config"
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href={site.favicon} /> <link rel="icon" type="image/svg+xml" href={config.meta.favicon} />
<meta name="generator" content={Astro.generator} /> <meta name="generator" content={Astro.generator} />
<title>{site.title} - {site.slogan}</title> <title>{config.meta.title} - {config.meta.slogan}</title>
<meta name="description" content={site.description} /> <meta name="description" content={config.meta.description} />
<script is:inline> <script is:inline>
// set theme before page load // set theme before page load
const theme = (() => { const theme = (() => {
@ -32,10 +32,8 @@ import { site } from "~/config"
} }
</script> </script>
</head> </head>
<body> <body class="dark:bg-[#121212] dark:text-white">
<div <div class="flex min-h-screen w-full justify-center px-10 md:p-0">
class="flex min-h-screen w-full justify-center dark:bg-[#121212] dark:text-white"
>
<slot /> <slot />
</div> </div>
</body> </body>

View file

@ -1,9 +1,13 @@
--- ---
import Header from "~/components/astro/header.astro"
import Nav from "~/components/astro/nav.astro"
import BaseLayout from "./base.astro" import BaseLayout from "./base.astro"
--- ---
<BaseLayout> <BaseLayout>
<main class="max-auto w-full max-w-3xl"> <main class="max-auto w-full max-w-3xl">
<Header />
<Nav />
<slot /> <slot />
</main> </main>
</BaseLayout> </BaseLayout>

14
src/layouts/post.astro Normal file
View file

@ -0,0 +1,14 @@
---
import type { CollectionEntry } from "astro:content"
import HomeLayout from "~/layouts/home.astro"
import "~/styles/post.css"
type Props = CollectionEntry<"posts">["data"]
const { title, description, pubDate, updatedDate } = Astro.props
---
<HomeLayout>
<article class="prose mt-10 dark:prose-invert">
<slot />
</article>
</HomeLayout>

56
src/pages/about.md Normal file
View file

@ -0,0 +1,56 @@
---
layout: ../layouts/post.astro
title: "关于我"
description: "前端开发者 | 摄影爱好者 | 骑行爱好者"
---
# 👋 你好,我是小孙同学
一名热爱技术、热爱生活的前端开发者。喜欢尝试新事物,记录生活点滴。
## 🎯 关于我
- 🖥️ 前端开发者,持续学习各种新技术
- 📸 摄影爱好者,喜欢用镜头记录美好瞬间
- 🚴 骑行爱好者,享受风吹过脸庞的感觉
- 🛸 喜欢旅行,探索世界的每个角落
- 🍎 科技产品发烧友,特别钟爱苹果生态
## 💻 技术栈
- 前端HTML, CSS, JavaScript, TypeScript
- 框架React, Vue, Astro
- 工具Git, Webpack, Vite
- 其他Node.js, 响应式设计
## 📸 摄影装备
- 相机Sony A7M3
- 镜头:
- 35mm f1.8 (风景、街拍)
- 85mm f1.8 (人像)
- 16-35mm f4 (广角风景)
## 🚲 骑行装备
- 公路车Specialized Allez
- 装备:头盔、手套、骑行服
## 📫 联系我
- GitHub: [github.com/sun0225SUN](https://github.com/sun0225SUN)
- Blog: [sunguoqi.com](https://sunguoqi.com)
## 🎯 未来计划
1. 继续深入学习前端技术
2. 多写技术博客,分享经验
3. 参与开源项目
4. 探索更多有趣的地方
5. 拍更多好看的照片
---
> 热爱可抵岁月漫长。山高路远,独善其身,看世界,也找自己。
这个博客将记录我在技术、摄影、骑行等方面的心得体会和生活感悟。希望能在这里遇见志同道合的朋友!

7
src/pages/archive.astro Normal file
View file

@ -0,0 +1,7 @@
---
import HomeLayout from "~/layouts/home.astro"
---
<HomeLayout>
<div>archive</div>
</HomeLayout>

7
src/pages/category.astro Normal file
View file

@ -0,0 +1,7 @@
---
import HomeLayout from "~/layouts/home.astro"
---
<HomeLayout>
<div>category</div>
</HomeLayout>

View file

@ -1,12 +1,12 @@
--- ---
import Blog from "~/components/astro/blog.astro"
import Footer from "~/components/astro/footer.astro" import Footer from "~/components/astro/footer.astro"
import Header from "~/components/astro/header.astro" import Intro from "~/components/astro/intro.astro"
import { Test } from "../components/react/test" import HomeLayout from "~/layouts/home.astro"
import HomeLayout from "../layouts/home.astro"
--- ---
<HomeLayout> <HomeLayout>
<Header /> <Intro />
<Test /> <Blog />
<Footer /> <Footer />
</HomeLayout> </HomeLayout>

View file

@ -0,0 +1,20 @@
---
import { type CollectionEntry, getCollection } from "astro:content"
import Post from "~/layouts/post.astro"
export async function getStaticPaths() {
const posts = await getCollection("posts")
return posts.map((post: { slug: string; [key: string]: any }) => ({
params: { slug: post.slug },
props: post,
}))
}
type Props = CollectionEntry<"posts">
const post = Astro.props
const { Content } = await post.render()
---
<Post {...post.data}>
<Content />
</Post>

7
src/pages/tags.astro Normal file
View file

@ -0,0 +1,7 @@
---
import HomeLayout from "~/layouts/home.astro"
---
<HomeLayout>
<div>tag</div>
</HomeLayout>

8
src/styles/post.css Normal file
View file

@ -0,0 +1,8 @@
article code {
@apply rounded bg-gray-100 px-1 dark:bg-gray-900;
}
article code::before,
article code::after {
content: none !important;
}

17
src/utils/index.ts Normal file
View file

@ -0,0 +1,17 @@
import type { CollectionEntry } from "astro:content"
import { getCollection } from "astro:content"
export const formatDate = (date: Date): string => {
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, "0")
const day = String(date.getDate()).padStart(2, "0")
return `${year}-${month}-${day}`
}
export const getPosts = async () => {
const posts = await getCollection("posts")
return posts.sort(
(a: CollectionEntry<"posts">, b: CollectionEntry<"posts">) =>
b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
)
}

View file

@ -5,5 +5,5 @@ export default {
theme: { theme: {
extend: {}, extend: {},
}, },
plugins: [], plugins: [require("@tailwindcss/typography")],
} }