Slides and Demo for Building Progressive Web Apps using CFML

Thanks everyone for coming to my talk at cf.Objective() 2017! If you missed my talk, or just want to learn more about Progressive Web Apps, feel free to browse the links below.

Browse the slides at http://slides.com/awayken/2017cfobjective

Find the code at https://github.com/awayken/pwa-marketing-site

Building Progressive Web Apps using CFML at cf.Objective() 2017

I’m giving a talk at cf.Objective() 2017. It’s called: Building Progressive Web Apps using CFML. If you, or someone you know (or someone you don’t know, I guess), is attending cf.Objective next week, check out my talk on July 20th, 11:00 AM – 12:00 PM.

Progressive Web Apps are more than just a UI fad, like parallax or scroll-triggered animations. PWAs are quickly becoming the best practice for creating reliable, fast and engaging user experiences. Like progressive enhancement, which treated JavaScript as an optional enhancement for a website, progressive web apps treat the network itself as an optional enhancement. By treating the network as untrustworthy, developers are forced to create better web apps that capitalize on modern browser features when they exist and fallback to traditional client-server communication when they don’t.

This talk builds the most cutting-edge client technologies upon the solid foundations of ColdBox, giving CFML developers a helpful path into the future. Google has been a strong supporter and proponent of PWAs and the Offline First movement, but their examples and toolkits make too many or too few assumptions about the reader’s server technology. This talk will use ColdBox and Lucee (through CommandBox) as the server language, allowing CFML developers to wrap their heads about this new movement and hopefully incorporate its philosophy and techniques into their existing and upcoming projects.

Learn more on the cf.Objective() website.

A Technique for Tracking Page Print Using CSS Background Images

Printing a web page is still one of the most popular ways that customers interact with a classifieds search engine. At AutoConX, we try to track that metric for our sellers, so they can see how frequently people print off their listings for safe keeping. Our legacy platform presents users a print-dedicated page to track such details. But what is a modern, responsive technique for tracking that kind of interaction? I wanted something that could target printing by any means possible: triggering a JavaScript print event, using browser keyboard shortcuts or menu items and even using the cloud printing capabilities on mobile devices. CSS’s print media seemed like the way to go.

First, how to handle the actual tracking. A common technique involves creating a “tracking pixel.” When an image tag is dropped into the page, it appears to load a small, transparent gif. What actually happens is that special code executes behind the scenes and just returns data in the form of a small, transparent pixel. I crafted a 1px by 1px transparent gif as the tracking pixel and created a handler event that would call a stored procedure that would track the print in the database. Then the handler would return the data from the transparent pixel to the browser to be rendered as any other image. The CFML code roughly looked like this:

Next, I needed to use that URL as the `src` for an image. I dropped an image tag into a section of code already setup to show only for print media. The section displays a QR code and canonical URL so people with the paper version can get back to the web version. It looked like this:

I opened Chrome Dev Tools, chose the Network panel and reloaded the page. A call to my tracking pixel was made even though the image was hidden from the screen. This is an age old situation that has made it necessary to create new tags like picture and attributes like srcset for displaying different images for different browser scenarios. It was worth a shot, but now I knew this wouldn’t be as easy as I’d hoped.

Let’s try the stylesheet instead. I created the selector `.detail--trackprint` and used my tracking pixel as a background image. It looked like this:

I reloaded the page and… oh, right. CSS URLs are relative to the CSS file. Another rookie mistake. What I needed is something that is relative to the executing page so that the CFML framework gets the appropriate listing information needed for tracking. I tried briefly to use data attributes to build my background image URL, but the `attr()` function is still only good for content. Inline styling would be my best bet. I modified my original view:

I reloaded the page and watched the Network. No call. I emulated print media and reloaded the page. CALL! Success! I deployed the code to our dev server and put some other team members on QA. They weren’t seeing tracking counts as high as they should be. I dug into it with my own testing and found that the browsers (I saw this behavior in several of them) were caching the print preview after the first print. It makes sense and saves the browser some work and data transfer. However, I need to get as close to accurate as possible. I added a cachebuster to the background image:

This proved to be the solution we needed. But it doesn’t track every print! I know. This technique is equivalent to what we have in our legacy system, so in that sense it is a responsive implementation of the same accuracy our sellers already have. I could add some long polling JavaScript to increment the cachebuster while the page is loaded. This would give us
stats on the same page without reloading, but that seems overkill for a secondary metric. That number still wouldn’t be entirely accurate, because users can print more than one copy at a time. In the end, this was just enough development to meet the needs of the sellers.

Building AVR, Part 4: CSS Architecture

Once AIM was built, we needed a product to display the inventory that had been managed. The AutoConX Vertical (Responsive), or AVR, is a white-label product that allows publishers (newspaper or magazine) list inventory from sellers in their area. It’s a digital classified system that offers a lot of customization and flexibility.

This project was trickier than AIM because AIM was a brand new product. AVR, however, had to be a modern and responsive site that met all the publishers’ expectations from the legacy product. Publishers wouldn’t switch unless they saw real value in the new system. We had to build a product that we would put our own products on.

This is the story of the CSS architecture for AVR.

Continue reading “Building AVR, Part 4: CSS Architecture”

Building AVR, Part 3: JavaScript Architecture

Once AIM was built, we needed a product to display the inventory that had been managed. The AutoConX Vertical (Responsive), or AVR, is a white-label product that allows publishers (newspaper or magazine) list inventory from sellers in their area. It’s a digital classified system that offers a lot of customization and flexibility.

This project was trickier than AIM because AIM was a brand new product. AVR, however, had to be a modern and responsive site that met all the publishers’ expectations from the legacy product. Publishers wouldn’t switch unless they saw real value in the new system. We had to build a product that we would put our own products on.

This is the story of the JavaScript architecture for AVR.

Continue reading “Building AVR, Part 3: JavaScript Architecture”

Building AVR, Part 2: CFML Architecture

Once AIM was built, we needed a product to display the inventory that had been managed. The AutoConX Vertical (Responsive), or AVR, is a white-label product that allows publishers (newspaper or magazine) list inventory from sellers in their area. It’s a digital classified system that offers a lot of customization and flexibility.

This project was trickier than AIM because AIM was a brand new product. AVR, however, had to be a modern and responsive site that met all the publishers’ expectations from the legacy product. Publishers wouldn’t switch unless they saw real value in the new system. We had to build a product that we would put our own products on.

This is the story of the CFML architecture for AVR.

Continue reading “Building AVR, Part 2: CFML Architecture”

Building AVR, Part 1: Project Architecture

Once AIM was built, we needed a product to display the inventory that had been managed. The AutoConX Vertical (Responsive), or AVR, is a white-label product that allows publishers (newspaper or magazine) list inventory from sellers in their area. It’s a digital classified system that offers a lot of customization and flexibility.

This project was trickier than AIM because AIM was a brand new product. AVR, however, had to be a modern and responsive site that met all the publishers’ expectations from the legacy product. Publishers wouldn’t switch unless they saw real value in the new system. We had to build a product that we would put our own products on.

This is the story of the project architecture for AVR.

Continue reading “Building AVR, Part 1: Project Architecture”

Building AIM, Part 4: CSS Architecture

We needed to build an inventory system, one that was free from the restrictions of our legacy system. We wanted to build a system that could describe any piece of inventory: from cars to carpets, from houses to job listings. We needed an interface for our sellers to actually manage that inventory. That interface is the AutoConX Inventory Manager, which we call AIM.

This is the story of the CSS architecture for AIM.

Continue reading “Building AIM, Part 4: CSS Architecture”

Building AIM, Part 3: JavaScript Architecture

We needed to build an inventory system, one that was free from the restrictions of our legacy system. We wanted to build a system that could describe any piece of inventory: from cars to carpets, from houses to job listings. We needed an interface for our sellers to actually manage that inventory. That interface is the AutoConX Inventory Manager, which we call AIM.

This is the story of the JavaScript architecture for AIM.

Continue reading “Building AIM, Part 3: JavaScript Architecture”

Building AIM, Part 2: CFML Architecture

We needed to build an inventory system, one that was free from the restrictions of our legacy system. We wanted to build a system that could describe any piece of inventory: from cars to carpets, from houses to job listings. We needed an interface for our sellers to actually manage that inventory. That interface is the AutoConX Inventory Manager, which we call AIM.

This is the story of the CFML architecture for AIM.

Continue reading “Building AIM, Part 2: CFML Architecture”

Building AIM, Part 1: Project Architecture

We needed to build an inventory system, one that was free from the restrictions of our legacy system which could only describe automotive, agricultural and recreational inventory for dealerships across the United States. We wanted to build a system that could describe any piece of inventory: from cars to carpets, from houses to job listings. The process started with our database structure and maintenance areas. Then came a REST API to give us a nice separation of concerns. Once that was in place, we needed an interface for our sellers to actually manage that inventory. That interface is the AutoConX Inventory Manager, which we call AIM.

This is the story of the project architecture for AIM.

Continue reading “Building AIM, Part 1: Project Architecture”

(2016) Best of Last Year

It’s time for the (2016) Best of Last Year mixlist!

It’s rare (exceedingly rare) that I get the playlist finalized before June. Life (in the form of kids, wife, job, inherent and pervasive laziness) tends to take over. Not this year, though! I murdered my wife and kids which caused me to lose my job! (Just kidding.)

I was surprised by this year’s list. Some decidedly “Top 40” tracks made their way in, but it was through the brilliant, musical mastery of the artist. My favorite album of the year ended up being the soundtrack to a musical I haven’t seen. And peppered between are new tracks by long-loved artists and undiscovered tracks that wouldn’t let me go.

See the playlist and listen to it on my (2016) Best of Last Year mixlist.

(2015) Best of Last Year

Every year I evaluate the best of the music I discovered during the previous 365 days. My aim is to get the playlist finalized in January, but life usually exerts itself instead. And this is it! The moment you’ve all been waiting for! The (2015) Best of Last Year mixlist!

(Yea! Hurrah! Awesome! Uh, what… what is this, now?)

Some old favorites released disappointing albums in the past year, while some up-and-comers released phenomenal ones. Ben Folds and Death Cab for Cutie both had new releases that failed to resonate with me. Meanwhile, Cold War Kids, The Decemberists and Shakey Graves really brought it home.

There’s some EDM, some covers and even some French hip-hop in the mix (so to speak). I guess there’s a little something for everyone! (Unless you really love polka; there’s no polka.)

See the playlist and listen to it on my (2015) Best of Last Year mixlist.