From a50785137a2605c617dc52a1cf410a7db483ee66 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gon=C3=A7alo=20Val=C3=A9rio?=
Date: Fri, 28 Jul 2023 19:10:22 +0100
Subject: [PATCH] add new example template
---
index.js | 33 +++++++++--
package-lock.json | 93 +++++++++++++++++-------------
package.json | 3 +-
templates/headlines.handlebars | 79 +++++++++++++++++++++++++
templates/headlines.precompiled.js | 61 ++++++++++++++++++++
5 files changed, 223 insertions(+), 46 deletions(-)
create mode 100644 templates/headlines.handlebars
create mode 100644 templates/headlines.precompiled.js
diff --git a/index.js b/index.js
index 929649f..2bee077 100644
--- a/index.js
+++ b/index.js
@@ -2,11 +2,27 @@ import Parser from 'rss-parser'
import { Feed } from 'feed'
import Handlebars from 'handlebars/runtime'
import template from './templates/default.precompiled'
+import * as striptags from 'striptags'
-addEventListener('scheduled', event => {
- event.waitUntil(handleScheduled(event))
+/**
+ * Extra Handlerbars template helpers
+ */
+Handlebars.registerHelper('isRowElemN', function(index, rowItems, n, options) {
+ return index % rowItems == n ? options.fn(this) : options.inverse(this)
})
+/**
+ * Handle CRON jobs
+ * Where information is gathered and HTML and RSS is generated.
+ */
+addEventListener('scheduled', event => {
+ event.waitUntil(handleScheduled())
+})
+
+/**
+ * Serve the existing generated elements.
+ * CACHE is used to speed up the operation.
+ */
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
@@ -55,10 +71,8 @@ async function handleRequest(request) {
* Fetch all source feeds and generate the aggregated content
*
* TODO implement a faster way to fetch several sources
- *
- * @param {*} event
*/
-async function handleScheduled(event) {
+async function handleScheduled() {
let feeds = FEEDS.split(',')
let content = []
let sources = []
@@ -167,6 +181,15 @@ function createFeed(items) {
function createHTML(items, sources) {
console.log(`[createHTML] building the HTML document`)
let template = Handlebars.templates['default']
+ let dateFormatter = new Intl.DateTimeFormat('pt-PT', { timeZone: 'UTC' })
+
+ for (let item of items) {
+ item.description = striptags(item.content).substring(0, 250) + '[...]'
+ item.formattedDate = item.pubDate
+ ? dateFormatter.format(new Date(item.pubDate))
+ : ''
+ }
+
return template({
items: items,
sources: sources,
diff --git a/package-lock.json b/package-lock.json
index 5ffbc7f..2c088e5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,8 @@
"dependencies": {
"feed": "^4.2.2",
"handlebars": "^4.7.7",
- "rss-parser": "^3.13.0"
+ "rss-parser": "^3.13.0",
+ "striptags": "3.2.0"
},
"devDependencies": {
"prettier": "^1.18.2",
@@ -31,9 +32,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-64": {
- "version": "1.20230518.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20230518.0.tgz",
- "integrity": "sha512-reApIf2/do6GjLlajU6LbRYh8gm/XcaRtzGbF8jo5IzyDSsdStmfNuvq7qssZXG92219Yp1kuTgR9+D1GGZGbg==",
+ "version": "1.20230717.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20230717.0.tgz",
+ "integrity": "sha512-NVwwAYEIJmXGnQRnrCig2i4XAYFwPPFD+324fvQGWqUyfvBXKDYF3Jkw92ZginwdojYU1W+2l2qP7t6JE9Sw0g==",
"cpu": [
"x64"
],
@@ -47,9 +48,9 @@
}
},
"node_modules/@cloudflare/workerd-darwin-arm64": {
- "version": "1.20230518.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20230518.0.tgz",
- "integrity": "sha512-1l+xdbmPddqb2YIHd1YJ3YG/Fl1nhayzcxfL30xfNS89zJn9Xn3JomM0XMD4mk0d5GruBP3q8BQZ1Uo4rRLF3A==",
+ "version": "1.20230717.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20230717.0.tgz",
+ "integrity": "sha512-toK0AadC35j0AiaXPYUq7yrAwPJR+5GLLXOXguHq5DHPqzzgD5pB9e4zlIKD+b09FAAEB6lO/k/eJSMYF/lfzA==",
"cpu": [
"arm64"
],
@@ -63,9 +64,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-64": {
- "version": "1.20230518.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20230518.0.tgz",
- "integrity": "sha512-/pfR+YBpMOPr2cAlwjtInil0hRZjD8KX9LqK9JkfkEiaBH8CYhnJQcOdNHZI+3OjcY09JnQtEVC5xC4nbW7Bvw==",
+ "version": "1.20230717.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20230717.0.tgz",
+ "integrity": "sha512-nxpfVzMkNLNa4hOvZ+Y7JHY13UkRf7or5tcQCRtfJ5sEhtCVGdfsOosQGnzw9G+045JUk0EKEY+gqNPRnt5u2w==",
"cpu": [
"x64"
],
@@ -79,9 +80,9 @@
}
},
"node_modules/@cloudflare/workerd-linux-arm64": {
- "version": "1.20230518.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20230518.0.tgz",
- "integrity": "sha512-q3HQvn3J4uEkE0cfDAGG8zqzSZrD47cavB/Tzv4mNutqwg6B4wL3ifjtGeB55tnP2K2KL0GVmX4tObcvpUF4BA==",
+ "version": "1.20230717.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20230717.0.tgz",
+ "integrity": "sha512-jWVSJmOP0bMJ23xNONqP5x6TEDS9h/4nr0d0gULMpkfh6W9qNZNLpF8urNanXOqTM9p6rX55aBvzXsHs8Jctqw==",
"cpu": [
"arm64"
],
@@ -95,9 +96,9 @@
}
},
"node_modules/@cloudflare/workerd-windows-64": {
- "version": "1.20230518.0",
- "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20230518.0.tgz",
- "integrity": "sha512-vNEHKS5gKKduNOBYtQjcBopAmFT1iScuPWMZa2nJboSjOB9I/5oiVsUpSyk5Y2ARyrohXNz0y8D7p87YzTASWw==",
+ "version": "1.20230717.0",
+ "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20230717.0.tgz",
+ "integrity": "sha512-y9Ys8j22LMHaMdy31OyaV7Qz1Xca8MhzpBlpX4Ay6saECXYP1DZHHwtcW8pBqBU2zyGfEkErBQhyH130SSHFJg==",
"cpu": [
"x64"
],
@@ -717,9 +718,9 @@
"dev": true
},
"node_modules/acorn": {
- "version": "8.9.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz",
- "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==",
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -969,9 +970,9 @@
]
},
"node_modules/better-sqlite3": {
- "version": "8.4.0",
- "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.4.0.tgz",
- "integrity": "sha512-NmsNW1CQvqMszu/CFAJ3pLct6NEFlNfuGM6vw72KHkjOD1UDnL96XNN1BMQc1hiHo8vE2GbOWQYIpZ+YM5wrZw==",
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.5.0.tgz",
+ "integrity": "sha512-vbPcv/Hx5WYdyNg/NbcfyaBZyv9s/NVbxb7yCeC5Bq1pVocNxeL2tZmSu3Rlm4IEOTjYdGyzWQgyx0OSdORBzw==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -1762,9 +1763,9 @@
}
},
"node_modules/detect-libc": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
- "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
+ "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
"dev": true,
"engines": {
"node": ">=8"
@@ -3491,9 +3492,9 @@
}
},
"node_modules/miniflare": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.0.2.tgz",
- "integrity": "sha512-tSwmK+JPwHsV2KR7/dSZFGtTF/2M30OShjPDY7e5lAxyGE8SkHqXn/ckjg2TVltc9B8rXCSffMnCfYW1pH7R4A==",
+ "version": "3.20230717.0",
+ "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20230717.0.tgz",
+ "integrity": "sha512-S1L3QKPEHAf7n+66b/JpWdsIusz/tlgHRnNcDztz0PfeDkWlfNPxDzrnMqv/cHm9MjzXqhz2XqFkWqZSfZJk5Q==",
"dev": true,
"dependencies": {
"acorn": "^8.8.0",
@@ -3504,10 +3505,11 @@
"glob-to-regexp": "^0.4.1",
"http-cache-semantics": "^4.1.0",
"kleur": "^4.1.5",
+ "set-cookie-parser": "^2.6.0",
"source-map-support": "0.5.21",
"stoppable": "^1.1.0",
"undici": "^5.13.0",
- "workerd": "^1.20230512.0",
+ "workerd": "1.20230717.0",
"ws": "^8.11.0",
"youch": "^3.2.2",
"zod": "^3.20.6"
@@ -4614,9 +4616,9 @@
}
},
"node_modules/semver": {
- "version": "7.5.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
- "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -4637,6 +4639,12 @@
"randombytes": "^2.1.0"
}
},
+ "node_modules/set-cookie-parser": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz",
+ "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==",
+ "dev": true
+ },
"node_modules/set-value": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
@@ -5296,6 +5304,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/striptags": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/striptags/-/striptags-3.2.0.tgz",
+ "integrity": "sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw=="
+ },
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -6183,9 +6196,9 @@
}
},
"node_modules/workerd": {
- "version": "1.20230518.0",
- "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20230518.0.tgz",
- "integrity": "sha512-VNmK0zoNZXrwEEx77O/oQDVUzzyDjf5kKKK8bty+FmKCd5EQJCpqi8NlRKWLGMyyYrKm86MFz0kAsreTEs7HHA==",
+ "version": "1.20230717.0",
+ "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20230717.0.tgz",
+ "integrity": "sha512-MTKF2u3pfqfpGlyaYe9BfZm8IoUwhQNe2vMWECYtv6Z8cGPJujVxcRe27ZT4l/G5lRijnnVeP3Ns3mMS9fjMsw==",
"dev": true,
"hasInstallScript": true,
"bin": {
@@ -6195,11 +6208,11 @@
"node": ">=16"
},
"optionalDependencies": {
- "@cloudflare/workerd-darwin-64": "1.20230518.0",
- "@cloudflare/workerd-darwin-arm64": "1.20230518.0",
- "@cloudflare/workerd-linux-64": "1.20230518.0",
- "@cloudflare/workerd-linux-arm64": "1.20230518.0",
- "@cloudflare/workerd-windows-64": "1.20230518.0"
+ "@cloudflare/workerd-darwin-64": "1.20230717.0",
+ "@cloudflare/workerd-darwin-arm64": "1.20230717.0",
+ "@cloudflare/workerd-linux-64": "1.20230717.0",
+ "@cloudflare/workerd-linux-arm64": "1.20230717.0",
+ "@cloudflare/workerd-windows-64": "1.20230717.0"
}
},
"node_modules/wrangler": {
diff --git a/package.json b/package.json
index 30576b9..1efbe32 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"dependencies": {
"feed": "^4.2.2",
"handlebars": "^4.7.7",
- "rss-parser": "^3.13.0"
+ "rss-parser": "^3.13.0",
+ "striptags": "3.2.0"
}
}
diff --git a/templates/headlines.handlebars b/templates/headlines.handlebars
new file mode 100644
index 0000000..b997b9a
--- /dev/null
+++ b/templates/headlines.handlebars
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+ {{page_title}}
+
+
+ {{!-- --}}
+
+
+
+
+
+
+
+
+
+ {{page_title}}
+ {{page_description}}
+
+
+
+ {{#each items}}
+ {{#isRowElemN @index 4 0 }}
+
+ {{/isRowElemN}}
+
+
+ {{title}}
+ {{formattedDate}}
+
+
+ {{{description}}}
+
+
+ More
+
+
+ {{#isRowElemN @index 4 3}}
+
+ {{/isRowElemN}}
+ {{/each}}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/headlines.precompiled.js b/templates/headlines.precompiled.js
new file mode 100644
index 0000000..da7a549
--- /dev/null
+++ b/templates/headlines.precompiled.js
@@ -0,0 +1,61 @@
+var Handlebars = require("handlebars/runtime"); var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
+templates['headlines'] = template({"1":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+ if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+ return parent[propertyName];
+ }
+ return undefined
+ };
+
+ return ((stack1 = (lookupProperty(helpers,"isRowElemN")||(depth0 && lookupProperty(depth0,"isRowElemN"))||alias2).call(alias1,(data && lookupProperty(data,"index")),4,0,{"name":"isRowElemN","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":35,"column":8},"end":{"line":37,"column":23}}})) != null ? stack1 : "")
+ + " \n \n "
+ + alias4(((helper = (helper = lookupProperty(helpers,"title") || (depth0 != null ? lookupProperty(depth0,"title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"title","hash":{},"data":data,"loc":{"start":{"line":40,"column":18},"end":{"line":40,"column":27}}}) : helper)))
+ + "\n "
+ + alias4(((helper = (helper = lookupProperty(helpers,"formattedDate") || (depth0 != null ? lookupProperty(depth0,"formattedDate") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"formattedDate","hash":{},"data":data,"loc":{"start":{"line":41,"column":21},"end":{"line":41,"column":38}}}) : helper)))
+ + "\n
\n \n "
+ + ((stack1 = ((helper = (helper = lookupProperty(helpers,"description") || (depth0 != null ? lookupProperty(depth0,"description") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"description","hash":{},"data":data,"loc":{"start":{"line":44,"column":14},"end":{"line":44,"column":31}}}) : helper))) != null ? stack1 : "")
+ + "\n
\n \n More\n
\n \n"
+ + ((stack1 = (lookupProperty(helpers,"isRowElemN")||(depth0 && lookupProperty(depth0,"isRowElemN"))||alias2).call(alias1,(data && lookupProperty(data,"index")),4,3,{"name":"isRowElemN","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":50,"column":8},"end":{"line":52,"column":23}}})) != null ? stack1 : "");
+},"2":function(container,depth0,helpers,partials,data) {
+ return " \n";
+},"4":function(container,depth0,helpers,partials,data) {
+ return "
\n";
+},"6":function(container,depth0,helpers,partials,data) {
+ var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+ if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+ return parent[propertyName];
+ }
+ return undefined
+ };
+
+ return " "
+ + alias4(((helper = (helper = lookupProperty(helpers,"name") || (depth0 != null ? lookupProperty(depth0,"name") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data,"loc":{"start":{"line":72,"column":37},"end":{"line":72,"column":45}}}) : helper)))
+ + "\n";
+},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
+ if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+ return parent[propertyName];
+ }
+ return undefined
+ };
+
+ return "\n\n \n \n \n \n "
+ + alias4(((helper = (helper = lookupProperty(helpers,"page_title") || (depth0 != null ? lookupProperty(depth0,"page_title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_title","hash":{},"data":data,"loc":{"start":{"line":7,"column":11},"end":{"line":7,"column":25}}}) : helper)))
+ + "\n \n \n \n \n \n \n \n \n \n
\n \n "
+ + alias4(((helper = (helper = lookupProperty(helpers,"page_title") || (depth0 != null ? lookupProperty(depth0,"page_title") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_title","hash":{},"data":data,"loc":{"start":{"line":29,"column":16},"end":{"line":29,"column":30}}}) : helper)))
+ + "
\n "
+ + alias4(((helper = (helper = lookupProperty(helpers,"page_description") || (depth0 != null ? lookupProperty(depth0,"page_description") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"page_description","hash":{},"data":data,"loc":{"start":{"line":30,"column":16},"end":{"line":30,"column":36}}}) : helper)))
+ + "
\n \n
\n
\n"
+ + ((stack1 = lookupProperty(helpers,"each").call(alias1,(depth0 != null ? lookupProperty(depth0,"items") : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":34,"column":6},"end":{"line":53,"column":15}}})) != null ? stack1 : "")
+ + " \n \n \n \n";
+},"useData":true});