BRAD GESSLER: All right. So, while these are, 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're single-page application, or just deploy straight-up Rails applications or all the logic on the server-side. So that's good. I, I hope you'll learn something new today about how my company, Poll Everywhere, which the, the product is what you're seeing. We're a software as a service company. We just sell this to presenters based on audience size. So, I'm gonna fire up the slides here. All right. My display settings are working, so this is good. All right, so Middleman. The missing view in the Rails API stack. Let's just jump into it. So, as I said before, I am Brad Gessler, CTO and co-founder of Poll Everywhere. We started this company about six years ago now. So, we were mobile first, whatever that meant, SMS. So we went through all the pains of having to upgrade, if you will, to the second vintage of mobile first, which is mobile, basically a mobile website. We had a lot of fun doing that and, and learning 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, the predominant static website generator. And if you go to the Ruby toolbox and you ask Ruby toolbox for, hey, what should I use to generate a static website? You're going to get Jekyll. But it's, it's not like Jekyll, in the sense that it uses a lot of the more modern, basically RubyGems inside of what you see in Rails 4 and Rails 3, which is, the fact that it uses tilt to manage all of the template and, and sass and all that good stuff. So, if you're looking for a tool to build a static site, don't be scared off by the fact that middleman is catching up with Jekyll. And you should feel a lot better about that after this talk. So, middleman is extraordinarily well-documented. Thomas Reynolds built middleman. He's the, the guy behind this. And he also built an amazing website with a lot of great documentation behind it. So if you go to, I believe it's middlemanapp dot com, you can get a sense of, of everything that, that this static site generator involves. Another really nice thing about this static site generator is that it's, it's very modular. So it actually uses rack in its gut, so if you understand rack, you can write a lot of extensions using rack, which is kind of crazy. A static site generator using rack to, to do certain things. And there's also a, an extension framework, where you can roll things out, like, a middleman blog, if you so please. So, middleman blog in middleman is essentially a, a drop and replacement for Jekyll. With a few other things. If you're used to writing GitHub-flavored markdown, there's a few tweaks that you have to make there to, to get that whole thing working. So, getting started with middleman is actually very similar to what it's like getting started in a Rails application. You install the gem, you initialize the application, it creates all of this boilerplate code. You can see from this directory structure you have your configuration file, default index.html.erb. You get a layout file and then you have all of your assets. Stylesheets and JavaScripts. And then you spin up the server, and it boots extremely fast. So, in under a second, you can hit this server and things are just working. So, the thing that I like a lot about middleman is that it's very easy to come into middleman from Rails. I said earlier that this uses tilt, so you can bring all the same gems and really the same toolset that you hopefully have come to love inside of Rails into middleman and start using it without too much of a problem. So the other interesting thing about middleman is that it's multi-environment aware. This is, I pulled this from a default middleman configuration from the boilerplate and simplified it a bit. But here you, you get an idea that in your development environment, you can put extensions in there and activate them. Like live reload. And you can pull these extensions off of that directory that is on the middleman website. And then your production environment in middleman is called your build environment. So, in there, you're going to activate certain extensions, like minifying css, JavaScript, having an asset hash so that you can basically hash your assets and do what you do in Rails where you, you give your asset path a, a hash and a path, so that you can cache it. So, once you have this configuration setup and your webpages and stuff are, are ready to go, you have to deploy it somehow. And this is another area where middleman really shines is that, deployments are incredibly easy. It's two steps easy. There is the build command, which takes all of the templates and files and whatnot, and it basically compiles a bunch of html, css, and JavaScript files into a build directory. And then the, the best part about it is that getting that build directory up to your web server is as simple as rsync. Or, if you want to throwback to the days of using DreamWeaver, you could use FTP to upload it. Or SFTP if you're into the whole security thing. I developed a, a gem called shart, appropriately, hoping that it would make for an awkward IT conversation in some corporate environment, where you can deploy your middleman website up to an S3 bucket, and you can actually set the headers that are going to emitted from that S3 bucket. Mostly caching headers on, on certain assets. So there's a ton of tools you can use, and there's a ton of deployment targets that you can choose from for middleman. If you do go the route of deploying to S3, it's an incredibly cheap way to really run your website. You just pay a couple cents a month for a, a personal website. And it's also incredibly scalable, whenever you're deploying to an S3 endpoint. So. Yippie. You have a static website. You know, why should you care about middleman? How is this going to, to help you scale your application? Before I dive into that, it's really important to kind of understand the place that middleman will have in this spectrum of dynacism, is what I call it. And it turns out dynacism is not actually a word, so. I had to ignore the, the spellchecker on this thing. And it looks something like this. So the graph that you saw earlier was actually a static web application. And if you access PollIt dot com slash brad on your smart phone, that was another static web application. So, that's a very dynamic application, though, in that the chart has to move and animate and pull this data from the server in real time. In under, you know, a second, it has to get from all of your phones, whether it comes from SMS or your smart phone, we have to get it up on that graph in a really short amount of time. So that is arguably a highly dynamic application. And we also have to make things really smooth and seem very fluid, because that's just what you have to do for presentations like this. So as we go down the dynacism spectrum, you have your GUI-oriented applications. So, Google spreadsheets - you're probably very familiar with that. Who hasn't used it? You're doing a lot of actions, a lot of very short actions, and you don't want to build applications where you click a button and then you have to wait for a response to come back to a server. The, basically the functions of the GUI are very tightly-coupled with what comes out of that. So we kind of start moving down into document-oriented web apps, like an invoicing application or Base Camp where you can, you start to get into Rails territory, where Rails is, it's kind of the sweet spot between these highly dynamic applications or these highly static applications. So moving down into the blogging platform world, you may have something like Subtle or PostHaven, that is backed by mySQL, but for the most part it's just storing these documents in a database server, just for the convenience of administering many users in a multi-tendency environment. And then you go on down to your personal blog, and maybe some of you have a GitHub site. Maybe you're using Jekyll for that. Maybe you're using middleman. All the way down to informational websites, like a mom and pop shop or Steve's plumping services. If somebody wants to make a killing, go out there and sell these restaurants that have flash websites, sell them on a middleman website so that we can get some html out there and have less flash on the internet. So, where does middleman kind of fit into all of this? If you're working on a green-filled application, it's pretty easy to get started right away. Kind of what you hear about doing today is, you build your single page html application over here and you build your smaller kind of API off to the side using Sinatra or some type of, of microframework. But, since we've been around as a company for, well, since 2008, we actually started out using Rails 1 point 2, I believe. It was before REST was even a thing in Rails. So we had this green-filled application. We spin this thing up. It was great. We were able to move pretty fast inside of this framework. And we just set up this application at polleverywhere dot com. The real time components we had, I don't know if anybody remembers RJS, but that was basically how we would make things appear in, in real time on Rails, was through these kind of, in retrospect, horrendous helpers that would emit JavaScript from the server and run on your web page. So, we got a lot of mileage out of that. But it wasn't, it wasn't really enough. We needed something that was more visually appealing than just updating some numbers on a table. So that's when we turned to flex, because they happened to have this bar chart library that everything updated in real time. There was just a lot of stuff that worked out of the box. And it also just happened, out of sheer dumb luck, that flash was installed on 99-some-odd-percent of, just all machines out on the internet. But even more compelling is that you could embed a flash asset into a PowerPoint slide because of good-old ActiveX. So we did this kind of weird hack where we would embed these swifts that we would generate. These Flex applications, and we would actually embed them into a PowerPoint slide and send those out up on the server so that people could download these polls embedded right into PowerPoint slides. So whenever they opened it, nothing really had to be loaded up over the conference wifi connections in their slide. The swift application would just connect out to our Rails app and start pulling data out of it. So we initially had this flex application in the same code repository as we did our Rails application. So as we started to build more customers, things became more complex, and we were able to afford a contractor who came in and just started shredding it on this Flex app and really making a lot of progress. To the point where we started getting annoyed at just how many commit messages that he would have in our, I believe it was actually SVN at the time. So we broke that out into a, a separate application. And we were able to move a lot quicker, in the fact that we got to separate deployments. So, we had this contractor working over here on the Flex app, and he was able to deploy those Swift assets out to production. And meanwhile the Rails app team was able to do their work and, kind of, push their updates out through a separate release cycle. And, of course, at the time, it was a lot easier for Flex to work with XML, so we had a very fashionable XML API. So, time went on, and mobile started to change. It wasn't just about SMS anymore. So we had to think about the smart phone thing that was, that was taking off. Really it was the advent of the iPhone. So, having a lot of really good luck in the past with frameworks, including Rails and, and some of the visual components that Flex gave us, naturally we gravitated towards using jQuery mobile. And the other thing, dot mobe extension, was this thing that I saw on RailsCasts about this new-fangled way to kind of say, hey, this dot mobe format is gonna serve up this, this mobile stuff that's kind of like html. So, it turned out that was a really bad idea. The way that jQuery mobile worked got us about 80% of the way there, but the other 20% was just extraordinarily painful. The jQuery mobile framework was extremely opinionated. It wanted data in a certain way. It wanted the DOM to be structured a certain way. It felt kind of clunky and we just felt like we were kind of stuck inside of the, the jQuery mobile world. So, our team had to, had to do some soul searching on this front. And what we decided, at the time, was, you know, instead of trying to pick a framework, let's actually focus at the specific problems that we're trying to solve, and let's focus on picking libraries. So, that made our thinking a lot more clear, and we were able to pick exactly what we needed it. Or, yeah, pick exactly what we need, and bring it in our application where we needed it. So, at the time, as well, there was still a lot going on in the JavaScript MVC world. You had sproutcore was one, was one of the frameworks that we looked at. And that was not really that good-looking in terms of where we came from with jQuery mobile. So, we decided to go full speed ahead and use backbone.js, which was, I think, at version point eight at the time. And we knew that we would probably be swapping out libraries, because the space was still maturing very rapidly, and there were a lot of changes. So this approach really let us hand-pick the libraries we need and swap them out as something else kind of pulled ahead of, you know, another library. So we ended up with this single page mobile application that we built entirely inside of middleman. So middleman was handling all of the assets that, that this application was using. And it uses kind of the standard sprockets pipeline that, that you have in Rails. So whenever you build this thing, we have three files. We upload it to our EngineX server, and we were pretty happy with how this stuff ends up working out on production, especially for deployments. So, if you go down this route of building these single-page web applications, one thing that you need to be very aware of is CORS. So whenever you went to the pollit dot com single-page site on your phone, that was actually making a AJAX request to our polleverywhere dot com host to an API endpoint on there. So in order to do that without CORS is you get all these cross-domain errors for AJAX. But what CORS lets you do is, the pollit dot com host says, hey, polleverywhere dot com, I'm from a different domain. I want to make these types of HTTP requests. A GET request, a POST request, and, oh, by the way, I want access to these headers. So our polleverywhere dot com service says, OK, you're on our whitelist, polleverywhere dot com, so here you go. Here's the data. Great. You want to POST something. I'll accept that request. And if another domain tried to access it, it would just give them the cross-domain error. So that's how we, we got around that issue. And then another really great thing about the way that we deploy this mobile app is, it's really easy to deploy this to a CDN. You actually have these assets that you can push out to other servers. So you can't really do that with a Rails app, per se. You can't just take it and stick it over here on this file system on this server without having to boot a bunch of stuff and go through all that. So another interesting kind of feature of that is that you can deploy to floppy discs. So when's the last time that anybody's seen one of these? And we have these readers here. You pick these up for about fifteen bucks off of Amazon. And what I'm actually going to do is a live hardware demo. Possibly the only one at RailsConf. And let's plug this in. The really surprising thing, to me, was that Mac OS actually recognizes floppy drives. So let's plug this guy in here. Op. Devices. I think that's devices. Oh, I got to put the disc in. All right. So you can hear the, hear the disc spinning. Oh, let's see. There it is. Boy, that's hard to see up here. All right. So here's the application. We'll just launch this. [laughter] So hopefully your network connection is faster than a, a floppy disc, but if you have a customer living somewhere remote and the only way to get something to them is by Pony Express, you can just put this floppy disc in a satchel and, and send the pony on its way. The really fun thing is opening network inspector on this and seeing how Chrome measures this. Is it latency, or is the file really taking that long to load? So, here you go. You just saw a web application booted from a floppy disc. I can go to my pollev page and submit a vote. So, we joke about coming up with a floppy.js library, because if you can see the inspector down there, I don't know if it shows, but the retina assets aren't loaded. Those were too big to fit on this floppy disc, so we came up with some fun ideas to span our JavaScript across floppy discs. But we had better things to do like fix bugs in production. So, great. You can put this on floppy discs. But I think more importantly there is, you can put them inside of phone gap or Cordova apps or we have some customers that they want to bundle our voting application with one of their mobile applications. So we can say, here is our html assets, you can put them within your application, and then whenever there's three-hundred people sitting in a conference room, it won't overload the wifi. So, caching aside, there's, there's another component to this. Flex, Flex started getting old. It started getting outdated. The writing was on the wall that this stuff was going to die. So, you know, we set out to write a utilization app, it was very natural for us to think, oh, you know what, let's use middleman. We want this thing to work on tablets, iPhones, and everywhere, so naturally we're going to use - oh, what do we call it today? HTML5. Let's use that. Let's use that HTML5 thing to talk to our JSON API. And that worked great. We got this application out there. It's actually what you saw today, it's that HTML5 application. We have all the benefits of caching and the CDN and whatnot. But, but something came up. Whenever we were looking at these visualizations day in and day out, we just said, jeez, these feel really slow, because we were using short polling. We were hitting our server once every couple of seconds to get the new data from our server to, to update on the graph. So we decided we wanted to do better than that. We rolled out a Stream API. We actually wrote our own server at the time, because socket io wasn't quite what we wanted. I, I actually gave a talk in 2012 about this, about streaming resources. So we threw up that streaming API server, but there were some problems with it. Back in 2012, when I gave that talk, we were using AMQP on the backend of this thing. And there were just a lot of stability issues with that. It wasn't quite working with the, with the grain of the web and how resources work and, and how caching and all that stuff works. So, we had these stability issues that we were trying to deal with, and what was really nice about having these client-side applications, is we were able to spit up our stream server on its own host, its own completely different host, and isolate it. Our team had a lot of learning to do to understand how to, not only build these real time web applications, how to operate them. How to scale them. So whenever we rolled this thing out, we'd have crashes, and our client-side application was able to seamlessly, basically fail over to HTTP short polling. So over time, our team got much better at just kind of managing all these pieces. And we had client-side SOA going on there. So, you can also, with CORS, if there's several APIs that you have out there, you can consume those from your JavaScript and kind of munch all that stuff together client side and just do whatever it is that you please with that data. So, we had so much success with all these middleman, these single-page middleman applications, that we started to build all of our other applications in these. So our approach towards native integrations has been, basically, let's build a special web browser that has these certain hooks into JavaScript so that our web developers can, can be more productive and interact more with basically the native application. So we can control a lot of different things with these integrations from JavaScript. So we start having all these backbone applications pop up. Now, if you've dealt with several applications, you may be thinking, jeez, you know, you're probably repeating yourself with a lot of different things. So how do you get a handle on this stuff in this world of sprockets and middleman? So what we did is we took all of kind of the common components of this, the session components, the models and backbone. We pulled all these into this one asset gem that then everything consumes from there. So to make those gems, it's just like making any other gem. You just say bundler gem and then whatever the name is of your gem. Here we have pollitassets. And the kind of different thing about this gem is that, you check is sprockets is there. And if it is, then you start appending all these paths toward the assets where your asset gem lives. So, for example, in our lib/assets JavaScripts gem, we have a user backbone model. We have a poll backbone model. The stylesheets. We actually use font icons everywhere, so that we can fit all this stuff on a floppy drive. So, we can have all these assets located here, which whenever all the other applications consume that, they can have a consistent look and feel that uses kind of the visual language that we want to use throughout all of our applications and all the different platforms. And of course you have your vendor JavaScript assets. So if you have four different projects out there, you're probably using four different versions of jQuery. This lets us use one version of jQuery and one version of backbone. The way that we manage these in our development environment is just through bundler. So you can imagine if you have one version of jQuery, well what happens whenever you bump from the one dot x to two dot x? You're probably gonna break a lot of stuff. But we actually don't have that problem, because like with RubyGems, you don't really care if there's an upgrade happening. What you care about is that you're getting the version that you asked for in your gem bundle. So we're able to control that by pushing our pollev assets up to a basic Git repository, and we reference that from this gemfile. You don't actually see the, the git reference in there, but you can see that, in this case, we're saying, hey, I want to use the new feature branch of pollev assets. The assets path thing above that is a nice little hack so that if you're making changes to the pollev assets project, you can pull those locally so that you don't have to run bundle update every time. And what's cool about middleman is, if you're developing these pollev assets locally, whenever you reload middleman, it actually picks up the changes from the, the assets gem. You don't have to reboot the server or do anything crazy like that. So, the way that we can build new features now, let's say that, let's say the worst case scenario, I have to build a new API to support a new feature. I can branch my Rails app project, and I can say, hey, branch this off. It's called new feature. I'm gonna add some kind of new visualization to it that needs a new API. So I can build that API out on my server. I can develop that locally. And I can point my middleman project at my local server. And I can branch it in here and I can branch pollev assets, and basically have three different branches or, sorry, one branch and three different repos, all working on the same feature. And then whenever I go to deploy, obviously deploy the API server functionality first, and then it would go on to roll out these middleman single page websites. So, does it work? I think so. It's, it's worked really well for us. We have to deal with some weird kind of bandwidth constrained environments, where you can't trust conference wifi connections. And it also, I realized that it worked really well for us when, about two months ago, Microsoft wanted to launch their PowerPoint 2013 store inside of the Microsoft Office Applications. They actually have an app store inside of there. And we were able to pull a bunch of assets from our mobile application into our sprockets asset gem and reuse all of that stuff, most of it, in the PowerPoint 2013 app. And then we were able to quickly make some customizations to that whole user experience to make it fit in with Office 2013 a little bit better. And, of course, whenever you're running a single-page JavaScript application inside of this little web iframe, essentially in Office, it feels very close. It feels very native. So that, that worked pretty well for us. But I think, even better than that, than reusing functionality is, inevitably, whenever you work on some of these projects, you make some kind of improvement. Something just feels better about maybe handling a login or some kind of status code or something. So these improvements that we make in these individual projects, we're able to pull them back into the sprockets assets gem and then push them back out to all of our other projects. So all these other projects you see up here benefit from the PowerPoint 2013 app, and that just keep, kind of reinforces itself. Reinforcing itself. So, in a sense, the sprockets assets gem turns into this little, perfect little framework for your organization that's extracted in the right way, where it's being extracted from stuff that's actually being used and being proven as successful by customers. So, that's a pretty good overview of one of the more complex middleman deployments I would say is out there, and just managing kind of multiple projects. One of the downsides and also plus sides of middleman is that there's no out-of-the-box JavaScript MVC app solution in there. So in the case of backbone, it's up to you to organize all the assets in some way that, that makes sense. And different JavaScript frameworks have, some are more organized than others. So that's both a blessing and a curse. It worked out for us because there really wasn't a framework. We kind of came up with our own and we didn't have to deal with, with somebody else's bad framework. So, that was the overview of the highly dynamic website, which has all these static applications stashed everywhere. What about static websites? The other side of the kind of token where Rails fills the middle ground? So, we're developing a lot of content for, for our website. There's an explosion of use cases and all sorts of stuff that we have to implement. So one thing that we'll probably do on this front is extract out a content directory from Rails app. How many of you have a, in your Rails app, it starts out. You have kind of the home page, and then it turns into this directory called content, and then you have all these content pages. Maybe you end up with twenty or thirty of them one day and, before you notice this big junk drawer of content, and you have to look in your routes file and kind of make sense of all this stuff. So, in middleman, you don't, the directory structure is the routing structure. So that stuff checks out a lot nicer. And it's just much easier to handle this content. And there's also much better support in there for different things like image compression. You can png crush everything. So if you have designers building image assets and they don't understand the technicalities of making pngs much smaller, middleman can take care of that in its asset pipeline. And, of course, on a static website like that, you still have some dynamic components. You can't just throw a static website out there and just tell everybody, like, oh, no, forget about login state. There's some common things that people want to see, so you can take care of that with JavaScript, and you can run all that stuff client-side. So you can have some really lightweight JS that checks with the server. Maybe it checks for the presence of a cookie to see if, if the user's logged in or not. And then, of course, if you have a contact us form or anything like that, you would test these integration points with Rails so that whenever somebody types in stuff into a form and submits it, it hits your Rails app and hopefully it doesn't blow up. And, of course, you have other JavaScript applications, like Google Analytics, Optimize the Stripe. All these little JavaScript-y tools that you can throw in there. And, you know, it makes it a little more dynamic. So the nice thing about a static website is that you can't get taken down that easily, especially if you have this stuff up in an S3 bucket or stashed in CDNs. I was at a middleman meet up about a year ago, and the folks from nest dot com were there. And they said they were using some CNS or some, some dynamic backend, and they kept being mentioned in the press. And their website kept getting really slow. So they looked at a few things and I think one option involved just throwing hardware at the problem. And they decided that wasn't sane. Let's just build a static website with middleman and push this stuff out there on a really simple server. And they no longer had any of these problems where their site would get taken down from a, an influx of, of traffic. So there's a lot of things to think about whenever you're building these middleman applications. I could probably give another two or three talks just on these items alone. If you want, ask me questions about this stuff later. But I don't have time to cover that now. And, of course, I encourage you to get out there. Build your next website with middleman, even if it's a personal website or a blog or something. Try it out. If you're working on single web page applications, you could take your handcrafted stuff and throw it into middleman and start using that. Start using the asset pipeline. A lot of these ideas that I've talked about today, and some of the things I didn't talk about, our company polleverything is actually abstracting out this framework and we're going to be releasing these bits into gitfannypack, or fannypack is gonna be the name of this, this kind of framework that uses middleman and deals with stuff like testing, binding to different environments and all that stuff. And, of course, if you want to work on this stuff every day and get paid for it, you can join at team at polleverywhere. So, that's my talk. I'm Brad Gessler. I'll be posting slides, links, and, and code, up on Twitter whenever I'm not working on these slides. Thanks.