Tuesday, May 26, 2015

google maps part 2

Last year I wrote about how integrating with Google Maps was pretty easy.

This year I've been helping a few other porchfests, in particular with getting drafts of their map together. (Though fair warning, double check the licensing of Google Maps API)

A bit ago when I was talking about PHP making easy things easy it was using PHP's file_get_contents() to hit the Google Maps geocoding API (URLs of the form https://maps.googleapis.com/­maps/­api/­geocode/­json?­address=SOME+­ENOCODED+­ADDRESS&­amp;­key=­YOUR_­API_­KEY) to convert addresse to the latitude/longitude the rest of the API uses. Wrapping that in a hacky PHP script rather than doing it by hand via a website sped things up, though you have to learn how to see if you've gotten a proper full match, or if it can't find it and is just locating the city center.

So, the site was looking for a printable version of their neighborhood map, with icons for the porches marked, vs an interactive thing for their site. A few tricks and traps:

I used this one Google chart marker API for the pins, though I guess technically that's deprecated - still it was somewhat easier than rolling my own markers in Processing. A sample URL for that was http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=K|00FFFF|000000 to make something like



Another issue I had was Google was showing me local business names, and that was making the map too confusing. stackoverflow to the rescue, the trick was to hide those via a styler.

Also, previously I mentioned phantom.js as a screencapture tool - in this case it let me make a virtual screen that was bigger than my physical monitor, by fiddling with the viewport size. (Admittedly, this whole thing is kind of weird for print, because you end up with something sized for screen resolutions and not print DPIs)

Finally, I also researched making phantom.js wait for a page to load - or rather, waiting 5 seconds before taking the screen shot, to allow the Google page to settle, when I was zoomed in a bit more. My final phantom.js script was:

var page = require('webpage').create();
page.viewportSize = {
  width: 1800,
  height: 3600
};
page.open('http://localhost/plum2015/view.php', function () {
    setTimeout(function(){
        page.render('plum17.png');
        phantom.exit();
    },5000);
});

Then I had to crop it... rather than setting up pixel magic, it was easier to do it on the OSX program Acorn, which had a nice "set a cropping box at a specific ratio" feature.

Thursday, May 21, 2015

changing the whole URL without the page flash

My coworker pointed out that when you're navigating through Youtube, you can go from page to page and the URL completely changes (i.e. it's not just changing stuff after the # anchor) but parts of the page, such as the side bar, remain constant (tampering with it with Inspect Element proves that it's the same DOM elements, not new copies each time)

I guess that's a thing, now! With appropriate js shims for older browsers. I don't have a reason to implement a proof of concept for myself right now, but it's a good thing to know about.

the secret of java's success

Is Java's secret to its longevity that it's relatively easy to read and foregoes weird character syntax-y things? The Slashdot article that pointed me to it has some debate.

Wednesday, May 20, 2015

trivial "excel download" in php

Personally I've never liked Excel, but it's a critical tool in business, and lots of people I collaborate with find in useful. (I think from an early age I was doing my data wrangling in Perl, so my Excel use was always clumsy)

Anyway, it's obviously usually easy to generate tab-delimited files, but it's even easier to then wrap that as a download-able "Excel file". (If you try to do the noble thing and just offer a ".tab" download, the Excel import wizard asks lots of questions that might distract a newbie, even though the defaults all work fine - it's also a little fiddly to tell a Mac that yes, please try opening this .tab in Excel even though you don't know Excel speaks "tab" kthxbye.)

So, as this page helpfully points out in PHP you can add these lines near the top:

header("Content-Disposition: attachment; filename=\"FILENAME.xls\""); 
header("Content-Type: application/vnd.ms-excel");

and the page will trigger a download of a file, rather than blast stuff to the screen. (And obviously any CGI-like platform can do similar)

There are a couple things to watch out for if you're doing this in PHP, like making sure you don't have any extraneous white space outside your <?php ?> tags, and you should run each chunk of data through something like this (stolen from the previously linked page)

function cleanData(&$str)
  {
    $str = preg_replace("/\t/", "\\t", $str);
    $str = preg_replace("/\r?\n/", "\\n", $str);
    if(strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"';
  }
to ensure the data is cleaned and ready to be join()'d with tabs.

Anyway, having a download that Just Works is likely a big and empowering win for your users, especially if they are Excel-savvy but not super technical.

UPDATE: In the comments Nathan Tolbert writes some additional steps that might help things play better with IE:
Just FYI, using this exact same technique, we've had issues with a few oddball versions/configurations of IE failing to properly download and open the attachment if you don't let it cache the attachment. Assuming a filename that's autogenerated based on a timestamp, we add something like the following, which helps IE not be stupid:

$expire = date("D, m M Y H:i:s", $pickAnExpirationDate);
header("Expires: $expire GMT");
header("Cache-Control: ");
header("Pragma: ");

Monday, May 18, 2015

tools as the cause of, not the solution to, all the web's speed problems

Daring Fireball linked to Tools don’t solve the web’s problems, they ARE the problem.

Here's a thought that echoes something that's been on my mind of late:
Still, the native avalanche has made us web developers insecure, and I think the search for ever-longer toolchains that solve ever-more-obscure problems is our answer to this insecurity. It’s the wrong answer, but there you go. (The traditional disdain with which server-side disciplines, especially Java, regard web technology doesn’t help here.) 
We use tools in order to prove that we’re seasoned and mature, and not because they solve problems that we couldn’t solve on our own with some basic knowledge of CSS and JavaScript and spending a few days extra on each project.
He talks a lot about the difference between front-enders and back-enders as well. I've had some enlightening conversations lately, and I think that is a strong factor. The narrative is more complex than "server side people want things so they don't have to think about the traditional web frontend structures of HTML5, CSS, and js" though, because those "back-enders" have a kind of odd alliance with the kids with shiniest tools on the block. (The back-enders see where big parts of the action are moving to, and want in on that, the "shiny tool kids" want the respect and authority the server-siders have enjoyed, and are willing to sacrifice their save-compile-run loop to get that.)

Still: a lot of companies making interesting things have people who are very excited about Angular et al, and because I want to work with these people I need to have fluency in this kind of toolset. I've been inadvertently creating friction at work by asking if we should consider alternative approaches (ranging from no-framework/microframeworks to even more opinion frameworks like ember.js, which in some ways seem more stable than Angular at the moment) but am not doubling down to renew the Angular knowledge I had last year.

So I've been looking for better books and tutorials than I had last year. A stackoverflow on “Thinking in AngularJS” if I have a jQuery background had a point that has stuck with me, in understanding how the Angular view veers from my comfort zone:
1. Don't design your page, and then change it with DOM manipulations 
In jQuery, you design a page, and then you make it dynamic. This is because jQuery was designed for augmentation and has grown incredibly from that simple premise. 
But in AngularJS, you must start from the ground up with your architecture in mind. Instead of starting by thinking "I have this piece of the DOM and I want to make it do X", you have to start with what you want to accomplish, then go about designing your application, and then finally go about designing your view.
An interesting point! I've been thinking that some of my resistance to Angular's paradigms comes from my old CGI-based history, like in the 90s, when all the work was done serverside and then brought to the browser in page-size chunks.  Then, around 2010, I got my first deep work experience using jQuery and CSS to move more of that work to the browser. Man was that fun! We backed away from our initial under-engineered attempts at SPA, but the idea that everything was static except for the info coming from endpoints was empowering.

I still tend to view the DOM as a fundamentally static thing, a view loosely coupled from the controller, with the controller mediating to the single source of truth model at specified points in time (in a kind of event driven way, so very natural to decorate with transitions and animations).

Angular turns its views into basically enhanced versions of the model. To me this seems a little jumpy and skitterish, and I'm not 100% at ease with how the DOM as implied by the unparsed template is utterly different than the DOM I see in the element inspector, but I'm warming up to it as a functional paradigm. 

And that's why that quote feels like a different world to me. Most jobs I'm on, they show me a comp (either image or HTML) of the finished webpage, and say "make this!". Designing from the model on out to the views is not a luxury I've often had. (And in practice, I think only internal-use, Plain-Old-CRUD-ish apps would alllow such a thing, without input from a designer.)

I've been working through thinkster's A Better Way to Learn Angular.js and its been going pretty well. I like that it dips into the core angular docs for some of the lessons.

I think building up this kind of flexibility is good exercise for my brain. That's the silver lining to giving up the feeling of smart I get when I'm making cool stuff from inside my comfort zone.

Thursday, May 14, 2015

against angular.js

Some very negative arguments against using Angular.js and some of this matches impressions I have - Hacker News' link to it had some counterpoints however.

It's interesting talking about this with people at work. Many smart people agree with me, and many smart people don't. There are very different mindsets out there about the way things should be. Some people prefer terse, concise, declarative code; others prefer conceptually simple, easy-to-trace, procedural approaches. People's personal development histories seems to weigh in heavily.

Anecdote:

I used to make web-based tools to help make the graphics for Atari 2600 games - PlayerPal2 being the most impressive, not terrible for 10 years old code, and before I knew jQuery and the like.

On Atari Age a developer gauauu announced a Playfield graphic editor, and I was interested to see he used angular.js.

When I mentioned that it that (in a neutral/positive way) he said
Yeah, I'm no expert with angular but I find its declarative style to be a whole lot easier to deal with than raw JavaScript or jquery for DOM manipulation.
My response was
It's funny, I find declarative style to be so annoying. It's very top down, and (IMO) hard to debug when things go wrong because of the distance between the code you wrote and the code that's actually running in the browser. But, it's a pretty popular style. I've been trying to figure out why I don't find it more intuitive. (One thing is, I kind of prefer thinking of the DOM as a decoupled, stable place to manipulate and read from, vs tightly coupled to shared memory. Writing code inside of tags feels very JSP like to me) ANYWAY
I was surprised by his response:
Yeah, debugging it is a nightmare. I find that for small projects it's worth the tradeoff. For bigger projects, the inability to debug reasonably or clearly see what's going on is killer. We experimented with Angular for a larger scoped project and work and found that the tradeoffs weren't necessarily worth it, in terms of productivity.
Huh! That's the opposite of what I usually here, in terms of people saying "sure, use jQuery or whatever for some small project, but when things get serious, you really need a framework".

And yet, he finds it easier for certain small one-off things like his editor.

Sometimes I think my years of experience making things via the DOM and js work against me...






tabs 2015 = taskbar 2005

Years ago, before I switched to OSX pretty much fulltime, I wrote why windows' taskbar beats osx' dock. I've acclimated to dock pretty well, and have grown to appreciate its minimalism.

My coworkers were teasing me for tending to run many chrome windows, vs leaning more heavily on tabs, and I admit that I was having trouble finding specific windows sometimes, even with Hyperdock's "show a thumbnail of every window on hover" feature. So I've been trying to limit myself to one chrome window, and I have to admit it's created a nice decluttering effect to my desktop life. I think "out of site, out of mind" was too much the rule when I started using more windows.

It occurs to me that the tab bar is almost exactly the same thing as the old Windows taskbar - a (generally horizontal, though I'm not convinced that's the optimal use of space) list of open things, one tab or button per "activity".

There's nothing new under the sun, I guess!

Tuesday, May 12, 2015

php making easy things easy

Good lord, I know I'm not impressing anyone by digging on PHP, but man does it do a good job making easy things easy.

I picked PHP for the core of my http://jpporchfest.org/ work because I figured if I ever shared with other groups, it was easier for them to dig up a server with that installed, plus I knew from experience it has a lot of convenient things baked-in. (Unlike the old days with me and Perl and wrestling with CPAN archives) When I wanted to make a simple client hitting Google's Map API for some geocoding, man was it easy. I figured I'd have to at least use a "curl" module of some kind but the default file_get_contents() function reads URLs no problem... json_decode(result, true) that and I'm on my way with a bunch of associative arrays.

PROTIP: I didn't want to flood the Google API (it has some kind of rate limit) so I put in a sleep 0.5 between requests, but that was causing the page not to render until every request had been made. The flush() command prevented that from being a problem.

Friday, May 1, 2015

chrome PROTIP: noisy tab icon can be a mute button

So I managed to get a little bit of reddit juice with
That Google Chrome "what tab is being noisy?" speaker icon should function as a mute button.
But then longandshortofit followed up with
enter "chrome://flags/#enable-tab-audio-muting" into a tab, hit enter, click enable.
Done and Done
Wow! Interesting that that isn't the default, especially because the icon is pretty clear when it gets muted.

I guess it's a beta feature that might be promoted.