feat: cms integration

This commit is contained in:
Cory Dransfeldt 2024-06-01 07:16:49 -07:00
parent ff77bdaf36
commit d23243b177
No known key found for this signature in database
1050 changed files with 1032 additions and 27229 deletions

View file

@ -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()))
}

View file

@ -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"
}

View file

@ -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'
}

View file

@ -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 = '&amp;'
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('')}`
}
}