Content Management
Relevant source files
The following files were used as context for generating this wiki page:
The portfolio project employs a dual-system approach for content management. The primary website is a static site built using the Hexo framework, where content is managed as Markdown files within the source directory. This system is ideal for blog posts, pages, and project descriptions.
Alongside the Hexo site, a dedicated, repository-based Newsletter Management System is used for creating, previewing, scheduling, and sending email newsletters. This system also uses Markdown files as its content source but is orchestrated through a custom Node.js program with its own CLI and GitHub Actions for automation. This provides a robust, version-controlled workflow for email content, separate from the main website's content.
Core Site Content (Hexo)
The main portfolio website is generated by Hexo. Content is written in Markdown and processed into static HTML files. The core configuration for this process is defined in _config.yml.
Sources: _config.yml, src/t.txt
Directory Configuration
The Hexo configuration file specifies the key directories for content management and generation.
| Configuration | Directory | Description |
|---|---|---|
source_dir | source | Contains all source files, including Markdown posts and pages. |
public_dir | ./dist | The output directory for the generated static site. |
tag_dir | tags | Directory for tag archive pages. |
archive_dir | archives | Directory for date-based archive pages. |
category_dir | categories | Directory for category archive pages. |
Sources: _config.yml:19-24
Build Process
The content generation is triggered by the hexo generate command. This command reads the files from the source_dir, processes them, and outputs the final HTML, CSS, and JS files into the public_dir (configured as dist).
The following diagram illustrates the basic Hexo build flow.
This diagram shows that Markdown source files are processed by Hexo, which uses theme templates to generate the final static HTML files.
The build log provides a real-world example of this process, showing .md files being transformed into .html files.
INFO Start processing
INFO Files loaded in 172 ms
...
INFO Generated: 2025/03/06/projet-RGPD/index.html
INFO Generated: 2025/03/06/projet-france-nuit/index.html
INFO 86 files generated in 147 ms
Sources: src/t.txt:5-6, 38-39
Newsletter Management System
A separate, more specialized system is used for managing newsletter content. This system is built around Markdown files with YAML frontmatter, a set of Node.js scripts for processing, and GitHub Actions for automation.
Sources: newsletters/README.md, newsletter-program/src/core/newsletter-composer.js
Newsletter File Format
Each newsletter is a single .md file located in the newsletters/ directory. These files use YAML frontmatter to define metadata and a {{variable}} syntax for templating.
Frontmatter Fields
The frontmatter contains essential metadata for the newsletter.
| Field | Type | Description |
|---|---|---|
subject | string | The email subject line. |
date | string | The display date for the newsletter. |
status | string | The current status: draft, scheduled, or sent. |
scheduled_at | string | ISO 8601 datetime for scheduled sending. |
website_url | string | Link to the main website. |
github_url | string | Link to the GitHub profile. |
preferences_url | string | Link for subscribers to manage preferences. |
unsubscribe_url | string | Link to unsubscribe from the newsletter. |
variables | object | A key-value map for custom template variables. |
Sources: newsletters/README.md:18-30
Example Template
The following is an example of a newsletter template, showing both frontmatter and Markdown content with template variables.
---
subject: Weekly Newsletter - {{date}}
date: {{current_date}}
status: draft
scheduled_at:
website_url: https://example.com
github_url: https://github.com/username
preferences_url: https://example.com/preferences
unsubscribe_url: https://example.com/unsubscribe
variables:
author: Newsletter Team
edition_number: 1
theme_color: "#3498db"
---
# Weekly Newsletter - Edition {{edition_number}}
Welcome to this week's newsletter! Here's what's been happening.
...
Sources: newsletters/newsletter-template.md:1-15
Newsletter Workflow
The system provides a complete workflow from creation to archival, managed via a CLI and automated by GitHub Actions.
This diagram shows the lifecycle of a newsletter.
Sources: newsletters/README.md:34-60
Content Processing and Composition
The newsletter-program contains the core logic for turning Markdown files and other content sources into final HTML emails.
NewsletterComposer
The NewsletterComposer class is responsible for parsing newsletter files, loading HTML templates, and composing the final email content.
This diagram illustrates the structure of the NewsletterComposer class.
The composition process involves several steps, as shown in the sequence diagram below.
This sequence shows how composeNewsletter reads a Markdown file, parses it, converts the Markdown to HTML, loads an HTML template, injects the content, and returns the final composed newsletter object.
Sources: newsletter-program/src/core/newsletter-composer.js:77-101
ContentProcessor
The ContentProcessor class provides utilities for handling various content types, sanitizing HTML, and rendering templates. It is notably used for converting RSS feed items into email content.
This diagram shows the flow for converting an RSS item to an email.
This process ensures that content from external sources like RSS feeds is safe and properly formatted before being included in a newsletter. The sanitizeContent method uses sanitize-html to allow a specific list of tags and attributes, preventing XSS attacks.
Sources: newsletter-program/src/core/content-processor.js:12-30, 42-60
Subscription Form Content Generation
The frontend newsletter subscription form dynamically generates the body of a GitHub issue. This issue body is structured with Markdown to be machine-readable by the backend GitHub Action.
// themes/matrix-flow/source/js/newsletter.js:401-424
generateIssueBody(formData) {
const topicsList = formData.topics.length > 0
? formData.topics.map(topic => `- [x] ${this.getTopicLabel(topic)}`).join('\\n')
: '- [ ] Aucun sujet spécifique sélectionné';
return `### Email Address
${formData.email}
### Newsletter Frequency
${formData.frequency}
### Topics of Interest
${topicsList}
### Email Format
${formData.format}
### Consent & Privacy
- [x] I consent to receiving newsletters at the provided email address
- [x] I understand that my email will be encrypted and stored securely
- [x] I understand I can unsubscribe at any time
### Additional Information (Optional)
Subscription automatique via le formulaire du site web.
Timestamp: ${formData.timestamp}`;
}
This function constructs a Markdown string that serves as a structured data payload, which is a key part of the content management workflow for new subscribers.
Sources: themes/matrix-flow/source/js/newsletter.js:401-424
Summary
Content in this project is managed through a developer-centric, file-based workflow. The Hexo static site generator handles the main portfolio content, converting Markdown files into a static website. For dynamic, scheduled content like newsletters, a custom-built Node.js application provides a powerful, version-controlled system that leverages Markdown, CLI tools, and GitHub Actions for a fully automated pipeline from composition to delivery and archival. This dual approach separates website content from email marketing content, allowing each to have a specialized and optimized workflow.