Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fixing Sort By Date functionality #34

Merged
merged 4 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .windsurfrules
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
This is a static website generator. You can learn more about static at https://static.devdojo.com.

Static is a static HTML website generator. It allows developers and designer the ability to easily create websites using only HTML.

Users can create layouts like this:

```html
<!DOCTYPE html>
<html lang="en">

<head>
<title>{title}</title>
</head>

<body>
{slot}
</body>

</html>
```

and easily use the layouts in any page by adding this:

```html
<layout src="layouts/main.html">
<h1>Static</h1>
</layout>
```

Users can also loop through content and much more.

This is a Node JS static website builder.
12 changes: 10 additions & 2 deletions bin/static
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,18 @@ if(cmd == 'new'){
var newCmd = require('../src/new.js');
if(arg2 != undefined){
template = arg2.replace('--template=', '');
newCmd.newProject(arg1, template);
newCmd.newProject(arg1, template)
.catch(err => {
console.error('Failed to create new project:', err);
process.exit(1);
});
return;
}
newCmd.newProject(arg1);
newCmd.newProject(arg1)
.catch(err => {
console.error('Failed to create new project:', err);
process.exit(1);
});
}

if(cmd == 'dev'){
Expand Down
66 changes: 53 additions & 13 deletions bin/static.test.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,80 @@
const execSync = require('child_process').execSync;

const packageJson = require('../package.json');
const fs = require('fs-extra');
const path = require('path');

function executeCommand(command) {
return execSync(command, { encoding: 'utf8' });
}

function cleanTestDirectory() {
if (fs.existsSync('testProject')) {
fs.removeSync('testProject');
}
}

// Helper function to wait for directory to be ready
function waitForDirectory(dir, maxAttempts = 30) {
let attempts = 0;
while (attempts < maxAttempts) {
if (fs.existsSync(dir)) {
return true;
}
execSync('sleep 1');
attempts++;
}
return false;
}

describe('bin/static CLI', () => {
jest.setTimeout(30000); // Set timeout to 30 seconds for all tests

beforeEach(() => {
process.env.NODE_ENV = 'test';
cleanTestDirectory();
});

afterEach(() => {
cleanTestDirectory();
});

it('should return version', () => {
const output = executeCommand('./bin/static --version');
expect(output.trim()).toBe(packageJson.version);
});

it('should create a new project', () => {
process.env.NODE_ENV = 'test';
const output = executeCommand('./bin/static new testProject');
const expectedOutput = [

// Wait for project directory to be ready
expect(waitForDirectory('testProject')).toBe(true);

expect(output.trim()).toBe([
"New setup initialized",
"Downloading starter template",
"Finished downloading template",
"Extracting template zip file",
"Finished unzipping",
"New site available inside testProject folder"
].join('\n');
expect(output.trim()).toBe(expectedOutput);
].join('\n'));
});

it('should build project', () => {
// First create the project
executeCommand('./bin/static new testProject');

// Wait for project to be ready
expect(waitForDirectory('testProject')).toBe(true);

// Ensure we're in a clean state
if (fs.existsSync(path.join('testProject', '_site'))) {
fs.removeSync(path.join('testProject', '_site'));
}

const output = executeCommand('cd testProject && ../bin/static build relative');
console.log('Output:', output);
console.log('Current Directory:', process.cwd());
console.log('Directory Contents:', executeCommand('ls -al'));

const expectedOutput = [
"Successfully built your new static website 🤘",
].join('\n');
expect(output.trim()).toBe(expectedOutput);
expect(output.trim()).toBe("Successfully built your new static website 🤘");

// Verify build output exists
expect(fs.existsSync(path.join('testProject', '_site'))).toBe(true);
});
});
50 changes: 32 additions & 18 deletions src/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const assets = require('./assets.js');
const url = 'relative';

module.exports = {
start(url='relative'){
start(url = 'relative') {

let staticJSON = {};

Expand All @@ -17,17 +17,17 @@ module.exports = {
}

if (staticJSON.hasOwnProperty('build')) {
if(typeof(staticJSON.build.url) != 'undefined'){
if (typeof(staticJSON.build.url) != 'undefined') {
url = staticJSON.build.url;
}
}

const pagesDir = path.join(currentDirectory, './pages');
const contentPagesDir = path.join(currentDirectory, './content');
let buildDir = path.join(currentDirectory, './_site');

if (staticJSON.hasOwnProperty('build')) {
if(typeof(staticJSON.build.directory) != 'undefined'){
if (typeof(staticJSON.build.directory) != 'undefined') {
buildDir = staticJSON.build.directory;
}
}
Expand All @@ -41,7 +41,9 @@ module.exports = {
assets.moveImages(buildDir);
assets.movePublicFolderContents(buildDir);

fs.mkdirSync(buildDir, { recursive: true });
fs.mkdirSync(buildDir, {
recursive: true
});
buildPages(pagesDir, buildDir, url);
buildContentPages(contentPagesDir, buildDir, url);

Expand All @@ -67,31 +69,39 @@ function removeDirectory(dirPath) {
}

function buildPages(pagesDir, buildDir, url) {
const entries = fs.readdirSync(pagesDir, { withFileTypes: true });
const entries = fs.readdirSync(pagesDir, {
withFileTypes: true
});
for (const entry of entries) {
const entryPath = path.join(pagesDir, entry.name);
if (entry.isDirectory()) {
const newBuildDir = path.join(buildDir, entry.name);
fs.mkdirSync(newBuildDir, { recursive: true });
fs.mkdirSync(newBuildDir, {
recursive: true
});
buildPages(entryPath, newBuildDir, url);
} else if (entry.isFile() && entry.name.endsWith('.html')) {
buildFile(entryPath, buildDir, url);
}
}
}

function buildContentPages(contentDir, buildDir, url){
function buildContentPages(contentDir, buildDir, url) {

if (!fs.existsSync(contentDir)) {
return;
}

const entries = fs.readdirSync(contentDir, { withFileTypes: true });

const entries = fs.readdirSync(contentDir, {
withFileTypes: true
});
for (const entry of entries) {
const entryPath = path.join(contentDir, entry.name);
if (entry.isDirectory()) {
const newBuildDir = path.join(buildDir, entry.name);
fs.mkdirSync(newBuildDir, { recursive: true });
fs.mkdirSync(newBuildDir, {
recursive: true
});
buildContentPages(entryPath, newBuildDir, url);
} else if (entry.isFile() && entry.name.endsWith('.md')) {
buildFile(entryPath, buildDir, url);
Expand All @@ -100,21 +110,23 @@ function buildContentPages(contentDir, buildDir, url){

}

function buildFile(filePath, buildDir, url){
function buildFile(filePath, buildDir, url) {

let content = null;

// Processing for Content Pages
if(filePath.endsWith('.md')){
if (filePath.endsWith('.md')) {
content = parser.processContent(filePath, true, url);
if (!filePath.endsWith('index.md')) {
const folderName = path.basename(filePath, '.md');
const folderPath = path.join(buildDir, folderName);
fs.mkdirSync(folderPath, { recursive: true });
fs.mkdirSync(folderPath, {
recursive: true
});
filePath = path.join(folderPath, 'index.html');
} else {
filePath = path.join(buildDir, path.basename(filePath));
if(filePath.endsWith('index.md')){
if (filePath.endsWith('index.md')) {
filePath = filePath.replace('index.md', 'index.html');
}
}
Expand All @@ -123,14 +135,16 @@ function buildFile(filePath, buildDir, url){
content = parser.processFile(filePath, true, url);

// ignore content pages
if(filePath.endsWith('[content].html')){
if (filePath.endsWith('[content].html')) {
return;
}

if (!filePath.endsWith('index.html')) {
const folderName = path.basename(filePath, '.html');
const folderPath = path.join(buildDir, folderName);
fs.mkdirSync(folderPath, { recursive: true });
fs.mkdirSync(folderPath, {
recursive: true
});
filePath = path.join(folderPath, 'index.html');
} else {
filePath = path.join(buildDir, path.basename(filePath));
Expand All @@ -139,7 +153,7 @@ function buildFile(filePath, buildDir, url){

content = parser.parseURLs(content, url);

if(content != null){
if (content != null) {
fs.writeFileSync(filePath, content);
}
}
Loading
Loading