Tags: php

35

sparkline

Monday, June 24th, 2019

Am I cached or not?

When I was writing about the lie-fi strategy I’ve added to adactio.com, I finished with this thought:

What I’d really like is some way to know—on the client side—whether or not the currently-loaded page came from a cache or from a network. Then I could add some kind of interface element that says, “Hey, this page might be stale—click here if you want to check for a fresher version.”

Trys heard my plea, and came up with a very clever technique to alter the HTML of a page when it’s put into a cache.

It’s a function that reads the response body stream in, returning a new stream. Whilst reading the stream, it searches for the character codes that make up: <html. If it finds them, it tacks on a data-cached attribute.

Nice!

But then I was discussing this issue with Tantek and Aaron late one night after Indie Web Camp Düsseldorf. I realised that I might have another potential solution that doesn’t involve the service worker at all.

Caveat: this will only work for pages that have some kind of server-side generation. This won’t work for static sites.

In my case, pages are generated by PHP. I’m not doing a database lookup every time you request a page—I’ve got a server-side cache of posts, for example—but there is a little bit of assembly done for every request: get the header from here; get the main content from over there; get the footer; put them all together into a single page and serve that up.

This means I can add a timestamp to the page (using PHP). I can mark the moment that it was served up. Then I can use JavaScript on the client side to compare that timestamp to the current time.

I’ve published the code as a gist.

In a script element on each page, I have this bit of coducken:

var serverTimestamp = <?php echo time(); ?>;

Now the JavaScript variable serverTimestamp holds the timestamp that the page was generated. When the page is put in the cache, this won’t change. This number should be the number of seconds since January 1st, 1970 in the UTC timezone (that’s what my server’s timezone is set to).

Starting with JavaScript’s Date object, I use a caravan of methods like toUTCString() and getTime() to end up with a variable called clientTimestamp. This will give the current number of seconds since January 1st, 1970, regardless of whether the page is coming from the server or from the cache.

var localDate = new Date();
var localUTCString = localDate.toUTCString();
var UTCDate = new Date(localUTCString);
var clientTimestamp = UTCDate.getTime() / 1000;

Then I compare the two and see if there’s a discrepency greater than five minutes:

if (clientTimestamp - serverTimestamp > (60 * 5))

If there is, then I inject some markup into the page, telling the reader that this page might be stale:

document.querySelector('main').insertAdjacentHTML('afterbegin',`
  <p class="feedback">
    <button onclick="this.parentNode.remove()">dismiss</button>
    This page might be out of date. You can try <a href="javascript:window.location=window.location.href">refreshing</a>.
  </p>
`);

The reader has the option to refresh the page or dismiss the message.

This page might be out of date. You can try refreshing.

It’s not foolproof by any means. If the visitor’s computer has their clock set weirdly, then the comparison might return a false positive every time. Still, I thought that using UTC might be a safer bet.

All in all, I think this is a pretty good method for detecting if a page is being served from a cache. Remember, the goal here is not to determine if the user is offline—for that, there’s navigator.onLine.

The upshot is this: if you visit my site with a crappy internet connection (lie-fi), then after three seconds you may be served with a cached version of the page you’re requesting (if you visited that page previously). If that happens, you’ll now also be presented with a little message telling you that the page isn’t fresh. Then it’s up to you whether you want to have another go.

I like the way that this puts control back into the hands of the user.

Saturday, March 9th, 2019

Updating email addresses with Mailchimp’s API

I’ve been using Mailchimp for years now to send out a weekly newsletter from The Session. But I never visit the Mailchimp website. Instead, I use the API to create a campaign each week, and then send it out. I also use the API whenever a member of The Session updates their email preferences (or changes their details).

I got an email from Mailchimp that their old API was being deprecated and I’d need to update to their more recent one. The code I was using had been happily running for about seven years, but now I’d have to change it.

Luckily, Drew has written a really handy Mailchimp API wrapper for PHP, the language that The Session’s codebase is in. Thanks, Drew! I downloaded that wrapper and updated my code accordingly.

Everything went pretty smoothly. I was able to create campaigns, send campaigns, add new subscribers, and delete subscribers. But I ran into an issue when I wanted to update someone’s email address (on The Session, you can edit your details at any time, including your email address).

Here’s the set up:

use \DrewM\MailChimp\MailChimp;
$MailChimp = new MailChimp('abc123abc123abc123abc123abc123-us1');
$list_id = 'b1234346';
$subscriber_hash = $MailChimp -> subscriberHash('currentemail@example.com');
$endpoint = 'lists/'.$listID.'/members/'.$subscriber_hash;

Now to update details, according to the API, I can use the patch method on that endpoint:

$MailChimp -> patch($endpoint, [
    'email_address' => 'newemail@example.com'
]);

But that doesn’t work. Mailchimp effectively treats email addresses as unique IDs for subscribers. So the only way to change someone’s email address appears to be to delete them, and then subscribe them fresh with the new email address:

$MailChimp -> delete($endpoint);
$newendpoint = 'lists/'.$listID.'/members';
$MailChimp -> post($newendpoint, [
    'email_address' => 'newemail@example.com',
    'status' => 'subscribed'
]);

That’s somewhat annoying, as the previous version of the API allowed email addresses to be updated, but this workaround isn’t too arduous.

Anyway, I figured it share this just in case it was useful for anyone else migrating to the newer API.

Update: Belay that. Turns out that you can update email addresses, but you have to be sure to include the status value:

$MailChimp -> patch($endpoint, [
    'email_address' => 'newemail@example.com',
    'status' => 'subscribed'
]);

Okay, that’s a lot more straightforward. Ignore everything I said.

Sunday, November 25th, 2018

Quick Note: Setting up a localhost on a Mac | scottohara.me

Okay, I knew about the Python shortcut—I mentioned it in Going Offline—but I had no idea it was so easy to do the same thing for PHP. This is a bit of a revelation for me!

Once in the desired directory, run:

php -S localhost:2222

Now you can go to “localhost:2222” in your browser, and if you have an index.html or .php file in your root directory, you’re in business.

Tuesday, September 26th, 2017

Essential Vanilla JavaScript Functions

The title is overkill, but these functions ported from PHP to JavaScript could be useful (especially for dealing with arrays).

Tuesday, August 22nd, 2017

A few technical words about Upsideclown, and some thoughts about audiences and the web (17 Aug., 2017, at Interconnected)

Matt writes about the pleasure of independent publishing on the web today:

It feels transgressive to have a website in 2017. Something about having a domain name and about coding HTML which is against the grain now. It’s something big companies do, not small groups. We’re supposed to put our content on Facebook or Medium, or keep our publishing to an email newsletter. But a website?

But he points out a tension between the longevity that you get from hosting the canonical content yourself, and the lack of unified analytics when you syndicate that content elsewhere.

There’s no simple online tool that lets me add up how many people have read a particular story on Upsideclown via the website, the RSS feed, and the email newsletter. Why not? If I add syndication to Facebook, Google, and Apple, I’m even more at sea.

Thursday, January 19th, 2017

bastianallgeier/letter: Letter is a simple, highly customizable tool to create letters in your browser.

A nice little use of print (and screen) styles from Bastian—compose letters in a web browser.

Instead of messing around in Word, Pages or even Indesign, you can write your letters in the browser, export them as HTML or PDF (via Apple Preview).

Tuesday, January 12th, 2016

VerbalExpressions/JSVerbalExpressions

Regular expressions are my kryptonite so I can definitely imagine using the PHP port of this plain English syntax.

Sunday, June 28th, 2015

100 words 098

When I’m grilling outside, I cook on a gas barbecue. There are quite a few people who would take issue with this. Charcoal is clearly better, they claim. And they’re right. But the thing is, I can fire up my gas barbecue quickly and just get down to cooking.

When I’m programming on the server, I code in PHP. There are quite a few people who would take issue with this. Any other language is clearly better, they claim. And they’re right. But the thing is, I can fire up my text editor quickly and just get down to coding.

Saturday, June 13th, 2015

PHP is the right tool for the job (for all the wrong reasons) - Sam says you should read this

I think there’s a lot of truth to this. By any objective measurement, PHP is clearly inferior to just about every other programming language out there …but its preinstalled out-of-the-box nature means it’s the path of least resistance.

Friday, December 12th, 2014

bramus/mixed-content-scan

A really handy command-line tool that scans your site for mixed content — very useful if you’re making the switch from http to https.

Sunday, October 20th, 2013

Unfashionably profitable

Rachel talks about some of the old-fashioned technologies and business practices driving Perch.

This reminds of a talk by Marco Arment at Webstock a few years back when he described the advantages of not using cutting-edge technologies: most of the time, “boring” well-established technologies are simply more stable.

Tuesday, June 4th, 2013

Craft a better web.

A new PHP-based content management system. It uses Twig for the templating, which I like.

Saturday, November 19th, 2011

Pattern primer

I’m on a workshopping roll. Fresh from running my Responsive Enhancement workshop in Belfast, I’m now heading to Düsseldorf for Beyond Tellerand where I’ll be running the workshop on Sunday (and if you can’t make it, don’t forget that you can book the workshop for your own workplace too).

As part of the process of building a responsive site from the content out rather than the canvas in, I talk about beginning with the individual components divorced from any layout context. Or, as Mark puts it, “start with the bits.”

That’s the way I’ve been starting most of my projects lately: beginning with the atomic units of content and styling them first before even thinking about layout. This ensures that those styles are extremely robust—because they don’t depend on any particular context, they can be safely dropped into any part of a page.

I’ve been calling this initial collection of markup snippets a pattern primer. To help create the pattern primer, I’ve written a little bit of PHP to automatically generate a page of patterns from a folder of HTML snippets.

In my workshop I keep promising to put that script on Github. I finally got around to doing that and you can find it at github.com/adactio/Pattern-Primer.

Take a look at an example pattern primer to get an idea of what a handy deliverable this can be if you’re handing off to other developers. It also acts like a page of unit tests for CSS—whenever you’ve been messing around in the stylesheet you can refresh the page to quickly check to see if anything looks screwed up.

Grab the code; improve upon it; share your changes.

Thursday, August 25th, 2011

Responsive HTML images

If you’re trying to retrofit an existing desktop-centric site for small screens, this server-side image-resizing technique might be useful but is definitely not the right tool for a content-out, small-screen-first approach.

Thursday, June 23rd, 2011

Markdownify: The HTML to Markdown converter for PHP

This could be handy for the editing process in my home-grown blogging system: a PHP script to convert HTML back to Markdown.

Friday, August 21st, 2009

Amazon® AWS HMAC signed request using PHP

Since Amazon decided to require signed requests for its API, I'm going to have to use this code to keep Huffduffer and The Session working. Grrrr... cool APIs don't change.

Saturday, August 1st, 2009

Let's make the web faster - Google Code

A whole heap of optimisation techniques from Google for faster CSS, JavaScript, markup and PHP.

Monday, July 6th, 2009

PHP Typography 1.0 beta 3 • KINGdesk

A PHP script that adds nice typography to your markup.

Tuesday, June 30th, 2009

PHP: goto - Manual

Wait... I thought this was considered harmful?

Monday, June 1st, 2009

Welcome - Perch - A Really Little Content Management System (CMS)

Drew and Rachel's little CMS looks very nice indeed.