diff --git a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/coda-clips-icon-files.zip b/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/coda-clips-icon-files.zip deleted file mode 100644 index b8e6031e..00000000 Binary files a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/coda-clips-icon-files.zip and /dev/null differ diff --git a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-hud.png b/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-hud.png deleted file mode 100644 index d97acec1..00000000 Binary files a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-hud.png and /dev/null differ diff --git a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-icon128.png b/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-icon128.png deleted file mode 100644 index e23f8ce0..00000000 Binary files a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-icon128.png and /dev/null differ diff --git a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-placeholder.png b/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-placeholder.png deleted file mode 100644 index 7b3e95c0..00000000 Binary files a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-placeholder.png and /dev/null differ diff --git a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-teaser.png b/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-teaser.png deleted file mode 100644 index 5412c9ed..00000000 Binary files a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/codaclips-teaser.png and /dev/null differ diff --git a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/coffee-cup-icon-kremalicious.png b/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/coffee-cup-icon-kremalicious.png deleted file mode 100644 index e3a88227..00000000 Binary files a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/coffee-cup-icon-kremalicious.png and /dev/null differ diff --git a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/index.md b/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/index.md deleted file mode 100644 index 5e8bcd83..00000000 --- a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/index.md +++ /dev/null @@ -1,514 +0,0 @@ ---- -title: Ultimate Share Link Bonanza For Coda, WordPress And Everything Else -download: /get/share-link-bonanza-coda-clips.zip - -date: 2009-03-29 23:12:15+00:00 - -tags: - - design - - development - - goodies - - tutorial - - wordpress ---- - -Ever wanted to include those sharing links to social or bookmarking sites so users can easily submit your content to these sites in a Wordpress site or any other platform? - -![Coda Clips Teaser](./codaclips-teaser.png) - -Then you might have experienced a rather time consuming search odyssey to get those links. But fear no more! In this article I've provided a huge collection of all the links to your favorite social sites compiled in two handy Coda Clip files in a plain and a Wordpress version. And the non-Coda users can download an html file with all the links included. - -Additionally you'll find a huge list within this article with the separated links in two versions for each site. And finally I've put together a quick tutorial for using buttons or icons with these links. This way you can easily add content submit/sharing links to your sites in no time. - -## Share Links Coda Clips Download - -Also all links are plain html code and therefore the non-JavaScript versions of the various social sites' submit capabilities. While most social/bookmark sites have some kind of tool section where they explain the use of their API near all of them want you to use JavaScript to access their API and submit your content to them through the use of a link on your website. - -But I think you don't want to load tons of scripts on your websites if you include links to tons of sharing sites. So mostly all links to submit your content to various social/bookmark sites can be realized in plain HTML as a generic a href link and that's what is provided here. - -To make this a bit more straightforward I provide these links compiled within two Coda Clip files for use with [Panic's Coda](http://panic.com/coda). While the first clip group contains all the plain link snippets the second group includes those snippets for use with Wordpress. Just download and add them to your Coda Clips collection: - -Download Share Links Coda Clips - -Included are a **total of 40 share links per clip group** for the following social/bookmark sites. This list uses the links provided in the Coda clips so you can test them out here with this article: - - - -_ -[Delicious](http://del.icio.us/post?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [StumbleUpon](http://www.stumbleupon.com/submit?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Facebook](http://www.facebook.com/sharer.php?u=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/?t=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Twitter](http://twitter.com/home?status=Awesome Coda Clips collection! https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/), [Digg](http://digg.com/submit?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else&media=NEWS&thumbnails=1), [Design Float](http://www.designfloat.com/submit.php?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Reddit](http://www.reddit.com/submit?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Technorati](http://www.technorati.com/faves/?add=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/), [Yahoo Buzz](http://buzz.yahoo.com/submit/?submitUrl=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&submitHeadline=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Newsvine](http://www.newsvine.com/_tools/seed&save?u=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&h=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Magnolia](http://ma.gnolia.com/bookmarklet/add?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Google Bookmarks](http://www.google.com/bookmarks/mark?op=edit&bkmk=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [FriendFeed](http://friendfeed.com/share?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Blogmarks](http://blogmarks.net/my/new.php?mini=1&url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [MySpace](http://www.myspace.com/Modules/PostTo/Pages/?l=3&u=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&t=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Script & Style](http://scriptandstyle.com/submit?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Blinklist](http://blinklist.com/index.php?Action=Blink/addblink.php&Url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&Title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Slashdot](http://slashdot.org/bookmark.pl?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [LinkedIn](http://www.linkedin.com/shareArticle?mini=true&url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else&source=), [Windows Live](https://favorites.live.com/quickadd.aspx?marklet=1&mkt=en-us&url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else&top=1), [Furl](http://furl.net/storeIt.jsp?u=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&t=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Yahoo Bookmarks](http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&u=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&t=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Mixx](http://www.mixx.com/submit?page_url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/), [Propeller](http://www.propeller.com/submit/?U=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&T=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Yigg](http://www.yigg.de/neu?exturl=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&exttitle=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Mr Wong](http://www.mister-wong.com/index.php?action=addurl&bm_url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&bm_description=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Diigo](http://secure.diigo.com/post?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [N4G](http://www.n4g.com/tips.aspx?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Current](http://current.com/clipper.htm?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else&src=st), [Simpy](http://www.simpy.com/simpy/LinkAdd.do?href=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Oknotizie](http://oknotizie.alice.it/post?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Care2](http://www.care2.com/news/compose?share[link_url]=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&share[title]=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Faves](http://www.faves.com/Authoring.aspx?u=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&t=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Meneame](http://meneame.net/submit.php?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/), [Fresqui](http://ocio.fresqui.com/post?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else), [Funp](http://funp.com/pages/submit/add.php?title=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else&url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&via=tools), [Kirtsy](http://www.kirtsy.com/submit.php?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/), [Dealspl.us](http://dealspl.us/add.php?ibm=1&url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/), [Xanga](http://www.xanga.com/private/editorx.aspx?t=Ultimate%20Share%20Link%20Bonanza%20For%20Coda%2C%20Wordpress%20And%20Everything%20Else&u=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/&s=), [Sphinn](http://sphinn.com/submit.php?url=https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/)_ - -## Bonus: Coda Clips Icon - -![Coda Clips Icon](./codaclips-icon128.png)There's no special icon for Coda Clips included in the recent Coda version (they use the blank one) so I quickly created one based on the other Coda file type icons. And the nice Panic guys allowed me to distribute this icon here. I've just made the 256px icon a bit sharper than the equivalent other coda file type icons. - -If you download the above Coda Clip files this icon is already applied on the clip files but here're just the icon files (icns, folder, iContainer, PNGs): - -Download Coda Clips Icon - -## 2. Usage - -![Coda Clips HUD](./codaclips-hud.png)Just download and double click the Coda clip documents and two new clip groups will be created in your Coda Clips HUD with the various clips inside of them. All you have to do in Coda is inserting the clip by double clicking in the Coda Clips HUD and start typing your link text or type your link text first, select it and double click the clip in order to insert it. - -That's because both collections have their placeholder selection (the ![Coda Clips Placeholder](./codaclips-placeholder.png)) located where the link text would be: - -```html -![Coda Clips Placeholder](./codaclips-placeholder.png) -``` - -As you can see I've also included the link title value usually with the name of the specific social site. Also I've already encoded all the entities so there shouldn't be any (X)HTML validation errors when using these links in your projects. - -And depending on which collection you use additional steps need to be done: - -## 2.1 Share Links - -Everything you need to replace for yourself is written in capital letters: - -**YOUR URL** -Here you have to provide the URL you want to have submitted when users use your share link. - -**YOUR TITLE** -For all social sites this title has to be URL-encoded to work correctly. So be sure to replace everything like spaces, punctuation, etc. with their equivalent URL-encoding (e.g. %20 for a space). [Here's a reference for this](http://www.w3schools.com/TAGS/ref_urlencode.asp). - -Apart from that some sites allow you to add and submit more informations than just the URL and the title and those things are also written in capital letters. Also I've included some usage comments where necessary like in the Digg link. - -## 2.2 Share Links (Wordpress Edition) - -The Wordpress edition of these share link collection includes some Wordpress php bits for dynamically creating the whole submit URL so there's no need to manually edit most of the links. The Wordpress template tags used are: - -- `` to create the URL dynamically depending on the article under which you have included the share and submit links. - -- `` to dynamically create the title which is used when your content gets submitted to one of the sites. - -Anyway, as I've said above some sites allow more to submit here and you'll find this also in capital letters. You have to adjust them manually too. - -## 3. Quick Tutorial For Using Icons With These Links - -![Tutorial icon by kremalicious](./tutorial-icon.png)I've also written a quick tutorial in case you want to use little images as icons beside your links. To achieve this these two solution provided here should fit every need for this. You can do this by using one of these two techniques realized with HTML and CSS: - -## 3.1 Use The <img /> Tag Element - -Just include an img element wrapped inside the link tag, like so: - -```html - Delicious -``` - -And if you want to just use an icon with no text use just an img element without providing any link text: - -```html - -``` - -## 3.2 Use CSS Background Images - -To me a more cleaner solution is to use the css background-image property to include the icon images. Just add a class or an id to every share link like so: - -```html -Delicious -``` - -And in your CSS select this class and style it with a background image. Assuming you want the site icon to appear left beside the link text you would also have to add some padding so the text won't overlap the icons: - -```css -.delicious { - background: url(delicious.png) no-repeat center center; - padding-left: 20px; -} -``` - -If you want to use just icons and no text you should provide a link text anyway but hide it with css. This is a good practice for accessibility and search engine optimization. Also you would have to provide the dimensions of the icon: - -```css -.delicious { - width: 16px; - height: 16px; - background: url(delicious.png) no-repeat center center; - text-indent: -999999px; -} -``` - -## 4. HTML File Download And All The Links Separated - -Sadly Coda's clips aren't in a portable format ([Panic guys](http://panic.com), consider this is a feature request!) so here's a comprehensive list for the non-Coda users of all the links included in the above Coda Clips with plain and the Wordpress version for every site. This comes as a downloadable stripped-down HTML file (meaning there's no HTML site structure included) and as a long list within in this article. First, here's the HTML file download. Just open this locally in your browser or in your favorite editor: - -Download Share Links HTML File - -And here's the huge list with all the share links in case you quickly want to grab just one of them. But be warned that this is a huge list so this is hidden by default. - -Just click the Toggle All Links button to reveal them and click it again to hide the whole list again. If you want to import one of these links into Coda you can just use the [Coda Clips bookmarklet created by kyle](http://www.rayogram.com/coda-clips-bookmarklet), as he points out [in the comments](https://kremalicious.com/ultimate-coda-wordpress-share-link-bonanza/#comment-42084). - -
-↓ Toggle All Links ↓ - -## Delicious - -**Plain** -`` - -**Wordpress** -`` - -## StumbleUpon - -**Plain** -`StumbleUpon` - -**Wordpress** -`StumbleUpon` - -## Facebook - -**Plain** -`Facebook` - -**Wordpress** -`Facebook` - -## Twitter - -**Plain** -`Twitter` - -**Wordpress** -`Twitter` - -## Digg - -### Plain - -```html - - Digg -``` - -**Wordpress** -`Digg` - -## Design Float - -**Plain** -`Design Float` - -**Wordpress** -`Design Float` - -## Reddit - -**Plain** -`Reddit` - -**Wordpress** -`Reddit` - -## Technorati - -**Plain** -`Technorati` - -**Wordpress** -`Technorati` - -## Yahoo Buzz - -**Plain** -`Yahoo Buzz` - -**Wordpress** -`Yahoo Buzz` - -## Newsvine - -**Plain** -`Newsvine` - -**Wordpress** -`Newsvine` - -## Magnolia - -**Plain** -`Magnolia` - -**Wordpress** -`Magnolia` - -## Google Bookmarks - -**Plain** -`Google Bookmarks` - -**Wordpress** -`Google Bookmarks` - -## FriendFeed - -**Plain** -`FriendFeed` - -**Wordpress** -`FriendFeed` - -## Blogmarks - -**Plain** -`Blogmarks` - -**Wordpress** -`Blogmarks` - -## MySpace - -**Plain** -`MySpace` - -**Wordpress** -`MySpace` - -## Script & Style - -**Plain** -`Script & Style` - -**Wordpress** -`Script & Style` - -## Blinklist - -**Plain** -`Blinklist` - -**Wordpress** -`Blinklist` - -## Slashdot - -**Plain** -`Slashdot` - -**Wordpress** -`Slashdot` - -## LinkedIn - -**Plain** -`LinkedIn` - -**Wordpress** -`LinkedIn` - -## Windows Live - -**Plain** -`Windows Live` - -**Wordpress** -`Windows Live` - -## Furl - -**Plain** -`Furl` - -**Wordpress** -`Furl` - -## Yahoo Bookmarks - -**Plain** -`Yahoo Bookmarks` - -**Wordpress** -`Yahoo Bookmarks` - -## Mixx - -**Plain** -`Mixx` - -**Wordpress** -`Mixx` - -## Propeller - -**Plain** -`Propeller` - -**Wordpress** -`Propeller` - -## Yigg - -**Plain** -`Yigg` - -**Wordpress** -`Yigg` - -## Mr Wong - -**Plain** -`Mr Wong` - -**Wordpress** -`Mr Wong` - -## Diigo - -**Plain** -`Diigo` - -**Wordpress** -`Diigo` - -## N4G - -**Plain** -`N4G` - -**Wordpress** -`N4G` - -## Current - -**Plain** -`Current` - -**Wordpress** -`Current` - -## Simpy - -**Plain** -`Simpy` - -**Wordpress** -`Simpy` - -## Oknotizie - -**Plain** -`Oknotizie` - -**Wordpress** -`Oknotizie` - -## Care2 - -**Plain** -`Care2` - -**Wordpress** -`Care2` - -## Faves - -**Plain** -`Faves` - -**Wordpress** -`Faves` - -## Meneame - -**Plain** -`Meneame` - -**Wordpress** -`Meneame` - -## Fresqui - -**Plain** -`Fresqui` - -**Wordpress** -`Fresqui` - -## Funp - -**Plain** -`Funp` - -**Wordpress** -`Funp` - -## Kirtsy - -**Plain** -`Kirtsy` - -**Wordpress** -`Kirtsy` - -## Dealspl.us - -**Plain** -`Dealspl.us` - -**Wordpress** -`Dealspl.us` - -## Xanga - -**Plain** -`Xanga` - -**Wordpress** -`Xanga` - -## Sphinn - -**Plain** -`Sphinn` - -**Wordpress** -`Sphinn` - -
- - - -## 5. Please Jump Around, Then Spread The Word - -![Coffee](./coffee-cup-icon-kremalicious.png) - -If you ever wanted or had to include such sharing links manually in your sites and searched hours for those you should already have recognized the value of this article and if not already happened you can now jump around to express your enjoyment. After this you should immediately bookmark or share this site on your favorite social site. And while you're at it [I could use another coffee](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=krema%40jpberlin%2ede&item_name=kremalicious%2ecom%20%2d%20Buy%20me%20a%20coffee%20or%20two%20or%20three%20or%20more&no_shipping=1&return=http%3a%2f%2fwww%2ekremalicious%2ecom%2fthank%2dyou%2f&tax=0¤cy_code=EUR&lc=US&bn=PP%2dDonationsBF&charset=UTF%2d8). - -And that's it. diff --git a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/share-link-bonanza-coda-clips.zip b/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/share-link-bonanza-coda-clips.zip deleted file mode 100644 index 712a971d..00000000 Binary files a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/share-link-bonanza-coda-clips.zip and /dev/null differ diff --git a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/share-link-bonanza-html.zip b/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/share-link-bonanza-html.zip deleted file mode 100644 index 6324cf06..00000000 Binary files a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/share-link-bonanza-html.zip and /dev/null differ diff --git a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/tutorial-icon.png b/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/tutorial-icon.png deleted file mode 100644 index 55512c70..00000000 Binary files a/content/articles/2009-03-29-ultimate-coda-wordpress-share-link-bonanza/tutorial-icon.png and /dev/null differ diff --git a/package-lock.json b/package-lock.json index e661842f..3941f2d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@astrojs/react": "^3.0.2", "@astrojs/rss": "^3.0.0", "@astrojs/sitemap": "^3.0.0", - "@astrojs/ts-plugin": "^1.1.3", + "@nanostores/query": "^0.2.4", "@nanostores/react": "^0.7.1", "@rainbow-me/rainbowkit": "^1.0.11", "astro": "3.2.2", @@ -73,7 +73,6 @@ "svgo": "^3.0.2", "ts-node": "^10.9.1", "typescript": "^5.2.2", - "typescript-plugin-css-modules": "^5.0.1", "unist-util-visit": "^5.0.0", "vite-tsconfig-paths": "^4.2.1", "vitest": "^0.34.6" @@ -302,18 +301,6 @@ "node": ">=18.14.1" } }, - "node_modules/@astrojs/ts-plugin": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@astrojs/ts-plugin/-/ts-plugin-1.1.3.tgz", - "integrity": "sha512-nErNpgHGMzOOBHmUdml3cEZv4nxowGpO4G+IfAsPBQXOKLLGbVXzNpIGrdIthk3ryGD3jsYOKBvv2/PrnTkRdA==", - "dependencies": { - "@astrojs/compiler": "1.5.7", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@volar/language-core": "~1.10.0", - "@volar/typescript": "~1.10.0", - "vscode-languageserver-textdocument": "^1.0.8" - } - }, "node_modules/@babel/code-frame": { "version": "7.22.13", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", @@ -1993,6 +1980,20 @@ "tslib": "^2.3.1" } }, + "node_modules/@nanostores/query": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@nanostores/query/-/query-0.2.4.tgz", + "integrity": "sha512-DCQWQsqjABf4/5eN4opGt9MbD6opNxGyewmR/yRAEB999WCl+Cgz6G6WTy37KiKNRjkBP0yK6GN6BEvgnhDoIQ==", + "dependencies": { + "nanoevents": "7" + }, + "engines": { + "node": "^14.0.0 || ^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "nanostores": ">0.7" + } + }, "node_modules/@nanostores/react": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@nanostores/react/-/react-0.7.1.tgz", @@ -2765,24 +2766,6 @@ "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" }, - "node_modules/@types/postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-0VLab/pcLTLcfbxi6THSIMVYcw9hEUBGvjwwaGpW77mMgRXfGF+a76t7BxTGyLh1y68tBvrffp8UWnqvm76+yg==", - "dev": true, - "dependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/@types/postcss-modules-scope": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/postcss-modules-scope/-/postcss-modules-scope-3.0.1.tgz", - "integrity": "sha512-LNkp3c4ML9EQj2dgslp4i80Jxj72YK3HjYzrTn6ftUVylW1zaKFGqrMlNIyqBmPWmIhZ/Y5r0Y4T49Hk1IuDUg==", - "dev": true, - "dependencies": { - "postcss": "^8.0.0" - } - }, "node_modules/@types/prop-types": { "version": "15.7.6", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.6.tgz", @@ -5756,7 +5739,8 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "is-what": "^3.14.1" }, @@ -6590,18 +6574,6 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" - } - }, "node_modules/dset": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.2.tgz", @@ -6675,6 +6647,7 @@ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "optional": true, + "peer": true, "dependencies": { "prr": "~1.0.1" }, @@ -8658,18 +8631,6 @@ "node": ">=0.10.0" } }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/identity-obj-proxy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", @@ -8714,6 +8675,7 @@ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", "optional": true, + "peer": true, "bin": { "image-size": "bin/image-size.js" }, @@ -8725,7 +8687,8 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", - "devOptional": true + "optional": true, + "peer": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -9299,7 +9262,8 @@ "version": "3.14.1", "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", - "devOptional": true + "optional": true, + "peer": true }, "node_modules/is-wsl": { "version": "3.1.0", @@ -9775,7 +9739,8 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", "integrity": "sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -9802,6 +9767,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "optional": true, + "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -9811,6 +9777,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "optional": true, + "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -9823,6 +9790,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "optional": true, + "peer": true, "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -9836,6 +9804,7 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "optional": true, + "peer": true, "bin": { "mime": "cli.js" }, @@ -9848,6 +9817,7 @@ "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", "optional": true, + "peer": true, "dependencies": { "debug": "^3.2.6", "iconv-lite": "^0.6.3", @@ -9865,6 +9835,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "optional": true, + "peer": true, "engines": { "node": ">=6" } @@ -9874,6 +9845,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "optional": true, + "peer": true, "bin": { "semver": "bin/semver" } @@ -9891,15 +9863,6 @@ "node": ">= 0.8.0" } }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -10032,12 +9995,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true - }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -12582,6 +12539,14 @@ "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" }, + "node_modules/nanoevents": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/nanoevents/-/nanoevents-7.0.1.tgz", + "integrity": "sha512-o6lpKiCxLeijK4hgsqfR6CNToPyRU3keKyyI6uwuHRvpRTbZ0wXw51WRgyldVugZqoJfkGFrjrIenYH3bfEO3Q==", + "engines": { + "node": "^14.0.0 || ^16.0.0 || >=18.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -13312,7 +13277,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.10" } @@ -13652,35 +13618,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postcss-load-config": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", - "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", - "dev": true, - "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^1.10.2" - }, - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", @@ -13688,50 +13625,6 @@ "dev": true, "optional": true }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", - "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", - "dev": true, - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, "node_modules/postcss-nested": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", @@ -14068,7 +13961,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "optional": true + "optional": true, + "peer": true }, "node_modules/psl": { "version": "1.9.0", @@ -15742,12 +15636,6 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "dev": true }, - "node_modules/reserved-words": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", - "integrity": "sha512-0S5SrIUJ9LfpbVl4Yzij6VipUdafHrOTzvmfazSw/jeZrZtQK303OPZW+obtkaw7jQlTQppy0UvZWm9872PbRw==", - "dev": true - }, "node_modules/resolve": { "version": "1.22.6", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", @@ -16254,7 +16142,8 @@ "version": "1.68.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.68.0.tgz", "integrity": "sha512-Lmj9lM/fef0nQswm1J2HJcEsBUba4wgNx2fea6yJHODREoMFnwRpZydBnX/RjyXw2REIwdkbqE4hrTo4qfDBUA==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -17232,7 +17121,8 @@ "version": "0.59.0", "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.59.0.tgz", "integrity": "sha512-lQ9w/XIOH5ZHVNuNbWW8D822r+/wBSO/d6XvtyHLF7LW4KaCIDeVbvn5DF8fGCJAUCwVhVi/h6J0NUcnylUEjg==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "@adobe/css-tools": "^4.0.1", "debug": "^4.3.2", @@ -17254,7 +17144,8 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -17274,7 +17165,8 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">= 8" } @@ -17745,20 +17637,6 @@ } } }, - "node_modules/tsconfig-paths": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", - "dev": true, - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/tsconfig-resolver": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/tsconfig-resolver/-/tsconfig-resolver-3.0.1.tgz", @@ -17962,33 +17840,6 @@ "semver": "^7.3.8" } }, - "node_modules/typescript-plugin-css-modules": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/typescript-plugin-css-modules/-/typescript-plugin-css-modules-5.0.1.tgz", - "integrity": "sha512-hKXObfwfjx2/myRq4JeQ8D3xIWYTFqusi0hS/Aka7RFX1xQEoEkdOGDWyXNb8LmObawsUzbI30gQnZvqYXCrkA==", - "dev": true, - "dependencies": { - "@types/postcss-modules-local-by-default": "^4.0.0", - "@types/postcss-modules-scope": "^3.0.1", - "dotenv": "^16.0.3", - "icss-utils": "^5.1.0", - "less": "^4.1.3", - "lodash.camelcase": "^4.3.0", - "postcss": "^8.4.21", - "postcss-load-config": "^3.1.4", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "reserved-words": "^0.1.2", - "sass": "^1.58.3", - "source-map-js": "^1.0.2", - "stylus": "^0.59.0", - "tsconfig-paths": "^4.1.2" - }, - "peerDependencies": { - "typescript": ">=4.0.0" - } - }, "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -19793,15 +19644,6 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index 4d8b092d..7b9b0004 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "preview": "astro preview", "typecheck:astro": "astro check", "typecheck:tsc": "tsc --noEmit --pretty", - "typecheck": "astro sync && run-p typecheck:astro typecheck:tsc", + "typecheck": "npm run typecheck:astro && npm run typecheck:tsc", "prebuild": "run-p --silent --continue-on-error create:symlinks create:icons move:downloads", "test:unit": "vitest run --config './test/vitest.config.ts' --coverage", "test:e2e": "playwright test --config './test/playwright.config.ts'", @@ -35,7 +35,7 @@ "@astrojs/react": "^3.0.2", "@astrojs/rss": "^3.0.0", "@astrojs/sitemap": "^3.0.0", - "@astrojs/ts-plugin": "^1.1.3", + "@nanostores/query": "^0.2.4", "@nanostores/react": "^0.7.1", "@rainbow-me/rainbowkit": "^1.0.11", "astro": "3.2.2", @@ -95,7 +95,6 @@ "svgo": "^3.0.2", "ts-node": "^10.9.1", "typescript": "^5.2.2", - "typescript-plugin-css-modules": "^5.0.1", "unist-util-visit": "^5.0.0", "vite-tsconfig-paths": "^4.2.1", "vitest": "^0.34.6" diff --git a/src/components/Footer/Networks.astro b/src/components/Footer/Networks.astro index 6f7ac89e..20e321d3 100644 --- a/src/components/Footer/Networks.astro +++ b/src/components/Footer/Networks.astro @@ -9,7 +9,7 @@ type Props = { const { links } = Astro.props --- -

+

{ links.map((link: string) => ( @@ -25,4 +25,4 @@ const { links } = Astro.props )) } -

+
diff --git a/src/components/Footer/Networks.module.css b/src/components/Footer/Networks.module.css index 2e3ca9a8..dca39a2d 100644 --- a/src/components/Footer/Networks.module.css +++ b/src/components/Footer/Networks.module.css @@ -1,3 +1,7 @@ +.networks { + margin-top: calc(var(--spacer) / 2); +} + .link { text-align: center; width: 2rem; diff --git a/src/components/Footer/Vcard.astro b/src/components/Footer/Vcard.astro index 6431fccc..e8bb0cd5 100644 --- a/src/components/Footer/Vcard.astro +++ b/src/components/Footer/Vcard.astro @@ -1,6 +1,7 @@ --- import { Image } from 'astro:assets' import Networks from './Networks.astro' +import Location from '../Location' import avatar from '@images/avatar.jpg' import config from '@config/blog.config' import styles from './Vcard.module.css' @@ -19,10 +20,12 @@ const links = [mastodon, github, rss, jsonfeed] />

- {config.siteDescription.replace(name, '')}{' '} + {config.siteDescription.replace(name, '')}

+ + diff --git a/src/components/Footer/Vcard.module.css b/src/components/Footer/Vcard.module.css index 34be7194..09a983ea 100644 --- a/src/components/Footer/Vcard.module.css +++ b/src/components/Footer/Vcard.module.css @@ -9,10 +9,9 @@ .description { font-size: var(--font-size-h5); - margin-top: 0; - margin-bottom: calc(var(--spacer) / var(--line-height)); + margin: 0; } .description a { - display: block; + display: inline-block; } diff --git a/src/components/Footer/index.astro b/src/components/Footer/index.astro index d559bb3a..60230ba0 100644 --- a/src/components/Footer/index.astro +++ b/src/components/Footer/index.astro @@ -21,7 +21,7 @@ const { name, url, github } = config.author View source - + Say Thanks diff --git a/src/components/Footer/index.module.css b/src/components/Footer/index.module.css index c2777495..d4108cd2 100644 --- a/src/components/Footer/index.module.css +++ b/src/components/Footer/index.module.css @@ -11,42 +11,31 @@ position: fixed; width: 100%; border: 0; - will-change: transform; z-index: 0; bottom: 0; - box-shadow: none; } } -.btc code { - font-size: 0.6rem; - background: none; - color: var(--link-color); - padding: 0; +.copyright { + margin-top: calc(var(--spacer) / var(--line-height)); + font-size: var(--font-size-mini); + color: var(--text-color-light); } .copyright p { margin-bottom: 0; - font-size: var(--font-size-mini); } -.copyright a, -.copyright button code { +.copyright a { color: var(--text-color-light); -} - -.copyright a, -.copyright button { margin-left: var(--spacer); } -.copyright a:hover, -.copyright button code { +.copyright a:hover { color: var(--link-color); } -.copyright a:first-child, -.copyright button:first-child { +.copyright a:first-child { margin-left: 0; } diff --git a/src/components/Location/Flag.tsx b/src/components/Location/Flag.tsx new file mode 100644 index 00000000..31f6c475 --- /dev/null +++ b/src/components/Location/Flag.tsx @@ -0,0 +1,23 @@ +import styles from './index.module.css' + +type Props = { + country: { + name: string + code: string + } +} + +export function Flag({ country }: Props) { + // offset between uppercase ascii and regional indicator symbols + const OFFSET = 127397 + + const emoji = country?.code.replace(/./g, (char) => + String.fromCodePoint(char.charCodeAt(0) + OFFSET) + ) + + return ( + + {emoji} + + ) +} diff --git a/src/components/Location/LocationItem.tsx b/src/components/Location/LocationItem.tsx new file mode 100644 index 00000000..40bb7fda --- /dev/null +++ b/src/components/Location/LocationItem.tsx @@ -0,0 +1,32 @@ +import type { ReactElement } from 'react' +import { Flag } from './Flag' + +type LocationProps = { + country: string + countryCode: string + city: string + time: string + showFlag?: boolean +} + +export function LocationItem({ + country, + countryCode, + city, + time, + showFlag = true +}: LocationProps): ReactElement { + return ( + <> + {showFlag && ( + + )} + {city} {time} + + ) +} diff --git a/src/components/Location/index.module.css b/src/components/Location/index.module.css new file mode 100644 index 00000000..9c6468d6 --- /dev/null +++ b/src/components/Location/index.module.css @@ -0,0 +1,41 @@ +.location { + font-size: var(--font-size-mini); + min-height: 36px; +} + +.location span { + font-style: italic; +} + +.emoji { + display: inline-block; + font-size: 1em; + line-height: 1em; + vertical-align: 'middle'; + margin-right: calc(var(--spacer) / 6); +} + +.next { + display: inline-block; + margin-left: calc(var(--spacer) / 3); +} + +.loading { + display: inline-block; + margin-left: calc(var(--spacer) / 3); + animation: flicker 0.3s linear infinite; +} + +@keyframes flicker { + 0% { + opacity: 0; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} diff --git a/src/components/Location/index.test.tsx b/src/components/Location/index.test.tsx new file mode 100644 index 00000000..26e7ee4c --- /dev/null +++ b/src/components/Location/index.test.tsx @@ -0,0 +1,94 @@ +import { + describe, + it, + expect, + beforeAll, + afterAll, + vi, + type SpyInstance +} from 'vitest' +import { render, screen } from '@testing-library/react' +import * as nanostores from '@nanostores/react' +import Location from '.' + +const mockData = { + now: { + country: 'USA', + country_code: 'US', + city: 'New York' + }, + next: { + country: 'Canada', + country_code: 'CA', + city: 'Toronto', + date_start: '2023-10-05' + } +} + +describe('Location component', () => { + let useStoreSpy: SpyInstance + + beforeAll(() => { + vi.mock('@nanostores/react') + useStoreSpy = vi.spyOn(nanostores, 'useStore') + }) + + afterAll(() => { + vi.restoreAllMocks() + }) + + it('renders the location items correctly', () => { + useStoreSpy.mockImplementationOnce(() => ({ + data: mockData, + loading: false, + error: null + })) + + render() + + expect(screen.getByLabelText('USA')).toBeInTheDocument() + expect(screen.getByText('New York')).toBeInTheDocument() + expect(screen.getByLabelText('Canada')).toBeInTheDocument() + expect(screen.getByText('Toronto')).toBeInTheDocument() + }) + + it('renders the loading indicator', () => { + useStoreSpy.mockImplementationOnce(() => ({ + data: null, + loading: true, + error: null + })) + + render() + + expect(screen.getByText('...')).toBeInTheDocument() + }) + + it('renders empty when there is no data', () => { + useStoreSpy.mockImplementationOnce(() => ({ + data: null, + loading: false, + error: null + })) + + render() + + expect(screen.queryByLabelText('Location')).toBeEmptyDOMElement() + }) + + it('renders nothing and logs error when error is encountered', () => { + const consoleErrorSpy = vi.spyOn(console, 'error') + useStoreSpy.mockImplementationOnce(() => ({ + data: null, + loading: false, + error: 'Error' + })) + + render() + + expect(screen.queryByLabelText('Location')).not.toBeInTheDocument() + expect(consoleErrorSpy).toHaveBeenCalledWith( + 'Failed to fetch location: Error' + ) + }) +}) diff --git a/src/components/Location/index.tsx b/src/components/Location/index.tsx new file mode 100644 index 00000000..2b1173f2 --- /dev/null +++ b/src/components/Location/index.tsx @@ -0,0 +1,45 @@ +import { useStore } from '@nanostores/react' +import { $location } from '@stores/location' +import { formatDistanceToNowStrict } from 'date-fns' +import { LocationItem } from './LocationItem' +import styles from './index.module.css' + +export default function Location() { + const { data, loading, error } = useStore($location) + if (error) { + console.error(`Failed to fetch location: ${error}`) + return null + } + + return ( +
+ {loading && !data ? ( + ... + ) : data?.now?.city ? ( + <> + + +
+ {data.next?.city && ( + + )} +
+ + ) : null} +
+ ) +} diff --git a/src/components/PostTeaser/index.astro b/src/components/PostTeaser/index.astro index 611c8db7..fd577115 100644 --- a/src/components/PostTeaser/index.astro +++ b/src/components/PostTeaser/index.astro @@ -1,5 +1,5 @@ --- -import PostTitle from '../layouts/Post/Title.astro' +import PostTitle from '@layouts/Post/Title.astro' import styles from './index.module.css' import Picture from '@components/Picture/index.astro' import type { CollectionEntry } from 'astro:content' diff --git a/src/components/layouts/Post/PrevNext.astro b/src/components/layouts/Post/PrevNext.astro deleted file mode 100644 index dcc9d04f..00000000 --- a/src/components/layouts/Post/PrevNext.astro +++ /dev/null @@ -1,41 +0,0 @@ ---- -import styles from './PrevNext.module.css' -import { ChevronLeft, ChevronRight } from '@images/components' - -interface Node { - title: string - slug: string -} - -type Props = { - prev: Node - next: Node -} - -const { prev, next } = Astro.props ---- - - diff --git a/src/components/layouts/Post/PrevNext.module.css b/src/components/layouts/Post/PrevNext.module.css deleted file mode 100644 index ac36e5f5..00000000 --- a/src/components/layouts/Post/PrevNext.module.css +++ /dev/null @@ -1,50 +0,0 @@ -.prevnext { - margin-top: calc(var(--spacer) * 2); - padding-top: calc(var(--spacer) * 2); - display: grid; - gap: var(--spacer); - grid-template-columns: 1fr 1fr; -} - -.prevnext svg { - stroke: var(--text-color-light); - margin-top: -0.05rem; - position: absolute; - left: 0.1rem; - top: calc(var(--spacer) * 1.1); -} - -.prevnext > div { - position: relative; -} - -.prevnext > div:first-child { - padding-left: var(--spacer); -} - -.prevnext > div:last-child { - padding-right: var(--spacer); - text-align: right; -} - -.prevnext > div:last-child svg { - right: 0.1rem; - left: auto; -} - -.title { - font-size: var(--font-size-large); - margin: 0; - color: var(--brand-grey-light) !important; -} - -a:hover .title { - color: var(--link-color) !important; -} - -.label { - margin-bottom: calc(var(--spacer) / 4); - font-size: var(--font-size-small); - color: var(--text-color-light); - opacity: 0.65; -} diff --git a/src/components/layouts/Archive.astro b/src/layouts/Archive.astro similarity index 100% rename from src/components/layouts/Archive.astro rename to src/layouts/Archive.astro diff --git a/src/components/layouts/Base/Head.astro b/src/layouts/Base/Head.astro similarity index 100% rename from src/components/layouts/Base/Head.astro rename to src/layouts/Base/Head.astro diff --git a/src/components/layouts/Base/SchemaOrg.astro b/src/layouts/Base/SchemaOrg.astro similarity index 100% rename from src/components/layouts/Base/SchemaOrg.astro rename to src/layouts/Base/SchemaOrg.astro diff --git a/src/components/layouts/Base/index.astro b/src/layouts/Base/index.astro similarity index 91% rename from src/components/layouts/Base/index.astro rename to src/layouts/Base/index.astro index 5368d4e5..f3c39c28 100644 --- a/src/components/layouts/Base/index.astro +++ b/src/layouts/Base/index.astro @@ -1,6 +1,6 @@ --- -import '../../../styles/global.css' -import '../../../styles/imports.css' +import '../../styles/global.css' +import '../../styles/imports.css' import type { ImageMetadata } from 'astro' import type { CollectionEntry } from 'astro:content' diff --git a/src/components/layouts/Base/index.module.css b/src/layouts/Base/index.module.css similarity index 100% rename from src/components/layouts/Base/index.module.css rename to src/layouts/Base/index.module.css diff --git a/src/components/layouts/Post/Action.astro b/src/layouts/Post/Action.astro similarity index 100% rename from src/components/layouts/Post/Action.astro rename to src/layouts/Post/Action.astro diff --git a/src/components/layouts/Post/Actions.astro b/src/layouts/Post/Actions.astro similarity index 100% rename from src/components/layouts/Post/Actions.astro rename to src/layouts/Post/Actions.astro diff --git a/src/components/layouts/Post/Actions.module.css b/src/layouts/Post/Actions.module.css similarity index 100% rename from src/components/layouts/Post/Actions.module.css rename to src/layouts/Post/Actions.module.css diff --git a/src/components/layouts/Post/Date.astro b/src/layouts/Post/Date.astro similarity index 100% rename from src/components/layouts/Post/Date.astro rename to src/layouts/Post/Date.astro diff --git a/src/components/layouts/Post/LinkActions.astro b/src/layouts/Post/LinkActions.astro similarity index 100% rename from src/components/layouts/Post/LinkActions.astro rename to src/layouts/Post/LinkActions.astro diff --git a/src/components/layouts/Post/LinkActions.module.css b/src/layouts/Post/LinkActions.module.css similarity index 100% rename from src/components/layouts/Post/LinkActions.module.css rename to src/layouts/Post/LinkActions.module.css diff --git a/src/components/layouts/Post/Meta.astro b/src/layouts/Post/Meta.astro similarity index 100% rename from src/components/layouts/Post/Meta.astro rename to src/layouts/Post/Meta.astro diff --git a/src/components/layouts/Post/Meta.module.css b/src/layouts/Post/Meta.module.css similarity index 100% rename from src/components/layouts/Post/Meta.module.css rename to src/layouts/Post/Meta.module.css diff --git a/src/components/layouts/Post/Title.astro b/src/layouts/Post/Title.astro similarity index 100% rename from src/components/layouts/Post/Title.astro rename to src/layouts/Post/Title.astro diff --git a/src/components/layouts/Post/Title.module.css b/src/layouts/Post/Title.module.css similarity index 100% rename from src/components/layouts/Post/Title.module.css rename to src/layouts/Post/Title.module.css diff --git a/src/components/layouts/Post/index.astro b/src/layouts/Post/index.astro similarity index 97% rename from src/components/layouts/Post/index.astro rename to src/layouts/Post/index.astro index 53f26ef7..22a37c71 100644 --- a/src/components/layouts/Post/index.astro +++ b/src/layouts/Post/index.astro @@ -68,7 +68,5 @@ const { linkurl } = data as CollectionEntry<'links'>['data'] {collection !== 'photos' && } - - {/* */} diff --git a/src/components/layouts/Post/index.module.css b/src/layouts/Post/index.module.css similarity index 100% rename from src/components/layouts/Post/index.module.css rename to src/layouts/Post/index.module.css diff --git a/src/pages/[...slug].astro b/src/pages/[...slug].astro index 02a96418..9f3d4ff8 100644 --- a/src/pages/[...slug].astro +++ b/src/pages/[...slug].astro @@ -3,8 +3,6 @@ import LayoutPost from '@layouts/Post/index.astro' import { getAllPosts } from '@lib/astro' import type { InferGetStaticPropsType } from 'astro' -type Props = InferGetStaticPropsType - export async function getStaticPaths() { const allPosts = await getAllPosts() @@ -19,6 +17,8 @@ export async function getStaticPaths() { }) } +type Props = InferGetStaticPropsType + const { entry } = Astro.props const { Content, remarkPluginFrontmatter } = await entry.render() --- diff --git a/src/pages/archive/[page].astro b/src/pages/archive/[page].astro index ff920505..00489e89 100644 --- a/src/pages/archive/[page].astro +++ b/src/pages/archive/[page].astro @@ -1,7 +1,7 @@ --- import { loadAndFormatCollection } from '@lib/astro' import type { GetStaticPathsOptions, InferGetStaticPropsType } from 'astro' -import LayoutArchive from '@components/layouts/Archive.astro' +import LayoutArchive from '@layouts/Archive.astro' import config from '@config/blog.config' type Props = InferGetStaticPropsType diff --git a/src/pages/photos/[page].astro b/src/pages/photos/[page].astro index 6d7e65ed..2e4e150f 100644 --- a/src/pages/photos/[page].astro +++ b/src/pages/photos/[page].astro @@ -1,7 +1,7 @@ --- import type { GetStaticPathsOptions, InferGetStaticPropsType } from 'astro' import { loadAndFormatCollection } from '@lib/astro' -import LayoutArchive from '@components/layouts/Archive.astro' +import LayoutArchive from '@layouts/Archive.astro' import config from '@config/blog.config' type Props = InferGetStaticPropsType diff --git a/src/pages/tags/[tag].astro b/src/pages/tags/[tag].astro index 8dec71a7..c2a04070 100644 --- a/src/pages/tags/[tag].astro +++ b/src/pages/tags/[tag].astro @@ -6,7 +6,7 @@ import type { Page } from 'astro' import { getAllTags, getPostsByTag } from '@lib/astro' -import LayoutArchive from '@components/layouts/Archive.astro' +import LayoutArchive from '@layouts/Archive.astro' type Props = InferGetStaticPropsType & { page: Page> diff --git a/src/pages/tags/index.astro b/src/pages/tags/index.astro index db341f35..e9e31bbd 100644 --- a/src/pages/tags/index.astro +++ b/src/pages/tags/index.astro @@ -1,7 +1,7 @@ --- import { getAllTags } from '@lib/astro' import Tag from '@components/Tag.astro' -import LayoutBase from '@components/layouts/Base/index.astro' +import LayoutBase from '@layouts/Base/index.astro' const allTags = await getAllTags() --- diff --git a/src/stores/fetcher.ts b/src/stores/fetcher.ts new file mode 100644 index 00000000..b28bdbee --- /dev/null +++ b/src/stores/fetcher.ts @@ -0,0 +1,6 @@ +import { nanoquery } from '@nanostores/query' + +export const [createFetcherStore, createMutatorStore] = nanoquery({ + fetcher: (...keys: (string | number)[]) => + fetch(keys.join('')).then((r) => r.json()) +}) diff --git a/src/stores/location.ts b/src/stores/location.ts new file mode 100644 index 00000000..d6db50a0 --- /dev/null +++ b/src/stores/location.ts @@ -0,0 +1,24 @@ +import { createFetcherStore } from './fetcher' + +export type Location = { + country: string + city: string + country_code: string + date_start: string + date_end: string +} + +export type LocationStore = + | { + now: Location + next: Location + previous: Location + } + | undefined + +const url = 'https://location.kremalicious.com' + +export const $location = createFetcherStore([url], { + refetchOnReconnect: true, + refetchOnFocus: true +}) diff --git a/tsconfig.json b/tsconfig.json index 4d510173..6fe8bdd5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,26 +2,21 @@ "extends": "astro/tsconfigs/strict", "compilerOptions": { "jsx": "react-jsx", - "plugins": [ - { "name": "typescript-plugin-css-modules" }, - { "name": "@astrojs/ts-plugin" } - ], "jsxImportSource": "react", "baseUrl": ".", "paths": { "@config/*": [".config/*"], "@components/*": ["src/components/*"], - "@layouts/*": ["src/components/layouts/*"], + "@layouts/*": ["src/layouts/*"], "@images/*": ["src/images/*"], "@lib/*": ["src/lib/*"], - "@hooks/*": ["src/hooks/*"], "@stores/*": ["src/stores/*"], "@content/*": ["content/*"], "@test/*": ["test/*"] }, "typeRoots": ["./src/@types", "./node_modules/@types"] }, - "exclude": ["node_modules", "dist", ".cache", "src/images/components"], + "exclude": ["src/images/components", "src/content"], "include": [ "src/**/*", "content/**/*",