-
Notifications
You must be signed in to change notification settings - Fork 1
Implementing blog #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
I think we should not includes built articles in GIT (they should be only useful for the build) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a comprehensive blog functionality for the NodeSecure landing page, adding a markdown-to-HTML article processing system with a complete blog interface.
- Blog article processing from markdown files with YAML frontmatter parsing
- HTML generation for both individual articles and blog index page with author information
- Complete blog styling and UI components including article cards and navigation
Reviewed Changes
Copilot reviewed 34 out of 35 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
vite.config.js | Adds blog entry discovery and multi-page build configuration |
src/build-articles.js | Implements markdown processing, HTML generation, and author integration |
public/css/blog.css | Provides complete blog styling including article cards and content formatting |
public/css/index.css | Adds blog-specific header styles and navigation elements |
public/css/reset.css | Adds cursor pointer style for anchor elements |
package.json | Adds markdown processing dependencies and build script integration |
index.html | Updates paths and adds blog navigation link |
blog/*.html | Generated blog pages including index and individual articles |
articles/*.md | Blog article source files with frontmatter metadata |
Comments suppressed due to low confidence (2)
src/build-articles.js:1
- Missing space in CSS selector: '>h3' should be '> h3' for consistency with other selectors.
// Import Node.js Dependencies
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
…authors with author gihub link
f65f146
to
ecaf383
Compare
|
||
|
||
|
||
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To much new line here at the end of the file
<script type="module" src="../src/particules.js"></script> | ||
</body> | ||
|
||
</html> No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing new line at the end of the file (there is emoji stop if you reviews files you will see it).
return ` | ||
<div class="article-card"> | ||
<div class="article-card-content"> | ||
<div class="article-card-header"> | ||
<a target="_blank" rel="noopener" href="https://github.com/${coreContributor.github}"> | ||
<img class="authorImg" src="${imgSource}" alt="Thomas"> | ||
</a> | ||
<div class="article-card-header-infos"> | ||
<span>${coreContributor?.name || article.author}</span> | ||
<span style="display: flex; align-items: center; gap: 10px;"> | ||
<span style="display: flex; align-items: center; gap: 5px;"> | ||
<img | ||
src="https://img.icons8.com/material-rounded/24/calendar--v1.png" | ||
alt="calendar" | ||
style="width:18px;height:18px;filter:invert(1) brightness(2);" | ||
/> | ||
<span>${formatDate(article.date)}</span> | ||
</span> | ||
<span style="display: flex; align-items: center; gap: 5px;"> | ||
<img | ||
src="https://img.icons8.com/forma-regular/24/clock.png" | ||
alt="clock" | ||
style="width:18px;height:18px;filter:invert(1) brightness(2);" | ||
/> | ||
<span>${article.readTime} min read</span> | ||
</span> | ||
</span> | ||
</div> | ||
</div> | ||
<a | ||
href="${article.path}" | ||
title="${article.title}" | ||
class="article-link"> | ||
<span>${article.title}</span> | ||
</a> | ||
<p>${article.description}</p> | ||
</div> | ||
</div> | ||
`; | ||
}) | ||
.join("\n "); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can probably be a template and you can use zup to inject things into it
const response = await fetch( | ||
"https://raw.githubusercontent.com/NodeSecure/Governance/main/contributors.json" | ||
); | ||
|
||
if (!response.ok) { | ||
throw new Error( | ||
`Error while fetching contributors list: ${response.status}` | ||
); | ||
} | ||
|
||
const contributors = await response.json(); | ||
const authors = contributors.core; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if you really need that here. With github you can do that:
https://github.com/${username}.png
function formatDate(date) { | ||
if (!(date instanceof Date)) { | ||
return date; | ||
} | ||
|
||
const day = date.getDate(); | ||
const month = date.toLocaleString("en-US", { month: "short" }); | ||
const year = date.getFullYear(); | ||
|
||
return `${month} ${day}, ${year}`; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can probably use Intl.DateTimeFormat to achieve the same result: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat
function parseYamlFile(content) { | ||
if (!content.startsWith("---")) { | ||
return { metadata: {}, content }; | ||
} | ||
|
||
const lines = content.split("\n"); | ||
let endLineIndex = -1; | ||
|
||
for (let i = 1; i < lines.length; i++) { | ||
if (lines[i].trim() === "---") { | ||
endLineIndex = i; | ||
break; | ||
} | ||
} | ||
|
||
if (endLineIndex === -1) { | ||
return { metadata: {}, content }; | ||
} | ||
|
||
// extract frontmatter | ||
const frontmatterLines = lines.slice(1, endLineIndex); | ||
const markdownLines = lines.slice(endLineIndex + 1); | ||
|
||
const markdownContent = markdownLines.join("\n").trim(); | ||
|
||
const metadata = {}; | ||
|
||
for (const line of frontmatterLines) { | ||
const trimmedLine = line.trim(); | ||
if (trimmedLine && trimmedLine.includes(":")) { | ||
const [key, ...valueParts] = trimmedLine.split(":"); | ||
|
||
const dataKey = key.trim(); | ||
const dataValue = valueParts.join(":").trim(); | ||
|
||
if (dataKey === "date") { | ||
const [day, month, year] = dataValue.split("/").map(Number); | ||
const date = new Date(year, month - 1, day); | ||
metadata[dataKey] = date; | ||
} | ||
else { | ||
metadata[dataKey] = dataValue; | ||
} | ||
} | ||
} | ||
|
||
return { metadata, content: markdownContent }; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should use showdown instead of marked, there is a built-in getMetadata() method. Feel weird to implement it by ourself.
linked to #4