tpl: include snippets

This commit is contained in:
Flummi 2020-04-06 13:16:21 +02:00
parent 47cc62b767
commit da9d29e727
2 changed files with 42 additions and 75 deletions

View File

@ -7,13 +7,17 @@ import lib from "../lib.mjs";
import tpl from "../tpl.mjs"; import tpl from "../tpl.mjs";
const templates = { const templates = {
contact: fs.readFileSync("./views/contact.html", "utf-8"), contact: fs.readFileSync("./views/contact.html", "utf-8"),
help: fs.readFileSync("./views/help.html", "utf-8"), how: fs.readFileSync("./views/how.html", "utf-8"),
how: fs.readFileSync("./views/how.html", "utf-8"), index: fs.readFileSync("./views/index.html", "utf-8"),
index: fs.readFileSync("./views/index.html", "utf-8"), item: fs.readFileSync("./views/item.html", "utf-8"),
item: fs.readFileSync("./views/item.html", "utf-8") snippets: {
navbar: fs.readFileSync("./views/snippets/navbar.html", "utf-8")
}
}; };
tpl.snippets = templates.snippets;
router.get("/", async (req, res) => { router.get("/", async (req, res) => {
const query = await sql.query("select id, mime from items order by id desc limit 300"); const query = await sql.query("select id, mime from items order by id desc limit 300");
const data = { const data = {
@ -21,85 +25,46 @@ router.get("/", async (req, res) => {
last: query[query.length - 1].id last: query[query.length - 1].id
}; };
res.reply({ res.reply({ body: tpl.render(templates.index, data) });
body: tpl.render(templates.index, data)
});
}); });
router.get(/^\/([0-9]+)$/, async (req, res) => { router.get(/^\/([0-9]+)$/, async (req, res) => {
const q = "select * from items where id = ? limit 1; " // get item const q = "select * from items where id = ? limit 1; " // get item
+ "select id from items where id = (select min(id) from items where id > ?); " // get previous item + "select id from items where id = (select min(id) from items where id > ?); " // get previous item
+ "select id from items where id = (select max(id) from items where id < ?)"; // get next item + "select id from items where id = (select max(id) from items where id < ?)"; // get next item
const query = await sql.query(q, [req.url.split[0], req.url.split[0], req.url.split[0]]); const query = await sql.query(q, Array(3).fill(req.url.split[0]));
if(!query[0][0])
return res.redirect("/404");
const e = query[0][0];
const data = { const data = {
id: '', user: {
username: '', name: e.username,
item: '', channel: e.userchannel,
src: '', network: e.usernetwork
dest: '', },
mime: '', item: {
size: '', id: e.id,
userchannel: '', src: {
usernetwork: '', long: e.src,
thumb: null, short: url.parse(e.src).hostname,
thumbnail: null, },
next: null, thumbnail: `${cfg.websrv.paths.thumbnails}/${e.id}.png`,
prev: null dest: `${cfg.websrv.paths.images}/${e.dest}`,
mime: e.mime,
size: lib.formatSize(e.size),
timestamp: new Date(e.stamp * 1000).toISOString()
},
next: query[1].length ? query[1][0].id : null,
prev: query[2].length ? query[2][0].id : null
}; };
res.reply({ body: tpl.render(templates.item, data) });
if(query[0][0]) {
const e = query[0][0];
switch(e.mime) {
case "image/png":
case "image/jpeg":
case "image/gif":
data.item = "image";
break;
case "video/webm":
case "video/mp4":
case "video/quicktime":
data.item = "video";
break;
case "audio/mpeg":
case "audio/ogg":
case "audio/flac":
case "audio/x-flac":
data.item = "audio";
break;
}
data.id = e.id;
data.username = e.username;
data.srcurl = e.src;
data.src = url.parse(e.src).hostname;
data.thumb = `${cfg.websrv.paths.thumbnails}/${e.id}.png`;
data.dest = `${cfg.websrv.paths.images}/${e.dest}`;
data.mime = e.mime;
data.size = lib.formatSize(e.size);
data.userchannel = e.userchannel;
data.usernetwork = e.usernetwork;
data.timestamp = new Date(e.stamp * 1000).toISOString();
if(query[1].length)
data.next = query[1][0].id;
if(query[2].length)
data.prev = query[2][0].id;
}
res.reply({
body: tpl.render(templates.item, data)
});
}); });
router.get(/^\/(contact|help|how)$/, (req, res) => { router.get(/^\/(contact|help|how)$/, (req, res) => {
res.reply({ res.reply({ body: tpl.render(templates[req.url.split[0]]) });
body: templates[req.url.split[0]]
});
}); });
router.get("/random", async (req, res) => { router.get("/random", async (req, res) => {
res res.redirect("/" + (await sql.query("select id from items order by rand() limit 1"))[0].id)
.writeHead(301, {
"Cache-Control": "no-cache, public",
"Location": "/" + (await sql.query("select id from items order by rand() limit 1"))[0].id
})
.end();
}); });

View File

@ -1,11 +1,13 @@
export default new class { export default new class {
snippets = {};
syntax = [ syntax = [
[ "each", t => `util.forEach(${t.slice(4).trim()},($value,$key)=>{` ], [ "each", t => `util.forEach(${t.slice(4).trim()},(value,key)=>{` ], // own valuename {{each items ->|as|=> item}}
[ "/each", () => "});" ], [ "/each", () => "});" ],
[ "if", t => `if(${t.slice(2).trim()}){` ], [ "if", t => `if(${t.slice(2).trim()}){` ],
[ "elseif", t => `}else if(${t.slice(6).trim()}){` ], [ "elseif", t => `}else if(${t.slice(6).trim()}){` ],
[ "else", () => "}else{" ], [ "else", () => "}else{" ],
[ "/if", () => "}" ], [ "/if", () => "}" ],
[ "include", t => `html+=util.snippets["${t.slice(7).trim()}"];`],
[ "=", t => `html+=${t.slice(1).trim()};` ] [ "=", t => `html+=${t.slice(1).trim()};` ]
]; ];
forEach(o, f) { forEach(o, f) {
@ -16,7 +18,7 @@ export default new class {
else else
throw new Error(`${o} is not a iterable object`); throw new Error(`${o} is not a iterable object`);
} }
render(tpl, data) { render(tpl, data = {}) {
return new Function("util", "data", "let html = \"\";with(data){" return new Function("util", "data", "let html = \"\";with(data){"
+ tpl.trim().replace(/[\n\r]/g, "").split(/{{\s*([^}]+)\s*}}/).filter(Boolean).map(t => { + tpl.trim().replace(/[\n\r]/g, "").split(/{{\s*([^}]+)\s*}}/).filter(Boolean).map(t => {
for(let i = 0; i < this.syntax.length; i++) for(let i = 0; i < this.syntax.length; i++)
@ -25,6 +27,6 @@ export default new class {
return `html+='${t}';`; return `html+='${t}';`;
}) })
.join`` + "}return html.trim().replace(/>[\\n\\r\\s]*?</g, '><')") .join`` + "}return html.trim().replace(/>[\\n\\r\\s]*?</g, '><')")
.bind(null, { forEach: this.forEach })(data); .bind(null, { forEach: this.forEach, snippets: this.snippets })(data);
} }
}; };