feat: cms integration
This commit is contained in:
parent
ff77bdaf36
commit
d23243b177
1050 changed files with 1032 additions and 27229 deletions
|
@ -1,5 +1,3 @@
|
|||
import authors from '../data/author-map.js'
|
||||
import tagAliases from '../data/tag-aliases.js'
|
||||
import { DateTime } from 'luxon'
|
||||
|
||||
export const searchIndex = (collection) => {
|
||||
|
@ -7,8 +5,9 @@ export const searchIndex = (collection) => {
|
|||
let id = 0
|
||||
const collectionData = collection.getAll()[0]
|
||||
const { data } = collectionData
|
||||
const { collections: { posts, links }, movies } = data
|
||||
const movieData = movies.movies.filter(movie => (movie.review?.length && movie.review?.length > 0 && movie.rating))
|
||||
const { posts, links, movies, books } = data
|
||||
const movieData = movies['movies'].filter(movie => (movie['review']?.length && movie['review']?.length > 0 && movie['rating']))
|
||||
const bookData = books.filter(book => (book['review']?.length && book['review']?.length > 0 && book['rating']))
|
||||
const addItemToIndex = (items, icon, getUrl, getTitle, getTags) => {
|
||||
if (items) {
|
||||
items.forEach((item) => {
|
||||
|
@ -23,9 +22,10 @@ export const searchIndex = (collection) => {
|
|||
}
|
||||
}
|
||||
|
||||
addItemToIndex(posts, '📝', item => item.url.includes('http') ? item.url : `https://coryd.dev${item.url}`, item => item.data.title, item => item.data.tags.filter(tag => tag !== 'posts'))
|
||||
addItemToIndex(links, '🔗', item => item.data.link, item => item.data.title, item => item.data.tags)
|
||||
if (movieData) addItemToIndex(movieData, '🎥', item => item.url, item => `${item.title} (${item.rating})`)
|
||||
addItemToIndex(posts, '📝', item => item['url'], item => item['title'], item => item['tags'])
|
||||
addItemToIndex(links, '🔗', item => item['link'], item => item['title'], item => item['tags'])
|
||||
if (movieData) addItemToIndex(movieData, '🎥', item => item['url'], item => `${item['title']} (${item['rating']})`, item => item['tags'])
|
||||
if (bookData) addItemToIndex(bookData, '📖', item => item['url'], item => `${item['title']} (${item['rating']})`, item => item['tags'])
|
||||
|
||||
return searchIndex
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ export const allContent = (collection) => {
|
|||
const collectionData = collection.getAll()[0]
|
||||
const { data } = collectionData
|
||||
const {
|
||||
collections: { posts, links },
|
||||
posts,
|
||||
links,
|
||||
books,
|
||||
movies: { movies }
|
||||
} = data
|
||||
|
@ -47,92 +48,30 @@ export const allContent = (collection) => {
|
|||
if (!parsedDate.isValid) parsedDate = DateTime.fromFormat(date, 'dd-MM-yyyy')
|
||||
return parsedDate.isValid ? parsedDate.toISO() : null
|
||||
}
|
||||
const authorLookup = (url) => {
|
||||
if (!url) return null
|
||||
const urlObject = new URL(url)
|
||||
const baseUrl = urlObject.origin
|
||||
return authors?.[baseUrl] || null
|
||||
}
|
||||
const addContent = (items, icon, getTitle, getDate) => {
|
||||
if (items) {
|
||||
items.forEach(item => {
|
||||
const author = authorLookup(item.data?.link)
|
||||
const content = {
|
||||
url: item.url?.includes('http') ? item.url : `https://coryd.dev${item.url}`,
|
||||
title: `${icon}: ${getTitle(item)}${author ? ' via ' + author : ''}`
|
||||
url: `https://coryd.dev${item['url']}`,
|
||||
title: `${icon}: ${getTitle(item)}${item?.['authors']?.['name'] ? ' via ' + item['authors']['name'] : ''}`
|
||||
}
|
||||
if (item.data?.link) content.url = item.data?.link
|
||||
if (item.data?.description) content.description = `${item.data.description}<br/><br/>`
|
||||
if (item?.description) content.description = `${item.description}<br/><br/>`
|
||||
if (item?.['link']) content['url'] = item?.['link']
|
||||
if (item?.['description']) content['description'] = `${item['description']}<br/><br/>`
|
||||
const date = getDate ? parseDate(getDate(item)) : null
|
||||
if (date) content.date = date
|
||||
if (date) content['date'] = date
|
||||
aggregateContent.push(content)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
addContent(posts, '📝', item => item.data.title, item => item.data.date)
|
||||
addContent(links, '🔗', item => item.data.title, item => item.data.date)
|
||||
addContent(books.filter(book => book.status === 'finished'), '📖', item => `${item.title}${item.rating ? ' (' + item.rating + ')' : ''}`, item => item.date)
|
||||
addContent(movies, '🎥', item => `${item.title}${item.rating ? ' (' + item.rating + ')' : ''}`, item => item.lastWatched)
|
||||
addContent(posts, '📝', item => item['title'], item => item['date'])
|
||||
addContent(links, '🔗', item => item['title'], item => item['date'])
|
||||
addContent(books.filter(book => book['status'] === 'finished'), '📖', item => `${item['title']}${item['rating'] ? ' (' + item['rating'] + ')' : ''}`, item => item['date'])
|
||||
addContent(movies, '🎥', item => `${item['title']}${item['rating'] ? ' (' + item['rating'] + ')' : ''}`, item => item['lastWatched'])
|
||||
|
||||
return aggregateContent.sort((a, b) => {
|
||||
const dateA = a.date ? DateTime.fromISO(a.date) : DateTime.fromMillis(0)
|
||||
const dateB = b.date ? DateTime.fromISO(b.date) : DateTime.fromMillis(0)
|
||||
const dateA = a['date'] ? DateTime.fromISO(a['date']) : DateTime.fromMillis(0)
|
||||
const dateB = b['date'] ? DateTime.fromISO(b['date']) : DateTime.fromMillis(0)
|
||||
return dateB - dateA
|
||||
})
|
||||
}
|
||||
|
||||
export const tagList = (collection) => {
|
||||
const tagsSet = new Set()
|
||||
collection.getAll().forEach((item) => {
|
||||
if (!item.data.tags) return
|
||||
item.data.tags
|
||||
.filter((tag) => !['posts', 'all'].includes(tag))
|
||||
.forEach((tag) => tagsSet.add(tag))
|
||||
})
|
||||
return Array.from(tagsSet).sort()
|
||||
}
|
||||
|
||||
export const tagMap = (collection) => {
|
||||
const tags = {}
|
||||
const collectionData = collection.getAll()[0]
|
||||
const { data } = collectionData
|
||||
const { collections: { posts, links }, books } = data
|
||||
const processItems = (items, getUrl, getTags) => {
|
||||
if (items) {
|
||||
items.forEach((item) => {
|
||||
const url = getUrl(item)
|
||||
const tagString = [...new Set(getTags(item).map(tag => tagAliases[tag.toLowerCase()]))]
|
||||
.join(' ')
|
||||
.trim()
|
||||
.replace(/\s+/g, ' ')
|
||||
if (tagString) tags[url] = tagString
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
processItems(posts, item => item.url.includes('http') ? item.url : `https://coryd.dev${item.url}`, item => item.data.tags || [])
|
||||
processItems(links, item => item.data.link, item => item.data.tags || [])
|
||||
processItems(books, item => item.tags || [], item => item.tags || [])
|
||||
|
||||
return tags
|
||||
}
|
||||
|
||||
export const tagsSortedByCount = (collection) => {
|
||||
const tagStats = {}
|
||||
collection.getFilteredByGlob('src/posts/**/*.*').forEach((item) => {
|
||||
if (!item.data.tags) return
|
||||
item.data.tags
|
||||
.filter((tag) => !['posts', 'all', 'politics', 'net neutrality'].includes(tag))
|
||||
.forEach((tag) => {
|
||||
if (!tagStats[tag]) tagStats[tag] = 1
|
||||
if (tagStats[tag]) tagStats[tag] = tagStats[tag] + 1
|
||||
})
|
||||
})
|
||||
return Object.entries(tagStats).sort((a, b) => b[1] - a[1]).map(([key, value]) => `${key}`)
|
||||
}
|
||||
|
||||
export const links = (collection) => collection.getFilteredByGlob('src/links/**/*.*').reverse()
|
||||
|
||||
export const booksToRead = (collection) => collection.getAll()[0].data.books.filter(book => book.status === 'want to read').sort((a, b) => a['title'].toLowerCase().localeCompare(b['title'].toLowerCase()))
|
||||
}
|
|
@ -1,242 +0,0 @@
|
|||
export default {
|
||||
"https://www.todayintabs.com": "Today in Tabs",
|
||||
"https://keithjgrant.com": "Keith J. Grant",
|
||||
"https://mxb.dev": "Max Böck",
|
||||
"https://niclake.me": "Nic Lake",
|
||||
"https://www.anildash.com": "Anil Dash",
|
||||
"https://knowler.dev": "Nathan Knowler",
|
||||
"https://www.vox.com": "Vox",
|
||||
"https://rachsmith.com": "Rach Smith",
|
||||
"https://zicklepop.com": "zicklepop",
|
||||
"https://simonwillison.net": "Simon Willison",
|
||||
"https://futurism.com": "Futurism",
|
||||
"https://adamjones.me": "Adam Jones",
|
||||
"https://janmaarten.com": "Jan Maarten",
|
||||
"https://sheep.horse": "Andrew Stephens",
|
||||
"https://nautil.us": "Nautilus",
|
||||
"https://www.takahe.org.nz": "takahē magazine",
|
||||
"https://shkspr.mobi": "Terence Eden",
|
||||
"https://www.statsignificant.com": "Daniel Parris",
|
||||
"https://statsignificant.com": "Daniel Parris",
|
||||
"https://fy.blackhats.net.au": "Firstyear",
|
||||
"https://512pixels.net" : "Stephen Hackett",
|
||||
"https://bradfrost.com": "Brad Frost",
|
||||
"https://theverge.com": "The Verge",
|
||||
"https://www.theverge.com": "The Verge",
|
||||
"https://www.theguardian.com": "The Guardian",
|
||||
"https://www.newyorker.com": "The New Yorker",
|
||||
"https://ploum.net": "Ploum.net",
|
||||
"https://www.businessinsider.com": "Business Insier",
|
||||
"https://ergaster.org": "Thibault Martin",
|
||||
"https://www.oddbird.net": "OddBird",
|
||||
"https://chrishannah.me": "Chris Hannah",
|
||||
"https://robinrendle.com": "Robin Rendle",
|
||||
"https://www.nngroup.com": "Nielsen Norman Group",
|
||||
"https://www.vulture.com": "Vulture",
|
||||
"https://blog.danslimmon.com": "Dan Slimmon",
|
||||
"https://freddiedeboer.substack.com": "Freddie deBoer",
|
||||
"https://educatedguesswork.org": "Eric Rescorla",
|
||||
"https://www.theprivacywhisperer.com": "Luiza Jarovsky",
|
||||
"https://www.matuzo.at": "Manuel Matuzović",
|
||||
"https://theoutline.com": "The Outline",
|
||||
"https://esif.dev": "Educational Sensational Inspirational Foundational",
|
||||
"https://chriscoyier.net": "Chris Coyier",
|
||||
"https://everythingchanges.us": "Mandy Brown",
|
||||
"https://addyosmani.com": "Addy Osmani",
|
||||
"https://thehistoryoftheweb.com": "The History of the Web",
|
||||
"https://css-tricks.com": "CSS Tricks",
|
||||
"https://www.latimes.com": "The LA Times",
|
||||
"https://seldo.com": "There's no such thing as the fundamentals of web development | Seldo.com",
|
||||
"https://defector.com": "Defector",
|
||||
"https://heather-buchel.com": "Heather Buchel",
|
||||
"https://blog.thecodewhisperer.com": "J. B. Rainsberger",
|
||||
"https://thehardtimes.net": "Dan Rice",
|
||||
"https://www.invisibleoranges.com": "Invisible Oranges",
|
||||
"https://nazhamid.com": "Naz Hamid",
|
||||
"https://ethanmarcotte.com": "Ethan Marcotte",
|
||||
"https://blog.jim-nielsen.com": "Jim Nielsen",
|
||||
"https://lucybellwood.com": "Lucy Bellwood",
|
||||
"https://dev.to": "Dev.to Community",
|
||||
"https://karawynn.substack.com": "Karawynn Long",
|
||||
"https://leahreich.substack.com": "Leah Reich",
|
||||
"https://erinkissane.com": "Erin Kissane",
|
||||
"https://www.smashingmagazine.com": "Smashing Magazine",
|
||||
"https://rknight.me": "Robb Knight",
|
||||
"https://stephanango.com": "Steph Ango",
|
||||
"https://pxlnv.com": "Nick Heer",
|
||||
"https://jacobin.com": "Jacobin",
|
||||
"https://www.techdirt.com": "TechDirt",
|
||||
"https://www.zachleat.com": "Zach Leatherman",
|
||||
"https://derekkedziora.com": "Derek Kedziora",
|
||||
"https://www.afterbabel.com": "Freya India",
|
||||
"https://jenniferplusplus.com": "Jennifer Moore",
|
||||
"https://www.wired.com": "Wired",
|
||||
"https://blog.j11y.io": "James Padolsey",
|
||||
"https://www.hunker.com": "Hunker",
|
||||
"https://www.htmhell.dev": "HTMHell",
|
||||
"https://blakewatson.com": "blakewatson.com – omg.lol: an oasis on the internetImported Layers",
|
||||
"https://www.ursulakleguin.com": "Ursula K. Le Guin",
|
||||
"https://pepelsbey.dev": "Vadim Makeev",
|
||||
"https://slate.com": "Slate",
|
||||
"https://adrianroselli.com": "Adrian Roselli",
|
||||
"https://manuelmoreale.com": "Manu Moreale",
|
||||
"https://frontside.com": "Frontside",
|
||||
"https://xeiaso.net": "Xe Iaso",
|
||||
"https://locusmag.com": "Locus",
|
||||
"https://wheresyoured.at": "Ed Zitron",
|
||||
"https://jacobian.org": "Jacob Kaplan-Moss",
|
||||
"https://danmcquillan.org": "Dan Mcquillan",
|
||||
"https://gkeenan.co": "Keenan",
|
||||
"https://fsfe.org": "FSFE",
|
||||
"https://pdx.su": "Jeff Sandberg",
|
||||
"https://chrismcleod.dev": "Chris McLeod",
|
||||
"https://flamedfury.com": "fLaMEd",
|
||||
"https://www.rollingstone.com": "Rolling Stone",
|
||||
"https://multiline.co": "Multiline Comment",
|
||||
"https://thebaffler.com": "The Baffler",
|
||||
"https://www.mayank.co": "Mayank",
|
||||
"https://benmyers.dev": "Ben Myers",
|
||||
"https://infrequently.org": "Alex Russell",
|
||||
"https://12daysofweb.dev": "12 Days of Web",
|
||||
"https://www.scientificamerican.com": "Scientific American",
|
||||
"https://cdevroe.com": "Colin Devroe",
|
||||
"https://tomcritchlow.com": "Tom Critchlow",
|
||||
"https://deathtobullshit.com": "Death to Bullshit",
|
||||
"https://eftegarie.com": "Amin Eftegarie",
|
||||
"https://library.xandra.cc": "the library of alexandra",
|
||||
"https://notebook.wesleyac.com": "Wesley Aptekar-Cassels",
|
||||
"https://24ways.org": "24 ways",
|
||||
"https://www.daniel.pizza": "Daniël van der Winden",
|
||||
"https://www.thejaymo.net": "Jay Springett",
|
||||
"https://dariusforoux.com": "Darius Foroux",
|
||||
"https://briankoberlein.com": "Brian Koberlein",
|
||||
"https://benhoyt.com": "Ben Hoyt",
|
||||
"https://atthis.link": "Marc",
|
||||
"https://ar.al": "Aral Balkan",
|
||||
"https://maerk.xyz": "Mark",
|
||||
"https://newrepublic.com": "Gil Duran",
|
||||
"https://prospect.org": "David Dayen",
|
||||
"https://gilest.org": "Giles Turnbull",
|
||||
"https://www.jackcheng.com": "Jack Cheng",
|
||||
"https://fromjason.xyz": "Jason Velazquez",
|
||||
"https://www.fromjason.xyz": "JASON VELAZQUEZ",
|
||||
"https://meyerweb.com": "Eric A. Meyer",
|
||||
"https://citationneeded.news": "Molly White",
|
||||
"https://hypercritical.co": "John Siracusa",
|
||||
"https://thathtml.blog": "Jared White",
|
||||
"https://proton.me": "Proton",
|
||||
"https://blog.cassidoo.co": "Cassidy Williams",
|
||||
"https://www.cassey.dev": "Cassey Lottman",
|
||||
"https://doctorow.medium.com": "Cory Doctorow",
|
||||
"https://jaredwhite.com": "Jared White",
|
||||
"https://remotesynthesis.com": "Remote Synthesis",
|
||||
"https://inessential.com": "Brent Simmons",
|
||||
"https://read.engineerscodex.com": "Leonardo Creed",
|
||||
"https://waxy.org": "Andy Baio",
|
||||
"https://www.anildash.com": "Anil Dash",
|
||||
"https://macwright.com": "Tom MacWright",
|
||||
"http://maerk.xyz": "Mark",
|
||||
"https://www.spacebar.news": "the spacebar",
|
||||
"https://johan.hal.se": "Johan Halse",
|
||||
"https://joanwestenberg.com": "Joan Westenberg",
|
||||
"https://zachholman.com": "Zach Holman",
|
||||
"https://jakelazaroff.com": "Jake Lazaroff",
|
||||
"https://cloudfour.com": "Cloud Four",
|
||||
"https://joe-steel.com": "Joe Rosensteel",
|
||||
"https://aworkinglibrary.com": "Mandy Brown",
|
||||
"https://max.engineer": "Max Chernyak",
|
||||
"https://hamatti.org": "Juha-Matti Santala",
|
||||
"https://blog.carlana.net": "Carlana Johnson",
|
||||
"https://darkvisitors.com": "Dark Visitors",
|
||||
"https://gomakethings.com": "Chris Ferdinandi",
|
||||
"https://www.wheresyoured.at": "Ed Zitron",
|
||||
"https://httpster.io": "Sami",
|
||||
"https://www.tylerjfisher.com": "Tyler Fisher",
|
||||
"https://baldurbjarnason.com": "Baldur Bjarnason",
|
||||
"https://www.baldurbjarnason.com": "Baldur Bjarnason",
|
||||
"https://lmnt.me": "Louie Mantia",
|
||||
"https://www.lrb.co.uk": "London Review of Books",
|
||||
"https://piccalil.li": "Andy Bell",
|
||||
"https://robhorning.substack.com": "Rob Horning",
|
||||
"https://explodingcomma.com": "Exploding Comma",
|
||||
"https://mikegrindle.com": "Mike Grindle",
|
||||
"https://garden.mattstein.com": "Matt Stein",
|
||||
"https://notes.neatnik.net": "Adam Newbold",
|
||||
"https://frills.dev": "Frills",
|
||||
"https://iamfran.com": "Fran",
|
||||
"https://www.citationneeded.news": "Molly White",
|
||||
"https://www.musicbusinessworldwide.com": "Music Business Worldwide",
|
||||
"https://joshcollinsworth.com": "Josh Collinsworth",
|
||||
"https://collider.com": "Chase Hutchinson",
|
||||
"https://bastianallgeier.com": "Bastian Allgeier",
|
||||
"https://storyfair.net": "Sean Hinn",
|
||||
"https://nuejs.org": "Nue",
|
||||
"https://whitep4nth3r.com": "Salma Alam-Naylor",
|
||||
"https://www.garbageday.email": "Ryan Broderick",
|
||||
"https://lynnandtonic.com": "Lynn Fisher",
|
||||
"https://blog.lukaszwojcik.net": "Łukasz Wójcik",
|
||||
"https://ohhelloana.blog": "Ana Rodrigues",
|
||||
"https://tonsky.me": "Nikita Prokopov",
|
||||
"https://blog.chriszacharias.com": "Chris Zacharias",
|
||||
"https://www.stereogum.com": "Stereogum",
|
||||
"https://paulrobertlloyd.com": "Paul Robert Lloy",
|
||||
"https://www.ramijames.com": "Rami James",
|
||||
"https://connortumbleson.com": "Connor Tumbleson",
|
||||
"http://www.aaronsw.com": "Aaron Swartz",
|
||||
"https://tante.cc": "Jürgen Geuter",
|
||||
"https://www.404media.co": "T404 Media",
|
||||
"https://kevquirk.com": "Kev Quirk",
|
||||
"https://zacharylipez.ghost.io": "Zachary Lipez",
|
||||
"https://www.tbray.org": "Tim Bray",
|
||||
"https://alistapart.com": "A List Apart",
|
||||
"https://abookapart.com": "A Book ApartThe Wax and the Wane of the Web – ",
|
||||
"https://www.esquire.com": "Esquire",
|
||||
"https://anhvn.com": "Anh",
|
||||
"https://www.avclub.com": "The AV Club",
|
||||
"https://yatil.net": "Eric Eggert",
|
||||
"https://kyleshevlin.com": "Kyle Shevlin",
|
||||
"https://www.technologyreview.com": "MIT Technology Review",
|
||||
"https://www.alexhyett.com": "Alex Hyett",
|
||||
"https://nicolasgallagher.com": "Nicolas Gallagher",
|
||||
"https://mxstbr.com": "Max Stoiber",
|
||||
"https://disconnect.blog": "Paris Marx",
|
||||
"https://matthiasott.com": "Matthias Ott",
|
||||
"https://daught.me": "Nathaniel Daught",
|
||||
"https://www.vice.com": "Vice",
|
||||
"https://boehs.org": "Evan Boehs",
|
||||
"https://theinternet.review": "Jared White",
|
||||
"https://zeldman.com": "Jeffrey Zeldman",
|
||||
"https://gittings.studio": "Gittings Studio",
|
||||
"https://www.schneier.com": "Bruce Schneier",
|
||||
"https://adactio.com": "Jeremy Keith",
|
||||
"https://hidde.blog": "Hidde de Vries",
|
||||
"https://darthmall.net": "Evan Sheehan",
|
||||
"https://darnell.day": "Darnell Clayton",
|
||||
"https://chrisburnell.com": "Chris Burnell",
|
||||
"https://css-irl.info": "CSS { In Real Life }",
|
||||
"https://ishadeed.com": "Ahmad Shadeed",
|
||||
"https://theconversation.com": "Danielle Williams",
|
||||
"https://shellsharks.com": "Michael Sass",
|
||||
"https://www.independent.com": "Santa Barbara Independent",
|
||||
"https://lasso-security.webflow.io": "Lasso Security",
|
||||
"https://www.ellyloel.com": "Elly Loel",
|
||||
"https://www.thewrap.com": "Natalie Korach",
|
||||
"https://alan.norbauer.com": "Alan Norbauer",
|
||||
"https://tylersticka.com": "Tyler Sticka",
|
||||
"https://seirdy.one": "Rohan Kumar",
|
||||
"https://bored.horse": "Thord D. Hedengren",
|
||||
"https://underlap.org": "Glyn Normington",
|
||||
"https://theintercept.com": "The Intercept",
|
||||
"https://softwarecrisis.dev": "Baldur Bjarnason",
|
||||
"https://daverupert.com": "Dave Rupert",
|
||||
"https://www.aalto.fi": "Aalto University",
|
||||
"https://www.hollywoodreporter.com": "The Hollywood Reporter",
|
||||
"https://creativegood.com": "Creative Good",
|
||||
"https://scottwillsey.com": "Scott Willsey",
|
||||
"https://www.jeremiak.com": "Jeremia Kimelman",
|
||||
"https://bjhess.com": "Barry Hess",
|
||||
"https://www.sandofsky.com": "Benjamin Sandofsky",
|
||||
"https://www.noemamag.com": "Noema Magazine",
|
||||
"https://sixcolors.com" :"Six Colors",
|
||||
"https://www.sixcolors.com" :"Six Colors"
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
export default {
|
||||
'11ty': '#Eleventy',
|
||||
accessibility: '#Accessibility',
|
||||
ai: '#AI',
|
||||
backblaze: '#Backblaze',
|
||||
'black metal': '#BlackMetal',
|
||||
blogging: '#Blogging',
|
||||
books: '#Books',
|
||||
climate: '#Climate',
|
||||
crypto: '#Crypto',
|
||||
css: '#CSS',
|
||||
'death metal': '#DeathMetal',
|
||||
design: '#Design',
|
||||
development: '#WebDev',
|
||||
economics: '#Economics',
|
||||
eleventy: '#Eleventy',
|
||||
email: '#Email',
|
||||
emo: '#Emo',
|
||||
fastmail: '#Email',
|
||||
fiction: '#Fiction',
|
||||
gmail: '#Email',
|
||||
grindcore: '#Grindcore',
|
||||
health: '#Health',
|
||||
'indie web': '#IndieWeb #SmallWeb',
|
||||
ios: '#iOS #Apple',
|
||||
javascript: '#JavaScript',
|
||||
'last.fm': '#Music',
|
||||
journalism: '#Journalism',
|
||||
labor: '#Work',
|
||||
lastfm: '#Music',
|
||||
macos: '#macOS #Apple',
|
||||
mastodon: '#Mastodon',
|
||||
music: '#Music',
|
||||
musicbrainz: '#MusicBrainz',
|
||||
mystery: '#Mystery',
|
||||
netlify: '#Netlify',
|
||||
nonfiction: '#NonFiction',
|
||||
plex: '#Plex',
|
||||
politics: '#Politics',
|
||||
privacy: '#Privacy',
|
||||
productivity: '#Productivity',
|
||||
react: '#JavaScript',
|
||||
rss: '#RSS',
|
||||
shoegaze: '#Shoegaze',
|
||||
science: "Science",
|
||||
'science-fiction': '#SciFi',
|
||||
scifi: '#SciFi',
|
||||
slack: '#Slack',
|
||||
'social media': '#SocialMedia',
|
||||
sports: '#Sports',
|
||||
spotify: '#Music',
|
||||
supabase: '#Supabase',
|
||||
'surveillance capitalism': '#SurveillanceCapitalism',
|
||||
'tattoos': '#Tattoos',
|
||||
tech: '#Tech',
|
||||
television: '#TV',
|
||||
technology: '#Tech',
|
||||
thriller: '#Thriller',
|
||||
tv: '#TV',
|
||||
'web components': '#WebComponents'
|
||||
}
|
|
@ -2,10 +2,8 @@ import { DateTime } from 'luxon'
|
|||
import { URL } from 'url'
|
||||
import slugify from 'slugify'
|
||||
import sanitizeHtml from 'sanitize-html';
|
||||
import authors from '../data/author-map.js'
|
||||
import { shuffleArray, sanitizeMediaString } from '../utilities/index.js'
|
||||
|
||||
const utmPattern = /[?&](utm_[^&=]+=[^&#]*)/gi
|
||||
const BASE_URL = 'https://coryd.dev'
|
||||
|
||||
export default {
|
||||
|
@ -19,18 +17,7 @@ export default {
|
|||
const replacement = '&'
|
||||
return string.replace(pattern, replacement)
|
||||
},
|
||||
stripUtm: (string) => {
|
||||
if (!string) return
|
||||
return string.replace(utmPattern, '')
|
||||
},
|
||||
replaceQuotes: (string) => string.replace(/"/g, "'"),
|
||||
slugifyString: (str) => {
|
||||
return slugify(str, {
|
||||
replacement: '-',
|
||||
remove: /[#,&,+()$~%.'":*?<>{}]/g,
|
||||
lower: true,
|
||||
})
|
||||
},
|
||||
formatNumber: (number) => number.toLocaleString('en-US'),
|
||||
shuffleArray,
|
||||
|
||||
|
@ -39,56 +26,29 @@ export default {
|
|||
const normalizedPage = page.includes('.html') ? page.replace('.html', '/') : page
|
||||
return !!normalizedPage && normalizedPage.includes(category) && !/\d+/.test(normalizedPage);
|
||||
},
|
||||
isPost: (url) => {
|
||||
if (url.includes('post')) return true;
|
||||
return false
|
||||
},
|
||||
|
||||
// analytics
|
||||
getPopularPosts: (posts, analytics) => {
|
||||
return posts
|
||||
.filter((post) => {
|
||||
if (analytics.find((p) => p.url.includes(post.url))) return true
|
||||
if (analytics.find((p) => p.url.includes(slugify(post.title).toLowerCase()))) return true
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const visitors = (page) => analytics.filter((p) => p.url.includes(page.url)).pop().value
|
||||
const visitors = (page) => analytics.filter((p) => p.url.includes(slugify(page.title).toLowerCase())).pop().value
|
||||
return visitors(b) - visitors(a)
|
||||
})
|
||||
},
|
||||
tagLookup: (url, tagMap) => {
|
||||
if (!url) return
|
||||
if (url.includes('#artists')) return '#Music'
|
||||
if (url.includes('https://coryd.dev/books')) return '#Books #FinishedReading'
|
||||
if (url.includes('https://coryd.dev/watching')) return '#Movies #Watched'
|
||||
return tagMap[url] || ''
|
||||
},
|
||||
|
||||
// posts
|
||||
filterByPostType: (posts, postType) => {
|
||||
if (postType === 'featured') return shuffleArray(posts.filter(post => post.data.featured === true)).slice(0, 3)
|
||||
if (postType === 'featured') return shuffleArray(posts.filter(post => post.featured === true)).slice(0, 3)
|
||||
return posts.slice(0, 5)
|
||||
},
|
||||
truncateByWordCount: (text, wordCount) => {
|
||||
const words = sanitizeHtml(text, { allowedTags: ['']}).split(/\s+/);
|
||||
if (words.length > wordCount) return `<p>${words.slice(0, wordCount).join(' ').replace(/[^a-zA-Z0-9]+$/, '')}...</p>`
|
||||
return text
|
||||
},
|
||||
|
||||
// watching
|
||||
featuredWatching: (watching, count) => shuffleArray(watching.filter(watch => watch.favorite === true)).slice(0, count),
|
||||
|
||||
// authors
|
||||
authorLookup: (url) => {
|
||||
if (!url) return null
|
||||
const urlObject = new URL(url)
|
||||
const baseUrl = urlObject.origin
|
||||
return authors?.[baseUrl] || null
|
||||
},
|
||||
|
||||
// dates
|
||||
readableDate: (date) => {
|
||||
return DateTime.fromISO(date).toFormat('LLLL d, yyyy')
|
||||
},
|
||||
isoDateOnly: (date, separator) => {
|
||||
let d = new Date(date)
|
||||
let month = '' + (d.getMonth() + 1)
|
||||
|
@ -100,10 +60,6 @@ export default {
|
|||
|
||||
return [year, month, day].join(separator)
|
||||
},
|
||||
stringToDate: (string) => {
|
||||
if (!string) return
|
||||
return new Date(string)
|
||||
},
|
||||
oldPost: (date) => {
|
||||
return DateTime.now().diff(DateTime.fromJSDate(new Date(date)), 'years').years > 3;
|
||||
},
|
||||
|
@ -154,8 +110,8 @@ export default {
|
|||
const feedNote = '<hr/><p>This is a full text feed, but not all content can be rendered perfectly within the feed. If something looks off, feel free to <a href="https://coryd.dev">visit my site</a> for the original post.</p>'
|
||||
|
||||
// set the entry url
|
||||
if (entry.url.includes('http')) url = entry.url
|
||||
if (!entry.url.includes('http')) url = new URL(entry.url, BASE_URL).toString()
|
||||
if (entry.url?.includes('http')) url = entry.url
|
||||
if (!entry.url?.includes('http')) url = new URL(entry.url, BASE_URL).toString()
|
||||
if (entry?.data?.link) url = entry.data.link
|
||||
|
||||
// set the entry excerpt
|
||||
|
@ -270,21 +226,5 @@ export default {
|
|||
: `<a href="/music/artists/${sanitizeMediaString(dataSlice[dataSlice.length - 1]['name_string'])}-${sanitizeMediaString(dataSlice[dataSlice.length - 1]['country'].toLowerCase())}">${dataSlice[dataSlice.length - 1]['name_string']}</a>`
|
||||
|
||||
return `${allButLast} and ${last}`
|
||||
},
|
||||
|
||||
// tags
|
||||
filterTags: (tags) => tags.filter((tag) => tag.toLowerCase() !== 'posts'),
|
||||
formatTag: (string) => {
|
||||
const capitalizeFirstLetter = (string) => string.charAt(0).toUpperCase() + string.slice(1)
|
||||
const normalizedString = string.toLowerCase()
|
||||
if (
|
||||
normalizedString === 'ios' ||
|
||||
normalizedString === 'macos' ||
|
||||
normalizedString === 'css' ||
|
||||
normalizedString === 'rss' ||
|
||||
normalizedString === 'ai'
|
||||
) return `#${string}`
|
||||
if (!string.includes(' ')) return `#${capitalizeFirstLetter(string)}`
|
||||
return `#${string.split(' ').map(s => capitalizeFirstLetter(s)).join('')}`
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue