Tags: calendar

41

sparkline

Thursday, December 6th, 2018

Mistletoe Offline

This article first appeared in 24 Ways, the online advent calendar for geeks.

It’s that time of year, when we gather together as families to celebrate the life of the greatest person in history. This man walked the Earth long before us, but he left behind words of wisdom. Those words can guide us every single day, but they are at the forefront of our minds during this special season.

I am, of course, talking about Murphy, and the golden rule he gave unto us:

Anything that can go wrong will go wrong.

So true! I mean, that’s why we make sure we’ve got nice 404 pages. It’s not that we want people to ever get served a File Not Found message, but we acknowledge that, despite our best efforts, it’s bound to happen sometime. Murphy’s Law, innit?

But there are some Murphyesque situations where even your lovingly crafted 404 page won’t help. What if your web server is down? What if someone is trying to reach your site but they lose their internet connection? These are all things than can—and will—go wrong.

I guess there’s nothing we can do about those particular situations, right?

Wrong!

A service worker is a Murphy-battling technology that you can inject into a visitor’s device from your website. Once it’s installed, it can intercept any requests made to your domain. If anything goes wrong with a request—as is inevitable—you can provide instructions for the browser. That’s your opportunity to turn those server outage frowns upside down. Take those network connection lemons and make network connection lemonade.

If you’ve got a custom 404 page, why not make a custom offline page too?

Get your server in order

Step one is to make …actually, wait. There’s a step before that. Step zero. Get your site running on HTTPS, if it isn’t already. You won’t be able to use a service worker unless everything’s being served over HTTPS, which makes sense when you consider the awesome power that a service worker wields.

If you’re developing locally, service workers will work fine for localhost, even without HTTPS. But for a live site, HTTPS is a must.

Make an offline page

Alright, assuming your site is being served over HTTPS, then step one is to create an offline page. Make it as serious or as quirky as is appropriate for your particular brand. If the website is for a restaurant, maybe you could put the telephone number and address of the restaurant on the custom offline page (unsolicited advice: you could also put this on the home page, you know). Here’s an example of the custom offline page for this year’s Ampersand conference.

When you’re done, publish the offline page at suitably imaginative URL, like, say /offline.html.

Pre-cache your offline page

Now create a JavaScript file called serviceworker.js. This is the script that the browser will look to when certain events are triggered. The first event to handle is what to do when the service worker is installed on the user’s device. When that happens, an event called install is fired. You can listen out for this event using addEventListener:

addEventListener('install', installEvent => {
// put your instructions here.
}); // end addEventListener

In this case, you want to make sure that your lovingly crafted custom offline page is put into a nice safe cache. You can use the Cache API to do this. You get to create as many caches as you like, and you can call them whatever you want. Here, I’m going to call the cache Johnny just so I can refer to it as JohnnyCache in the code:

addEventListener('install', installEvent => {
  installEvent.waitUntil(
    caches.open('Johnny')
    .then( JohnnyCache => {
      JohnnyCache.addAll([
       '/offline.html'
      ]); // end addAll
     }) // end open.then
  ); // end waitUntil
}); // end addEventListener

I’m betting that your lovely offline page is linking to a CSS file, maybe an image or two, and perhaps some JavaScript. You can cache all of those at this point:

addEventListener('install', installEvent => {
  installEvent.waitUntil(
    caches.open('Johnny')
    .then( JohnnyCache => {
      JohnnyCache.addAll([
       '/offline.html',
       '/path/to/stylesheet.css',
       '/path/to/javascript.js',
         '/path/to/image.jpg'
      ]); // end addAll
     }) // end open.then
  ); // end waitUntil
}); // end addEventListener

Make sure that the URLs are correct. If just one of the URLs in the list fails to resolve, none of the items in the list will be cached.

Intercept requests

The next event you want to listen for is the fetch event. This is probably the most powerful—and, let’s be honest, the creepiest—feature of a service worker. Once it has been installed, the service worker lurks on the user’s device, waiting for any requests made to your site. Every time the user requests a web page from your site, a fetch event will fire. Every time that page requests a style sheet or an image, a fetch event will fire. You can provide instructions for what should happen each time:

addEventListener('fetch', fetchEvent => {
// What happens next is up to you!
}); // end addEventListener

Let’s write a fairly conservative script with the following logic:

  • Whenever a file is requested,
  • First, try to fetch it from the network,
  • But if that doesn’t work, try to find it in the cache,
  • But if that doesn’t work, and it’s a request for a web page, show the custom offline page instead.

Here’s how that translates into JavaScript:

// Whenever a file is requested
addEventListener('fetch', fetchEvent => {
  const request = fetchEvent.request;
  fetchEvent.respondWith(
    // First, try to fetch it from the network
    fetch(request)
    .then( responseFromFetch => {
      return responseFromFetch;
    }) // end fetch.then
    // But if that doesn't work
    .catch( fetchError => {
      // try to find it in the cache
      caches.match(request)
      .then( responseFromCache => {
        if (responseFromCache) {
         return responseFromCache;
       // But if that doesn't work
       } else {
         // and it's a request for a web page
         if (request.headers.get('Accept').includes('text/html')) {
           // show the custom offline page instead
           return caches.match('/offline.html');
         } // end if
       } // end if/else
     }) // end match.then
   }) // end fetch.catch
  ); // end respondWith
}); // end addEventListener

I am fully aware that I may have done some owl-drawing there. If you need a more detailed breakdown of what’s happening at each point in the code, I’ve written a whole book for you. It’s the perfect present for Murphymas.

Hook up your service worker script

You can publish your service worker script at /serviceworker.js but you still need to tell the browser where to look for it. You can do that using JavaScript. Put this in an existing JavaScript file that you’re calling in to every page on your site, or add this in a script element at the end of every page’s HTML:

if (navigator.serviceWorker) {
  navigator.serviceWorker.register('/serviceworker.js');
}

That tells the browser to start installing the service worker, but not without first checking that the browser understands what a service worker is. When it comes to JavaScript, feature detection is your friend.

You might already have some JavaScript files in a folder like /assets/js/ and you might be tempted to put your service worker script in there too. Don’t do that. If you do, the service worker will only be able to handle requests made to for files within /assets/js/. By putting the service worker script in the root directory, you’re making sure that every request can be intercepted.

Go further!

Nicely done! You’ve made sure that if—no, when—a visitor can’t reach your website, they’ll get your hand-tailored offline page. You have temporarily defeated the forces of chaos! You have briefly fought the tide of entropy! You have made a small but ultimately futile gesture against the inevitable heat-death of the universe!

This is just the beginning. You can do more with service workers.

What if, every time you fetched a page from the network, you stored a copy of that page in a cache? Then if that person tries to reach that page later, but they’re offline, you could show them the cached version.

Or, what if instead of reaching out the network first, you checked to see if a file is in the cache first? You could serve up that cached version—which would be blazingly fast—and still fetch a fresh version from the network in the background to pop in the cache for next time. That might be a good strategy for images.

So many options! The hard part isn’t writing the code, it’s figuring out the steps you want to take. Once you’ve got those steps written out, then it’s a matter of translating them into JavaScript.

Inevitably there will be some obstacles along the way—usually it’s a misplaced curly brace or a missing parenthesis. Don’t be too hard on yourself if your code doesn’t work at first. That’s just Murphy’s Law in action.

Tuesday, December 4th, 2018

Mistletoe Offline ◆ 24 ways

They let me write a 24 Ways article again. Will they never learn?

This one’s a whirlwind tour of using a service worker to provide a custom offline page, in the style of Going Offline.

By the way, just for the record, I initially rejected this article’s title out of concern that injecting a Cliff Richard song into people’s brains was cruel and unusual punishment. I was overruled.

Thursday, May 31st, 2018

Design Patterns on CodePen

This ever-growing curated collection of interface patterns on CodePen is a reliable source of inspiration.

UTC is Enough for Everyone, Right?

A wonderful—and humorous—deep dive into all things time-related.

Building a calendar sucks. Like there’s really cool shit you can do, since every calendar out there today is basically straight outta 2005, but at the end of the day you’re stuck dealing with all of the edge cases that all your dork friends have warned you about since the dawn of time. (Like literally, the dawn of time is a separate edge case you have to account for as well.)

This also contains a well-deserved shout-out to ISO 8601:

ISO 8601 is one of my favorite standards and/or RFC out there. And yes, you should definitely have a favorite.

I do have a favourite RFC—ask me about it sometime over a beer.

Tuesday, October 3rd, 2017

Robtober 2017 | Rob Weychert

What an excellent example of a responsive calendar!

Thursday, January 19th, 2017

Making input type=date complicated – Samsung Internet Developers – Medium

PPK has posted some excellent thinking on calendar widgets to Ev’s blog.

Monday, August 4th, 2014

Open standards for contact details and calendar events | Technology at GDS

I’ve been suggesting h-event and h-card as open standards for UK government sites.

Wednesday, December 14th, 2011

HTML5 and CSS3 Advent 2011

Here’s a geek advent calendar I missed. There are some great CSS techniques here.

Thursday, February 17th, 2011

Microformats | weblog | Facebook Adds hCalendar and hCard Microformats to Millions of Events

As of today, every single public event on Facebook is marked up using hCalendar. Take the Great British Booze-up, for example…

Sunday, December 5th, 2010

Time Zones

A very handy tool for planning intercontinental communication.

Wednesday, December 1st, 2010

Adfonting

It’s the start of the Christmas season. I know it’s the start of the Christmas season, not just because Brighton is currently blanketed in snow, but also because 24 Ways—the advent calendar for geeks—has kicked off with its first article. Hurray! And this year, all of the articles will be available as a book from Five Simple Steps for a mere £8, with all the proceeds going to charity. Grab a copy before the end of December because this is a time-limited offer.

This year, 24 Ways isn’t the only advent calendar for geeks. While I was off galavanting up and down the west coast of the US last month, my cohorts at Clearleft were scheming up a little something special: an advent calendar for fonts. Every day, for 24 days, release a Fontdeck font for one year’s free use.

When they told me, I thought “great idea!” …then they told me they were going to call it an “adfont” calendar and there was much groaning and gnashing of teeth.

The Adfont Calendar 2010 (groan) is now live.

The lovely visual design comes courtesy of Michelle, the latest addition to the Clearleft team, and it mimics a type case; just like the one we happen to have in the office. Every office needs a type case.

Originally, the interface was going to be one looooong type case with some JavaScript layered on top to allow smooth horizontal navigation. But when Rich asked me for some advice on implementing it, I steered him down a different path. Instead of displaying everything horizontally, why not use media queries to show just enough drawers to fit the user’s browser window and allow the rest to stack vertically?

I didn’t think he’d take my challenge seriously but he’s only gone and bloody done it!

Adfont Calendar — 480 Adfont Calendar — 960 Adfont Calendar — 1280 Adfont Calendar — 1680 Adfont Calendar — 2320

Have a poke around and see what’s behind drawer number one.

Saturday, November 27th, 2010

Adfont Calendar 2010 | A free font every day from Fontdeck

It's a type drawer that's also an advent calendar. Responsive too. Check it every day between December 1st and 24th.

Friday, October 1st, 2010

the nerds are on the march

Geek Calendar is a celebration of the nerdishness of contemporary British life. It's also a project to raise money for libel reform.

Thursday, December 10th, 2009

appvent calendar 2009 | every day a free iPhone game

A free iPhone/iPod Touch game for every day of advent.

Tuesday, August 25th, 2009

The Value Class Pattern - Articles - MIX Online

A microformats article by yours truly, reworking a blog post from a while back about the value class pattern.

Thursday, May 14th, 2009

The Worldwide System

A proposal for decimal time and measurement. It'll never defeat inertia but I love seeing the thought process that's gone into it.

Thursday, December 25th, 2008

The Ten Days of Newton - Olivia Judson Blog - NYTimes.com

On the tenth day of Newton, My true love gave to me, Ten drops of genius, Nine silver co-oins, Eight circling planets, Seven shades of li-ight, Six counterfeiters, Cal-Cu-Lus! Four telescopes, Three Laws of Motion, Two awful feuds, And …

Wednesday, December 10th, 2008

SitePoint » 4 Easy-to-Use Microformat Tools to Beef Up Your Site

A rundown of microformat-extracting tools. "Ultimately, microformats are a bit like plumbing. They don’t do very much on their own, but if you make use of the data they provide, you can quickly and easily create useful functionality your visitors …

Monday, December 8th, 2008

Hubble Space Telescope Advent Calendar 2008 - The Big Picture - Boston.com

An advent calendar from the Hubble telescope. Check back every day for a new image.

Thursday, December 4th, 2008

PHP Advent Calendar 2008

Like 24 Ways, this is an advent calendar for geeks. But this one is focused on PHP.