@terrymooreii/sia 2.3.2 → 2.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/README.md +46 -8
- package/docs/front-matter.md +40 -2
- package/lib/content.js +51 -2
- package/lib/migrate.js +5 -2
- package/lib/new.js +9 -3
- package/package.json +1 -1
package/docs/README.md
CHANGED
|
@@ -71,17 +71,26 @@ my-site/
|
|
|
71
71
|
├── _config.yml # Site configuration
|
|
72
72
|
├── src/
|
|
73
73
|
│ ├── posts/ # Blog posts (markdown)
|
|
74
|
-
│ │
|
|
75
|
-
│ │
|
|
76
|
-
│ │
|
|
74
|
+
│ │ ├── 2024-12-17-my-post/ # Flat structure (default)
|
|
75
|
+
│ │ │ ├── index.md
|
|
76
|
+
│ │ │ └── (assets can go here)
|
|
77
|
+
│ │ └── 2024/ # Or date-organized (if path: posts/:year/:month)
|
|
78
|
+
│ │ └── 12/
|
|
79
|
+
│ │ └── 2024-12-17-my-post/
|
|
80
|
+
│ │ ├── index.md
|
|
81
|
+
│ │ └── (assets can go here)
|
|
77
82
|
│ ├── pages/ # Static pages
|
|
78
83
|
│ │ └── about/
|
|
79
84
|
│ │ ├── index.md
|
|
80
85
|
│ │ └── (assets can go here)
|
|
81
86
|
│ ├── notes/ # Short notes/tweets
|
|
82
|
-
│ │
|
|
83
|
-
│ │
|
|
84
|
-
│ │
|
|
87
|
+
│ │ ├── 2024-12-17-note-1234567890/ # Flat structure (default)
|
|
88
|
+
│ │ │ ├── index.md
|
|
89
|
+
│ │ │ └── (assets can go here)
|
|
90
|
+
│ │ └── 2024/ # Or date-organized (if path: notes/:year)
|
|
91
|
+
│ │ └── 2024-12-17-note-1234567890/
|
|
92
|
+
│ │ ├── index.md
|
|
93
|
+
│ │ └── (assets can go here)
|
|
85
94
|
│ └── images/ # Images
|
|
86
95
|
├── assets/ # Static assets (optional)
|
|
87
96
|
├── static/ # Static assets (optional)
|
|
@@ -97,10 +106,39 @@ my-site/
|
|
|
97
106
|
|
|
98
107
|
Each post, page, and note is created as a folder containing an `index.md` file. This allows you to organize assets (images, PDFs, etc.) alongside your content in the same folder.
|
|
99
108
|
|
|
109
|
+
**Note:** You can organize posts and notes by date using date variables in the `path` configuration (e.g., `posts/:year/:month`). See [Date Variables in Paths](#date-variables-in-paths) for details.
|
|
110
|
+
|
|
100
111
|
## Configuration
|
|
101
112
|
|
|
102
113
|
Edit `_config.yml` to customize your site:
|
|
103
114
|
|
|
115
|
+
### Date Variables in Paths
|
|
116
|
+
|
|
117
|
+
You can organize posts and notes by date using date variables in the `path` property:
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
collections:
|
|
121
|
+
posts:
|
|
122
|
+
path: posts/:year/:month # Organizes posts by year and month
|
|
123
|
+
# New posts will be created in: posts/2024/01/2024-01-15-slug/
|
|
124
|
+
|
|
125
|
+
notes:
|
|
126
|
+
path: notes/:year # Organizes notes by year only
|
|
127
|
+
# New notes will be created in: notes/2024/2024-01-15-note-1234567890/
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Supported date variables:**
|
|
131
|
+
- `:year` - 4-digit year (e.g., `2024`)
|
|
132
|
+
- `:month` - 2-digit month (e.g., `01`, `12`)
|
|
133
|
+
- `:day` - 2-digit day (e.g., `01`, `31`)
|
|
134
|
+
|
|
135
|
+
**Examples:**
|
|
136
|
+
- `posts/:year/:month` → `posts/2024/01/`
|
|
137
|
+
- `posts/:year` → `posts/2024/`
|
|
138
|
+
- `notes/:year/:month/:day` → `notes/2024/01/15/`
|
|
139
|
+
|
|
140
|
+
When loading collections, Sia automatically searches recursively through all date-organized directories, so existing content will be found regardless of the path structure.
|
|
141
|
+
|
|
104
142
|
```yaml
|
|
105
143
|
site:
|
|
106
144
|
title: "My Blog"
|
|
@@ -117,7 +155,7 @@ output: dist
|
|
|
117
155
|
|
|
118
156
|
collections:
|
|
119
157
|
posts:
|
|
120
|
-
path: posts
|
|
158
|
+
path: posts # Or use date variables: posts/:year/:month
|
|
121
159
|
layout: post
|
|
122
160
|
permalink: /blog/:slug/
|
|
123
161
|
sortBy: date
|
|
@@ -127,7 +165,7 @@ collections:
|
|
|
127
165
|
layout: page
|
|
128
166
|
permalink: /:slug/
|
|
129
167
|
notes:
|
|
130
|
-
path: notes
|
|
168
|
+
path: notes # Or use date variables: notes/:year
|
|
131
169
|
layout: note
|
|
132
170
|
permalink: /notes/:slug/
|
|
133
171
|
|
package/docs/front-matter.md
CHANGED
|
@@ -165,13 +165,32 @@ Blog posts are stored in `src/posts/` (or your configured path).
|
|
|
165
165
|
# From _config.yml
|
|
166
166
|
collections:
|
|
167
167
|
posts:
|
|
168
|
-
path: posts
|
|
168
|
+
path: posts # Or use date variables: posts/:year/:month
|
|
169
169
|
layout: post
|
|
170
170
|
permalink: /blog/:slug/
|
|
171
171
|
sortBy: date
|
|
172
172
|
sortOrder: desc
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
+
**Date Variables in Paths:**
|
|
176
|
+
|
|
177
|
+
You can organize posts by date using date variables in the `path` property:
|
|
178
|
+
|
|
179
|
+
```yaml
|
|
180
|
+
collections:
|
|
181
|
+
posts:
|
|
182
|
+
path: posts/:year/:month # Creates: posts/2024/01/2024-01-15-slug/
|
|
183
|
+
# Or
|
|
184
|
+
path: posts/:year # Creates: posts/2024/2024-01-15-slug/
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Supported variables:**
|
|
188
|
+
- `:year` - 4-digit year (e.g., `2024`)
|
|
189
|
+
- `:month` - 2-digit month (e.g., `01`, `12`)
|
|
190
|
+
- `:day` - 2-digit day (e.g., `01`, `31`)
|
|
191
|
+
|
|
192
|
+
When you create a new post, it will be automatically placed in the correct date-organized directory based on the current date.
|
|
193
|
+
|
|
175
194
|
### Typical Post Front Matter
|
|
176
195
|
|
|
177
196
|
```yaml
|
|
@@ -268,13 +287,32 @@ Notes are short-form content stored in `src/notes/` (or your configured path). T
|
|
|
268
287
|
# From _config.yml
|
|
269
288
|
collections:
|
|
270
289
|
notes:
|
|
271
|
-
path: notes
|
|
290
|
+
path: notes # Or use date variables: notes/:year
|
|
272
291
|
layout: note
|
|
273
292
|
permalink: /notes/:slug/
|
|
274
293
|
sortBy: date
|
|
275
294
|
sortOrder: desc
|
|
276
295
|
```
|
|
277
296
|
|
|
297
|
+
**Date Variables in Paths:**
|
|
298
|
+
|
|
299
|
+
You can organize notes by date using date variables in the `path` property:
|
|
300
|
+
|
|
301
|
+
```yaml
|
|
302
|
+
collections:
|
|
303
|
+
notes:
|
|
304
|
+
path: notes/:year # Creates: notes/2024/2024-01-15-note-1234567890/
|
|
305
|
+
# Or
|
|
306
|
+
path: notes/:year/:month # Creates: notes/2024/01/2024-01-15-note-1234567890/
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Supported variables:**
|
|
310
|
+
- `:year` - 4-digit year (e.g., `2024`)
|
|
311
|
+
- `:month` - 2-digit month (e.g., `01`, `12`)
|
|
312
|
+
- `:day` - 2-digit day (e.g., `01`, `31`)
|
|
313
|
+
|
|
314
|
+
When you create a new note, it will be automatically placed in the correct date-organized directory based on the current date.
|
|
315
|
+
|
|
278
316
|
### Typical Note Front Matter
|
|
279
317
|
|
|
280
318
|
Notes often have minimal front matter since they're short-form:
|
package/lib/content.js
CHANGED
|
@@ -321,6 +321,49 @@ function truncateMarkdownSafely(text, maxLength) {
|
|
|
321
321
|
return text.substring(0, truncateAt).trim() + '...';
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
+
/**
|
|
325
|
+
* Expand date variables in a path template
|
|
326
|
+
* Supports :year, :month, :day variables
|
|
327
|
+
* @param {string} pathTemplate - Path template with date variables (e.g., "posts/:year/:month")
|
|
328
|
+
* @param {Date} date - Date to use for expansion
|
|
329
|
+
* @returns {string} Expanded path
|
|
330
|
+
*/
|
|
331
|
+
export function expandDatePath(pathTemplate, date) {
|
|
332
|
+
if (!pathTemplate || typeof pathTemplate !== 'string') {
|
|
333
|
+
return pathTemplate;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const year = date.getFullYear();
|
|
337
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
338
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
339
|
+
|
|
340
|
+
return pathTemplate
|
|
341
|
+
.replace(/:year/g, year)
|
|
342
|
+
.replace(/:month/g, month)
|
|
343
|
+
.replace(/:day/g, day);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Get base path from a path template (removes date variables for recursive searching)
|
|
348
|
+
* @param {string} pathTemplate - Path template with date variables
|
|
349
|
+
* @returns {string} Base path (everything before the first date variable)
|
|
350
|
+
*/
|
|
351
|
+
export function getBasePath(pathTemplate) {
|
|
352
|
+
if (!pathTemplate || typeof pathTemplate !== 'string') {
|
|
353
|
+
return pathTemplate;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Find the first occurrence of a date variable (can be at start or after a slash)
|
|
357
|
+
const firstVariable = pathTemplate.match(/:(\w+)/);
|
|
358
|
+
if (!firstVariable) {
|
|
359
|
+
// No date variables, return as-is
|
|
360
|
+
return pathTemplate;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Return everything before the first date variable
|
|
364
|
+
return pathTemplate.substring(0, firstVariable.index);
|
|
365
|
+
}
|
|
366
|
+
|
|
324
367
|
/**
|
|
325
368
|
* Generate a URL-friendly slug from a string
|
|
326
369
|
*/
|
|
@@ -577,7 +620,11 @@ export async function loadCollection(config, collectionName) {
|
|
|
577
620
|
return [];
|
|
578
621
|
}
|
|
579
622
|
|
|
580
|
-
|
|
623
|
+
// If path contains date variables, use base path for recursive searching
|
|
624
|
+
// Otherwise use the path as-is
|
|
625
|
+
const pathTemplate = collectionConfig.path;
|
|
626
|
+
const basePath = getBasePath(pathTemplate);
|
|
627
|
+
const collectionDir = join(config.inputDir, basePath);
|
|
581
628
|
const files = getMarkdownFiles(collectionDir);
|
|
582
629
|
|
|
583
630
|
const items = await Promise.all(
|
|
@@ -671,6 +718,8 @@ export default {
|
|
|
671
718
|
getMarkdownFiles,
|
|
672
719
|
loadCollection,
|
|
673
720
|
loadAllCollections,
|
|
674
|
-
addMarkedExtension
|
|
721
|
+
addMarkedExtension,
|
|
722
|
+
expandDatePath,
|
|
723
|
+
getBasePath
|
|
675
724
|
};
|
|
676
725
|
|
package/lib/migrate.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readdirSync, statSync, existsSync, mkdirSync, renameSync } from 'fs';
|
|
2
2
|
import { join, dirname, basename, extname } from 'path';
|
|
3
3
|
import { loadConfig } from './config.js';
|
|
4
|
-
import { getMarkdownFiles } from './content.js';
|
|
4
|
+
import { getMarkdownFiles, getBasePath } from './content.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Check if a file is already in folder-based structure
|
|
@@ -102,7 +102,10 @@ export async function migrateContent(options = {}) {
|
|
|
102
102
|
continue;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
// If path contains date variables, use base path for recursive searching
|
|
106
|
+
const pathTemplate = collectionConfig.path;
|
|
107
|
+
const basePath = getBasePath(pathTemplate);
|
|
108
|
+
const collectionDir = join(config.inputDir, basePath);
|
|
106
109
|
|
|
107
110
|
if (!existsSync(collectionDir)) {
|
|
108
111
|
console.log(`⚠️ Collection directory not found: ${collectionDir}`);
|
package/lib/new.js
CHANGED
|
@@ -2,7 +2,7 @@ import prompts from 'prompts';
|
|
|
2
2
|
import { writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { loadConfig } from './config.js';
|
|
5
|
-
import { slugify } from './content.js';
|
|
5
|
+
import { slugify, expandDatePath } from './content.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Get current date in YYYY-MM-DD format
|
|
@@ -52,7 +52,10 @@ function createPost(config, options) {
|
|
|
52
52
|
const slug = slugify(options.title);
|
|
53
53
|
const date = getDateString();
|
|
54
54
|
const folderName = `${date}-${slug}`;
|
|
55
|
-
const
|
|
55
|
+
const now = new Date();
|
|
56
|
+
const pathTemplate = config.collections.posts?.path || 'posts';
|
|
57
|
+
const expandedPath = expandDatePath(pathTemplate, now);
|
|
58
|
+
const postsDir = join(config.inputDir, expandedPath);
|
|
56
59
|
const postFolder = join(postsDir, folderName);
|
|
57
60
|
const filePath = join(postFolder, 'index.md');
|
|
58
61
|
|
|
@@ -129,7 +132,10 @@ function createNote(config, options) {
|
|
|
129
132
|
const date = getDateString();
|
|
130
133
|
const timestamp = Date.now();
|
|
131
134
|
const folderName = `${date}-${slug}-${timestamp}`;
|
|
132
|
-
const
|
|
135
|
+
const now = new Date();
|
|
136
|
+
const pathTemplate = config.collections.notes?.path || 'notes';
|
|
137
|
+
const expandedPath = expandDatePath(pathTemplate, now);
|
|
138
|
+
const notesDir = join(config.inputDir, expandedPath);
|
|
133
139
|
const noteFolder = join(notesDir, folderName);
|
|
134
140
|
const filePath = join(noteFolder, 'index.md');
|
|
135
141
|
|