diff --git a/applications/view/public/__init__.py b/applications/view/public/__init__.py
index a6513b2..8bcf779 100644
--- a/applications/view/public/__init__.py
+++ b/applications/view/public/__init__.py
@@ -1,5 +1,5 @@
"""
-前台公开蓝图:导航聚合页 / 分类详情页
+前台公开蓝图:导航聚合页 / 分类详情页 / 关于本站
URL 前缀:/site(避免与后台 / 路由冲突)
鉴权要求:无(任何用户都可访问,含未登录匿名用户)
@@ -7,7 +7,15 @@ URL 前缀:/site(避免与后台 / 路由冲突)
注意:不要给这些视图加 @authorize 装饰器,否则会强制登录_required。
"""
from applications.view.public.nav import bp as nav_bp
+from applications.view.public.about import bp as about_bp
+from applications.view.public.friend import bp as friend_bp
# 把 nav 蓝图作为 public 包的对外入口
-bp = nav_bp
\ No newline at end of file
+bp = nav_bp
+
+
+def register_public_bp(app):
+ """注册 public 子蓝图"""
+ app.register_blueprint(about_bp)
+ app.register_blueprint(friend_bp)
\ No newline at end of file
diff --git a/applications/view/public/about.py b/applications/view/public/about.py
new file mode 100644
index 0000000..413f00b
--- /dev/null
+++ b/applications/view/public/about.py
@@ -0,0 +1,49 @@
+"""
+前台公开"关于本站"页面。
+
+不需要登录,匿名可访问。Markdown 在模板里渲染。
+"""
+import re
+
+import markdown as _markdown
+from flask import Blueprint, render_template
+
+from applications.models import About
+
+bp = Blueprint('public_about', __name__, url_prefix='/site')
+
+
+def _get_about() -> About:
+ """复用 model 的种子逻辑,避免空表时炸"""
+ a = About.query.get(1)
+ if a is None:
+ from applications.extensions import db
+ a = About(id=1, site_name='旺珂 · 导航')
+ db.session.add(a)
+ db.session.commit()
+ return a
+
+
+@bp.get('/about')
+def about():
+ a = _get_about()
+ html = _render_md(a.content_md)
+ return render_template('public/about.html', about=a, content_html=html)
+
+
+_URL_RE = re.compile(r'(https?://[^\s)<>"\\]+|[\w.+-]+@[\w-]+\.[\w.-]+)')
+
+
+def _render_md(text: str) -> str:
+ """Markdown → HTML;自动把裸链接/邮箱变可点;同时禁掉 script/iframe。"""
+ if not text or not text.strip():
+ return ''
+ html = _markdown.markdown(
+ text,
+ extensions=['fenced_code', 'tables', 'nl2br', 'sane_lists'],
+ output_format='html5',
+ )
+ # 防御:清掉
+{% endraw %}
+
+```
+
+**注意 footer include 必须放在所有业务 `
+