326 lines
20 KiB
HTML
326 lines
20 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="{{ 'zh-CN' if lang == 'zh' else 'en' }}">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{{ seo.title if seo else (l('论坛', 'Forum') ~ ' - ' ~ l('云价眼', 'VPS Price')) }}</title>
|
|
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='img/site-logo-mark.svg') }}">
|
|
{% if seo %}
|
|
<meta name="description" content="{{ seo.description }}">
|
|
<meta name="keywords" content="{{ seo.keywords }}">
|
|
<meta name="robots" content="{{ seo.robots }}">
|
|
<meta name="theme-color" content="#0F172A">
|
|
<link rel="canonical" href="{{ seo.canonical_url }}">
|
|
{% if seo.prev_canonical_url %}<link rel="prev" href="{{ seo.prev_canonical_url }}">{% endif %}
|
|
{% if seo.next_canonical_url %}<link rel="next" href="{{ seo.next_canonical_url }}">{% endif %}
|
|
{% for hreflang, href in seo.alternate_links.items() %}
|
|
<link rel="alternate" hreflang="{{ hreflang }}" href="{{ href }}">
|
|
{% endfor %}
|
|
{% if seo.feed_url %}
|
|
<link rel="alternate" type="application/rss+xml" title="{{ l('论坛 RSS 订阅', 'Forum RSS Feed') }}" href="{{ seo.feed_url }}">
|
|
{% endif %}
|
|
<meta property="og:type" content="{{ seo.og_type }}">
|
|
<meta property="og:url" content="{{ seo.og_url }}">
|
|
<meta property="og:title" content="{{ seo.og_title }}">
|
|
<meta property="og:description" content="{{ seo.og_description }}">
|
|
<meta property="og:image" content="{{ seo.og_image }}">
|
|
<meta name="twitter:card" content="{{ seo.twitter_card }}">
|
|
<meta name="twitter:title" content="{{ seo.twitter_title }}">
|
|
<meta name="twitter:description" content="{{ seo.twitter_description }}">
|
|
<meta name="twitter:image" content="{{ seo.og_image }}">
|
|
{% if seo_schema %}
|
|
<script type="application/ld+json">{{ seo_schema | tojson }}</script>
|
|
{% endif %}
|
|
{% endif %}
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
<link rel="stylesheet" href="/static/css/forum.css">
|
|
</head>
|
|
<body class="forum-page">
|
|
{% set cards = post_cards if post_cards is defined else [] %}
|
|
{% set sb = sidebar if sidebar is defined else {'total_users': 0, 'total_posts': 0, 'total_comments': 0, 'category_counts': [], 'active_users': []} %}
|
|
<header class="forum-header">
|
|
<div class="forum-header-inner forum-header-inner-with-center">
|
|
<div class="forum-header-left">
|
|
<a href="{{ url_for('forum_index') }}" class="forum-logo">
|
|
<img src="{{ url_for('static', filename='img/site-logo-mark.svg') }}" alt="{{ l('云价眼 Logo', 'VPS Price Logo') }}">
|
|
<span>{{ l('云价眼论坛', 'VPS Price Forum') }}</span>
|
|
</a>
|
|
</div>
|
|
<nav class="forum-top-nav" aria-label="{{ l('站点导航', 'Site navigation') }}">
|
|
<a href="{{ url_for('forum_index') }}" class="active">{{ l('论坛', 'Forum') }}</a>
|
|
<a href="{{ url_for('index') }}">{{ l('价格表', 'Pricing') }}</a>
|
|
</nav>
|
|
<div class="forum-header-right">
|
|
<span class="lang-switch">
|
|
<a href="{{ lang_url('zh') }}" class="{{ 'active' if lang == 'zh' else '' }}" title="切换到中文">中文</a>
|
|
<span class="lang-sep">|</span>
|
|
<a href="{{ lang_url('en') }}" class="{{ 'active' if lang == 'en' else '' }}" title="Switch to English">English</a>
|
|
</span>
|
|
{% if current_user %}
|
|
<span class="forum-user-chip">{{ current_user.username }}{% if current_user.is_banned %}{{ l('(封禁)', ' (Banned)') }}{% endif %}</span>
|
|
<a href="{{ url_for('user_profile') }}" class="forum-link">{{ l('个人中心', 'Profile') }}</a>
|
|
<a href="{{ url_for('user_notifications') }}" class="forum-link nav-link-with-badge">{{ l('通知', 'Notifications') }}{% if notifications_unread_count %}<span class="nav-badge">{{ notifications_unread_count }}</span>{% endif %}</a>
|
|
<a href="{{ url_for('user_logout') }}" class="forum-link">{{ l('退出', 'Logout') }}</a>
|
|
{% else %}
|
|
<a href="{{ url_for('user_login') }}" class="forum-link">{{ l('登录', 'Login') }}</a>
|
|
<a href="{{ url_for('user_register') }}" class="forum-link">{{ l('注册', 'Register') }}</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="forum-shell">
|
|
<section class="forum-hero" aria-labelledby="forum-hero-title">
|
|
<p class="forum-hero-kicker">{{ l('商业化社区入口', 'Commercial Community Hub') }}</p>
|
|
<h1 id="forum-hero-title">{{ forum_heading if forum_heading is defined else l('VPS 社区论坛', 'VPS Community Forum') }}</h1>
|
|
<p>{{ forum_intro if forum_intro is defined else l('聚合 VPS 评测、运维经验与采购讨论。', 'A discussion space for VPS reviews, operations, and buying decisions.') }}</p>
|
|
<div class="forum-hero-meta">
|
|
<span>{{ l('帖子总数', 'Total topics') }} {{ sb.total_posts }}</span>
|
|
<span>{{ l('活跃用户', 'Active users') }} {{ sb.total_users }}</span>
|
|
<a href="{{ forum_feed_url if forum_feed_url is defined else seo.feed_url }}" class="forum-link">{{ l('RSS 订阅', 'RSS Feed') }}</a>
|
|
</div>
|
|
</section>
|
|
<section class="forum-topline">
|
|
<div class="forum-tabs">
|
|
{% for item in tab_links %}
|
|
<a class="{{ 'active' if item.active else '' }}" href="{{ item.url }}">{{ item.label }}</a>
|
|
{% endfor %}
|
|
<a class="{{ 'active' if selected_category else '' }}" href="{{ category_nav_url }}">{{ l('分类', 'Categories') }}</a>
|
|
</div>
|
|
<div class="forum-actions">
|
|
{% if current_user and not current_user.is_banned %}
|
|
<a href="{{ url_for('forum_post_new') }}" class="forum-btn-primary">+ {{ l('发布主题', 'New Topic') }}</a>
|
|
{% elif current_user and current_user.is_banned %}
|
|
<span class="forum-btn-muted">{{ l('账号封禁中', 'Account banned') }}</span>
|
|
{% else %}
|
|
<a href="{{ url_for('user_login', next='/forum/post/new') }}" class="forum-btn-primary">{{ l('登录后发帖', 'Login to post') }}</a>
|
|
{% endif %}
|
|
</div>
|
|
</section>
|
|
{% if message %}
|
|
<p class="form-success">{{ message }}</p>
|
|
{% endif %}
|
|
{% if error %}
|
|
<p class="form-error">{{ error }}</p>
|
|
{% endif %}
|
|
|
|
<section class="forum-tools">
|
|
<form method="get" action="{{ url_for('forum_index') }}" class="forum-search-form">
|
|
<input type="hidden" name="tab" value="{{ active_tab }}">
|
|
<input type="hidden" name="per_page" value="{{ per_page }}">
|
|
{% if selected_category %}
|
|
<input type="hidden" name="category" value="{{ selected_category }}">
|
|
{% endif %}
|
|
<label for="forum-search-q" class="visually-hidden">{{ l('搜索帖子', 'Search topics') }}</label>
|
|
<input id="forum-search-q" type="text" name="q" value="{{ search_query or '' }}" placeholder="{{ l('搜索标题、正文、作者', 'Search title, content, author') }}" maxlength="80">
|
|
<button type="submit" class="forum-btn-primary">{{ l('搜索', 'Search') }}</button>
|
|
{% if search_query %}
|
|
<a href="{{ clear_search_url }}" class="forum-btn-muted">{{ l('清空搜索', 'Clear Search') }}</a>
|
|
{% endif %}
|
|
{% if has_filters %}
|
|
<a href="{{ clear_all_url }}" class="forum-btn-muted">{{ l('重置全部', 'Reset All') }}</a>
|
|
{% endif %}
|
|
</form>
|
|
<nav class="category-bar" aria-label="{{ l('论坛分类', 'Forum categories') }}">
|
|
{% for item in category_links %}
|
|
<a href="{{ item.url }}" class="category-chip {{ 'active' if item.active else '' }}">
|
|
<span>{{ item.name }}</span>
|
|
{% if item.count is not none %}
|
|
<strong>{{ item.count }}</strong>
|
|
{% endif %}
|
|
</a>
|
|
{% endfor %}
|
|
</nav>
|
|
</section>
|
|
|
|
<section class="forum-layout" aria-labelledby="forum-topic-list-title">
|
|
<div class="topic-stream">
|
|
<h2 id="forum-topic-list-title" class="visually-hidden">{{ l('论坛主题列表', 'Forum topic list') }}</h2>
|
|
<div class="topic-head">
|
|
<div class="topic-col-main">{{ l('主题', 'Topic') }}</div>
|
|
<div class="topic-col-mini">{{ l('回复', 'Replies') }}</div>
|
|
<div class="topic-col-mini">{{ l('浏览', 'Views') }}</div>
|
|
<div class="topic-col-mini">{{ l('活动', 'Activity') }}</div>
|
|
</div>
|
|
|
|
{% if cards %}
|
|
<ul class="topic-list topic-list-chronicle">
|
|
{% for item in cards %}
|
|
{% set post = item.post %}
|
|
{% set cover_tone = (loop.index0 % 4) + 1 %}
|
|
<li class="topic-row topic-row-chronicle" data-tone="{{ cover_tone }}">
|
|
<div class="topic-main">
|
|
<div class="topic-visual tone-{{ cover_tone }}" aria-hidden="true">
|
|
<span>{{ item.author_initial }}</span>
|
|
</div>
|
|
<div class="topic-content">
|
|
<div class="topic-cover tone-{{ cover_tone }}" aria-hidden="true">
|
|
<span class="topic-cover-kicker">{{ l('讨论精选', 'Featured Thread') }}</span>
|
|
<span class="topic-cover-chip">{{ post.category or l('综合讨论', 'General') }}</span>
|
|
<span class="topic-cover-time">{{ item.latest_activity_text }}</span>
|
|
</div>
|
|
<a href="{{ url_for('forum_post_detail', post_id=post.id) }}" rel="bookmark" class="topic-title">
|
|
{% if post.is_pinned %}<span class="topic-flag flag-pinned">{{ l('置顶', 'Pinned') }}</span>{% endif %}
|
|
{% if post.is_featured %}<span class="topic-flag flag-featured">{{ l('精华', 'Featured') }}</span>{% endif %}
|
|
{% if post.is_locked %}<span class="topic-flag flag-locked">{{ l('锁帖', 'Locked') }}</span>{% endif %}
|
|
{{ post.title }}
|
|
</a>
|
|
<div class="topic-meta">
|
|
<span class="topic-category">{{ post.category or l('综合讨论', 'General') }}</span>
|
|
<span>{{ item.author_name }}</span>
|
|
{% if post.created_at %}
|
|
<time datetime="{{ post.created_at.strftime('%Y-%m-%dT%H:%M:%SZ') }}">{{ post.created_at.strftime('%Y-%m-%d %H:%M') }}</time>
|
|
{% endif %}
|
|
<span>{{ l('点赞', 'Likes') }} {{ item.like_count }}</span>
|
|
<span>{{ l('收藏', 'Bookmarks') }} {{ item.bookmark_count }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="topic-stat" data-label="{{ l('回复', 'Replies') }}"><strong>{{ item.reply_count }}</strong></div>
|
|
<div class="topic-stat" data-label="{{ l('浏览', 'Views') }}"><strong>{{ item.view_count }}</strong></div>
|
|
<div class="topic-stat topic-activity" data-label="{{ l('活动', 'Activity') }}" title="{{ item.latest_activity.strftime('%Y-%m-%d %H:%M') if item.latest_activity else '' }}"><strong>{{ item.latest_activity_text }}</strong></div>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
{% else %}
|
|
<div class="topic-empty">{{ empty_hint }}</div>
|
|
{% endif %}
|
|
{% if total_posts %}
|
|
<div class="topic-footer">
|
|
<div class="topic-result">
|
|
{% if lang == 'en' %}
|
|
Page {{ current_page }} / {{ total_pages }} · Showing {{ result_start }} - {{ result_end }} of {{ total_posts }}
|
|
{% else %}
|
|
第 {{ current_page }} / {{ total_pages }} 页 · 显示 {{ result_start }} - {{ result_end }} / 共 {{ total_posts }} 条
|
|
{% endif %}
|
|
</div>
|
|
<div class="topic-footer-controls">
|
|
{% if total_pages > 1 %}
|
|
<nav class="forum-pagination forum-pagination-inline" aria-label="{{ l('帖子分页', 'Post pagination') }}">
|
|
{% if has_prev %}
|
|
<a href="{{ prev_page_url }}" class="page-link">{{ l('上一页', 'Prev') }}</a>
|
|
{% else %}
|
|
<span class="page-link disabled">{{ l('上一页', 'Prev') }}</span>
|
|
{% endif %}
|
|
{% for item in page_links %}
|
|
<a href="{{ item.url }}" class="page-link {{ 'active' if item.active else '' }}">{{ item.num }}</a>
|
|
{% endfor %}
|
|
{% if has_next %}
|
|
<a href="{{ next_page_url }}" class="page-link">{{ l('下一页', 'Next') }}</a>
|
|
{% else %}
|
|
<span class="page-link disabled">{{ l('下一页', 'Next') }}</span>
|
|
{% endif %}
|
|
</nav>
|
|
{% endif %}
|
|
<form method="get" action="{{ url_for('forum_index') }}" class="page-size-form">
|
|
<input type="hidden" name="tab" value="{{ active_tab }}">
|
|
{% if selected_category %}
|
|
<input type="hidden" name="category" value="{{ selected_category }}">
|
|
{% endif %}
|
|
{% if search_query %}
|
|
<input type="hidden" name="q" value="{{ search_query }}">
|
|
{% endif %}
|
|
<label for="per-page-select">{{ l('每页', 'Per page') }}</label>
|
|
<select id="per-page-select" name="per_page" onchange="this.form.submit()">
|
|
{% for size in per_page_options %}
|
|
<option value="{{ size }}" {{ 'selected' if size == per_page else '' }}>{{ size }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<span>{{ l('条', 'items') }}</span>
|
|
<noscript><button type="submit" class="forum-btn-muted">{{ l('应用', 'Apply') }}</button></noscript>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<aside class="forum-sidebar">
|
|
<div class="side-card side-profile-card">
|
|
<div class="side-profile-head">
|
|
<div class="side-avatar">
|
|
{% if current_user and current_user.username %}
|
|
{{ current_user.username[0]|upper }}
|
|
{% else %}
|
|
V
|
|
{% endif %}
|
|
</div>
|
|
<div class="side-profile-meta">
|
|
<strong>
|
|
{% if current_user and current_user.username %}
|
|
{{ current_user.username }}
|
|
{% else %}
|
|
{{ l('访客', 'Guest') }}
|
|
{% endif %}
|
|
</strong>
|
|
<span>
|
|
{% if current_user and not current_user.is_banned %}
|
|
{{ l('欢迎回来,继续你的 VPS 讨论。', 'Welcome back. Continue your VPS discussions.') }}
|
|
{% elif current_user and current_user.is_banned %}
|
|
{{ l('账号封禁中,仅可阅读内容。', 'Account banned. Read-only mode.') }}
|
|
{% else %}
|
|
{{ l('登录后可发布主题、评论与收藏。', 'Login to post topics, comment, and bookmark.') }}
|
|
{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="form-actions">
|
|
{% if current_user and not current_user.is_banned %}
|
|
<a href="{{ url_for('forum_post_new') }}" class="forum-btn-primary">{{ l('发布主题', 'New Topic') }}</a>
|
|
<a href="{{ url_for('user_profile') }}" class="forum-btn-muted">{{ l('个人中心', 'Profile') }}</a>
|
|
{% elif current_user and current_user.is_banned %}
|
|
<a href="{{ url_for('user_profile') }}" class="forum-btn-muted">{{ l('查看封禁说明', 'View Account Status') }}</a>
|
|
{% else %}
|
|
<a href="{{ url_for('user_login', next='/forum') }}" class="forum-btn-primary">{{ l('登录社区', 'Login to Forum') }}</a>
|
|
<a href="{{ url_for('user_register', next='/forum') }}" class="forum-btn-muted">{{ l('立即注册', 'Create Account') }}</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="side-card side-notice-card">
|
|
<h3>{{ l('社区公告', 'Community Notes') }}</h3>
|
|
<ul class="side-notice-list">
|
|
<li>{{ l('优先阅读“精华”主题,减少试错成本。', 'Prioritize featured topics to reduce trial-and-error.') }}</li>
|
|
<li>{{ l('发帖建议写明预算、地区和业务类型。', 'Include budget, region, and workload when posting.') }}</li>
|
|
<li>{{ l('涉及采购请最终以厂商官方条款为准。', 'For purchasing decisions, always verify official provider terms.') }}</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="side-card">
|
|
<h3>{{ l('分类标签云', 'Category Tags') }}</h3>
|
|
{% if sb.category_counts %}
|
|
<div class="side-tag-cloud">
|
|
{% for name, count in sb.category_counts %}
|
|
<a href="{{ url_for('forum_index', category=name) }}" class="side-tag">{{ name }}<strong>{{ count }}</strong></a>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<p class="side-empty">{{ l('暂无分类数据', 'No category data') }}</p>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="side-card">
|
|
<h3>{{ l('社区统计', 'Community Stats') }}</h3>
|
|
<div class="side-stats">
|
|
<div><span>{{ l('用户', 'Users') }}</span><strong>{{ sb.total_users }}</strong></div>
|
|
<div><span>{{ l('帖子', 'Posts') }}</span><strong>{{ sb.total_posts }}</strong></div>
|
|
<div><span>{{ l('评论', 'Comments') }}</span><strong>{{ sb.total_comments }}</strong></div>
|
|
</div>
|
|
</div>
|
|
<div class="side-card">
|
|
<h3>{{ l('活跃作者', 'Active Authors') }}</h3>
|
|
{% if sb.active_users %}
|
|
<ul class="side-list">
|
|
{% for username, post_count in sb.active_users %}
|
|
<li><span>{{ username }}</span><strong>{{ post_count }}</strong></li>
|
|
{% endfor %}
|
|
</ul>
|
|
{% else %}
|
|
<p class="side-empty">{{ l('暂无活跃作者', 'No active authors') }}</p>
|
|
{% endif %}
|
|
</div>
|
|
</aside>
|
|
</section>
|
|
</main>
|
|
</body>
|
|
</html>
|