feature: support more than html for SSI
This commit is contained in:
parent
02c10aaa72
commit
b3e5a4e1b4
4 changed files with 190 additions and 4 deletions
19
README.md
19
README.md
|
@ -33,7 +33,23 @@ different types of content with a great deal of control.
|
||||||
The default handlers are:
|
The default handlers are:
|
||||||
|
|
||||||
- HTML with SSI support
|
- HTML with SSI support
|
||||||
eg: <html><body><!-- #include file="./body.html" --></body></html>
|
eg:
|
||||||
|
|
||||||
|
```
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<!-- #include file="./header.html" -->
|
||||||
|
|
||||||
|
<!-- can include markdown, which will be converted to html -->
|
||||||
|
<!-- #include file="./essay.md" -->
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
<!-- you can include text files as well -->
|
||||||
|
<!-- #include file="./somedir/footer.txt" >
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
- markdown
|
- markdown
|
||||||
will serve markdown as HTML (or raw with an Accept header of text/markdown)
|
will serve markdown as HTML (or raw with an Accept header of text/markdown)
|
||||||
- Typescript
|
- Typescript
|
||||||
|
@ -92,7 +108,6 @@ object indicating permission is denied or similar.
|
||||||
|
|
||||||
- [ ] reload typescript if it is modified on disk
|
- [ ] reload typescript if it is modified on disk
|
||||||
|
|
||||||
|
|
||||||
#### NOTE ON WINDOWS
|
#### NOTE ON WINDOWS
|
||||||
|
|
||||||
Because Windows has more restrictions on filenames, you can use `___` in place of `:` in
|
Because Windows has more restrictions on filenames, you can use `___` in place of `:` in
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@andyburke/serverus",
|
"name": "@andyburke/serverus",
|
||||||
"description": "A flexible HTTP server for mixed content. Throw static files, markdown, Typescript and (hopefully, eventually) more into a directory and serverus can serve it up a bit more like old-school CGI.",
|
"description": "A flexible HTTP server for mixed content. Throw static files, markdown, Typescript and (hopefully, eventually) more into a directory and serverus can serve it up a bit more like old-school CGI.",
|
||||||
"version": "0.7.1",
|
"version": "0.8.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./serverus.ts",
|
".": "./serverus.ts",
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as path from '@std/path';
|
import * as path from '@std/path';
|
||||||
|
import { md_to_html } from '@andyburke/serverus/handlers/markdown';
|
||||||
|
|
||||||
// https://stackoverflow.com/a/75205316
|
// https://stackoverflow.com/a/75205316
|
||||||
const replaceAsync = async (str: string, regex: RegExp, asyncFn: (match: any, ...args: any) => Promise<any>) => {
|
const replaceAsync = async (str: string, regex: RegExp, asyncFn: (match: any, ...args: any) => Promise<any>) => {
|
||||||
|
@ -34,7 +35,27 @@ async function load_html_with_ssi(html_file: string): Promise<string> {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await load_html_with_ssi(resolved);
|
const HANDLERS: Record<string, (include_path: string) => Promise<string> | string> = {
|
||||||
|
default: async (include_path: string) => {
|
||||||
|
try {
|
||||||
|
return await Deno.readTextFile(include_path);
|
||||||
|
} catch (error) {
|
||||||
|
console.dir({ error });
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'.md': async (include_path: string) => {
|
||||||
|
const markdown_content = await Deno.readTextFile(include_path);
|
||||||
|
return md_to_html(markdown_content);
|
||||||
|
},
|
||||||
|
|
||||||
|
'.html': load_html_with_ssi
|
||||||
|
};
|
||||||
|
|
||||||
|
const extension = path.extname(resolved);
|
||||||
|
const handler = extension ? (HANDLERS[extension.toLowerCase()] ?? HANDLERS.default) : HANDLERS.default;
|
||||||
|
return await handler(resolved);
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
|
|
|
@ -71,3 +71,153 @@ Deno.test({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: 'get html file with markdown included',
|
||||||
|
permissions: {
|
||||||
|
env: true,
|
||||||
|
read: true,
|
||||||
|
write: true,
|
||||||
|
net: true
|
||||||
|
},
|
||||||
|
fn: async () => {
|
||||||
|
let test_server_info: EPHEMERAL_SERVER | null = null;
|
||||||
|
const cwd = Deno.cwd();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Deno.chdir('./tests/www');
|
||||||
|
test_server_info = await get_ephemeral_listen_server();
|
||||||
|
|
||||||
|
const response = await fetch(`http://${test_server_info.hostname}:${test_server_info.port}/includes/with_markdown.html`);
|
||||||
|
|
||||||
|
const body = await response.text();
|
||||||
|
|
||||||
|
asserts.assert(response.ok);
|
||||||
|
asserts.assert(body);
|
||||||
|
asserts.assertMatch(body, /\<html\>.*?\<h1\>This is Markdown\<\/h1\>.*?\<\/html\>/is);
|
||||||
|
} finally {
|
||||||
|
Deno.chdir(cwd);
|
||||||
|
if (test_server_info) {
|
||||||
|
await test_server_info?.server?.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: 'get html file with text included',
|
||||||
|
permissions: {
|
||||||
|
env: true,
|
||||||
|
read: true,
|
||||||
|
write: true,
|
||||||
|
net: true
|
||||||
|
},
|
||||||
|
fn: async () => {
|
||||||
|
let test_server_info: EPHEMERAL_SERVER | null = null;
|
||||||
|
const cwd = Deno.cwd();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Deno.chdir('./tests/www');
|
||||||
|
test_server_info = await get_ephemeral_listen_server();
|
||||||
|
|
||||||
|
const response = await fetch(`http://${test_server_info.hostname}:${test_server_info.port}/includes/with_text.html`);
|
||||||
|
|
||||||
|
const body = await response.text();
|
||||||
|
|
||||||
|
asserts.assert(response.ok);
|
||||||
|
asserts.assert(body);
|
||||||
|
asserts.assertMatch(body, /\<html\>.*?Just some random text in a random text file\..*?\<\/html\>/is);
|
||||||
|
} finally {
|
||||||
|
Deno.chdir(cwd);
|
||||||
|
if (test_server_info) {
|
||||||
|
await test_server_info?.server?.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: 'get html file with lots of includes',
|
||||||
|
permissions: {
|
||||||
|
env: true,
|
||||||
|
read: true,
|
||||||
|
write: true,
|
||||||
|
net: true
|
||||||
|
},
|
||||||
|
fn: async () => {
|
||||||
|
let test_server_info: EPHEMERAL_SERVER | null = null;
|
||||||
|
const cwd = Deno.cwd();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Deno.chdir('./tests/www');
|
||||||
|
test_server_info = await get_ephemeral_listen_server();
|
||||||
|
|
||||||
|
const response = await fetch(
|
||||||
|
`http://${test_server_info.hostname}:${test_server_info.port}/includes/with_lots_of_includes.html`
|
||||||
|
);
|
||||||
|
|
||||||
|
const body = await response.text();
|
||||||
|
|
||||||
|
asserts.assert(response.ok);
|
||||||
|
asserts.assert(body);
|
||||||
|
asserts.assertEquals(
|
||||||
|
body,
|
||||||
|
`<html>
|
||||||
|
<body>
|
||||||
|
<p>Hello. Markdown should follow:</p>
|
||||||
|
|
||||||
|
<h1>This is Markdown</h1>
|
||||||
|
<br>
|
||||||
|
Welcome to it.
|
||||||
|
<br>
|
||||||
|
<h2>This is a level 2 heading</h2>
|
||||||
|
<br>
|
||||||
|
Can you read this?
|
||||||
|
<br>
|
||||||
|
<h3>Let's go deeper, level 3 heading</h3>
|
||||||
|
<br>
|
||||||
|
<ul>
|
||||||
|
<li> this</li>
|
||||||
|
<br>
|
||||||
|
<li> is</li>
|
||||||
|
<br>
|
||||||
|
<li> a</li>
|
||||||
|
<br>
|
||||||
|
<li> list?</li>
|
||||||
|
<br>
|
||||||
|
</ul>
|
||||||
|
<br>
|
||||||
|
<h3>How about a table?</h3>
|
||||||
|
<br>
|
||||||
|
| column 1 | column 2 |
|
||||||
|
| -------- | -------- |
|
||||||
|
| hi | hey |
|
||||||
|
| hoy | hah |
|
||||||
|
<br>
|
||||||
|
<h2>Ok, that seems sufficient?</h2>
|
||||||
|
<br>
|
||||||
|
Hardly, but we'll get back to this.
|
||||||
|
|
||||||
|
Just some random text in a random text file.
|
||||||
|
|
||||||
|
<div>Include #1</div>
|
||||||
|
|
||||||
|
<div>Include #2!</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div>Include #3</div>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Goodbye. The include should be above.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
Deno.chdir(cwd);
|
||||||
|
if (test_server_info) {
|
||||||
|
await test_server_info?.server?.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue