const fs = require('fs');
const path = require('path');
const { handlebars } = require('../template/engine');
const { getSubmenuForNavItem } = require('../config');
const { escapeHtml } = require('../utils/html');
const { createLogger, isVerbose } = require('../utils/logger');
const log = createLogger('render');
// 生成导航菜单
function generateNavigation(navigation, config) {
return navigation
.map((nav) => {
// 根据页面ID获取对应的子菜单项(分类)
let submenuItems = '';
// 使用辅助函数获取子菜单数据
const submenu = getSubmenuForNavItem(nav, config);
// 如果存在子菜单,生成HTML
if (submenu && Array.isArray(submenu)) {
submenuItems = `
`;
}
return `
`;
})
.join('\n');
}
// 生成网站卡片HTML
function generateSiteCards(sites) {
if (!sites || !Array.isArray(sites) || sites.length === 0) {
return `暂无网站
`;
}
return sites
.map(
(site) => `
${escapeHtml(site.name || '未命名站点')}
${escapeHtml(site.description || '')}
`
)
.join('\n');
}
// 生成分类板块
function generateCategories(categories) {
if (!categories || !Array.isArray(categories) || categories.length === 0) {
return `
`;
}
return categories
.map(
(category) => `
${escapeHtml(category.name)}
${generateSiteCards(category.sites)}
`
)
.join('\n');
}
// 生成社交链接HTML
function generateSocialLinks(social) {
if (!social || !Array.isArray(social) || social.length === 0) {
return '';
}
// 尝试使用 Handlebars 模板
try {
const socialLinksPath = path.join(process.cwd(), 'templates', 'components', 'social-links.hbs');
if (fs.existsSync(socialLinksPath)) {
const templateContent = fs.readFileSync(socialLinksPath, 'utf8');
const template = handlebars.compile(templateContent);
// 确保数据格式正确
return template(social); // 社交链接模板直接接收数组
}
} catch (error) {
log.warn('渲染 social-links 模板失败,已回退到内置渲染', {
message: error && error.message ? error.message : String(error),
});
if (isVerbose() && error && error.stack) console.error(error.stack);
// 出错时回退到原始生成方法
}
// 回退到原始生成方法
return social
.map(
(link) => `
${escapeHtml(link.name || '社交链接')}
`
)
.join('\n');
}
// 生成页面内容(包括首页和其他页面)
function generatePageContent(pageId, data) {
// 确保数据对象存在
if (!data) {
log.warn('页面数据缺失,已回退为占位页面', { page: pageId });
return `
`;
}
// 首页使用 profile 数据,其他页面使用自身数据
if (pageId === 'home') {
const profile = data.profile || {};
return `
${escapeHtml(profile.title || '欢迎使用')}
${escapeHtml(profile.subtitle || '个人导航站')}
${generateCategories(data.categories)}`;
} else {
// 其他页面使用通用结构
const title = data.title || `${pageId} 页面`;
const subtitle = data.subtitle || '';
const categories = data.categories || [];
return `
${escapeHtml(title)}
${escapeHtml(subtitle)}
${generateCategories(categories)}`;
}
}
// 生成搜索结果页面
function generateSearchResultsPage(config) {
// 获取所有导航页面ID
const pageIds = config.navigation.map((nav) => nav.id);
// 生成所有页面的搜索结果区域
const sections = pageIds
.map((pageId) => {
// 根据页面ID获取对应的图标和名称
const navItem = config.navigation.find((nav) => nav.id === pageId);
const icon = navItem ? navItem.icon : 'fas fa-file';
const name = navItem ? navItem.name : pageId;
return `
`;
})
.join('\n');
return `
`;
}
module.exports = {
generateNavigation,
generateSiteCards,
generateCategories,
generateSocialLinks,
generatePageContent,
generateSearchResultsPage,
};