Implement page structure for blog
This commit is contained in:
15
src/_includes/blog.pug
Normal file
15
src/_includes/blog.pug
Normal file
@@ -0,0 +1,15 @@
|
||||
extends ./obsidian
|
||||
|
||||
block content
|
||||
.container#top
|
||||
.inner
|
||||
section#blog-header
|
||||
h1 Garrett's Blog
|
||||
p.button-links
|
||||
a.button(href='/blog') Home
|
||||
a.button(href='/blog/archive') Archive
|
||||
a.button(href='/blog/tags') Tags
|
||||
a.button(href='/blog/feeds') Feeds
|
||||
|
||||
block blog_content
|
||||
.content-wrapper !{content}
|
||||
10
src/_includes/blog_post.pug
Normal file
10
src/_includes/blog_post.pug
Normal file
@@ -0,0 +1,10 @@
|
||||
extends ./blog
|
||||
|
||||
block blog_content
|
||||
h2 #{title}
|
||||
p by Garrett Mills on #{page.date.toISOString().split('T')[0]}
|
||||
.post-tags
|
||||
p.button-links
|
||||
each tag in blogtags
|
||||
a.button-small.secondary(href='/blog/tag/' + tag) ##{tag}
|
||||
.blog.content-wrapper !{content}
|
||||
@@ -213,10 +213,19 @@ blockquote {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
font-size: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.blog.content-wrapper img {
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
center {
|
||||
margin: 0 20px;
|
||||
color: var(--color-2);
|
||||
|
||||
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Bold.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Bold.woff2
Normal file
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-BoldItalic.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-BoldItalic.woff2
Normal file
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-ExtraBold.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-ExtraBold.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-ExtraLight.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-ExtraLight.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Italic.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Italic.woff2
Normal file
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Light.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Light.woff2
Normal file
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-LightItalic.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-LightItalic.woff2
Normal file
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Medium.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Medium.woff2
Normal file
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-MediumItalic.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-MediumItalic.woff2
Normal file
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Regular.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Regular.woff2
Normal file
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-SemiBold.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-SemiBold.woff2
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Thin.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-Thin.woff2
Normal file
Binary file not shown.
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-ThinItalic.woff2
Normal file
BIN
src/assets/font/jetbrains-mono/JetBrainsMono-ThinItalic.woff2
Normal file
Binary file not shown.
259
src/assets/rss_opml.xml
Normal file
259
src/assets/rss_opml.xml
Normal file
@@ -0,0 +1,259 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<opml version="2.0">
|
||||
<head>
|
||||
<title>NewsFlash OPML export</title>
|
||||
</head>
|
||||
<body>
|
||||
<outline text="Food" title="Food">
|
||||
<outline text="Just One Cookbook" type="rss" htmlUrl="https://www.justonecookbook.com/" title="Just One Cookbook" xmlUrl="https://www.justonecookbook.com/feed/" />
|
||||
<outline htmlUrl="https://www.mexicanplease.com/" title="Mexican Please" type="rss" text="Mexican Please" xmlUrl="https://www.mexicanplease.com/feed/" />
|
||||
<outline text="Homesick Texan" type="rss" xmlUrl="https://www.homesicktexan.com/feed/" htmlUrl="https://www.homesicktexan.com/" title="Homesick Texan" />
|
||||
<outline title="The Pasta Project" text="The Pasta Project" type="rss" htmlUrl="https://www.the-pasta-project.com/" xmlUrl="https://www.the-pasta-project.com/feed/" />
|
||||
<outline text="Sandwich Tribunal" htmlUrl="https://www.sandwichtribunal.com/" title="Sandwich Tribunal" xmlUrl="https://www.sandwichtribunal.com/feed/" type="rss" />
|
||||
</outline>
|
||||
<outline title="Misc Blogs" text="Misc Blogs">
|
||||
<outline text="The Untourists" htmlUrl="http://www.theuntourists.com/" xmlUrl="http://www.theuntourists.com/feed/" type="rss" title="The Untourists" />
|
||||
<outline xmlUrl="https://chrisglass.com/feed/" text="Chris Glass - Photos" type="rss" title="Chris Glass - Photos" htmlUrl="https://chrisglass.com/" />
|
||||
<outline type="rss" xmlUrl="https://chrisglass.com/links/feed/" title="Bookmarks – Chris Glass" text="Bookmarks – Chris Glass" htmlUrl="https://chrisglass.com/" />
|
||||
<outline htmlUrl="https://onefoottsunami.com/" xmlUrl="https://onefoottsunami.com/feed/atom/" type="rss" title="One Foot Tsunami" text="One Foot Tsunami" />
|
||||
<outline xmlUrl="https://kenthendricks.com/feed/" type="rss" text="Kent Hendricks" title="Kent Hendricks" htmlUrl="https://kenthendricks.com/" />
|
||||
<outline type="rss" xmlUrl="https://www.filfre.net/feed/" text="The Digital Antiquarian" htmlUrl="https://www.filfre.net/" title="The Digital Antiquarian" />
|
||||
<outline type="rss" title="Craig Mod — Writer + Photographer" xmlUrl="https://craigmod.com/index.xml" text="Craig Mod — Writer + Photographer" htmlUrl="https://craigmod.com/" />
|
||||
<outline htmlUrl="https://www.nomadicnotes.com/" type="rss" text="Nomadic Notes" xmlUrl="https://www.nomadicnotes.com/feed/" title="Nomadic Notes" />
|
||||
<outline htmlUrl="https://www.timemachinego.com/linkmachinego" title="LinkMachineGo" text="LinkMachineGo" type="rss" xmlUrl="https://www.timemachinego.com/linkmachinego/feed/" />
|
||||
<outline xmlUrl="https://goodstuff.simonpanrucker.com/index.xml" title="Good Stuff" text="Good Stuff" type="rss" htmlUrl="https://goodstuff.simonpanrucker.com/" />
|
||||
<outline type="rss" xmlUrl="https://erinkissane.com/feed.rss" htmlUrl="https://erinkissane.com/" title=" Erin Kissane's small internet website" text=" Erin Kissane's small internet website" />
|
||||
<outline text="kottke.org" xmlUrl="https://feeds.kottke.org/main" type="rss" htmlUrl="https://kottke.org/" title="kottke.org" />
|
||||
<outline xmlUrl="https://nazhamid.com/links.xml" title="Links by Naz Hamid" htmlUrl="https://nazhamid.com/links" text="Links by Naz Hamid" type="rss" />
|
||||
<outline htmlUrl="https://www.citationneeded.news/" type="rss" text="Citation Needed by Molly White" xmlUrl="https://www.citationneeded.news/rss/" title="Citation Needed by Molly White" />
|
||||
<outline text="The Noah Kalina Newsletter" type="rss" htmlUrl="https://noahkalina.substack.com/" title="The Noah Kalina Newsletter" xmlUrl="https://noahkalina.substack.com/feed" />
|
||||
<outline type="rss" htmlUrl="https://tracydurnell.com/" text="Tracy Durnell's Mind Garden" xmlUrl="https://tracydurnell.com/feed/" title="Tracy Durnell's Mind Garden" />
|
||||
<outline xmlUrl="https://davidallengreen.com/feed/" type="rss" htmlUrl="https://davidallengreen.com/" title="The Law and Policy Blog" text="The Law and Policy Blog" />
|
||||
<outline text="Ten minutes past deadline" xmlUrl="https://tenminutespastdeadline.wordpress.com/feed/" type="rss" title="Ten minutes past deadline" htmlUrl="https://tenminutespastdeadline.wordpress.com/" />
|
||||
<outline xmlUrl="https://bigthink.com/feed/strange-maps" text="Strange Maps - Big Think" htmlUrl="https://bigthink.com//feed/strange-maps" type="rss" title="Strange Maps - Big Think" />
|
||||
<outline type="rss" htmlUrl="https://nazhamid.com/" title="Naz Hamid" text="Naz Hamid" xmlUrl="https://nazhamid.com/feed.xml" />
|
||||
<outline title="www.marginalia.nu on marginalia.nu" text="www.marginalia.nu on marginalia.nu" type="rss" xmlUrl="https://www.marginalia.nu/index.xml" htmlUrl="https://www.marginalia.nu/" />
|
||||
<outline xmlUrl="https://dynomight.net/feed.xml" text="DYNOMIGHT" type="rss" htmlUrl="https://dynomight.net/" title="DYNOMIGHT" />
|
||||
<outline title="ooh.directory recently added blogs" xmlUrl="https://ooh.directory/feeds/recently-added.xml" type="rss" text="ooh.directory recently added blogs" htmlUrl="https://ooh.directory/" />
|
||||
<outline text="Pluralistic: Daily links from Cory Doctorow" type="rss" xmlUrl="https://pluralistic.net/feed/" htmlUrl="https://pluralistic.net/" title="Pluralistic: Daily links from Cory Doctorow" />
|
||||
<outline text="1000 Awesome Things" title="1000 Awesome Things" htmlUrl="https://1000awesomethings.com/" xmlUrl="https://1000awesomethings.com/feed/" type="rss" />
|
||||
<outline text="Azimuth" title="Azimuth" xmlUrl="https://johncarlosbaez.wordpress.com/feed/" type="rss" htmlUrl="https://johncarlosbaez.wordpress.com/" />
|
||||
<outline text="Tegowerk" type="rss" htmlUrl="https://tegowerk.eu/" title="Tegowerk" xmlUrl="https://tegowerk.eu/index.xml" />
|
||||
<outline type="rss" title="A Citizen's Guide to Indiana" xmlUrl="https://www.masson.us/blog/feed/" text="A Citizen's Guide to Indiana" htmlUrl="https://www.masson.us/blog/" />
|
||||
<outline type="rss" xmlUrl="https://worriedaf.blogspot.com/feeds/posts/default" text="The Chronicles of a Girl Worried AF" htmlUrl="https://worriedaf.blogspot.com/" title="The Chronicles of a Girl Worried AF" />
|
||||
<outline xmlUrl="https://writing.kemitchell.com/feed.xml" type="rss" title="/dev/lawyer" text="/dev/lawyer" htmlUrl="https://writing.kemitchell.com/" />
|
||||
</outline>
|
||||
<outline title="Books & Reading" text="Books & Reading">
|
||||
<outline text="The Neglected Books Page" type="rss" title="The Neglected Books Page" htmlUrl="https://neglectedbooks.com/" xmlUrl="https://neglectedbooks.com/?feed=rss2" />
|
||||
<outline type="rss" xmlUrl="https://theuntranslated.wordpress.com/feed/" htmlUrl="https://theuntranslated.wordpress.com/" title="The Untranslated" text="The Untranslated" />
|
||||
<outline type="rss" title="The Dusty Bookcase" htmlUrl="https://brianbusby.blogspot.com/" text="The Dusty Bookcase" xmlUrl="https://brianbusby.blogspot.com/feeds/posts/default" />
|
||||
</outline>
|
||||
<outline text="Design" title="Design">
|
||||
<outline type="rss" htmlUrl="https://journal.buzzusborne.com/" xmlUrl="https://journal.buzzusborne.com/rss" text="Design Inspiration" title="Design Inspiration" />
|
||||
<outline text="BLAG (Better Letters Magazine)" xmlUrl="https://bl.ag/rss/" htmlUrl="https://bl.ag/" title="BLAG (Better Letters Magazine)" type="rss" />
|
||||
<outline text="Latest Dispatches - Scott Boms" title="Latest Dispatches - Scott Boms" htmlUrl="https://scottboms.com/documenting" type="rss" xmlUrl="https://scottboms.com/rss" />
|
||||
<outline htmlUrl="https://www.thisiscolossal.com/" xmlUrl="https://www.thisiscolossal.com/feed/" type="rss" title="Colossal" text="Colossal" />
|
||||
<outline htmlUrl="https://noisydecentgraphics.typepad.com/design/" text="Noisy Decent Graphics" type="rss" xmlUrl="https://feeds.feedburner.com/noisydecentgraphics" title="Noisy Decent Graphics" />
|
||||
<outline title="Graphic Journey Blog" xmlUrl="https://mikedempsey.typepad.com/graphic_journey_blog/atom.xml" text="Graphic Journey Blog" type="rss" htmlUrl="https://mikedempsey.typepad.com/graphic_journey_blog/" />
|
||||
</outline>
|
||||
<outline title="Games" text="Games">
|
||||
<outline htmlUrl="https://haikushane.com/" text="Project Work by Shane P." type="rss" title="Project Work by Shane P." xmlUrl="https://haikushane.com/feed/" />
|
||||
<outline xmlUrl="https://jrients.blogspot.com/feeds/posts/default" type="rss" title="Jeffs Gameblog" text="Jeffs Gameblog" htmlUrl="https://jrients.blogspot.com/" />
|
||||
<outline text="SPACE-BIFF!" htmlUrl="https://spacebiff.com/" xmlUrl="https://spacebiff.com/feed/" title="SPACE-BIFF!" type="rss" />
|
||||
<outline title="Peter Berthoud" xmlUrl="https://www.peterberthoud.co.uk/blog-feed.xml" text="Peter Berthoud" htmlUrl="https://www.peterberthoud.co.uk/" type="rss" />
|
||||
<outline text="Hipsters of the Coast" title="Hipsters of the Coast" type="rss" htmlUrl="https://www.hipstersofthecoast.com/" xmlUrl="https://www.hipstersofthecoast.com/feed/" />
|
||||
<outline htmlUrl="https://opinionatedgamers.com/" title="The Opinionated Gamers" text="The Opinionated Gamers" type="rss" xmlUrl="https://opinionatedgamers.com/feed/" />
|
||||
<outline type="rss" text="Sly Flourish" xmlUrl="https://slyflourish.com/index.xml" htmlUrl="https://slyflourish.com/" title="Sly Flourish" />
|
||||
<outline type="rss" xmlUrl="https://direbane.blogspot.com/feeds/posts/default" title="Direbane: An RPG Home Brewed Repository" htmlUrl="https://direbane.blogspot.com/" text="Direbane: An RPG Home Brewed Repository" />
|
||||
</outline>
|
||||
<outline text="Photography" title="Photography">
|
||||
<outline xmlUrl="https://www.postcard-past.com/rss/" type="rss" htmlUrl="https://www.postcard-past.com/" title="Postcard Past / Present Photo" text="Postcard Past / Present Photo" />
|
||||
<outline xmlUrl="https://paulclarke.com/feed/" title="Paul Clarke" text="Paul Clarke" type="rss" htmlUrl="https://paulclarke.com/" />
|
||||
<outline text="Bill Fortney" type="rss" xmlUrl="https://billfortney.com/?feed=rss2" title="Bill Fortney" htmlUrl="https://billfortney.com/" />
|
||||
<outline text="Fup Duck Photography" htmlUrl="https://fupduckphoto.wordpress.com/" title="Fup Duck Photography" xmlUrl="https://fupduckphoto.wordpress.com/feed/" type="rss" />
|
||||
<outline xmlUrl="https://randomwire.com/feed/" type="rss" htmlUrl="https://randomwire.com/" text="Randomwire" title="Randomwire" />
|
||||
<outline text="The Wandering Lensman" type="rss" xmlUrl="https://www.thewanderinglensman.com/feeds/posts/default" htmlUrl="https://www.thewanderinglensman.com/" title="The Wandering Lensman" />
|
||||
<outline xmlUrl="https://fiftyfootshadows.net/feed/" text="fiftyfootshadows.net" type="rss" title="fiftyfootshadows.net" htmlUrl="https://fiftyfootshadows.net/" />
|
||||
<outline text="A Life in Photography" htmlUrl="https://alifeinphotography.blogspot.com/" xmlUrl="https://alifeinphotography.blogspot.com/feeds/posts/default" title="A Life in Photography" type="rss" />
|
||||
<outline type="rss" title="Iconic Photos" xmlUrl="https://iconicphotos.wordpress.com/feed/" text="Iconic Photos" htmlUrl="https://iconicphotos.wordpress.com/" />
|
||||
<outline type="rss" text="Iconic Photos" title="Iconic Photos" htmlUrl="https://iconic-photos.com/" xmlUrl="https://iconic-photos.com/feed/" />
|
||||
<outline htmlUrl="https://www.outsidetheworld.com/" title="Outside the World dot com" text="Outside the World dot com" xmlUrl="https://www.outsidetheworld.com/feeds/posts/default" type="rss" />
|
||||
<outline type="rss" htmlUrl="https://thefamilymuseum.co.uk/" title="THE FAMILY MUSEUM" xmlUrl="https://thefamilymuseum.co.uk/feed/" text="THE FAMILY MUSEUM" />
|
||||
<outline text="Long Delays Possible" type="rss" title="Long Delays Possible" htmlUrl="https://www.longdelayspossible.com/" xmlUrl="https://www.longdelayspossible.com/feed/" />
|
||||
<outline htmlUrl="https://www.theatlantic.com/author/alan-taylor/" title="Alan Taylor | The Atlantic" xmlUrl="https://www.theatlantic.com/feed/author/alan-taylor/" text="Alan Taylor | The Atlantic" type="rss" />
|
||||
</outline>
|
||||
<outline title="Places" text="Places">
|
||||
<outline htmlUrl="https://nazhamid.com/newsletter/" text="Weightshifting by Naz Hamid and Jen Schuetz" xmlUrl="https://nazhamid.com/weightshifting.xml" type="rss" title="Weightshifting by Naz Hamid and Jen Schuetz" />
|
||||
<outline type="rss" xmlUrl="https://ephemeralnewyork.wordpress.com/feed/" htmlUrl="https://ephemeralnewyork.wordpress.com/" title="Ephemeral New York" text="Ephemeral New York" />
|
||||
</outline>
|
||||
<outline title="Urbanism" text="Urbanism">
|
||||
<outline xmlUrl="https://urbanhikeskc.com/feed/" text="Urban Hikes KC " type="rss" htmlUrl="https://urbanhikeskc.com/" title="Urban Hikes KC " />
|
||||
<outline xmlUrl="https://kevinklinkenberg.substack.com/feed" title="The Messy City | Kevin Linkenberg" type="rss" text="The Messy City | Kevin Linkenberg" htmlUrl="https://kevinklinkenberg.substack.com/" />
|
||||
<outline htmlUrl="https://www.strongtowns.org/journal/" title="Strong Towns Media" type="rss" xmlUrl="https://www.strongtowns.org/journal?format=rss" text="Strong Towns Media" />
|
||||
<outline htmlUrl="https://www.granolashotgun.com/" type="rss" title="Granola Shotgun" text="Granola Shotgun" xmlUrl="https://www.granolashotgun.com/granolashotguncom?format=rss" />
|
||||
<outline title="BICYCLE DUTCH" type="rss" text="BICYCLE DUTCH" xmlUrl="https://bicycledutch.wordpress.com/feed/" htmlUrl="https://bicycledutch.wordpress.com/" />
|
||||
<outline xmlUrl="https://cornersideyard.blogspot.com/feeds/posts/default" title="The Corner Side Yard" text="The Corner Side Yard" type="rss" htmlUrl="https://cornersideyard.blogspot.com/" />
|
||||
<outline type="rss" xmlUrl="https://petesaunders.substack.com/feed" title="The Corner Side Yard" text="The Corner Side Yard" htmlUrl="https://petesaunders.substack.com/" />
|
||||
<outline type="rss" htmlUrl="https://usa.streetsblog.org/" xmlUrl="https://usa.streetsblog.org/feed" text="Streetsblog USA" title="Streetsblog USA" />
|
||||
<outline xmlUrl="https://brucefnesmith.blogspot.com/feeds/posts/default" text="Holy Mountain: A Blog about Our Common Life" title="Holy Mountain: A Blog about Our Common Life" type="rss" htmlUrl="https://brucefnesmith.blogspot.com/" />
|
||||
</outline>
|
||||
<outline text="Garrett Mills" title="Garrett Mills">
|
||||
<outline xmlUrl="https://garrettmills.dev/food/rss2.xml" htmlUrl="https://garrettmills.dev/food" type="rss" text="Eating the World" title="Eating the World" />
|
||||
<outline htmlUrl="https://garrettmills.dev/feed/" type="rss" text="Garrett Mills - Posts & Updates" title="Garrett Mills - Posts & Updates" xmlUrl="https://garrettmills.dev/feed/rss.xml" />
|
||||
<outline text="Garrett's Blog" htmlUrl="https://garrettmills.dev/blog" xmlUrl="https://garrettmills.dev/blog/rss2.xml" type="rss" title="Garrett's Blog" />
|
||||
<outline htmlUrl="https://garrettmills.dev/links" text="Garrett's Bookmarks" type="rss" xmlUrl="https://garrettmills.dev/links/rss2.xml" title="Garrett's Bookmarks" />
|
||||
</outline>
|
||||
<outline title="Tech Blogs" text="Tech Blogs">
|
||||
<outline title="fabiensanglard.net" text="fabiensanglard.net" xmlUrl="https://fabiensanglard.net/rss.xml" htmlUrl="https://fabiensanglard.net/" type="rss" />
|
||||
<outline xmlUrl="https://www.anildash.com/feed.xml" text="Anil Dash" type="rss" htmlUrl="https://anildash.com/" title="Anil Dash" />
|
||||
<outline text="Daring Fireball" xmlUrl="https://daringfireball.net/feeds/main" title="Daring Fireball" type="rss" htmlUrl="https://daringfireball.net/" />
|
||||
<outline text="Dennis Schubert - Blog" xmlUrl="https://overengineer.dev/blog/feeds/all.xml" htmlUrl="https://overengineer.dev/" type="rss" title="Dennis Schubert - Blog" />
|
||||
<outline type="rss" xmlUrl="https://mattcool.tech/rss.xml" title="MattCool.tech" htmlUrl="https://mattcool.tech/" text="MattCool.tech" />
|
||||
<outline text="anderegg.ca" xmlUrl="https://anderegg.ca/feed.xml" type="rss" htmlUrl="https://anderegg.ca/" title="anderegg.ca" />
|
||||
<outline type="rss" text="DKB Blog" xmlUrl="https://dkb.blog/feed" title="DKB Blog" htmlUrl="https://dkb.blog/" />
|
||||
<outline htmlUrl="https://blog.acolyer.org/" text="the morning paper" title="the morning paper" xmlUrl="https://blog.acolyer.org/feed/" type="rss" />
|
||||
<outline type="rss" xmlUrl="https://drew.shoes/feed.xml" text="drew dot shoes" htmlUrl="https://drew.shoes/" title="drew dot shoes" />
|
||||
<outline type="rss" text="Jeff Geerling's Blog" xmlUrl="https://www.jeffgeerling.com/blog.xml" title="Jeff Geerling's Blog" htmlUrl="https://www.jeffgeerling.com/" />
|
||||
<outline htmlUrl="http://ignorethecode.net/" title="ignorethecode.net" type="rss" xmlUrl="http://feeds.feedburner.com/IgnoreTheCode" text="ignorethecode.net" />
|
||||
<outline xmlUrl="https://feed.ctrl.blog/latest.atom" type="rss" htmlUrl="https://www.ctrl.blog/" text="Ctrl blog" title="Ctrl blog" />
|
||||
<outline xmlUrl="https://webcurios.co.uk/feed/" htmlUrl="https://webcurios.co.uk/" text="webcurios" type="rss" title="webcurios" />
|
||||
<outline xmlUrl="https://solar.lowtechmagazine.com/index.xml" type="rss" title="LOW←TECH MAGAZINE English" text="LOW←TECH MAGAZINE English" htmlUrl="https://solar.lowtechmagazine.com/" />
|
||||
<outline xmlUrl="https://feedpress.me/512pixels" title="512 Pixels" htmlUrl="http://512pixels.net/" type="rss" text="512 Pixels" />
|
||||
</outline>
|
||||
<outline title="Misc Nerd Shit" text="Misc Nerd Shit">
|
||||
<outline htmlUrl="https://ciechanow.ski/" title="Bartosz Ciechanowski" text="Bartosz Ciechanowski" type="rss" xmlUrl="https://ciechanow.ski/atom.xml" />
|
||||
<outline xmlUrl="http://joe-steel.com/feed" type="rss" title="Unauthoritative Pronouncements" text="Unauthoritative Pronouncements" htmlUrl="https://joe-steel.com/" />
|
||||
<outline type="rss" title="Cool Tools" xmlUrl="https://feedpress.me/CoolTools" text="Cool Tools" htmlUrl="https://kk.org/cooltools" />
|
||||
<outline type="rss" title="Combinatorics and more" xmlUrl="https://gilkalai.wordpress.com/feed/" htmlUrl="https://gilkalai.wordpress.com/" text="Combinatorics and more" />
|
||||
</outline>
|
||||
<outline text="Industry & Culture" title="Industry & Culture">
|
||||
<outline text="Kevin Drum – Mother Jones" title="Kevin Drum – Mother Jones" type="rss" xmlUrl="https://www.motherjones.com/kevin-drum/feed/" htmlUrl="https://www.motherjones.com/" />
|
||||
<outline type="rss" title="Stratechery by Ben Thompson" text="Stratechery by Ben Thompson" xmlUrl="https://stratechery.com/feed/" htmlUrl="https://stratechery.com/" />
|
||||
</outline>
|
||||
<outline text="Web Comics" title="Web Comics">
|
||||
<outline htmlUrl="https://www.smbc-comics.com/" type="rss" text="Saturday Morning Breakfast Cereal" title="Saturday Morning Breakfast Cereal" xmlUrl="https://www.smbc-comics.com/comic/rss" />
|
||||
<outline title="Dimspire.me" htmlUrl="https://dimspire.me/" type="rss" text="Dimspire.me" xmlUrl="https://feedpress.me/dimspire.xml" />
|
||||
<outline text="CommitStrip" htmlUrl="https://www.commitstrip.com/" xmlUrl="https://www.commitstrip.com/en/feed/?" type="rss" title="CommitStrip" />
|
||||
<outline text="Bloom County" xmlUrl="https://www.comicsrss.com/rss/bloomcounty.rss" type="rss" title="Bloom County" htmlUrl="https://www.gocomics.com/bloomcounty" />
|
||||
<outline xmlUrl="https://xkcd.com/atom.xml" title="xkcd.com" text="xkcd.com" htmlUrl="https://xkcd.com/" type="rss" />
|
||||
<outline type="rss" title="PHD Comics" xmlUrl="https://phdcomics.com/gradfeed.php" text="PHD Comics" htmlUrl="http://www.phdcomics.com/" />
|
||||
</outline>
|
||||
<outline text="Space" title="Space">
|
||||
<outline htmlUrl="https://blogs.nasa.gov/" text="NASA Blogs" xmlUrl="https://blogs.nasa.gov/feed/" type="rss" title="NASA Blogs" />
|
||||
<outline htmlUrl="https://www.nasa.gov/image-of-the-day/" xmlUrl="https://www.nasa.gov/rss/dyn/lg_image_of_the_day.rss" type="rss" title="NASA Image of the Day" text="NASA Image of the Day" />
|
||||
<outline text="Nasa News Blog" title="Nasa News Blog" htmlUrl="https://nasa-newsblog.blogspot.com/" type="rss" xmlUrl="https://nasa-newsblog.blogspot.com/feeds/posts/default?alt=rss" />
|
||||
<outline text="NASA Mars Perseverance Rover: Mission Updates" title="NASA Mars Perseverance Rover: Mission Updates" htmlUrl="https://mars.nasa.gov/mars2020/mission/status/" xmlUrl="https://mars.nasa.gov/rss/api/?feed=blogs&category=mars2020&feedtype=rss" type="rss" />
|
||||
</outline>
|
||||
<outline title="News" text="News">
|
||||
<outline title="Mirror Indy" type="rss" xmlUrl="https://mirrorindy.org/feed/" htmlUrl="https://mirrorindy.org/" text="Mirror Indy" />
|
||||
<outline title="Indianapolis Monthly" htmlUrl="https://www.indianapolismonthly.com/" type="rss" xmlUrl="https://www.indianapolismonthly.com/feed/" text="Indianapolis Monthly" />
|
||||
<outline title="WFYI - Indianapolis - Local News" htmlUrl="https://www.wfyi.org/news/wfyi-news" text="WFYI - Indianapolis - Local News" type="rss" xmlUrl="https://www.wfyi.org/news/wfyi-news/rss" />
|
||||
<outline text="The Lawrence Times" type="rss" xmlUrl="https://lawrencekstimes.com/feed/" htmlUrl="https://lawrencekstimes.com/" title="The Lawrence Times" />
|
||||
<outline xmlUrl="https://www.wfyi.org/news/arts-and-culture/rss" title="WFYI - Indianapolis - Arts & Culture" text="WFYI - Indianapolis - Arts & Culture" htmlUrl="https://www.wfyi.org/news/arts-and-culture" type="rss" />
|
||||
<outline htmlUrl="https://www.nuvo.net/search/?f=rss&t=article&l=50&s=start_time&sd=desc" xmlUrl="https://www.nuvo.net/search/?f=rss&t=article&l=50&s=start_time&sd=desc" text="NUVO - Indianapolis" type="rss" title="NUVO - Indianapolis" />
|
||||
<outline title="Ars Technica - All content" xmlUrl="https://feeds.arstechnica.com/arstechnica/index/" type="rss" text="Ars Technica - All content" htmlUrl="https://arstechnica.com/" />
|
||||
</outline>
|
||||
<outline title="Dev Blogs" text="Dev Blogs">
|
||||
<outline title="Hackle's blog" type="rss" xmlUrl="https://www.hacklewayne.com/rss/index.xml" htmlUrl="https://hacklewayne.com/" text="Hackle's blog" />
|
||||
<outline title="Gunnar Wolf - Nice grey life" type="rss" htmlUrl="https://gwolf.org/" xmlUrl="https://gwolf.org/rss.xml" text="Gunnar Wolf - Nice grey life" />
|
||||
<outline title="Mathias Verraes" text="Mathias Verraes" htmlUrl="https://verraes.net/" type="rss" xmlUrl="https://verraes.net/feed.atom" />
|
||||
<outline text="John D. Cook" type="rss" xmlUrl="https://www.johndcook.com/blog/feed/" title="John D. Cook" htmlUrl="https://www.johndcook.com/blog" />
|
||||
<outline type="rss" title="David Smith, Independent iOS Developer" htmlUrl="http://david-smith.org/" text="David Smith, Independent iOS Developer" xmlUrl="https://www.david-smith.org/atom.xml" />
|
||||
<outline xmlUrl="https://samwho.dev/rss.xml" htmlUrl="https://samwho.dev/" type="rss" title="samwho.dev" text="samwho.dev" />
|
||||
<outline htmlUrl="https://css-tricks.com/" title="CSS-Tricks" xmlUrl="https://css-tricks.com/feed/" text="CSS-Tricks" type="rss" />
|
||||
<outline text="Davor Minchorov | Articles" title="Davor Minchorov | Articles" xmlUrl="https://davorminchorov.com/feed/articles" htmlUrl="https://davorminchorov.com/articles" type="rss" />
|
||||
<outline title="Chris Coyier" type="rss" htmlUrl="https://chriscoyier.net/" xmlUrl="https://chriscoyier.net/feed/" text="Chris Coyier" />
|
||||
<outline htmlUrl="https://blog.codinghorror.com/" xmlUrl="https://blog.codinghorror.com/rss/" text="Coding Horror" type="rss" title="Coding Horror" />
|
||||
<outline xmlUrl="https://devblogs.microsoft.com/oldnewthing/author/oldnewthing/feed" text="Raymond Chen, Author at The Old New Thing" htmlUrl="https://devblogs.microsoft.com/oldnewthing/author/oldnewthing" title="Raymond Chen, Author at The Old New Thing" type="rss" />
|
||||
<outline xmlUrl="https://iamsang.com/rss.xml" title="I am Sang" type="rss" htmlUrl="https://iamsang.com/" text="I am Sang" />
|
||||
<outline text="Drew DeVault's blog" title="Drew DeVault's blog" type="rss" xmlUrl="https://drewdevault.com/blog/index.xml" htmlUrl="https://drewdevault.com/" />
|
||||
<outline xmlUrl="https://grant.jurgensen.dev/feed.xml" htmlUrl="https://grant.jurgensen.dev/" text="Grant Jurgensen" title="Grant Jurgensen" type="rss" />
|
||||
<outline htmlUrl="https://lornajane.net/" text="LornaJane" title="LornaJane" type="rss" xmlUrl="https://lornajane.net/feed" />
|
||||
<outline text="Learning TypeScript Blog" xmlUrl="https://www.learningtypescript.com/articles/rss.xml" title="Learning TypeScript Blog" type="rss" htmlUrl="https://www.learningtypescript.com/articles" />
|
||||
<outline text="Cees-Jan Kiewiet's blog" htmlUrl="https://blog.wyrihaximus.net/" title="Cees-Jan Kiewiet's blog" xmlUrl="https://blog.wyrihaximus.net/atom.xml" type="rss" />
|
||||
<outline htmlUrl="http://research.swtch.com/feed.atom" title="research!rsc" type="rss" xmlUrl="https://research.swtch.com/feed.atom" text="research!rsc" />
|
||||
<outline type="rss" xmlUrl="https://xn--rpa.cc/feed.atom" htmlUrl="http://xn--rpa.cc/" text="ʞ.cc - lexi hale" title="ʞ.cc - lexi hale" />
|
||||
<outline text="Dan Luu" xmlUrl="https://danluu.com/atom.xml" type="rss" htmlUrl="https://danluu.com/atom/index.xml" title="Dan Luu" />
|
||||
<outline title="Tania Rascia | RSS Feed" xmlUrl="https://www.taniarascia.com/rss.xml" text="Tania Rascia | RSS Feed" type="rss" htmlUrl="https://www.taniarascia.com/" />
|
||||
<outline text="Holovaty.com" htmlUrl="https://www.holovaty.com/" type="rss" title="Holovaty.com" xmlUrl="https://www.holovaty.com/rss/" />
|
||||
<outline htmlUrl="http://jvns.ca/" text="Julia Evans" xmlUrl="https://jvns.ca/atom.xml" title="Julia Evans" type="rss" />
|
||||
<outline htmlUrl="https://leancrew.com/all-this/" title="And now it’s all this" xmlUrl="http://www.leancrew.com/all-this/feed/" text="And now it’s all this" type="rss" />
|
||||
<outline text="Dustycloud Brainstorms" htmlUrl="https://dustycloud.org/dustycloud.org" title="Dustycloud Brainstorms" type="rss" xmlUrl="https://dustycloud.org/blog/index.xml" />
|
||||
<outline type="rss" xmlUrl="https://notes.eatonphil.com/rss.xml" title="Phil Eaton - Notes on software development" text="Phil Eaton - Notes on software development" htmlUrl="http://notes.eatonphil.com/" />
|
||||
<outline text="Posts :: TheOrangeOne" xmlUrl="https://theorangeone.net/posts/feed/" type="rss" title="Posts :: TheOrangeOne" htmlUrl="https://theorangeone.net/" />
|
||||
<outline title="Bram.us" text="Bram.us" type="rss" xmlUrl="https://www.bram.us/feed/" htmlUrl="https://www.bram.us/" />
|
||||
<outline text="Random ASCII – tech blog of Bruce Dawson" htmlUrl="https://randomascii.wordpress.com/" title="Random ASCII – tech blog of Bruce Dawson" xmlUrl="https://randomascii.wordpress.com/feed/" type="rss" />
|
||||
<outline title="Nathan Grigg's blog" text="Nathan Grigg's blog" type="rss" htmlUrl="https://nathangrigg.com/" xmlUrl="https://nathangrigg.com/feed/all.rss" />
|
||||
<outline title="Aral Balkan" htmlUrl="https://ar.al/" text="Aral Balkan" xmlUrl="https://ar.al/index.xml" type="rss" />
|
||||
<outline text="Terence Eden’s Blog" htmlUrl="https://shkspr.mobi/blog" title="Terence Eden’s Blog" type="rss" xmlUrl="https://shkspr.mobi/blog/feed/atom/" />
|
||||
<outline xmlUrl="https://joeferguson.me/blog/feed.atom" text="Joe Ferguson" type="rss" htmlUrl="https://joeferguson.me/" title="Joe Ferguson" />
|
||||
<outline type="rss" htmlUrl="https://www.infrastructureposts.com/" title="Infrastructure as Posts" xmlUrl="https://www.infrastructureposts.com/feed" text="Infrastructure as Posts" />
|
||||
<outline type="rss" title="Ben Hoyt's technical writing" text="Ben Hoyt's technical writing" xmlUrl="https://benhoyt.com/writings/rss.xml" htmlUrl="https://benhoyt.com/writings/" />
|
||||
<outline type="rss" htmlUrl="https://kieranhealy.org/blog/" text="Kieran Healy" xmlUrl="https://kieranhealy.org/blog/index.xml" title="Kieran Healy" />
|
||||
<outline type="rss" xmlUrl="https://anttih.com/feed.xml" htmlUrl="http://anttih.com/" text="Antti Holvikari" title="Antti Holvikari" />
|
||||
<outline text="Liss is More" type="rss" htmlUrl="https://www.caseyliss.com/" xmlUrl="https://www.caseyliss.com/rss" title="Liss is More" />
|
||||
<outline type="rss" xmlUrl="https://scottrichmond.me/feed/" text="Scott C. Richmond" htmlUrl="https://scottrichmond.me/" title="Scott C. Richmond" />
|
||||
<outline title="nikic's blog" text="nikic's blog" type="rss" xmlUrl="https://www.npopov.com/rss.xml" htmlUrl="https://www.npopov.com/" />
|
||||
<outline type="rss" text="Catch TS" title="Catch TS" xmlUrl="https://catchts.com/api/rss" htmlUrl="https://catchts.com/" />
|
||||
<outline xmlUrl="https://benholmen.com/rss.xml" type="rss" htmlUrl="https://benholmen.com/" title="Ben Holmen" text="Ben Holmen" />
|
||||
<outline text="Bitsplitting.org" htmlUrl="https://bitsplitting.org/" type="rss" xmlUrl="https://bitsplitting.org/feed/" title="Bitsplitting.org" />
|
||||
<outline type="rss" htmlUrl="https://ferd.ca/" title="Ferd.ca" text="Ferd.ca" xmlUrl="https://ferd.ca/feed.rss" />
|
||||
<outline htmlUrl="https://derickrethans.nl/archive.html" text="Derick Rethans" xmlUrl="https://derickrethans.nl/feed.xml" type="rss" title="Derick Rethans" />
|
||||
<outline type="rss" title="Primary Unit" xmlUrl="https://www.robjwells.com/rss" htmlUrl="https://www.robjwells.com/" text="Primary Unit" />
|
||||
<outline htmlUrl="https://ethanmarcotte.com/" xmlUrl="https://ethanmarcotte.com/wrote/feed.xml" title="Ethan Marcotte’s website" text="Ethan Marcotte’s website" type="rss" />
|
||||
<outline htmlUrl="https://gankra.github.io/blah/" text="Faultlore" type="rss" title="Faultlore" xmlUrl="https://faultlore.com/blah/rss.xml" />
|
||||
<outline xmlUrl="https://matt.might.net/articles/feed.rss" htmlUrl="http://matt.might.net/" text="Matt Might's blog" title="Matt Might's blog" type="rss" />
|
||||
<outline htmlUrl="https://freek.dev/feed" type="rss" title="freek.dev - all blogposts" text="freek.dev - all blogposts" xmlUrl="https://freek.dev/feed" />
|
||||
<outline type="rss" text="Secret Weblog" htmlUrl="https://blog.startifact.com/" title="Secret Weblog" xmlUrl="https://blog.startifact.com/atom.xml" />
|
||||
<outline xmlUrl="http://brett.trpstra.net/brettterpstra" htmlUrl="https://brettterpstra.com/" text="The Mad Science of Brett Terpstra" type="rss" title="The Mad Science of Brett Terpstra" />
|
||||
<outline type="rss" htmlUrl="https://inessential.com/" title="inessential by Brent Simmons" text="inessential by Brent Simmons" xmlUrl="https://inessential.com/xml/rss.xml" />
|
||||
<outline title="Eric L. Barnes" type="rss" text="Eric L. Barnes" xmlUrl="https://ericlbarnes.com/feed/" htmlUrl="https://ericlbarnes.com/" />
|
||||
<outline title="Raph Levien’s blog" text="Raph Levien’s blog" htmlUrl="https://raphlinus.github.io/" type="rss" xmlUrl="https://raphlinus.github.io/feed.xml" />
|
||||
<outline type="rss" htmlUrl="https://chown.me/" title="Daniel Jakots" text="Daniel Jakots" xmlUrl="https://chown.me/blog/feeds/atom.xml" />
|
||||
<outline title="Matt's Headroom" type="rss" htmlUrl="https://blog.millerti.me/" text="Matt's Headroom" xmlUrl="https://blog.millerti.me/index.xml" />
|
||||
<outline title="Christoph Rumpel Blog Feed" type="rss" text="Christoph Rumpel Blog Feed" xmlUrl="https://christoph-rumpel.com/feed" htmlUrl="https://christoph-rumpel.com/feed" />
|
||||
</outline>
|
||||
<outline title="Forums & Collectives" text="Forums & Collectives" />
|
||||
<outline text="Projects & Products" title="Projects & Products">
|
||||
<outline text="Fish-shell Blog" xmlUrl="https://fishshell.com/blog/feed.xml" type="rss" title="Fish-shell Blog" htmlUrl="https://fishshell.com/blog/" />
|
||||
<outline htmlUrl="https://aws.amazon.com/about-aws/whats-new/recent/" title="AWS - Recent Announcements" type="rss" text="AWS - Recent Announcements" xmlUrl="https://aws.amazon.com/about-aws/whats-new/recent/feed/" />
|
||||
<outline type="rss" xmlUrl="https://kubernetes.io/feed.xml" text="Kubernetes Blog" htmlUrl="https://kubernetes.io/" title="Kubernetes Blog" />
|
||||
<outline text="The JetBrains Blog" type="rss" htmlUrl="https://blog.jetbrains.com/" title="The JetBrains Blog" xmlUrl="https://blog.jetbrains.com/feed/" />
|
||||
<outline htmlUrl="https://hacks.mozilla.org/" type="rss" title="Mozilla Hacks – the Web developer blog" xmlUrl="https://hacks.mozilla.org/feed/" text="Mozilla Hacks – the Web developer blog" />
|
||||
<outline xmlUrl="https://developer.apple.com/news/releases/rss/releases.rss" text="Releases - Apple Developer" type="rss" htmlUrl="https://developer.apple.com/news/" title="Releases - Apple Developer" />
|
||||
<outline xmlUrl="https://blog.remirepo.net/feed/atom" htmlUrl="https://blog.remirepo.net/" title="Remi's RPM repository - Blog" text="Remi's RPM repository - Blog" type="rss" />
|
||||
<outline xmlUrl="https://blog.thunderbird.net/feed/" text="The Thunderbird Blog" htmlUrl="https://blog.thunderbird.net/" type="rss" title="The Thunderbird Blog" />
|
||||
<outline type="rss" xmlUrl="https://blog.mozilla.org/en/feed/" title="The Mozilla Blog" text="The Mozilla Blog" htmlUrl="https://blog.mozilla.org/en/" />
|
||||
<outline text="Angular Blog - Medium" xmlUrl="https://blog.angular.io/feed" type="rss" title="Angular Blog - Medium" htmlUrl="https://blog.angular.dev/?source=rss----447683c3d9a3---4" />
|
||||
<outline type="rss" htmlUrl="https://blog.gitea.com/" xmlUrl="https://blog.gitea.io/index.xml" text="Blog" title="Blog" />
|
||||
<outline xmlUrl="https://nodejs.org/en/feed/blog.xml" htmlUrl="https://nodejs.org/en/feed/blog.xml" title="Node.js Blog" type="rss" text="Node.js Blog" />
|
||||
<outline xmlUrl="https://feed.laravel-news.com/" text="Laravel News" htmlUrl="https://laravel-news.com/" title="Laravel News" type="rss" />
|
||||
<outline title="The Cloudflare Blog" type="rss" text="The Cloudflare Blog" htmlUrl="https://blog.cloudflare.com/" xmlUrl="https://blog.cloudflare.com/rss/" />
|
||||
<outline title="Laravel" type="rss" text="Laravel" htmlUrl="https://blog.laravel.com/feed" xmlUrl="https://blog.laravel.com/feed" />
|
||||
</outline>
|
||||
<outline title="IT Blogs" text="IT Blogs">
|
||||
<outline text="Schneier on Security" xmlUrl="https://www.schneier.com/feed/" type="rss" htmlUrl="https://www.schneier.com/" title="Schneier on Security" />
|
||||
<outline text="SecList - Microsoft Sec Notification" type="rss" title="SecList - Microsoft Sec Notification" htmlUrl="https://seclists.org/#microsoft" xmlUrl="https://seclists.org/rss/microsoft.rss" />
|
||||
<outline htmlUrl="https://securelist.com/" title="Securelist" xmlUrl="https://securelist.com/feed/" text="Securelist" type="rss" />
|
||||
<outline text="Amazon Web Services Service Status" xmlUrl="https://status.aws.amazon.com/rss/all.rss" htmlUrl="https://status.aws.amazon.com/" title="Amazon Web Services Service Status" type="rss" />
|
||||
<outline type="rss" xmlUrl="https://krebsonsecurity.com/feed/" text="Krebs on Security" htmlUrl="https://krebsonsecurity.com/" title="Krebs on Security" />
|
||||
<outline title="EFF Deeplinks" text="EFF Deeplinks" type="rss" xmlUrl="https://www.eff.org/rss/updates.xml" htmlUrl="https://www.eff.org/rss/updates.xml" />
|
||||
<outline type="rss" htmlUrl="https://brr.fyi/" xmlUrl="https://brr.fyi/feed.xml" text="brr | Antarctica Blog" title="brr | Antarctica Blog" />
|
||||
<outline text="Trail of Bits Blog" title="Trail of Bits Blog" xmlUrl="https://blog.trailofbits.com/feed/" htmlUrl="https://blog.trailofbits.com/" type="rss" />
|
||||
<outline title="Errata Security" text="Errata Security" xmlUrl="https://blog.erratasec.com/feeds/posts/default" type="rss" htmlUrl="https://blog.erratasec.com/" />
|
||||
<outline text="SecLists - Bugtraq" type="rss" xmlUrl="https://seclists.org/rss/bugtraq.rss" htmlUrl="https://seclists.org/#bugtraq" title="SecLists - Bugtraq" />
|
||||
</outline>
|
||||
<outline text="Architecture" title="Architecture">
|
||||
<outline text="Tasmanian 20th Century Modernism Blog - Thomas Ryan Photography" type="rss" xmlUrl="https://www.tryanphotos.com/tasmanian-modernism-blog?format=rss" title="Tasmanian 20th Century Modernism Blog - Thomas Ryan Photography" htmlUrl="https://www.tryanphotos.com/tasmanian-modernism-blog/" />
|
||||
<outline htmlUrl="https://socks-studio.com/" type="rss" title="SOCKS Studio" text="SOCKS Studio" xmlUrl="https://feeds.feedburner.com/socks-studio" />
|
||||
<outline xmlUrl="https://abandoned.photos/rss" htmlUrl="https://abandoned.photos/" text="Destroyed and Abandoned" title="Destroyed and Abandoned" type="rss" />
|
||||
<outline text="The Spaces" xmlUrl="https://thespaces.com/feed/" htmlUrl="https://thespaces.com/" title="The Spaces" type="rss" />
|
||||
<outline htmlUrl="https://vintagehomeplans.tumblr.com/" title="Vintage Home Plans" type="rss" xmlUrl="https://vintagehomeplans.tumblr.com/rss" text="Vintage Home Plans" />
|
||||
<outline text="BLDGBLOG" htmlUrl="https://www.bldgblog.com/" xmlUrl="https://www.bldgblog.com/feed/" title="BLDGBLOG" type="rss" />
|
||||
<outline htmlUrl="https://archeyes.com/" xmlUrl="https://archeyes.com/feed/" type="rss" title="ArchEyes" text="ArchEyes" />
|
||||
<outline htmlUrl="https://municipaldreams.wordpress.com/" title="Municipal Dreams" xmlUrl="https://municipaldreams.wordpress.com/feed/" type="rss" text="Municipal Dreams" />
|
||||
<outline title="Pylon of the Month" text="Pylon of the Month" xmlUrl="https://www.pylonofthemonth.org/atom.xml" htmlUrl="https://www.pylonofthemonth.org/" type="rss" />
|
||||
<outline type="rss" title="Spoon & Tamago" xmlUrl="https://www.spoon-tamago.com/feed/" text="Spoon & Tamago" htmlUrl="https://www.spoon-tamago.com/" />
|
||||
</outline>
|
||||
</body>
|
||||
</opml>
|
||||
13
src/blog/archive.pug
Normal file
13
src/blog/archive.pug
Normal file
@@ -0,0 +1,13 @@
|
||||
extends /blog
|
||||
|
||||
block blog_content
|
||||
h2 Post Archive
|
||||
|
||||
.recent-posts
|
||||
each year in collections.blogByYear
|
||||
h3 #{year.year}
|
||||
ul.plain
|
||||
each post in year.posts
|
||||
li
|
||||
.secondary #{post.date.toISOString().split('T')[0]}
|
||||
a.title(href=post.url) #{post.data.title}
|
||||
23
src/blog/feeds-stub.md
Normal file
23
src/blog/feeds-stub.md
Normal file
@@ -0,0 +1,23 @@
|
||||
## An RSS Manifesto
|
||||
|
||||
> More than a convenience, _RSS is good for the web_.
|
||||
|
||||
This blog is available via [RSS](/blog/rss2.xml), [Atom](/blog/atom.xml), or [JSON](/blog/json.json) syndication.
|
||||
|
||||
For the uninitiated, RSS/Atom/JSON feeds make the content of a website available in a standard format. This allows you to consume the blog's content in whatever feed reader you prefer, rather than visiting the site directly.
|
||||
|
||||
RSS & Atom are standard feed formats based on XML. RSS is by far the most popular. [JSON feed](https://www.jsonfeed.org/) is a somewhat less popular syndication format based on JSON.
|
||||
|
||||
While RSS is no longer a "mainstream" format for consuming works on the internet, it still has a thriving community of dedicated fans.
|
||||
|
||||
You might be surprised to learn that RSS feeds are still everywhere. Nearly every news/blog-style website will have an RSS feed out-of-the box. Everything from [The New York Times](https://www.nytimes.com/rss) to [NASA](https://www.nasa.gov/content/nasa-rss-feeds) to [_every single podcast_](https://99percentinvisible.org/listen/) can be subscribed to via RSS.
|
||||
|
||||
More than a convenience, _RSS is good for the web_. It provides a standard format for programmatically fetching content from a disparate collection of websites, is (nearly) always available.
|
||||
|
||||
From a user's perspective, it allows us (as consumers) to choose what content we subscribe to and receive timely updates without relying on an algorithm. Plus, since RSS is a pure HTML format, it is often better from a user-privacy standpoint than visiting websites directly.
|
||||
|
||||
Finally, RSS promotes platform diversity by enabling small authors & creators to publish their works online in a standard, approachable format without needing a larger platform to reach their subscribers.
|
||||
|
||||
If you couldn't tell, I ❤️ open syndication, and I think it's really important to continue making these feeds available to users.
|
||||
|
||||
To that end, I'm trying to collect a list of independent RSS feeds that I enjoy:
|
||||
20
src/blog/feeds.njk
Normal file
20
src/blog/feeds.njk
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
layout: blog
|
||||
---
|
||||
|
||||
{% renderFile "src/blog/feeds-stub.md" %}
|
||||
|
||||
<h3>Garrett's RSS List</h3>
|
||||
|
||||
<blockquote>
|
||||
This list is also available in the standard <a href="/assets/rss_opml.xml" download>OPML format</a>.
|
||||
</blockquote>
|
||||
|
||||
{% for cat in collections.opmlByCategory %}
|
||||
<h4 style="background-color: var(--c-font)">{{ cat.title }}</h4>
|
||||
<ul>
|
||||
{% for sub in cat.subs %}
|
||||
<li><a href="{{ sub.xmlUrl }}" download>{{ sub.title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
13
src/blog/index.pug
Normal file
13
src/blog/index.pug
Normal file
@@ -0,0 +1,13 @@
|
||||
extends /blog
|
||||
|
||||
block blog_content
|
||||
p Write-ups and musings, often technical, sometimes not.
|
||||
|
||||
h2 Recent(ish) Posts
|
||||
|
||||
.recent-posts
|
||||
ul.plain
|
||||
each post in collections.blog.slice(0, 10)
|
||||
li
|
||||
.secondary #{post.data.date.toISOString().split('T')[0]}
|
||||
a.title(href=post.url) #{post.data.title}
|
||||
129
src/blog/posts/2025-01-11-postgres.md
Normal file
129
src/blog/posts/2025-01-11-postgres.md
Normal file
@@ -0,0 +1,129 @@
|
||||
---
|
||||
layout: blog_post
|
||||
tags: blog
|
||||
title: Salvaging a Corrupted Table from PostgreSQL
|
||||
permalink: /blog/2025/01/11/Salvaging-a-Corrupted-Table-from-PostgreSQL/
|
||||
slug: Salvaging-a-Corrupted-Table-from-PostgreSQL
|
||||
date: 2025-01-11 20:00:00
|
||||
blogtags:
|
||||
- linux
|
||||
- hosting
|
||||
- postgres
|
||||
---
|
||||
|
||||

|
||||
|
||||
> ⚠️ <b>DO NOT DO THIS...</b> well ever really, but especially on a server with failing disks. This is done on a server with perfectly fine disks, but corrupted Postgres blocks.
|
||||
|
||||
I spend a lot of time in my professional work and my home lab trying to learn and implement the “correct” or “responsible” way of implementing a solution — highly-available deployments, automated and tested backups, infrastructure-as-code, &c.
|
||||
|
||||
This is not that.
|
||||
|
||||
This is a very dirty, no-holds-barred, absolutely insane thing to do, and if you’re working in any kind of environment that _matters_, you should [read this](https://wiki.postgresql.org/wiki/Corruption) and hire a professional.
|
||||
|
||||
For unimportant reasons, I’ve been dealing with data corruption on the Postgres server in my home lab. The server was terminated uncleanly a couple times and the disk data was corrupted. Because there’s nothing more permanent than a temporary solution, I did not have backups for this server.
|
||||
|
||||
For most of the data, I was able to use `pg_dump` to dump the schemata and data and re-import it into my new Postgres server (which, yes, has backups configured now).
|
||||
|
||||
```none
|
||||
pg_dump -U postgres -h localhost my_database > my_database.sql
|
||||
```
|
||||
|
||||
For databases with corrupted tables, though, `pg_dump` fails out with this unsettling error:
|
||||
|
||||
```none
|
||||
> pg_dump -U postgres -h localhost www_p1 > www_p1.sql
|
||||
pg_dump: error: Dumping the contents of table "page_views" failed: PQgetResult() failed.
|
||||
pg_dump: detail: Error message from server: ERROR: invalid page in block 31869 of relation base/16384/16417
|
||||
pg_dump: detail: Command was: COPY public.page_views (page_view_id, visited_at, hostname, ip, method, endpoint, user_id, xhr) TO stdout;
|
||||
```
|
||||
|
||||
(…yes, that’s the database for my personal website. 👀) Somewhat to my surprise, I couldn’t find many details/strategies for how to “best effort” recover data from a corrupt Postgres table, so here we go.
|
||||
|
||||
Luckily, since the corruption was the result of unclean Postgres exits and not bad physical disks, it only affected table(s) with frequent writes at the time. In this case, that was the `sessions` table and the `page_views` table. The `sessions` table is entirely disposable — I just re-created it empty on the new server and moved on with my life.
|
||||
|
||||
It wouldn’t be the end of the world if I lost the `page_views` table, but there are some 6.5 million historical page-views recorded in that table that would kind of suck to lose. So… let’s do some sketchy shit.
|
||||
|
||||
My goal here isn’t to recover the entire table. If that was the goal, I would’ve stopped and hired a professional. Instead, my goal is to recover as many rows of the table as possible.
|
||||
|
||||
One reason `pg_dump` fails is because it tries to read the data using a cursor, which fails when the fundamental assumptions of Postgres are violated (e.g. bad data in disk blocks, invalid indices).
|
||||
|
||||
My strategy here is to create a 2nd table on the bad server with the same schema, then loop over each row in the `page_views` individually and insert them into the clean table, skipping rows in disk blocks with bad data. Shout out to [this Stack Overflow answer](https://stackoverflow.com/a/63905054/4971138) that loosely inspired this strategy.
|
||||
|
||||
```sql
|
||||
CREATE OR REPLACE PROCEDURE pg_recover_proc()
|
||||
LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
cnt BIGINT := 0;
|
||||
BEGIN
|
||||
-- Get the maximum page_view_id from the page_views table
|
||||
cnt := (SELECT MAX(page_view_id) FROM page_views);
|
||||
|
||||
-- Loop through the page_views table in reverse order by page_view_id
|
||||
LOOP
|
||||
BEGIN
|
||||
-- Insert the row with the current page_view_id into page_views_recovery
|
||||
INSERT INTO page_views_recovery
|
||||
SELECT * FROM page_views WHERE page_view_id = cnt and entrypoint is not null;
|
||||
|
||||
-- Decrement the counter
|
||||
cnt := cnt - 1;
|
||||
|
||||
-- Exit the loop when cnt < 1
|
||||
EXIT WHEN cnt < 1;
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
-- Handle exceptions (e.g., data corruption)
|
||||
IF POSITION('block' in SQLERRM) > 0 OR POSITION('status of transaction' in SQLERRM) > 0 OR POSITION('memory alloc' in SQLERRM) > 0 OR POSITION('data is corrupt' in SQLERRM) > 0 OR POSITION('MultiXactId' in SQLERRM) > 0 THEN
|
||||
RAISE WARNING 'PGR_SKIP: %', cnt;
|
||||
cnt := cnt - 1;
|
||||
CONTINUE;
|
||||
ELSE
|
||||
RAISE;
|
||||
END IF;
|
||||
END;
|
||||
|
||||
IF MOD(cnt, 500) = 0 THEN
|
||||
RAISE WARNING 'PGR_COMMIT: %', cnt;
|
||||
COMMIT;
|
||||
END IF;
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
```
|
||||
|
||||
There are some cool and absolutely terrible things here. In modern versions of Postgres, stored procedures can periodically commit their in-progress top-level transactions by calling `COMMIT` repeatedly. I’m (ab)using this here to flush the recovered rows to the new table as the procedure runs in case it fails partway through.
|
||||
|
||||
I'm doing some rough string analysis for error messages related to corrupt data and skipping the current row if that's the case. Another interesting edge-case: a couple times, I ran into a case where the `INSERT` into the recovery table failed because the `SELECT` query against the bad table was returning `null` values, even though that should technically never be possible. Told you we're violating some foundational assumptions about Postgres here. Adding an `is not null` to a different non-null column helped avoid this.
|
||||
|
||||
My original draft of this procedure was designed to keep looping and just skip the fatal errors caused by disk corruption (the various dirty `POSITION` checks in the error handler).
|
||||
|
||||
Quickly, however, I ran into a new error:
|
||||
|
||||
> SQL Error \[57P03\]: FATAL: the database system is in recovery mode
|
||||
|
||||
Turns out, if you keep intentionally forcing Postgres to try to read data from bad disk blocks, eventually its internal data structures hit an inconsistent state and the server process restarts itself out for safety.
|
||||
|
||||
This is (obviously) a problem because we can’t catch that and force the procedure to keep running against its will. So instead I resorted to adding `IF` conditions to manually skip over primary key regions that caused the server process to crash. (I told you this was crazy.)
|
||||
|
||||
Every time the server would crash, I would dump out the rows I’d recovered so far, just in case:
|
||||
|
||||
```none
|
||||
pg_dump -U postgres -h localhost --table page_views2 www_p1 > page_views2-1.sql
|
||||
```
|
||||
|
||||
Then I’d skip a new region of primary key, drop and re-create the recovery table, and try again. Why drop and re-create it? Because I discovered that when the server process crashed, it would occasionally write bad data to the *recovery* table, which is obviously no good:
|
||||
|
||||
```none
|
||||
pg_dump: error: Dumping the contents of table "page_views_recovery" failed: PQgetResult() failed.
|
||||
pg_dump: detail: Error message from server: ERROR: invalid memory alloc request size 18446744073709551613
|
||||
pg_dump: detail: Command was: COPY public.page_views_recovery (page_view_id, visited_at, hostname, ip, method, endpoint, user_id, xhr) TO stdout;
|
||||
```
|
||||
|
||||
Predictably, this got really annoying to do by hand, so I did what any good Linux nerd would do and wrote a script for it, which [you can find here](https://code.garrettmills.dev/garrettmills/pg-recover). The gist:
|
||||
|
||||
```none
|
||||
./pg-recover.sh postgres localhost www_p1 page_views page_view_id entrypoint
|
||||
```
|
||||
|
||||
Of the 6,628,903 rows in the corrupt table, I was able to recover 6,444,118 of them. You know what they say — if it’s stupid and it works, it’s still stupid and you’re just lucky.
|
||||
21
src/blog/tag.njk
Normal file
21
src/blog/tag.njk
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
layout: blog
|
||||
pagination:
|
||||
data: collections.blogByTag
|
||||
size: 1
|
||||
alias: tag
|
||||
permalink: "/blog/tag/{{ tag.tag }}/"
|
||||
---
|
||||
|
||||
<h2>Posts w/ Tag: {{ tag.tag }}</h2>
|
||||
|
||||
<div class="recent-posts">
|
||||
<ul class="plain">
|
||||
{% for post in tag.posts %}
|
||||
<li>
|
||||
<div class="secondary">{{ post.date.toISOString().split('T')[0] }}</div>
|
||||
<a class="title" href="{{ post.url }}">{{ post.data.title }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
9
src/blog/tags.pug
Normal file
9
src/blog/tags.pug
Normal file
@@ -0,0 +1,9 @@
|
||||
extends /blog
|
||||
|
||||
block blog_content
|
||||
h2 Tags
|
||||
|
||||
.post-tags.listed
|
||||
ul
|
||||
each tag in collections.blogByTag
|
||||
li <a class="button" href="/blog/tag/#{tag.tag}">##{tag.tag}</a> <span style="color: var(--color-2); font-variant-ligatures: none;">(#{tag.posts.length})</a>
|
||||
Reference in New Issue
Block a user