添加标签和完整元数据显示
列表页: - 显示标签(最多5个) - 显示作者、发布时间、平台、时长 - 显示源链接 - 显示类型(视频/文章) - 平台颜色徽章 文章页: - 新增元数据卡片 - 显示所有元数据信息 - 显示所有标签 - 源链接可点击跳转
This commit is contained in:
@@ -6,11 +6,9 @@ $user = getCurrentUser();
|
||||
$username = $user['username'];
|
||||
$docDir = getUserDocDir($username);
|
||||
|
||||
// 获取文件名
|
||||
$file = $_GET['file'] ?? '';
|
||||
$search = $_GET['q'] ?? '';
|
||||
|
||||
// 安全检查
|
||||
if (empty($file) || strpos($file, '..') !== false) {
|
||||
die('无效的文件名');
|
||||
}
|
||||
@@ -30,12 +28,15 @@ if (!file_exists($filePath)) {
|
||||
$content = file_get_contents($filePath);
|
||||
|
||||
// 解析元数据
|
||||
$title = basename($file);
|
||||
$meta = [
|
||||
'title' => $title,
|
||||
'title' => basename($file),
|
||||
'author' => '',
|
||||
'date' => '',
|
||||
'platform' => ''
|
||||
'platform' => '',
|
||||
'url' => '',
|
||||
'tags' => [],
|
||||
'duration' => '',
|
||||
'type' => 'article'
|
||||
];
|
||||
|
||||
// 提取并移除 YAML front matter
|
||||
@@ -43,10 +44,8 @@ if (preg_match('/^---\s*\n(.*?)\n---\s*\n(.*)$/s', $content, $matches)) {
|
||||
$yaml = $matches[1];
|
||||
$content = $matches[2];
|
||||
|
||||
// 解析元数据(用于页面标题)
|
||||
if (preg_match('/^title:\s*["\']?(.+?)["\']?\s*$/m', $yaml, $m)) {
|
||||
$title = trim($m[1], '"\'');
|
||||
$meta['title'] = $title;
|
||||
$meta['title'] = trim($m[1], '"\'');
|
||||
}
|
||||
if (preg_match('/^author:\s*(.+?)\s*$/m', $yaml, $m)) {
|
||||
$meta['author'] = trim($m[1]);
|
||||
@@ -57,43 +56,47 @@ if (preg_match('/^---\s*\n(.*?)\n---\s*\n(.*)$/s', $content, $matches)) {
|
||||
if (preg_match('/^platform:\s*(.+?)\s*$/m', $yaml, $m)) {
|
||||
$meta['platform'] = trim($m[1]);
|
||||
}
|
||||
if (preg_match('/^url:\s*(.+?)\s*$/m', $yaml, $m)) {
|
||||
$meta['url'] = trim($m[1]);
|
||||
}
|
||||
if (preg_match('/^duration:\s*(.+?)\s*$/m', $yaml, $m)) {
|
||||
$meta['duration'] = trim($m[1]);
|
||||
$meta['type'] = 'video';
|
||||
}
|
||||
if (preg_match('/^tags:\s*\[(.+)\]\s*$/m', $yaml, $m)) {
|
||||
$tagsStr = $m[1];
|
||||
preg_match_all('/"([^"]+)"/', $tagsStr, $tagMatches);
|
||||
$meta['tags'] = $tagMatches[1] ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
// 简单的 Markdown 转换
|
||||
// Markdown 转换
|
||||
function markdownToHtml($text) {
|
||||
// 标题
|
||||
$text = preg_replace('/^#### (.*$)/m', '<h4>$1</h4>', $text);
|
||||
$text = preg_replace('/^### (.*$)/m', '<h3>$1</h3>', $text);
|
||||
$text = preg_replace('/^## (.*$)/m', '<h2>$1</h2>', $text);
|
||||
$text = preg_replace('/^# (.*$)/m', '<h1>$1</h1>', $text);
|
||||
|
||||
// 粗体和斜体
|
||||
$text = preg_replace('/\*\*(.+?)\*\*/', '<strong>$1</strong>', $text);
|
||||
$text = preg_replace('/\*(.+?)\*/', '<em>$1</em>', $text);
|
||||
|
||||
// 代码块
|
||||
$text = preg_replace('/```(\w*)\n(.*?)```/s', '<pre><code class="language-$1">$2</code></pre>', $text);
|
||||
$text = preg_replace('/`(.+?)`/', '<code>$1</code>', $text);
|
||||
|
||||
// 链接
|
||||
$text = preg_replace('/\[(.+?)\]\((.+?)\)/', '<a href="$2" target="_blank">$1</a>', $text);
|
||||
|
||||
// 列表
|
||||
$text = preg_replace('/^- (.*$)/m', '<li>$1</li>', $text);
|
||||
$text = preg_replace('/(<li>.*<\/li>\n?)+/', '<ul>$0</ul>', $text);
|
||||
|
||||
// 段落
|
||||
$text = preg_replace('/\n\n/', '</p><p>', $text);
|
||||
$text = '<p>' . $text . '</p>';
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
// 高亮搜索词
|
||||
function highlightSearch($text, $search) {
|
||||
if (empty($search)) return $text;
|
||||
return preg_replace('/(' . preg_quote($search, '/') . ')/i',
|
||||
'<mark>$1</mark>', $text);
|
||||
return preg_replace('/(' . preg_quote($search, '/') . ')/i', '<mark>$1</mark>', $text);
|
||||
}
|
||||
|
||||
$htmlContent = markdownToHtml(htmlspecialchars($content));
|
||||
@@ -102,13 +105,26 @@ if ($search) {
|
||||
}
|
||||
|
||||
$folder = dirname($file) !== '.' ? dirname($file) : '';
|
||||
|
||||
// 平台配置
|
||||
function getPlatformInfo($platform) {
|
||||
$platforms = [
|
||||
'bilibili' => ['name' => 'Bilibili', 'icon' => '📺', 'color' => '#fb7299'],
|
||||
'youtube' => ['name' => 'YouTube', 'icon' => '▶️', 'color' => '#ff0000'],
|
||||
'zhihu' => ['name' => '知乎', 'icon' => '💡', 'color' => '#0084ff'],
|
||||
'wechat' => ['name' => '微信', 'icon' => '💬', 'color' => '#07c160'],
|
||||
];
|
||||
return $platforms[$platform] ?? ['name' => $platform ?: '未知', 'icon' => '📄', 'color' => '#666'];
|
||||
}
|
||||
|
||||
$platformInfo = getPlatformInfo($meta['platform']);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?php echo htmlspecialchars($title); ?> - 知识库</title>
|
||||
<title><?php echo htmlspecialchars($meta['title']); ?> - 知识库</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
@@ -117,12 +133,68 @@ $folder = dirname($file) !== '.' ? dirname($file) : '';
|
||||
<a href="dashboard.php<?php echo $search ? '?q=' . urlencode($search) : ''; ?>" class="btn-back">
|
||||
← 返回列表
|
||||
</a>
|
||||
<h1><?php echo htmlspecialchars($title); ?></h1>
|
||||
<h1><?php echo htmlspecialchars($meta['title']); ?></h1>
|
||||
<?php if ($folder): ?>
|
||||
<div class="folder-info">📁 <?php echo htmlspecialchars($folder); ?></div>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<!-- 元数据卡片 -->
|
||||
<div class="meta-card">
|
||||
<div class="meta-row">
|
||||
<?php if ($meta['author']): ?>
|
||||
<div class="meta-field">
|
||||
<span class="meta-label">作者</span>
|
||||
<span class="meta-value">👤 <?php echo htmlspecialchars($meta['author']); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($meta['date']): ?>
|
||||
<div class="meta-field">
|
||||
<span class="meta-label">发布时间</span>
|
||||
<span class="meta-value">📅 <?php echo htmlspecialchars($meta['date']); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($meta['platform']): ?>
|
||||
<div class="meta-field">
|
||||
<span class="meta-label">平台</span>
|
||||
<span class="meta-value platform-badge" style="--platform-color: <?php echo $platformInfo['color']; ?>">
|
||||
<?php echo $platformInfo['icon']; ?> <?php echo $platformInfo['name']; ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($meta['duration']): ?>
|
||||
<div class="meta-field">
|
||||
<span class="meta-label">时长</span>
|
||||
<span class="meta-value">⏱️ <?php echo htmlspecialchars($meta['duration']); ?></span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="meta-field">
|
||||
<span class="meta-label">类型</span>
|
||||
<span class="meta-value"><?php echo $meta['type'] === 'video' ? '🎬 视频' : '📝 文章'; ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($meta['url']): ?>
|
||||
<div class="meta-source">
|
||||
<span class="meta-label">源链接</span>
|
||||
<a href="<?php echo htmlspecialchars($meta['url']); ?>" target="_blank" class="source-url">
|
||||
🔗 <?php echo htmlspecialchars($meta['url']); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($meta['tags'])): ?>
|
||||
<div class="meta-tags">
|
||||
<span class="meta-label">标签</span>
|
||||
<div class="tags-list">
|
||||
<?php foreach ($meta['tags'] as $tag): ?>
|
||||
<span class="tag"><?php echo htmlspecialchars($tag); ?></span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="document-content">
|
||||
<?php echo $htmlContent; ?>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user