00:00:16.320
Alright, while these responses are coming in, it looks like quite a few people have either handcrafted HTML and CSS applications. I'm not sure if they are built as single-page applications or if they are simply deploying straight-up Rails applications with all the logic on the server side.
00:00:23.590
That's good to hear! I hope you'll learn something new today about how my company, Poll Everywhere, works. The product you are seeing is a software as a service application, and we sell this to presenters based on audience size. So, I'm going to fire up the slides here.
00:00:40.630
Alright, my display settings are working, which is good. So, let’s jump into it. This presentation is titled "Middleman: The Missing View in the Rails API Stack." As I mentioned before, I'm Brad Gessler, the CTO and co-founder of Poll Everywhere. We started this company about six years ago, and we have always been mobile-first, initially focusing on SMS.
00:01:11.560
We've gone through all the pains of upgrading to the second vintage of mobile-first, which is basically a mobile website. We had a lot of fun doing that and learned many things the hard way. But first, what is Middleman? How many of you have heard of Jekyll in this room? That seems to be the predominant static website generator.
00:01:31.360
If you go to Ruby Toolbox and ask, "Hey, what should I use to generate a static website?" you are likely to get Jekyll as a recommendation. However, Middleman is not like Jekyll in that it uses many modern Ruby gems commonly found in Rails 4 and Rails 3. For instance, it uses Tilt to manage templating and Sass, and all that good stuff.
00:02:09.399
So, if you're looking for a tool to build a static site, don't be discouraged by the comparisons to Jekyll; you should feel a lot better about Middleman after this talk. Middleman is extraordinarily well documented. Thomas Reynolds is the mastermind behind it, and he built an amazing website with comprehensive documentation.
00:02:31.360
If you go to middlemanapp.com, you'll find everything you need about this static site generator. Another fantastic aspect of Middleman is its modularity; it uses Rack under the hood. So, if you understand Rack, you can write lots of extensions for Middleman, which is quite impressive for a static site generator.
00:03:02.820
There’s also an extension framework, allowing you to roll out features like a Middleman blog. Essentially, Middleman is a drop-in replacement for Jekyll, with a few additional features. If you are used to writing GitHub-flavored Markdown, there are some tweaks you'll need to make to get everything functioning smoothly.
00:03:40.900
Getting started with Middleman is also quite similar to starting a Rails application. You install the gem, initialize the application, and it creates all of this boilerplate code. You get a directory structure that includes your configuration file, a default index HTML ERB file, a layout file, and all your assets, such as stylesheets and JavaScripts. You can spin up the server, and it boots extremely fast; you can have everything working in under a second.
00:04:25.630
One thing I love about Middleman is how easy it is to come into it from Rails. As I mentioned before, it uses Tilt, so you can bring in all the same gems and the same toolset that you hopefully have come to love in Rails without too much trouble. Another interesting aspect of Middleman is that it is multi-environment aware.
00:05:00.820
This is a default configuration from Middleman, simplified a bit. In your development environment, you can include various extensions, like live reload. You can pull these extensions from the directory on the Middleman website. In production, Middleman refers to this as the build environment, where you'd activate certain extensions like minifying CSS or JavaScript, or using asset hashing.
00:05:39.760
Once you have this configuration set up and your web pages ready to go, you need to deploy them. This is another area where Middleman truly shines. Deployments are incredibly easy—it's just two steps. First, there’s the build command, which compiles all these templates and files into a build directory.
00:06:26.270
The best part is that getting that build directory up to your web server is as simple as an rsync command. If you want to throw back to the days of using Dreamweaver, you could still use FTP or SFTP, if you're into security. I developed a gem called Shart to facilitate this process, humorously hoping it would spark awkward IT conversations in corporate environments.
00:06:50.100
With Shart, you can deploy your Middleman website to an S3 bucket and set the headers for certain assets. There are tons of tools available for this, and deploying to S3 is incredibly cost-effective—just a few cents a month for a personal website. It’s also a highly scalable solution for your static websites.
00:07:14.790
So, now that you have a static website, you might wonder why you should care about Middleman. How is it going to help you scale your application? To answer that, it’s crucial to understand Middleman’s place in this spectrum of dynamic and static applications.
00:07:49.640
I refer to this spectrum as "Dyna-scizzum." But it turns out, 'dinah scizzum' is not actually a word, so I had to ignore the spell checker. The graph I mentioned earlier represented a static web application. If you access pollev.com on your smartphone, that was another static web application.
00:08:06.430
However, that was a rather dynamic application because the chart had to move, animate, and pull data from the server in real-time under one second. We needed to ensure that this data could get from all your phones—whether through SMS or smartphones—up to the graph very quickly. So, this is a highly dynamic application.
00:08:54.470
Additionally, we needed to make everything very smooth and fluid for presentations. As we move down the Dyna-scizzum spectrum, we have GUI-oriented applications, such as Google Spreadsheets. Most people are familiar with that; it involves many different actions that need to be swift. You don’t want to build applications where you click a button and wait for a server response.
00:09:41.280
The functions of the GUI should be closely coupled with the server operations. We then move into document-oriented web apps like invoicing applications or Basecamp, which sit in the sweet spot between highly dynamic applications and highly static applications. Moving further down is the blogging platform world, with systems like Subtle or Posthaven that are backed by MySQL.
00:10:31.560
For the most part, they simply store documents in a database server for convenience in administering numerous users and a multi-tenant environment. At the bottom of the spectrum are personal blogs, possibly hosted on GitHub using Jekyll or Middleman, and informational websites like small local businesses.
00:11:04.830
So, where does Middleman fit into all of this? If you're working on a greenfield application, it’s straightforward to get started. You typically build your single-page application and a smaller API using Sinatra or some micro-framework.
00:11:39.030
Since we started as a company in 2008, we initially built our application using Rails 1.2, even before REST was a thing. We set up an application on pollev.com, and we incorporated real-time components. I don't know if anyone remembers RJS, but back then, we used those horrendous helpers to emit JavaScript from the server to your web page.
00:12:42.000
We achieved a lot with that, but eventually realized we needed something more visually appealing than just updating numbers in a table. So, we turned to Flex, which offered a great bar chart library that updated in real-time and just worked out of the box. It also just happened that Flash was installed on an overwhelming majority of networking machines, which made it easy to embed Flex assets in PowerPoint.
00:13:56.620
We executed a quirky hack where we would embed those Flex applications in PowerPoint slides and let people download polls already embedded in their slides. When they opened it, nothing actually needed to load from the Wi-Fi at the conference; the Flex application connects directly to our Rails app to pull that data.
00:14:38.210
Initially, we had this Flex application within the same repository as our Rails application, but as we grew and scaled, things became more complex. Eventually, we could afford a contractor who worked on the Flex app, enhancing it and enabling faster deployments. This led us to separate the applications, allowing our Rails app team to push updates independently.
00:15:41.650
Over time, mobile started evolving beyond just SMS, primarily thanks to the advent of the iPhone. We had good luck in the past with frameworks like Rails and some visual components from Flex, which naturally led us to use jQuery Mobile. At that time, some suggested using the .mobi extension to serve up mobile content, but that turned out to be a poor decision.
00:16:27.170
jQuery Mobile worked for about 80% of our needs, but the last 20% was extraordinarily painful. We found jQuery Mobile to be extremely prescriptive in how it structured DOM elements, and it felt somewhat clunky to work with. This led the team to rethink our approach: instead of choosing one rigid framework, we opted to focus on the specific problems we needed to solve.
00:17:14.670
By selecting specific libraries for each task, we created a much clearer development path and brought in what we needed for our application. Around that time, various JavaScript MVC frameworks emerged, including SproutCore, but we decided to move forward with Backbone.js.
00:18:03.300
At the time, it was still maturing, and we knew we might need to switch libraries as things evolved. This approach enabled us to handpick the exact libraries we needed and to swap them out when we found better options. Our result was a single-page mobile application built entirely within Middleman.
00:19:17.790
Middleman handled all the assets for this application using the standard Sprockets pipeline found in Rails. Whenever we built the application, we ended up with three files that we uploaded to our NGINX server, and we were very happy with how everything functioned in production, especially regarding deployments.
00:20:40.020
If you choose to build single-page web applications, you should be aware of CORS (Cross-Origin Resource Sharing). When you loaded pollev.com on your phone, it made AJAX requests to our API endpoint, and without CORS, you would receive cross-domain errors. CORS allowed our server to whitelist requests.
00:21:52.700
Another interesting feature of how we deployed this mobile app was its ease of deployment to CDNs. You can push your assets out to separate servers, which isn’t as feasible with a Rails app since you can't just move it over to a different server's filesystem without booting everything up.
00:22:56.220
A fun and unexpected feature we discovered was the ability to deploy our application onto floppy disks! I had floppy drives, available for about 15 dollars on Amazon, and surprisingly, MacOS supports floppy drives, which made for an amusing live hardware demo.
00:23:36.080
Imagine having a customer in a remote area, and the only way to get something to them is via Pony Express. You could place this floppy disk in a satchel and send it off. It was quite amusing to see the Network Inspector reveal the latency issue of booting up a web application from a floppy disk.
00:24:26.000
While joking about creating a library called ‘Floppy.js’ due to limitations with large assets not fitting, it would illustrate that our primary focus was still on fixing production bugs instead. More importantly, you can package hollow applications with HTML assets through PhoneGap. We had customers who wanted to bundle our polling application with their mobile apps.
00:25:50.010
We provided our HTML assets to integrate within their applications. So even when 300 people are in a conference room voting, it wouldn’t overload the Wi-Fi. That said, Flex began aging, and the writing was on the wall for its eventual obsolescence.
00:26:54.300
This gave us a natural driving purpose: to create a visualization app. We decided to utilize Middleman, aiming to build something that works on tablets and iPhones, leveraging HTML5 to communicate with our JSON API. It worked remarkably well, and today, you are witnessing that HTML5 application in action.
00:27:54.410
We have all the advantages of caching and CDNs with this application. However, a challenge arose when we started noticing slow performance with our visualizations because we depended on short polling—hitting our server to get new data every few seconds to update our graphs.
00:29:06.190
To improve this, we rolled out a streaming API. At that time, we also wrote our own server as Socket.io didn’t meet our needs. I previously gave a talk in 2012 on streaming resources, and we set up our stream server on a separate host, isolating it. Even during this experimentation, we faced stability issues.
00:30:29.490
However, our client-side applications were able to seamlessly fall back to HTTP short polling whenever there were issues with the stream. Over time, the team became much better at handling these elements, managing client-side service-oriented architecture (SOA). Additionally, CORS enabled us to consume multiple APIs and combine their data in JavaScript.
00:31:27.770
We found so much success with these Middleman single-page applications that we started to develop all our other applications in this manner. Our approach to native integrations evolved into creating specialized web browsers with unique JavaScript hooks, allowing web developers to be more productive and versatile.
00:32:15.950
We've had numerous Backbone.js applications emerge from this work. Now, if you’re dealing with various applications, you may think about reevaluating your strategy to prevent redundancy and achieve better organization in a world filled with Sprockets and Middleman.
00:33:04.960
We extracted common components—session components, models, and Backbone—into one asset gem for all applications to consume from. So, building these gems becomes just like creating any other gem with Bundler, allowing us to manage dependency versions seamlessly.
00:33:25.800
Utilizing Bundler, we prevent breaking changes when updating libraries; we can continue using the versions we specify in our gem bundles. We host our assets in a Git repository and reference them in a gemfile, enabling local updates during development.
00:34:16.870
Whenever a branch is updated in the Pull of Assets repository, changes get picked up the next time you reload Middleman without restarting the whole server. This allows for a smooth feature-building process, as we can branch our Rails app project and the Middleman project simultaneously. Ultimately, we can deploy them in the correct order, with APIs implemented first.
00:35:05.150
Does it work? Yes, it has worked remarkably well for us—especially when infrastructure gets complicated, such as dealing with bandwidth-constrained environments or unreliable conference Wi-Fi. Just two months ago, Microsoft launched their PowerPoint 2013 app store.
00:36:00.290
We managed to pull many assets from our mobile application into our Sprockets asset gem to reuse most of that work. Quick customizations enabled us to integrate smoothly with Office 2013. Whether you're running a single-page application inside an iframe in Office, it feels very native.
00:37:05.350
This practice of reusing functionality proved beneficial. Working on any given project often results in improvements—better handling of logins or status codes or similar features. These improvements can be integrated back into the Sprockets asset gem and pushed out to other projects, leading to system-wide benefits.
00:37:56.090
This reinforcement of functionality turns the Sprockets asset gem into a cohesive framework, extracted in a way that is both practical and successful for our customers. That was an overview of one of the more complex Middleman deployments, illustrating how to manage multiple projects while highlighting the adaptable nature of Middleman.
00:39:02.300
One downside is there is no out-of-the-box JavaScript MVC app solution in Middleman. For example, when using Backbone, you're responsible for organizing a lot of the assets, which may vary in quality across different frameworks. This situation was a boon for us, as it compelled us to create our own, sidestepping issues related to someone else's less-than-ideal framework.
00:39:59.790
Lastly, let's address static websites on the other end of the spectrum where Rails balances everything in the middle. We're developing a lot of content for our website, with an explosion of use cases demanding implementation. One thought on our front is to extract a content directory from our Rails app.
00:40:54.540
Raise your hands if your Rails app started with a home page, then evolved into a content directory with twenty or thirty pages. Before long, that repository becomes a disorganized junk drawer of pages. In Middleman, the directory structure is also the routing structure, simplifying organization.
00:41:34.290
Middleman offers much better support for aspects like image compression, enabling designers to focus on creating while Middleman optimizes images for the web. For static websites like this, you can't simply ignore components like login states; JavaScript can help maintain some dynamism.
00:42:38.930
You can implement client-side checks to verify if a user is logged in by checking cookies, and you can integrate server interactions through forms. Furthermore, you can add other JavaScript applications like Google Analytics, Optimizely, or Stripe, enhancing functionality while keeping your site primarily static.
00:43:33.910
The advantage of static websites is their resilience; they don't get easily taken down, especially if hosted on S3 buckets or CDNs. I attended a Middleman meetup a year ago, where attendees mentioned their CMS or dynamic back end kept slowing down their website due to press mentions.
00:44:44.370
Instead of throwing money at the problem, they opted for building a static website with Middleman and deploying it on simple servers, eliminating those traffic issues. There are many considerations to take into account when building these Middleman applications.
00:45:49.610
I could probably give several more talks solely focused on this, and I'd be happy to answer questions later. I encourage everyone to try building their next website using Middleman! Whether it's a personal website, a blog, or something else—give it a shot.
00:46:45.460
You can migrate your hand-crafted setups into Middleman and start leveraging the asset pipeline. Furthermore, I didn't mention that my company, Poll Everywhere, is also working on extracting the framework and will be releasing these components as ‘Fanny Pack.’ Fanny Pack will handle testing, binding to different environments, and more.
00:47:30.960
If you’d like to work on Middleman projects professionally, consider joining our team at Poll Everywhere. That concludes my talk. I'm Brad Gessler, and I will be sharing slides, links, and code on Twitter when I’m not busy working on these projects. Thank you!
00:48:12.560
Thank you.