Compare commits

...

3 Commits

Author SHA1 Message Date
xiaomai
b05faddfc0 feat(seo): implement dynamic page titles
This commit enhances SEO and user experience by setting dynamic page titles for detail pages and updating the global title configuration.

- Event, Hall of Fame, and News detail pages now use the specific item's title as the page title.
- The global `titleTemplate` and default `title` in `nuxt.config.ts` have been updated for better branding.
- These changes ensure each page has a unique, descriptive title, which is beneficial for search engine ranking and browser tab clarity.
2025-10-04 11:03:21 +08:00
xiaomai
950dc60891 feat(seo): implement SEO enhancements and social media embeds
This commit introduces significant SEO improvements and enhances content embedding capabilities.

- Integrates `@nuxtjs/seo`, `@nuxtjs/sitemap`, and `@nuxtjs/robots` to boost search engine visibility.
- Configures global meta tags, including Open Graph and Twitter Cards, for richer social media sharing.
- Adds support for embedding YouTube and Facebook content directly within markdown pages.
- Introduces a new `TikTokEmbed` component for future use.
2025-10-04 10:10:46 +08:00
xiaomai
a6970b46cd refactor(assets): self-host all images
Migrated all images from the external host `img.tootaio.com` to be self-hosted within the project's `public` directory. This change improves performance, reliability, and
removes dependency on a third-party service. Additionally, the analytics script has been temporarily disabled.
2025-10-03 17:10:21 +08:00
24 changed files with 997 additions and 87 deletions

2
.gitignore vendored
View File

@@ -22,3 +22,5 @@ logs
.env
.env.*
!.env.example
repomix-output.xml

View File

@@ -0,0 +1,26 @@
<script setup lang="ts">
import { onMounted } from "vue";
const props = defineProps<{
url: string
}>()
onMounted(() => {
// 如果 TikTok embed 脚本未加载,动态注入
if (!document.querySelector('script[src="https://www.tiktok.com/embed.js"]')) {
const s = document.createElement("script");
s.src = "https://www.tiktok.com/embed.js";
s.async = true;
document.body.appendChild(s);
} else {
// 如果脚本已存在,调用它刷新 embed
// 官方脚本会自动处理,不需要手动 init
}
});
</script>
<template>
<blockquote class="tiktok-embed" :cite="url" data-video-id="" style="max-width: 605px; min-width: 325px;">
<a :href="url">View on TikTok</a>
</blockquote>
</template>

View File

@@ -2,7 +2,7 @@
<div>
<!-- Hero Banner -->
<section class="relative bg-primary py-32 md:py-48 lg:py-64 text-center bg-cover bg-center"
style="background-image: url('http://img.tootaio.com/i/2025/10/01/nu13l1.jpg');">
style="background-image: url('/hero-image.jpg');">
<!-- 遮罩 -->
<div class="absolute inset-0 bg-black/40"></div>

View File

@@ -56,6 +56,10 @@ const { data: event } = await useAsyncData('event-detail', () =>
.path(`/events/${route.params.slug}`)
.first()
)
useHead({
title: event.value?.title
})
</script>
<style scoped></style>

View File

@@ -24,7 +24,8 @@
class="w-full h-48 object-cover transition-transform duration-500 group-hover:scale-110" />
<div
class="absolute inset-0 bg-black/0 group-hover:bg-black/30 transition-all duration-300 flex items-center justify-center">
<Icon name="mdi:like" class="w-12 h-12 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300"/>
<Icon name="mdi:like"
class="w-12 h-12 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
</div>
</div>
</div>
@@ -40,6 +41,10 @@ const { data: person } = await useAsyncData('hall-of-fames-detail', () =>
.path(`/hall-of-fames/${route.params.slug}`)
.first()
)
useHead({
title: person.value?.name
})
</script>
<style></style>

View File

@@ -24,6 +24,10 @@ const { data: n } = await useAsyncData('new-detail', () =>
.path(`/news/${route.params.slug}`)
.first()
)
useHead({
title: n.value?.title
})
</script>
<style></style>

View File

@@ -3,16 +3,16 @@ title: "927 永中 • 钟意你"
subtitle: "永中校友会 39周年庆"
date: "2025-09-27"
location: "永平中学校园"
cover: "http://img.tootaio.com/i/2025/10/03/guw8wo.jpg"
cover: "/events/20250927-return-to-school/event-photo-1.jpg"
---
# 永中校友会39周年会庆午宴 温馨欢聚350人
![来宾打卡照](http://img.tootaio.com/i/2025/10/03/guw8wo.jpg)
![来宾打卡照](/events/20250927-return-to-school/event-photo-1.jpg)
来宾打卡照(星洲日报记者,邹智敏摄)
永平中学校友会于 9 月 27 日举办“927 永中·钟意你”39 周年会庆午宴,吸引约 350 位校友与社会贤达齐聚一堂,共度温馨时光,场面热闹盛大。
![嘉宾合照](http://img.tootaio.com/i/2025/10/03/guw9z0.jpg)
![嘉宾合照](/events/20250927-return-to-school/event-photo-2.jpg)
与会嘉宾向永中校友会献上祝福,左起:许敏捷、王飞兴、林添顺、李煜斌、刘镇东、蓝宜宏、傅庆隆、张嘉群及郑凯聪(星洲日报记者,邹智敏摄)
本次会庆出席嘉宾包括:
@@ -44,6 +44,16 @@ cover: "http://img.tootaio.com/i/2025/10/03/guw8wo.jpg"
---
<iframe
src="https://www.facebook.com/plugins/post.php?href=https%3A%2F%2Fwww.facebook.com%2Fstory.php%3Fstory_fbid%3D10163303061049019%26id%3D667519018"
class="w-full"
height="720"
scrolling="no"
frameborder="0"
allowfullscreen="true"
allow="autoplay; clipboard-write; encrypted-media; picture-in-picture; web-share">
</iframe>
# 午宴 • 征信录
## 乐捐名单

View File

@@ -1,17 +1,20 @@
---
name: "何四荣学长"
photo: "http://img.tootaio.com/i/2025/10/03/ff51je.png"
photo: "hall-of-fame/he-si-rong/何四荣学长.png"
title: "画家、作家与文化记录者"
description: "马来西亚柔佛永平人,永平中学 1974 年毕业生。何学长为资深当代画家、作家与文化记录者,曾于吉隆坡美术学院深造,其创作多以「波光倒影 / 流动色彩」为主题,作品抽象且具内在意象,曾受媒体专访并在多项展览与校内艺术联展中担任特邀艺术家。"
gallery:
gallery:
[
"https://i.ytimg.com/vi/Nu50FOvrGhI/maxresdefault.jpg",
"https://thumb.artron.net/Img/image?c=0&h=0&src=https%3A%2F%2Fimg10.artimg.net%2Fpublic%2Fbeian%2Fpng%2F202301%2Fefc77b56df4478d28bab8c00a7298669.png&w=800",
"https://images.openai.com/thumbnails/45906510beb1aadaab0a2db3fc34a8e3.jpeg"
"/hall-of-fame/he-si-rong/采访照 1.jpg",
"/hall-of-fame/he-si-rong/采访照 2.webp",
"/hall-of-fame/he-si-rong/作品 1.webp",
]
---
# 何四荣学长
<iframe width="560" height="315" src="https://www.youtube.com/embed/Nu50FOvrGhI?si=Bq06-PFEfAhS4pvE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
## 基本背景
何四荣学长出生并成长于柔佛州永平,系永平中学 1974 年届(第九届)毕业生,之后赴吉隆坡深造艺术相关学业。作为家乡出身的艺术家,他长期活跃于本地与区域艺术圈,並多次受邀参与校内外的艺术活动与联展。([vtour.my](https://vtour.my/local-artist-%E6%9C%AC%E5%9C%9F%E7%94%BB%E5%AE%B6/?utm_source=chatgpt.com "Local artist 本土画家| VTOUR"))

View File

@@ -1,24 +1,27 @@
---
name: "马文清学长"
photo: "http://img.tootaio.com/i/2025/10/03/fgbegj.png"
photo: "/hall-of-fame/ma-wong-ching/马文清学长.png"
title: "俐马集团董事长、永平中学董事长"
---
# 马文清学长
<iframe width="560" height="315" src="https://www.youtube.com/embed/PWcWdJsADAY?si=S73q0jvCZkWrIAAt" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
**马文清1951年生马来西亚柔佛州永平人**
现任 **俐马集团Ramatex Berhad董事长****永平中学董事长**
现任 **俐马集团Ramatex Berhad董事长****永平中学董事长**
马文清校友早年赴台湾就读逢甲大学海外青年技术训练班纺织科1972年毕业后返马投身纺织产业。1973年他与胞弟马文明及校友共同创业创立向荣针织公司1976年扩展为 **俐马集团** 并亲自担任董事长带领企业走向国际。集团现已在马来西亚、中国、越南、柬埔寨及约旦设厂产品行销全球长期入选《亚洲周刊》国际华商500强被誉为 **马来西亚纺织业巨擘**
在事业成就之外,马文清校友始终秉持「 **再穷不能穷教育** 」的理念,热心公益、扶植教育。作为永平中学董事长,他累计捐资 **超过5,600万令吉** 并慷慨捐赠33亩土地兴建新校区大力改善校舍设备、设立助学金推动课程与师资改革积极拓展国际交流奠定永中迈向优质化与国际化的坚实基础。他同时长期支持台湾高教捐赠逢甲大学逾新台币1.2亿元,用于奖助学金与校务发展。
在事业成就之外,马文清校友始终秉持「 **再穷不能穷教育** 」的理念,热心公益、扶植教育。作为永平中学董事长,他累计捐资 **超过5,600万令吉** 并慷慨捐赠33亩土地兴建新校区大力改善校舍设备、设立助学金推动课程与师资改革积极拓展国际交流奠定永中迈向优质化与国际化的坚实基础。他同时长期支持台湾高教捐赠逢甲大学逾新台币1.2亿元,用于奖助学金与校务发展。
在文化推广方面他于2019年推动成立「 **永平中学丛书工作坊** 」,出版涵盖地方史、社会评论与时代议题的系列著作,成为华文教育与文化传承的重要典范。
凭借其对产业、教育与社会的卓越贡献,马文清校友荣获:
* **逢甲大学第五届杰出校友2003年**
* **逢甲大学荣誉博士学位2023年第8位获此荣衔校友**
* **2025全球杰出僑生校友 企业工商奖**
- **逢甲大学第五届杰出校友2003年**
- **逢甲大学荣誉博士学位2023年第8位获此荣衔校友**
- **2025全球杰出僑生校友 企业工商奖**
马文清校友以企业家的远见、教育家的情怀与社会责任感,书写了跨越产业与公益的荣耀篇章,堪为永中人之典范。

View File

@@ -4,7 +4,7 @@ date: "2025-10-01"
updated: "2025-10-01"
author: "麦祖奕学长"
description: "永中校友会官网正式上线,为校友提供最新资讯、活动报名及互动交流平台。"
cover: "http://img.tootaio.com/i/2025/10/02/t1pq4s.png"
cover: "/news/20251001-official-web-launch/Screenshot.png"
tags: ["活动", "公告", "产品更新"]
category: "通知"
highlight: true

View File

@@ -4,20 +4,53 @@ import tailwindcss from "@tailwindcss/vite";
export default defineNuxtConfig({
compatibilityDate: "2025-07-15",
devtools: { enabled: true },
modules: ["@nuxt/content", "@nuxt/image", "@nuxt/ui", "reka-ui/nuxt"],
modules: [
"@nuxt/content",
"@nuxt/image",
"@nuxt/ui",
"reka-ui/nuxt",
"@nuxtjs/robots",
"@nuxtjs/seo",
"@nuxtjs/sitemap",
],
css: ["~/assets/css/main.css"],
vite: {
plugins: [tailwindcss()],
},
app: {
head: {
title: "永平中学校友会",
titleTemplate: "%s | 永中校友会",
title: "永中校友圈",
script: [
{
src: "/analytics.js",
tagPosition: "head",
},
],
meta: [
// 基础 SEO
{ name: "description", content: "永平中学校友会官网 - 连接校友,共享资源,传承母校精神。" },
{ name: "keywords", content: "永平中学, 校友会, 永平中学校友, 永平校友, 同学会" },
{ name: "author", content: "永平中学校友会" },
{ name: "viewport", content: "width=device-width, initial-scale=1" },
// Open GraphFacebook/LinkedIn
{ property: "og:title", content: "永平中学校友会" },
{ property: "og:description", content: "永平中学校友会官网 - 连接校友,共享资源,传承母校精神。" },
{ property: "og:type", content: "website" },
{ property: "og:url", content: "https://yphsalumni.org" }, // ✅ 换成你网站的真实域名
{ property: "og:image", content: "https://yphsalumni.org/hero-image.jpg" }, // ✅ 上传一张封面图
// Twitter Card
{ name: "twitter:card", content: "summary_large_image" },
{ name: "twitter:title", content: "永平中学校友会" },
{ name: "twitter:description", content: "连接校友,共享资源,传承母校精神。" },
{ name: "twitter:image", content: "https://yphsalumni.org/hero-image.jpg" },
],
},
},
});
site: {
url: "https://yphsalumni.com",
name: "永中校友会 YPHS Alumni"
}
});

View File

@@ -13,6 +13,9 @@
"@nuxt/content": "3.7.1",
"@nuxt/image": "1.11.0",
"@nuxt/ui": "4.0.0",
"@nuxtjs/robots": "5.5.5",
"@nuxtjs/seo": "3.2.2",
"@nuxtjs/sitemap": "7.4.7",
"@tailwindcss/vite": "^4.1.13",
"better-sqlite3": "^12.4.1",
"element-plus": "^2.11.4",

936
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1000 1000" style="enable-background:new 0 0 1000 1000;" xml:space="preserve">
viewBox="0 0 1000 1000" style="enable-background:new 0 0 1000 1000;" xml:space="preserve"
width="200" height="200">
<style type="text/css">
.st0{fill:#FFCC00;stroke:#000000;stroke-width:8.0717;stroke-miterlimit:10;}
.st1{fill:#C51A1B;}
@@ -16,18 +17,6 @@
.st10{fill:#FFFFFF;}
.st11{fill:none;stroke:#FFFFFF;stroke-width:1.9665;stroke-miterlimit:10;}
</style>
<g id="Border">
</g>
<g id="Red_Circle">
</g>
<g id="Blue_Cirle">
</g>
<g id="Sun">
</g>
<g id="Triangle">
</g>
<g id="Decorations">
</g>
<g id="Text">
<g>
<g>

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

BIN
public/hero-image.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB