Compare commits

...

7 Commits

Author SHA1 Message Date
voson
055eef9a0f chore: remove README.md and update deploy documentation with Chinese localization and detailed setup instructions [skip ci] 2026-02-04 13:32:18 +08:00
voson
ee87ae4fee fix: enhance ArticleCard component to conditionally hide expand button and fade effect based on content height
All checks were successful
deploy / build-and-deploy (push) Successful in 54s
2026-02-04 09:41:43 +08:00
voson
8019ebd226 chore: update deploy workflow to run on Debian and add notification step for deployment status
All checks were successful
deploy / build-and-deploy (push) Successful in 58s
2026-02-04 09:29:55 +08:00
voson
eb9ffb62ba ci: trigger rebuild
All checks were successful
deploy / build-and-deploy (push) Successful in 4m3s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-04 09:21:40 +08:00
voson
96c35afab6 chore: update deploy workflow to use sshpass for SSH authentication and cache npm dependencies
Some checks failed
deploy / build-and-deploy (push) Failing after 1m6s
2026-02-03 17:31:42 +08:00
voson
c2e540cc0d chore: remove unused favicon files and blog placeholder images, add new frog icon
All checks were successful
deploy / build-and-deploy (push) Successful in 1m10s
2026-02-03 17:09:36 +08:00
voson
5031b24d28 chore: update version to 0.1.0 and remove Footer component from blog index 2026-02-03 16:53:03 +08:00
21 changed files with 312 additions and 374 deletions

View File

@@ -7,7 +7,7 @@ on:
jobs:
build-and-deploy:
runs-on: self-hosted
runs-on: debian
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -16,37 +16,81 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Cache npm dependencies
# gitea 不支持 actions/cache@v4使用 v3 代替
uses: actions/cache@v3
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: npm-
- name: Install
run: npm ci
- name: Build
env:
SITE_URL: ${{ secrets.SITE_URL }}
SITE_URL: ${{ vars.SITE_URL }}
run: npm run build
- name: Write deploy key
env:
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
- name: Install sshpass
run: |
mkdir -p ~/.ssh
python3 - <<'PY'
import os
from pathlib import Path
key = os.environ['DEPLOY_SSH_KEY']
p = Path.home() / '.ssh' / 'deploy_key'
p.write_text(key, encoding='utf-8')
PY
chmod 600 ~/.ssh/deploy_key
if ! command -v sshpass &> /dev/null; then
if command -v apt-get &> /dev/null; then
sudo apt-get update && sudo apt-get install -y sshpass
elif command -v yum &> /dev/null; then
sudo yum install -y sshpass
elif command -v apk &> /dev/null; then
sudo apk add --no-cache sshpass
fi
fi
- name: Add known_hosts
run: |
mkdir -p ~/.ssh
ssh-keyscan -p "${{ secrets.DEPLOY_SSH_PORT }}" -H "${{ secrets.DEPLOY_SSH_HOST }}" >> ~/.ssh/known_hosts
ssh-keyscan -p "${{ vars.DEPLOY_SSH_PORT }}" -H "${{ vars.DEPLOY_SSH_HOST }}" >> ~/.ssh/known_hosts
- name: Deploy via tar over SSH
env:
SSHPASS: ${{ secrets.DEPLOY_SSH_PASSWORD }}
run: |
tar -C dist -czf - . | \
ssh -o BatchMode=yes -o StrictHostKeyChecking=yes -o ConnectTimeout=15 -i ~/.ssh/deploy_key -p "${{ secrets.DEPLOY_SSH_PORT }}" "${{ secrets.DEPLOY_SSH_USER }}@${{ secrets.DEPLOY_SSH_HOST }}" \
"bash -lc 'set -euo pipefail; tmp=\"\${{ secrets.DEPLOY_PATH }}.tmp\"; rm -rf \"\$tmp\"; mkdir -p \"\$tmp\"; tar -xzf - -C \"\$tmp\"; rm -rf \"\${{ secrets.DEPLOY_PATH }}\"; mv \"\$tmp\" \"\${{ secrets.DEPLOY_PATH }}\"'"
sshpass -e ssh -o StrictHostKeyChecking=yes -o ConnectTimeout=15 -p "${{ vars.DEPLOY_SSH_PORT }}" "${{ vars.DEPLOY_SSH_USER }}@${{ vars.DEPLOY_SSH_HOST }}" \
"set -euo pipefail; tmp='${{ vars.DEPLOY_PATH }}.tmp'; rm -rf \"\$tmp\"; mkdir -p \"\$tmp\"; tar -xzf - -C \"\$tmp\"; rm -rf '${{ vars.DEPLOY_PATH }}'; mv \"\$tmp\" '${{ vars.DEPLOY_PATH }}'"
- name: 发送通知
if: always()
continue-on-error: true
env:
WEBHOOK_URL: ${{ vars.WEBHOOK_URL }}
run: |
[ -z "$WEBHOOK_URL" ] && exit 0
if [ "${{ job.status }}" = "success" ]; then
status_text="部署成功 ✅"
else
status_text="部署失败 ❌"
fi
commit_title=$(git log -1 --pretty=format:"%s" 2>/dev/null || echo "N/A")
workflow_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}"
site_url="${{ vars.SITE_URL }}"
if [ "${{ job.status }}" = "success" ]; then
payload=$(jq -n \
--arg title "${{ github.event.repository.name }} ${status_text}" \
--arg commit "$commit_title" \
--arg author "${{ github.actor }}" \
--arg site "$site_url" \
--arg url "$workflow_url" \
'{msg_type: "text", content: {text: "\($title)\n提交\($commit)\n作者\($author)\n站点\($site)\n详情\($url)"}}')
else
payload=$(jq -n \
--arg title "${{ github.event.repository.name }} ${status_text}" \
--arg commit "$commit_title" \
--arg author "${{ github.actor }}" \
--arg url "$workflow_url" \
'{msg_type: "text", content: {text: "\($title)\n提交\($commit)\n作者\($author)\n详情\($url)"}}')
fi
curl -sS -H "Content-Type: application/json" -X POST -d "$payload" "$WEBHOOK_URL"

108
AGENTS.md Normal file
View File

@@ -0,0 +1,108 @@
# AI 代理指南
本文档为 AI 代理提供项目上下文和操作指南。
## 项目概述
- **类型**Astro 静态博客站点
- **域名**https://wuyouwulv.me
- **仓库**voson/publishGitea
- **部署**Gitea Actions → SSH → Vultr 服务器
## 技术栈
- **框架**Astro 5.x
- **语言**TypeScript
- **样式**:全局 CSS
- **部署**Gitea Actions + SSH 密码认证
## 目录结构
```
publish/
├── .gitea/workflows/deploy.yml # CI/CD 部署工作流
├── deploy/ # 部署文档和配置示例
├── public/ # 静态资源
├── src/
│ ├── components/ # Astro 组件
│ ├── content/blog/ # 博客文章Markdown
│ ├── layouts/ # 页面布局
│ ├── pages/ # 页面路由
│ └── styles/ # 全局样式
└── astro.config.mjs # Astro 配置
```
## 服务器配置
| 项目 | 值 |
|------|-----|
| 服务器 IP | `45.32.105.53` |
| SSH 用户 | `root` |
| SSH 端口 | `22` |
| 部署路径 | `/var/www/publish` |
| Web 服务器 | Caddy |
服务器配置文件位置:`/Users/voson/Library/Mobile Documents/com~apple~CloudDocs/refining/config.toml`
## Gitea 配置
- **实例**https://gitea.refining.dev
- **仓库**voson/publish注意不是 refining/publish
- **Token**:见 `config.toml` 中的 `[services.gitea]`
### Actions 变量vars
| 变量 | 说明 |
|------|------|
| `SITE_URL` | 站点 URL必须包含 `https://` |
| `DEPLOY_SSH_HOST` | 服务器 IP |
| `DEPLOY_SSH_PORT` | SSH 端口 |
| `DEPLOY_SSH_USER` | SSH 用户名 |
| `DEPLOY_PATH` | 部署目录 |
| `WEBHOOK_URL` | 飞书通知 Webhook |
### Actions 密钥secrets
| 密钥 | 说明 |
|------|------|
| `DEPLOY_SSH_PASSWORD` | SSH 登录密码 |
## 常见操作
### 查看构建日志
```bash
# 获取最近的运行
curl -s -H "Authorization: token TOKEN" \
"https://gitea.refining.dev/api/v1/repos/voson/publish/actions/runs?limit=1" | jq .
# 获取 job 日志
curl -s -H "Authorization: token TOKEN" \
"https://gitea.refining.dev/api/v1/repos/voson/publish/actions/jobs/JOB_ID/logs"
```
### 设置仓库变量
```bash
curl -X POST -H "Authorization: token TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":"VALUE","value":"VALUE"}' \
"https://gitea.refining.dev/api/v1/repos/voson/publish/actions/variables/VAR_NAME"
```
### 手动部署
```bash
cd /Users/voson/publish
npm run build
tar -C dist -czf - . | sshpass -p 'PASSWORD' ssh root@45.32.105.53 \
"set -euo pipefail; tmp='/var/www/publish.tmp'; rm -rf \"\$tmp\"; mkdir -p \"\$tmp\"; tar -xzf - -C \"\$tmp\"; rm -rf '/var/www/publish'; mv \"\$tmp\" '/var/www/publish'"
```
## 注意事项
1. **仓库路径**:仓库是 `voson/publish`,不是 `refining/publish`
2. **SITE_URL**:必须包含 `https://` 前缀,否则 Astro 构建会报 "Invalid url"
3. **SSH 认证**使用密码认证sshpass不是 SSH 密钥
4. **Gitea Cache**Gitea 不支持 `actions/cache@v4`,必须使用 `v3`
5. **变量 vs 密钥**:敏感信息(密码)用 secrets其他用 vars

View File

@@ -1,62 +0,0 @@
# Astro Starter Kit: Blog
```sh
npm create astro@latest -- --template blog
```
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
Features:
- ✅ Minimal styling (make it your own!)
- ✅ 100/100 Lighthouse performance
- ✅ SEO-friendly with canonical URLs and OpenGraph data
- ✅ Sitemap support
- ✅ RSS Feed support
- ✅ Markdown & MDX support
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:
```text
├── public/
├── src/
│   ├── components/
│   ├── content/
│   ├── layouts/
│   └── pages/
├── astro.config.mjs
├── README.md
├── package.json
└── tsconfig.json
```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
The `src/content/` directory contains "collections" of related Markdown and MDX documents. Use `getCollection()` to retrieve posts from `src/content/blog/`, and type-check your frontmatter using an optional schema. See [Astro's Content Collections docs](https://docs.astro.build/en/guides/content-collections/) to learn more.
Any static assets, like images, can be placed in the `public/` directory.
## 🧞 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?
Check out [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
## Credit
This theme is based off of the lovely [Bear Blog](https://github.com/HermanMartinus/bearblog/).

View File

@@ -1,26 +1,126 @@
# Server deploy (static)
# 部署文档
This repo builds an Astro static site into `dist/` and deploys it to a Linux server via rsync over SSH.
本项目使用 Astro 构建静态站点,通过 Gitea Actions 自动部署到 Linux 服务器。
## One-time server setup
## 架构概览
1. Create a deploy directory, e.g. `/var/www/publish`.
2. Configure your web server (Caddy or Nginx) to serve that directory.
3. Create an SSH key for CI and add its public key to the server.
```
本地开发 → Git Push → Gitea Actions → 构建 → SSH 部署 → 服务器
飞书通知
```
## Gitea Actions secrets (repo settings)
## 服务器信息
- `SITE_URL`
- `PUBLIC_NEWSLETTER_ACTION`
- `PUBLIC_NEWSLETTER_EMAIL_FIELD`
- `PUBLIC_NEWSLETTER_TITLE` (optional)
- `PUBLIC_NEWSLETTER_DESCRIPTION` (optional)
- `DEPLOY_SSH_HOST`
- `DEPLOY_SSH_PORT`
- `DEPLOY_SSH_USER`
- `DEPLOY_PATH`
- `DEPLOY_SSH_KEY` (private key)
| 项目 | 值 |
|------|-----|
| IP | `45.32.105.53` |
| 用户名 | `root` |
| 部署路径 | `/var/www/publish` |
| Web 服务器 | Caddy |
| 站点域名 | `https://wuyouwulv.me` |
## Example Caddyfile
## 一次性服务器配置
See `deploy/Caddyfile.example`.
1. 创建部署目录:
```bash
mkdir -p /var/www/publish
```
2. 配置 Caddy参考 `Caddyfile.example`
```bash
sudo vim /etc/caddy/Caddyfile
sudo systemctl reload caddy
```
3. 确保服务器已安装 `tar`(用于解压部署包)
## Gitea Actions 配置
### 仓库变量vars
在仓库设置 → Actions → Variables 中配置:
| 变量名 | 值 | 说明 |
|--------|-----|------|
| `SITE_URL` | `https://wuyouwulv.me` | 站点 URL用于 Astro 构建 |
| `DEPLOY_SSH_HOST` | `45.32.105.53` | 服务器 IP |
| `DEPLOY_SSH_PORT` | `22` | SSH 端口 |
| `DEPLOY_SSH_USER` | `root` | SSH 用户名 |
| `DEPLOY_PATH` | `/var/www/publish` | 部署目录 |
| `WEBHOOK_URL` | 飞书 Webhook URL | 部署通知(可选) |
### 仓库密钥secrets
在仓库设置 → Actions → Secrets 中配置:
| 密钥名 | 说明 |
|--------|------|
| `DEPLOY_SSH_PASSWORD` | SSH 登录密码 |
### 通过 API 配置变量
```bash
# 设置变量
curl -X POST -H "Authorization: token YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":"VALUE","value":"VALUE"}' \
"https://gitea.refining.dev/api/v1/repos/OWNER/REPO/actions/variables/VAR_NAME"
# 设置密钥
curl -X PUT -H "Authorization: token YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":"SECRET_VALUE"}' \
"https://gitea.refining.dev/api/v1/repos/OWNER/REPO/actions/secrets/SECRET_NAME"
```
## 部署流程
1. **Checkout** - 检出代码
2. **Setup Node** - 安装 Node.js 20
3. **Cache npm** - 缓存 npm 依赖(使用 `actions/cache@v3`
4. **Install** - `npm ci` 安装依赖
5. **Build** - `npm run build` 构建站点
6. **Install sshpass** - 安装 SSH 密码认证工具
7. **Add known_hosts** - 添加服务器到已知主机
8. **Deploy** - 通过 tar + SSH 部署到服务器
9. **通知** - 发送飞书通知(成功/失败)
## 手动部署
如需手动部署,可以在本地执行:
```bash
# 构建
npm run build
# 部署(需要 sshpass
tar -C dist -czf - . | \
sshpass -p 'PASSWORD' ssh -p 22 root@45.32.105.53 \
"set -euo pipefail; tmp='/var/www/publish.tmp'; rm -rf \"\$tmp\"; mkdir -p \"\$tmp\"; tar -xzf - -C \"\$tmp\"; rm -rf '/var/www/publish'; mv \"\$tmp\" '/var/www/publish'"
```
## Caddy 配置示例
参考 `Caddyfile.example` 文件。
## 故障排查
### 构建失败Invalid url
检查 `SITE_URL` 变量是否包含完整的 URL包括 `https://` 前缀)。
### 部署失败SSH 连接问题
1. 检查 `DEPLOY_SSH_PASSWORD` 密钥是否正确
2. 检查服务器 IP 和端口是否正确
3. 检查服务器是否允许密码登录
### 变量在 UI 中不显示
Gitea UI 可能有显示问题,可以通过 API 验证变量是否存在:
```bash
curl -s -H "Authorization: token YOUR_TOKEN" \
"https://gitea.refining.dev/api/v1/repos/OWNER/REPO/actions/variables" | jq .
```

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "publish",
"version": "0.0.1",
"version": "0.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "publish",
"version": "0.0.1",
"version": "0.1.0",
"dependencies": {
"@astrojs/mdx": "^4.3.13",
"@astrojs/rss": "^4.0.15",

View File

@@ -1,7 +1,7 @@
{
"name": "publish",
"type": "module",
"version": "0.0.1",
"version": "0.1.0",
"scripts": {
"dev": "astro dev",
"build": "astro build && pagefind --site dist",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 B

View File

@@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

Before

Width:  |  Height:  |  Size: 749 B

BIN
public/frog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -51,12 +51,25 @@ const hasContent = Astro.slots.has('default');
if (!card) return;
const content = card.querySelector('[data-content]') as HTMLElement;
const contentInner = content?.querySelector('.content-inner') as HTMLElement;
const fade = card.querySelector('[data-fade]') as HTMLElement;
const btn = card.querySelector('[data-expand-btn]') as HTMLButtonElement;
const text = btn?.querySelector('[data-expand-text]');
const icon = btn?.querySelector('[data-expand-icon]') as SVGElement;
if (!content || !btn || !text || !icon) return;
if (!content || !contentInner || !btn || !text || !icon) return;
// 检查内容实际高度是否超过最大高度
const maxHeight = 800;
const actualHeight = contentInner.scrollHeight;
// 如果内容不超过最大高度,隐藏展开按钮和渐变效果
if (actualHeight <= maxHeight) {
content.style.maxHeight = 'none';
if (fade) fade.style.display = 'none';
btn.style.display = 'none';
return;
}
let isExpanded = false;

View File

@@ -3,7 +3,6 @@
// all pages through the use of the <BaseHead /> component.
import '../styles/global.css';
import type { ImageMetadata } from 'astro';
import FallbackImage from '../assets/blog-placeholder-1.jpg';
import { SITE_TITLE } from '../consts';
interface Props {
@@ -14,14 +13,13 @@ interface Props {
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
const { title, description, image = FallbackImage } = Astro.props;
const { title, description, image } = Astro.props;
---
<!-- Global Metadata -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" href="/favicon.ico" />
<link rel="icon" type="image/png" href="/frog.png" />
<link rel="sitemap" href="/sitemap-index.xml" />
<link
rel="alternate"
@@ -41,18 +39,4 @@ const { title, description, image = FallbackImage } = Astro.props;
<!-- Primary Meta Tags -->
<title>{title}</title>
<meta name="title" content={title} />
<meta name="description" content={description} />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image.src, Astro.url)} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={Astro.url} />
<meta property="twitter:title" content={title} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={new URL(image.src, Astro.url)} />
<meta name="description" content={description} />

View File

@@ -1,16 +1,8 @@
---
title: 'First post'
description: 'Lorem ipsum dolor sit amet'
description: '我的第一篇博客'
pubDate: '2026-2-2'
heroImage: '../../assets/blog-placeholder-3.jpg'
heroImage: ''
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra massa massa ultricies mi.
Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id cursus metus aliquam eleifend mi.
Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.
nothing to say

View File

@@ -1,214 +0,0 @@
---
title: 'Markdown Style Guide'
description: 'Here is a sample of some basic Markdown syntax that can be used when writing Markdown content in Astro.'
pubDate: 'Jun 19 2024'
heroImage: '../../assets/blog-placeholder-1.jpg'
---
Here is a sample of some basic Markdown syntax that can be used when writing Markdown content in Astro.
## Headings
The following HTML `<h1>``<h6>` elements represent six levels of section headings. `<h1>` is the highest section level while `<h6>` is the lowest.
# H1
## H2
### H3
#### H4
##### H5
###### H6
## Paragraph
Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.
Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.
## Images
### Syntax
```markdown
![Alt text](./full/or/relative/path/of/image)
```
### Output
![blog placeholder](../../assets/blog-placeholder-about.jpg)
## Blockquotes
The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations.
### Blockquote without attribution
#### Syntax
```markdown
> Tiam, ad mint andaepu dandae nostion secatur sequo quae.
> **Note** that you can use _Markdown syntax_ within a blockquote.
```
#### Output
> Tiam, ad mint andaepu dandae nostion secatur sequo quae.
> **Note** that you can use _Markdown syntax_ within a blockquote.
### Blockquote with attribution
#### Syntax
```markdown
> Don't communicate by sharing memory, share memory by communicating.<br>
> — <cite>Rob Pike[^1]</cite>
```
#### Output
> Don't communicate by sharing memory, share memory by communicating.<br>
> — <cite>Rob Pike[^1]</cite>
[^1]: The above quote is excerpted from Rob Pike's [talk](https://www.youtube.com/watch?v=PAAkCSZUG1c) during Gopherfest, November 18, 2015.
## Tables
### Syntax
```markdown
| Italics | Bold | Code |
| --------- | -------- | ------ |
| _italics_ | **bold** | `code` |
```
### Output
| Italics | Bold | Code |
| --------- | -------- | ------ |
| _italics_ | **bold** | `code` |
## Code Blocks
### Syntax
we can use 3 backticks ``` in new line and write snippet and close with 3 backticks on new line and to highlight language specific syntax, write one word of language name after first 3 backticks, for eg. html, javascript, css, markdown, typescript, txt, bash
````markdown
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Example HTML5 Document</title>
</head>
<body>
<p>Test</p>
</body>
</html>
```
````
### Output
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Example HTML5 Document</title>
</head>
<body>
<p>Test</p>
</body>
</html>
```
## List Types
### Ordered List
#### Syntax
```markdown
1. First item
2. Second item
3. Third item
```
#### Output
1. First item
2. Second item
3. Third item
### Unordered List
#### Syntax
```markdown
- List item
- Another item
- And another item
```
#### Output
- List item
- Another item
- And another item
### Nested list
#### Syntax
```markdown
- Fruit
- Apple
- Orange
- Banana
- Dairy
- Milk
- Cheese
```
#### Output
- Fruit
- Apple
- Orange
- Banana
- Dairy
- Milk
- Cheese
## Other Elements — abbr, sub, sup, kbd, mark
### Syntax
```markdown
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
H<sub>2</sub>O
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
```
### Output
<abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
H<sub>2</sub>O
X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.

View File

@@ -1,16 +0,0 @@
---
title: 'Second post'
description: 'Lorem ipsum dolor sit amet'
pubDate: 'Jul 15 2022'
heroImage: '../../assets/blog-placeholder-4.jpg'
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra massa massa ultricies mi.
Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id cursus metus aliquam eleifend mi.
Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.

View File

@@ -2,7 +2,6 @@
import { Image } from 'astro:assets';
import { getCollection } from 'astro:content';
import BaseHead from '../../components/BaseHead.astro';
import Footer from '../../components/Footer.astro';
import FormattedDate from '../../components/FormattedDate.astro';
import Header from '../../components/Header.astro';
import { SITE_DESCRIPTION, SITE_TITLE } from '../../consts';
@@ -109,6 +108,5 @@ const posts = (await getCollection('blog')).sort(
</ul>
</section>
</main>
<Footer />
</body>
</html>