The "Add Post" Helper
Relevant source files
The following files were used as context for generating this wiki page:The "Add Post" helper is a local utility designed for manually adding news items to the feed. While the primary function of the nodejs-news-feeder is to automatically collect news from GitHub releases, issues, and discussions, this helper provides a way for curators to inject custom or external news items. It consists of a simple web interface, a lightweight Express.js backend server, and a JSON file for persistence.
To run this helper, use the start script defined in the project's package.json.
npm run start
This command executes node server.js, making the tool available at http://localhost:3000.
Sources: package.json:11, server.js:55-57
Architecture
The "Add Post" helper follows a simple client-server architecture. The frontend is a single HTML file (add-post.html) that communicates with a backend Express.js server (server.js). The server handles API requests to read from and write to a manual-posts.json file, which acts as the data store. The data from manual-posts.json is then consumed by a separate script (scripts/collect-manual-posts.js) to integrate it into the main RSS feed.
Sources: add-post.html, server.js, scripts/collect-manual-posts.js
The following diagram illustrates the high-level architecture of the manual post feature.
Frontend Interface
The user interface is a single static page, add-post.html, served by the Express server. It provides a form to submit new posts and a list to display currently stored manual posts.
Sources: server.js:14-16, add-post.html:1-81
Form Fields
The form (#add-post-form) contains the necessary fields to create a new news item.
| Field ID | Label | Type | Required | Description |
|---|---|---|---|---|
title | Title | text | Yes | The title of the news post. |
description | Description | textarea | Yes | The main content of the post. |
link | Link | text | Yes | A URL associated with the news item. |
published_at | Publication Date | datetime-local | No | The date and time of publication. If omitted, the server uses the current time. |
Sources: add-post.html:20-35, server.js:46-47
Client-Side Logic
The page includes JavaScript to handle user interactions.
getPosts(): On page load, this asynchronous function sends aGETrequest to/api/poststo fetch all existing manual posts. It then dynamically renders them in the#posts-listdiv.- Form Submission: An event listener on the form's
submitevent prevents the default browser action. It captures the form data, converts it to a JSON object, and sends it via aPOSTrequest to/api/posts. If the request is successful (HTTP 201), the form is reset and thegetPosts()function is called again to refresh the list.
Sources: add-post.html:45-79
The sequence diagram below shows the interaction flow when a user adds a new post.
Sources: add-post.html:45-79, server.js:31-53
Backend API
The backend is an Express server defined in server.js. It serves the static add-post.html and provides two API endpoints to manage manual posts.
Sources: server.js:5-59
API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/posts | Reads the manual-posts.json file. If the file exists, it returns its content as a JSON array. If the file does not exist (ENOENT error), it returns an empty array []. |
POST | /api/posts | Receives a new post object. It reads the existing posts from manual-posts.json, appends the new post with a generated id (from Date.now()) and an ISO-formatted published_at date, and writes the updated array back to the file. |
Sources: server.js:18-53
Data Handling
When a new post is submitted via POST /api/posts, the server processes the data as follows:
- It reads the existing posts from
manual-posts.json. If the file doesn't exist, it starts with an empty array. - It creates a
newPostobject from the request body. - It adds a unique
idusingDate.now(). - It ensures
published_atis a valid ISO 8601 string. If the user provided a date, it's converted; otherwise, the current date and time are used. - The
newPostis pushed into thepostsarray. - The entire array is written back to
manual-posts.jsonwith an indentation of 2 spaces for readability.
Sources: server.js:32-51
Data Storage and Integration
The manual posts are stored in manual-posts.json and are later integrated into the main feed.xml.
Data Structure (manual-posts.json)
The manual-posts.json file contains a JSON array of post objects. Each object has the following structure, as created by server.js.
| Field | Type | Description |
|---|---|---|
title | string | The title of the post. |
description | string | The content of the post. |
link | string | The URL for the post. |
published_at | string | The publication date in ISO 8601 format (e.g., YYYY-MM-DDTHH:mm:ss.sssZ). |
id | number | A unique identifier generated from Date.now(). |
Sources: server.js:44-48
Feed Integration
The scripts/collect-manual-posts.js script is responsible for integrating the manual posts into the main RSS feed.
The following flowchart shows the process:
Key steps in this script:
- Get Posts: It reads and parses
manual-posts.json. If the file doesn't exist, it returns an empty array. - Transform Posts: It maps over the array of posts, transforming each one into an RSS
<item>XML string using helper functions fromutils/index.js:composeFeedItem: Creates the<item>structure.md2html: Converts the post'sdescriptionfrom Markdown to HTML and wraps it in<![CDATA[...]]>.buildRFC822Date: Formats thepublished_atdate string into the RFC 822 format required for RSS feeds.
- Inject into Feed: If any relevant posts were found, the script reads the existing
feed.xml, splits it using abreakDelimiter(defined as</image>inconfig.json), injects the new XML items, and overwritesfeed.xmlwith the updated content.
Sources: scripts/collect-manual-posts.js:9-29, utils/index.js:14, 131, 173, config.json:11
Conclusion
The "Add Post" helper is a straightforward yet crucial feature for the nodejs-news-feeder project. It provides a simple web-based interface for curators to manually add news items that fall outside the scope of automated collection. By leveraging a simple Express server and a JSON file for storage, it effectively decouples manual content creation from the main feed generation logic, which later consumes this data to enrich the final RSS feed.