diff --git a/feeds.json b/feeds.json index f245163..b823df1 100644 --- a/feeds.json +++ b/feeds.json @@ -38,5 +38,9 @@ "author_name": "The HullCSS team", "github_username": "hullcss", "feed_uri": "https://hullcss.org/feed.xml" + { + "author_name": "Eirika Doe", + "github_username": "EirikaDoesntCode", + "feed_uri": "https://edcblog.netlify.app/feed/feed.xml" } ] diff --git a/src/bloggers.11tydata.js b/src/bloggers.11tydata.js new file mode 100644 index 0000000..55b1605 --- /dev/null +++ b/src/bloggers.11tydata.js @@ -0,0 +1,47 @@ +"use strict"; + +const path = require("path"); +const fs = require("fs"); + +const fetch_json = require("./lib/fetch_json.js"); +const shuffle = require("./lib/shuffle.js"); + +async function fetch_info(blogger) { + if(typeof blogger.github_username !== "string") return; + + const github_userdata = (await fetch_json(`https://api.github.com/users/${blogger.github_username}`)).body; + + if(typeof github_userdata.message === "string") { + console.error(github_userdata.message); + } + + blogger.bio = github_userdata.bio; + blogger.url_blog = github_userdata.blog; + blogger.url_github = github_userdata.html_url; + blogger.url_twitter = github_userdata.twitter_username === null ? null : `https://twitter.com/@${github_userdata.twitter_username.replace(/^@/, "")}`; + blogger.url_avatar = github_userdata.avatar_url; + + // If the link to the blog doesn't include a protocol, default to https. + // If this breaks your blog, then you should enable https to fix the issue. + // ALL Internet traffic should be encrypted. Your blog is not an exception. + if(blogger.url_blog.search(/^[a-zA-Z]+:\/\//) === -1) + blogger.url_blog = `https://${blogger.url_blog}`; + + if(typeof blogger.url_blog !== "string" || blogger.url_blog.length == 0) + blogger.url_blog = null; +} + +module.exports = async function() { + const feeds_data = JSON.parse(await fs.promises.readFile(path.resolve(__dirname, "../feeds.json"), "utf-8")); + await Promise.all(feeds_data.map(fetch_info)); + + shuffle(feeds_data); // Don't give any 1 person the advantage + + return { + layout: "main.njk", + title: "Bloggers", + tags: "navigable", + date: "2001-01-01", + bloggers: feeds_data + } +} \ No newline at end of file diff --git a/src/bloggers.html b/src/bloggers.html new file mode 100644 index 0000000..2f03c17 --- /dev/null +++ b/src/bloggers.html @@ -0,0 +1,27 @@ +

Check out these cool people who are featured here on hullblogs.com!

+ +
+ {% for blogger in bloggers %} +
+ {{ blogger.author_name | htmlentities }} +
+ {{ blogger.author_name | htmlentities }} + + {% if blogger.url_blog %} + {{ blogger.author_name | htmlentities }}'s blog + {% endif %} + + {{ blogger.author_name | htmlentities }}'s blog feed + + + {{ blogger.author_name | htmlentities }}'s GitHub account + + {% if blogger.url_twitter %} + {{ blogger.author_name | htmlentities }}'s GitHub account + {% endif %} + + {{ blogger.bio }} +
+
+ {% endfor %} +
\ No newline at end of file diff --git a/src/css/theme.css b/src/css/theme.css index 040d662..3db8aec 100644 --- a/src/css/theme.css +++ b/src/css/theme.css @@ -208,6 +208,28 @@ nav > span[aria-current] > a { text-decoration: none; } +.blogger { + display: flex; + flex-direction: row; + margin: 1.5em; +} +.blogger:nth-child(even) { + background: var(--shadow); +} +.blogger-info { + flex: 1; + display: flex; + flex-direction: column; + margin: 0 0.5em; + gap: 0.5em; +} +.blogger-icons { + display: flex; + flex-direction: row; + gap: 0.5em; +} +.blogger-bio { flex: 1; } + footer { padding-bottom: 3em; grid-area: footer; @@ -290,6 +312,7 @@ input[type=text], input[type=number], textarea .medium-icon-abs { width: 1.25em; height: 1.25em; vertical-align: middle; } .large-icon { max-width: 1.5em; max-height: 1.5em; vertical-align: middle; } .tiny-image { max-width: 5em; max-height: 5em; } +.kinda-tiny-image{ max-width: 7em; max-height: 7em; } .small-image { max-width: 10em; max-height: 10em; } .medium-image { max-width: 20em; max-height: 20em; } .large-image { max-width: 30em; max-height: 30em; } diff --git a/src/images/rss.svg b/src/images/rss.svg new file mode 100644 index 0000000..4f1c279 --- /dev/null +++ b/src/images/rss.svg @@ -0,0 +1 @@ + diff --git a/src/images/twitter.svg b/src/images/twitter.svg new file mode 100644 index 0000000..59c727f --- /dev/null +++ b/src/images/twitter.svg @@ -0,0 +1,65 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/lib/fetch_json.js b/src/lib/fetch_json.js new file mode 100644 index 0000000..aa075bc --- /dev/null +++ b/src/lib/fetch_json.js @@ -0,0 +1,23 @@ +const fs = require("fs"); +const path = require("path"); +const os = require("os"); + +const phin = require("phin"); + +async function fetch_json(url) { + let package = JSON.parse(await fs.promises.readFile( + path.join(path.dirname(path.dirname(__dirname)), "package.json"), "utf8" + )); + + return (await phin({ + url, + headers: { + "user-agent": `HullBlogsStaticBuilder/${package.version} (Node.js/${process.version}; ${os.platform()} ${os.arch()}) eleventy/${package.dependencies["@11ty/eleventy"].replace(/\^/, "")}` + }, + followRedirects: true, + parse: "json" + })); +} + + +module.exports = fetch_json; diff --git a/src/lib/shuffle.js b/src/lib/shuffle.js new file mode 100644 index 0000000..1395c65 --- /dev/null +++ b/src/lib/shuffle.js @@ -0,0 +1,22 @@ +"use strict"; + + +function shuffle(array) { + let currentIndex = array.length, randomIndex; + + // While there remain elements to shuffle. + while (currentIndex != 0) { + + // Pick a remaining element. + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex--; + + // And swap it with the current element. + [array[currentIndex], array[randomIndex]] = [ + array[randomIndex], array[currentIndex]]; + } + + return array; +} + +module.exports = shuffle; \ No newline at end of file