vowel 0.1.5 → 0.1.6
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/content/$features/cards.md +7 -0
- package/content/$features/editing.md +7 -0
- package/content/$features/emoji.md +7 -0
- package/content/$features/frontmatter.md +7 -0
- package/content/$features/lists.md +7 -0
- package/content/$features/navigation.md +7 -0
- package/content/$features/rich-previews.md +7 -0
- package/content/$features/robots.md +7 -0
- package/content/$features/rss.md +7 -0
- package/content/$features/sitemap.md +7 -0
- package/content/$features/speed.md +7 -0
- package/content/$features/static.md +7 -0
- package/content/$features/taxonomies.md +7 -0
- package/content/docs/file-structure.md +1 -1
- package/content/docs/folder-settings.md +1 -0
- package/content/docs/items.md +13 -0
- package/content/docs/run-build-deploy.md +1 -1
- package/content/home.md +1 -43
- package/content/vercel.json +5 -0
- package/package.json +1 -1
- package/server.js +3 -2
- package/src/lib/components/DefaultStyles.svelte +60 -2
- package/src/lib/components/Markdown/validators.js +1 -1
- package/src/lib/components/Nav.svelte +2 -2
- package/src/lib/components/Page.svelte +1 -1
- package/src/lib/components/Sitemap.svelte +2 -2
- package/src/lib/utilities/createPageClass.js +1 -0
- package/src/lib/utilities/getPagesByFolder.js +22 -20
- package/src/lib/utilities/processMarkdownFiles.js +11 -5
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Items
|
|
2
|
+
|
|
3
|
+
With Vowel, you can create reusable pieces of content and embed them throughout your website.
|
|
4
|
+
|
|
5
|
+
To create one, prefix a file or folder with a `$`, such as `$faqs`. The file or folder will not produce a page, but the content can be displayed on other pages, like so:
|
|
6
|
+
|
|
7
|
+
```md
|
|
8
|
+
Here are answers to common questions:
|
|
9
|
+
|
|
10
|
+
/$faqs?count=10
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This also allows richer content, as the item will be displayed with frontmatter.
|
package/content/home.md
CHANGED
|
@@ -26,49 +26,7 @@ Vowel is created by Sam Littlefair. If you have questions or comments, [reach ou
|
|
|
26
26
|
|
|
27
27
|
# Features
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Submit your website to search engines with a sitemap that lists all of your pages.
|
|
32
|
-
|
|
33
|
-
## RSS 📡
|
|
34
|
-
|
|
35
|
-
Deliver your content to RSS readers with an Atom feed that lists your full posts in reverse-chronology.
|
|
36
|
-
|
|
37
|
-
## Speed ⚡️
|
|
38
|
-
|
|
39
|
-
Get a blazing-fast, Svelte-rendered website.
|
|
40
|
-
|
|
41
|
-
## Static generation 🗿
|
|
42
|
-
|
|
43
|
-
Load pages quickly with plain HTML.
|
|
44
|
-
|
|
45
|
-
## Copyright 🔒
|
|
46
|
-
|
|
47
|
-
Display an up-to-date copyright in the footer of your website.
|
|
48
|
-
|
|
49
|
-
## Rich link previews 🔗
|
|
50
|
-
|
|
51
|
-
Create rich links with titles and images, both internally and externally.
|
|
52
|
-
|
|
53
|
-
## Navigation 🚏
|
|
54
|
-
|
|
55
|
-
Structure your content with a header, nav, sitemap, and breadcrumbs.
|
|
56
|
-
|
|
57
|
-
## Emoji favicon 🙃
|
|
58
|
-
|
|
59
|
-
Use any emoji you want for your website's icon.
|
|
60
|
-
|
|
61
|
-
## Custom taxonomies 🖇️
|
|
62
|
-
|
|
63
|
-
Go beyond tags to create authors and categories.
|
|
64
|
-
|
|
65
|
-
## Advanced frontmatter 🧮
|
|
66
|
-
|
|
67
|
-
Display dates, lists, nested properties, links, and images in your frontmatter.
|
|
68
|
-
|
|
69
|
-
## Live editing 👩🎤
|
|
70
|
-
|
|
71
|
-
See updates live as you save.
|
|
29
|
+
/$features?count=20
|
|
72
30
|
|
|
73
31
|
# Try it
|
|
74
32
|
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -58,8 +58,9 @@ async function buildProject() {
|
|
|
58
58
|
|
|
59
59
|
const jsonData = JSON.stringify(vercelDefaults, null, 2);
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
await writeFile(
|
|
61
|
+
const path = join($home, 'vercel.json');
|
|
62
|
+
await writeFile(path, jsonData, 'utf-8');
|
|
63
|
+
// await writeFile(vercelConfigPath, jsonData, 'utf-8');
|
|
63
64
|
console.log('Build completed successfully.');
|
|
64
65
|
} catch (err) {
|
|
65
66
|
console.error('Build failed:', err);
|
|
@@ -352,7 +352,7 @@
|
|
|
352
352
|
padding-right: 0;
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
-
:where(pre, blockquote, dl, figure, table, p, ul, ol, form, article):not(:last-child) {
|
|
355
|
+
:where(pre, blockquote, dl, figure, table, p, ul, ol, form, article, section):not(:last-child) {
|
|
356
356
|
margin-bottom: 2.5rem;
|
|
357
357
|
}
|
|
358
358
|
|
|
@@ -365,10 +365,14 @@
|
|
|
365
365
|
|
|
366
366
|
/* Header */
|
|
367
367
|
|
|
368
|
+
header {
|
|
369
|
+
margin-top: 4rem;
|
|
370
|
+
}
|
|
371
|
+
|
|
368
372
|
nav.top-bar {
|
|
369
373
|
border: 1px solid var(--border-color);
|
|
370
374
|
padding: 6px 10px;
|
|
371
|
-
margin-inline: -
|
|
375
|
+
margin-inline: -3px;
|
|
372
376
|
border-radius: 5px;
|
|
373
377
|
display: flex;
|
|
374
378
|
column-gap: 2rem;
|
|
@@ -422,6 +426,10 @@
|
|
|
422
426
|
cursor: default;
|
|
423
427
|
}
|
|
424
428
|
|
|
429
|
+
header .breadcrumbs > a:only-child {
|
|
430
|
+
display: none;
|
|
431
|
+
}
|
|
432
|
+
|
|
425
433
|
header .breadcrumbs {
|
|
426
434
|
margin-block: 4rem 1rem;
|
|
427
435
|
}
|
|
@@ -455,5 +463,55 @@
|
|
|
455
463
|
.page.home > main > h1 {
|
|
456
464
|
display: none;
|
|
457
465
|
}
|
|
466
|
+
|
|
467
|
+
.page.home .content p:first-child {
|
|
468
|
+
font-size: 1.2em;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
section[class*='$'] {
|
|
472
|
+
display: grid;
|
|
473
|
+
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
474
|
+
grid-auto-rows: auto;
|
|
475
|
+
grid-gap: 2rem;
|
|
476
|
+
|
|
477
|
+
& article {
|
|
478
|
+
margin: 0;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
article.item {
|
|
483
|
+
display: grid;
|
|
484
|
+
flex-direction: column;
|
|
485
|
+
grid-template-areas:
|
|
486
|
+
'title icon'
|
|
487
|
+
'description description';
|
|
488
|
+
align-content: start;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
article.item h1 {
|
|
492
|
+
grid-area: title;
|
|
493
|
+
font-size: 1.6rem;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
article.item dl.icon {
|
|
497
|
+
grid-area: icon;
|
|
498
|
+
font-size: 1.5em;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
article.item dl.icon dd {
|
|
502
|
+
text-align: right;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
article.item .description {
|
|
506
|
+
grid-area: description;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
article.item dt {
|
|
510
|
+
display: none;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
article.item dl.icon {
|
|
514
|
+
order: -1;
|
|
515
|
+
}
|
|
458
516
|
}
|
|
459
517
|
</style>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
function filterFolder(folder) {
|
|
8
8
|
const filteredFolder = {};
|
|
9
9
|
for (let key in folder) {
|
|
10
|
-
if (!folder[key]['$']?.date) {
|
|
10
|
+
if (!folder[key]['$']?.date && !key.startsWith('$')) {
|
|
11
11
|
filteredFolder[key] = folder[key];
|
|
12
12
|
}
|
|
13
13
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
{#if Object.keys(evergreen).some((key) => key !== '$' && key !== '_')}
|
|
21
21
|
<nav class="top-bar">
|
|
22
|
-
{#if !child
|
|
22
|
+
{#if !child}
|
|
23
23
|
<a aria-current={isActiveLink(segments)} href={evergreen['$']?.url}
|
|
24
24
|
>{getFolderLabel(evergreen)}</a
|
|
25
25
|
>
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
</li>
|
|
20
20
|
{/if}
|
|
21
21
|
{#each Object.keys(section) as key}
|
|
22
|
-
{#if Object.keys(section[key]).length === 1 && section[key].$ && !section[key].$.date}
|
|
22
|
+
{#if Object.keys(section[key]).length === 1 && section[key].$ && !section[key].$.date && !key.startsWith('$')}
|
|
23
23
|
<li class={key}>
|
|
24
24
|
<a aria-current={isActiveLink(segments, key)} href={section[key].$.url}>
|
|
25
25
|
{getFileLabel(section[key]['$'], true) || getFolderLabel(section[key], true)}
|
|
26
26
|
</a>
|
|
27
27
|
</li>
|
|
28
|
-
{:else if section[key].$ && !section[key].$.date}
|
|
28
|
+
{:else if section[key].$ && !section[key].$.date && !key.startsWith('$')}
|
|
29
29
|
<li class={key}>
|
|
30
30
|
<a aria-current={isActiveLink(segments, key)} href={section[key].$.url}>
|
|
31
31
|
{getFileLabel(section[key]['$']) || getFolderLabel(section[key])}
|
|
@@ -17,30 +17,32 @@ function traverseFolder(folder, root = false, property = '.') {
|
|
|
17
17
|
let pages = [];
|
|
18
18
|
|
|
19
19
|
for (let key in folder) {
|
|
20
|
-
if (key
|
|
21
|
-
if (
|
|
22
|
-
if (
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
if (!key.startsWith('$') || key.length === 1) {
|
|
21
|
+
if (key === '$') {
|
|
22
|
+
if (!root) {
|
|
23
|
+
if (propertyKey) {
|
|
24
|
+
if (
|
|
25
|
+
folder[key].hasOwnProperty(propertyKey) &&
|
|
26
|
+
folder[key][propertyKey] === propertyValue
|
|
27
|
+
) {
|
|
28
|
+
pages.push(folder[key]);
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
27
31
|
pages.push(folder[key]);
|
|
28
32
|
}
|
|
29
|
-
} else {
|
|
30
|
-
pages.push(folder[key]);
|
|
31
33
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const child = folder[key];
|
|
34
|
+
// if (
|
|
35
|
+
// !root &&
|
|
36
|
+
// folder[key].$?.hasOwnProperty(propertyKey) &&
|
|
37
|
+
// folder[key][propertyKey] === propertyValue
|
|
38
|
+
// )
|
|
39
|
+
// pages.push(folder[key]);
|
|
40
|
+
} else if (key !== '_') {
|
|
41
|
+
const child = folder[key];
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
pages.push(...traverseFolder(child, false, property));
|
|
45
|
+
}
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
|
|
@@ -90,7 +90,7 @@ function DefaultDirectory(path) {
|
|
|
90
90
|
* @param {import('./loadCache').Cache} cache
|
|
91
91
|
* @returns {Promise<Directory>}
|
|
92
92
|
*/
|
|
93
|
-
async function readFolder(folderPath, parents, cache) {
|
|
93
|
+
async function readFolder(folderPath, parents, cache, hidden) {
|
|
94
94
|
function filterFiles(file) {
|
|
95
95
|
if (file.name.startsWith('.')) return false;
|
|
96
96
|
if (file.name.startsWith('README')) return false;
|
|
@@ -105,7 +105,9 @@ async function readFolder(folderPath, parents, cache) {
|
|
|
105
105
|
|
|
106
106
|
console.log(`filesfound:${files.length}`);
|
|
107
107
|
|
|
108
|
-
const promises = files.map(
|
|
108
|
+
const promises = files.map(
|
|
109
|
+
async (file) => await readFile(file, parents, cache, folderPath, hidden)
|
|
110
|
+
);
|
|
109
111
|
|
|
110
112
|
const folder = (await Promise.all(promises)).reduce((acc, obj) => ({ ...acc, ...obj }), {});
|
|
111
113
|
|
|
@@ -123,13 +125,15 @@ async function readFolder(folderPath, parents, cache) {
|
|
|
123
125
|
return folder;
|
|
124
126
|
}
|
|
125
127
|
|
|
126
|
-
async function readFile(file, parents, cache, folderPath) {
|
|
128
|
+
async function readFile(file, parents, cache, folderPath, hidden) {
|
|
127
129
|
const route = path.parse(file.name).name;
|
|
128
130
|
const url = buildURL(parents, route);
|
|
129
131
|
const filePath = path.join(folderPath, file.name);
|
|
130
132
|
|
|
131
133
|
const extension = path.extname(file.name);
|
|
132
134
|
|
|
135
|
+
const hide = file.name.startsWith('$') || hidden;
|
|
136
|
+
|
|
133
137
|
if (file.isFile() && extension === '.md') {
|
|
134
138
|
const startLoad = performance.now();
|
|
135
139
|
const shortPath = parents + '/' + file.name;
|
|
@@ -150,13 +154,15 @@ async function readFile(file, parents, cache, folderPath) {
|
|
|
150
154
|
}
|
|
151
155
|
};
|
|
152
156
|
}
|
|
157
|
+
|
|
153
158
|
return {
|
|
154
159
|
[route]: {
|
|
155
160
|
$: {
|
|
156
161
|
...frontmatter,
|
|
157
162
|
imputedProperties,
|
|
158
163
|
ast,
|
|
159
|
-
url
|
|
164
|
+
// url,
|
|
165
|
+
url: hide ? false : url
|
|
160
166
|
}
|
|
161
167
|
}
|
|
162
168
|
};
|
|
@@ -173,7 +179,7 @@ async function readFile(file, parents, cache, folderPath) {
|
|
|
173
179
|
const shortPath = parents + '/' + file.name;
|
|
174
180
|
|
|
175
181
|
const startLoad = performance.now();
|
|
176
|
-
const folder = await readFolder(path.join(folderPath, file.name), url, cache);
|
|
182
|
+
const folder = await readFolder(path.join(folderPath, file.name), url, cache, hide);
|
|
177
183
|
|
|
178
184
|
const loadTime = (performance.now() - startLoad).toFixed(2);
|
|
179
185
|
// console.log(`📁 ${shortPath} (${loadTime}ms)`);
|