feat: initial release of pengzhan.dev personal editorial blog platform
- Editorial web platform built with Node.js, Express, EJS, and Vanilla CSS - Markdown content engine with YAML frontmatter, bilingual variants, and hot-reload watcher - Unified SQLite with FTS5 search indexing, query logging, and schema filters - Centered editorial post layout with margin-docked left TOC and mobile bottom sheet - WordPress-grade comment system with moderation dashboard and bulk operations under /guanli - Complete SEO suite (JSON-LD structured data, RSS/Atom feeds, XML sitemap, robots.txt) - CI/CD workflows for linting, security audits (Gitleaks), automated tests, and Docker releases
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
// Content directory: prioritize ENV var, then /app/content (in K8s), fallback to ./sample-content
|
||||
function resolveContentDir() {
|
||||
if (process.env.CONTENT_DIR && fs.existsSync(process.env.CONTENT_DIR)) {
|
||||
return path.resolve(process.env.CONTENT_DIR);
|
||||
}
|
||||
if (fs.existsSync('/app/content')) {
|
||||
return '/app/content';
|
||||
}
|
||||
return path.resolve(__dirname, '../sample-content');
|
||||
}
|
||||
|
||||
const CONTENT_DIR = resolveContentDir();
|
||||
|
||||
function loadSiteConfig() {
|
||||
const configPath = path.join(CONTENT_DIR, 'config.yaml');
|
||||
const defaults = {
|
||||
site: {
|
||||
title: "Pengzhan",
|
||||
tagline: "Was childish, Now foolish",
|
||||
url: "https://pengzhan.dev",
|
||||
author: {
|
||||
name: "Pengzhan Hao",
|
||||
subtitle: "Software engineer on Cloud",
|
||||
gravatar: ""
|
||||
}
|
||||
},
|
||||
navigation: [
|
||||
{ label: "Home", path: "/" },
|
||||
{ label: "Blogs", path: "/blogs" },
|
||||
{ label: "Search", path: "/search" },
|
||||
{ label: "Quick Links", path: "/quick-links" }
|
||||
],
|
||||
social: [
|
||||
{ platform: "github", url: "https://github.com/CoderSherlock" },
|
||||
{ platform: "instagram", url: "https://www.instagram.com/pengzhan.hao/" },
|
||||
{ platform: "linkedin", url: "https://www.linkedin.com/in/pengzhanhao/" },
|
||||
{ platform: "email", address: "[email protected]" }
|
||||
],
|
||||
search: {
|
||||
recommended: []
|
||||
},
|
||||
plugins: {}
|
||||
};
|
||||
|
||||
if (fs.existsSync(configPath)) {
|
||||
try {
|
||||
const fileContent = fs.readFileSync(configPath, 'utf8');
|
||||
const parsed = yaml.load(fileContent);
|
||||
return { ...defaults, ...parsed };
|
||||
} catch (err) {
|
||||
console.error(`[Config] Error loading ${configPath}:`, err);
|
||||
}
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
CONTENT_DIR,
|
||||
loadSiteConfig
|
||||
};
|
||||
Reference in New Issue
Block a user