Skip to content

Commit

Permalink
拆分菜单为独立功能
Browse files Browse the repository at this point in the history
  • Loading branch information
qianmoQ committed Feb 9, 2025
1 parent 6ca8f70 commit 0d30275
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 108 deletions.
15 changes: 5 additions & 10 deletions lib/file-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const {
getPagePath,
appendHtml,
getRelativeBasePath,
transformNavigation,
isFeatureEnabled
} = require("./utils");
const TemplateEngine = require("./template-engine");
Expand All @@ -19,31 +18,27 @@ const SearchIndexBuilder = require('./indexer-generator');
const HtmlMinifier = require('./html-minifier');
const GitInfoProvider = require('./git-info-provider');
const I18nProcessor = require('./i18n-processor');
const NavigationProcessor = require('./navigation-processor');

class FileProcessor {
constructor(config, pages, sourcePath, outputPath) {
this.config = config;
this.pages = pages;
this.sourcePath = sourcePath;
this.outputPath = outputPath;
this.navigationCache = new Map();

this.templateEngine = new TemplateEngine(config.templatePath);

if (config.feature?.compress?.enable) {
this.htmlMinifier = new HtmlMinifier(config);
}
this.templateEngine = new TemplateEngine(config.templatePath);
this.gitInfoProvider = new GitInfoProvider(config);
this.i18nProcessor = new I18nProcessor(config, pages);
this.navigationProcessor = new NavigationProcessor(config, pages);
}

// 获取缓存的导航数据
getCachedNavigation(locale) {
if (!this.navigationCache.has(locale)) {
const navData = transformNavigation(this.config.nav, this.pages, this.config, locale);
this.navigationCache.set(locale, navData);
}
return this.navigationCache.get(locale);
return this.navigationProcessor.getCachedNavigation(locale);
}

// 构建站点地图数据
Expand Down Expand Up @@ -212,7 +207,7 @@ class FileProcessor {
};

// 应用国际化处理
pageData = this.i18nProcessor.buildI18nPageData(pageData, metadata, locale);
pageData = this.i18nProcessor.buildI18nPageData(pageData, metadata, locale, this.getCachedNavigation(locale));

// 渲染页面
let html = await this.templateEngine.renderWithLayout('layouts/page', pageData);
Expand Down
102 changes: 4 additions & 98 deletions lib/i18n-processor.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,115 +80,21 @@ class I18nProcessor {
return `${baseName.replace(/\.md$/, '')}.html`;
}

/**
* 附加 HTML 扩展名并处理语言路径
*/
appendHtml(pathStr, locale) {
if (typeof pathStr === 'string') {
if (this.isEnabled()) {
pathStr = pathStr.replace(`.${locale}`, '');
}

return pathStr.endsWith('.md')
? pathStr.replace('.md', '.html')
: pathStr.endsWith('.html')
? pathStr
: `${pathStr}.html`;
}

if (Array.isArray(pathStr)) {
return this.appendHtml(pathStr[0], locale);
}

if (typeof pathStr === 'object' && pathStr !== null) {
const firstKey = Object.keys(pathStr)[0];
return this.appendHtml(pathStr[firstKey], locale);
}

return pathStr;
}

/**
* 转换导航数据,处理国际化
*/
transformNavigation(navigation, locale) {
if (this.navigationCache.has(locale)) {
return this.navigationCache.get(locale);
}

const processItem = (item) => {
if (typeof item === 'string') {
const pageData = this.getLocalizedPage(item, locale);
if (pageData) {
const title = pageData.title
? this.getTranslation(pageData.title, locale)
: pageData.title;

return {
...pageData,
title,
href: this.appendHtml(item, locale)
};
}
return {
title: item.split('/').pop(),
href: this.appendHtml(item, locale)
};
}

if (typeof item === 'object') {
const [[title, items]] = Object.entries(item);
return {
title: this.getTranslation(title, locale),
href: this.appendHtml(items[0], locale),
items: Array.isArray(items) ? items.map(processItem) : []
};
}

return item;
};

const transformed = navigation.map(processItem);
this.navigationCache.set(locale, transformed);
return transformed;
}

/**
* 获取本地化的页面数据
*/
getLocalizedPage(pagePath, locale) {
const normalizedPath = pagePath.replace(/\.(md|html)$/, '');

if (this.isEnabled() && locale !== this.getDefaultLocale()) {
const localePath = `${normalizedPath}.${locale}`;
const localizedData = this.pages.get(localePath);
if (localizedData) {
return localizedData;
}
}

return this.pages.get(normalizedPath);
}

/**
* 构建国际化相关的页面数据
*/
buildI18nPageData(pageData, metadata, locale) {
// 处理标题翻译
buildI18nPageData(pageData, metadata, locale, navigation) {
const translatedTitle = metadata.title
? this.getTranslation(metadata.title, locale)
: metadata.title;

// 更新页面数据
pageData.pageData.title = translatedTitle;
pageData.pageData.language = locale;

// 添加语言列表
pageData.siteData.languages = this.getAvailableLocales();

// 处理导航数据
if (pageData.siteData.nav) {
pageData.siteData.nav = this.transformNavigation(pageData.siteData.nav, locale);
// 使用传入的导航数据
if (navigation) {
pageData.siteData.nav = navigation;
}

return pageData;
Expand Down
119 changes: 119 additions & 0 deletions lib/navigation-processor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
const I18nProcessor = require('./i18n-processor');
const {transformNavigation} = require("./utils");

class NavigationProcessor {
constructor(config, pages) {
this.config = config;
this.pages = pages;
this.navigationCache = new Map();
this.i18nProcessor = new I18nProcessor(config, pages);
}

/**
* 获取缓存的导航数据
*/
getCachedNavigation(locale) {
if (!this.navigationCache.has(locale)) {
const navData = this.transformNavigation(this.config.nav, locale);
this.navigationCache.set(locale, navData);
}
return this.navigationCache.get(locale);
}

/**
* 转换导航数据,处理国际化
*/
transformNavigation(navigation, locale) {
if (!navigation) {
return [];
}

const processItem = (item) => {
if (typeof item === 'string') {
const pageData = this.getLocalizedPage(item, locale);
if (pageData) {
const title = pageData.title
? this.i18nProcessor.getTranslation(pageData.title, locale)
: pageData.title;

return {
...pageData,
title,
href: this.appendHtml(item, locale)
};
}
return {
title: item.split('/').pop(),
href: this.appendHtml(item, locale)
};
}

if (typeof item === 'object') {
const [[title, items]] = Object.entries(item);
return {
title: this.i18nProcessor.getTranslation(title, locale),
href: this.appendHtml(items[0], locale),
items: Array.isArray(items) ? items.map(processItem) : []
};
}

return item;
};

return navigation.map(processItem);
}

/**
* 获取本地化的页面数据
*/
getLocalizedPage(pagePath, locale) {
const normalizedPath = pagePath.replace(/\.(md|html)$/, '');

if (this.i18nProcessor.isEnabled() && locale !== this.i18nProcessor.getDefaultLocale()) {
const localePath = `${normalizedPath}.${locale}`;
const localizedData = this.pages.get(localePath);
if (localizedData) {
return localizedData;
}
}

return this.pages.get(normalizedPath);
}

/**
* 附加 HTML 扩展名并处理语言路径
*/
appendHtml(pathStr, locale) {
if (typeof pathStr === 'string') {
if (this.i18nProcessor.isEnabled()) {
pathStr = pathStr.replace(`.${locale}`, '');
}

return pathStr.endsWith('.md')
? pathStr.replace('.md', '.html')
: pathStr.endsWith('.html')
? pathStr
: `${pathStr}.html`;
}

if (Array.isArray(pathStr)) {
return this.appendHtml(pathStr[0], locale);
}

if (typeof pathStr === 'object' && pathStr !== null) {
const firstKey = Object.keys(pathStr)[0];
return this.appendHtml(pathStr[firstKey], locale);
}

return pathStr;
}

/**
* 清除导航缓存
*/
clearCache() {
this.navigationCache.clear();
}
}

module.exports = NavigationProcessor;

0 comments on commit 0d30275

Please sign in to comment.