Exactly What You Write Makes a Lot of Difference

I wrote a blog post in 2003 about a not-very-useful error message I got while working on a .NET SOAP web service*: Server did not recognize the value of HTTP Header SOAPAction.

I wrote at the end of the blog post: “If you’re having a similar problem but can’t work what I’m saying here, feel free to mail me on bakert+web@gmail.com”.

Although this is an obscure blog post on an obscure blog over the nine years since I wrote it I’ve received 159 emails asking for help. I think I’ve received a total of about 2 emails about other blog posts of mine.

I suppose if I added my email address to the bottom of each of my posts and exhorted the reader to email me I’d have a lot more emails. This reminds me of Dustin Curtis’ article about following him on Twitter.

* = I’m not proud of this chapter in my programming history!

Painless Social Sign In with Oneall

I had a need for social sign in recently in a project that I needed to complete in a weekend. Rather than build something using Facebook/Google/Twitter/etc. APIs I used oneall. A small amount of javascript and a backend call later and I have pretty good social sign in integration with a bunch of providers. Your control over the look of the div they supply is limited (at least in the free version) but the integration is good. Recommended.

Move Fast and Break Things

I had lunch at the Facebook campus yesterday. They have transported all their motivational posters to their new(ish) location in Menlo Park (which is really, really nice). “Move Fast and Break Things”, “What Would You Do If You Weren’t Afraid?”, etc.

This led to a short conversation about how, exactly, you move fast and still produce good code. Facebook don’t have QA instead they have systems designed to automatically catch errors before they hit production. D thought that if you had good tests you didn’t need documentation or QA or code review. I’m a bit more cynical about tests and I love code review for sharing knowledge and style as well as finding bugs.

Also saw two Facebookers with “Fix More, Whine Less” tshirts.  It’s the slogan of the Site Reliability team. They do seem to be scaling their startup-ish culture to a larger scale than most companies manage.

Things You Can’t Do With CSS

We spent some time looking at this yesterday and found it surprising.

We wanted to create a set of three divs where the size of none is of a fixed width. The left and the right should expand to match the size of the content. And the middle div should pick up the slack and make the whole thing as wide as the page. The middle div needs to also contain a search box (input) that stretches out to fill the div.

<div class="left">Some variable content here</div>
<div class="middle">
    <input type="text" class="text">
</div>
<div class="right">Some other variable content here</div>

Apparently it can’t be done without tables (which messes up our responsive design). We tried floats and relative positioning.

It was interesting to me that this literally couldn’t be done. Or can it?

Dice.com curl Billboard

dice.com Billboard

I just don’t understand who could know enough to come up with this but not enough to know how flagrantly wrong it is and how it would read to someone who just even knows what curl is. Is the idea the programmers will become so incensed by the mess that is this commandline that they write in angrily and then you offer them a job? It completely baffles me. I’d love to hear an explanation.

Web App Checklist

  • It is more important to have a standard than what the standard is.
  • ‘use strict’ in JavaScript.
  • jslint
  • jQuery
  • Throw objects not strings as exceptions in JavaScript:
    throw {
        'name': 'MyException',
        'message': 'Something went wrong',
        'code': 500,
        'previous': e // Nested exception.
    }
    
  • Controllers should be super-skinny (because they are hard to test).
  • HTML5
  • Only read querystring and post body in the controller.
  • Say *why* you did something in the commit message, don’t just describe what you did.
  • The first line of a commit message should be a short standalone message.
  • Err on the side of verbosity in commit messages.
  • Don’t form HTML in JavaScript strings.
  • Good internationalization is hard (ICU?).
  • Run the tests before pushing.
  • Automate deployment.
  • Keep markup as semantic as possible.
  • Code review is a priority.
  • LESS
  • SMACSS
  • Responsive Design
  • Backbone
  • Automatically pull dependencies in, don’t add them to the repo.
  • Don’t store artifacts generated by the build process alongside the source code.
  • git
  • Unit tests
  • The unit tests should run *fast* and offline.
  • Send the right HTTP response code.
  • JSON

FuelPHP Updates

In working with FuelPHP recently a few thing have come up. The devs on #fuelphp on Freenode have been awesome at coming up with or accepting fixes. Here are the problems with immediate workarounds and long term solutions.

Fuel won’t let you refer to a View_Model with a templating engine extension

While View::forge('hello/world.twig') works fine, ViewModel::forge('hello/world.twig') fails to find the ViewModel because of the “.twig” part.

Workaround is to instead explicitly set the view on your ViewModel with public $_view = 'world.twig';

Long term fix is coming in Fuel 1.2.1 maintenance release https://github.com/fuel/core/commit/c06b0c67c027ee17bafa59cb089bd6c5baee80ab

Fuel insists that controllers are in the global namespace and prefixed with “Controller_”

No workaround.

Long term fix coming in Fuel 1.3 that will allow you to namespace and prefix controllers as you desire (as you already can with views) via a config setting: https://github.com/fuel/core/commit/882e564de66dc3f4edf83181b8fa36a8a8b083cd

Fuel’s View_Smarty does not expose the “plugins_dir” option.

Workaround is to set the option anyway, direct on the Parser object in your controller(s). The trouble is that accessing this object (and working out if it is Smarty-related) can be complicated. The naive version is something like:

$this->view->parser()->addPluginsDir(APPPATH.DS.'pluginsdirectoryname');

But if you want to continue to support non-Smarty rendering engines and are using ViewModels and Controller_Template it ends up looking more like (don’t judge me!):

        if (is_object($this->canvas)) {
            $rc = new \ReflectionClass($this->canvas);
            if ($rc->hasMethod('parser')) {
                $parser = $this->canvas->parser();
            } else if ($rc->hasProperty('_view')) {
                $parser = $this->canvas->_view->parser();
            } else {
                throw new YokoException('Unable to initialize Smarty i18n plugin.');
            }
            $smartyParam = 'plugins_dir';
            $ourPluginsDir = APPPATH . '/smarty';
            $pluginsDir = array_merge($parser->$smartyParam, [$ourPluginsDir]);
            $parser->$smartyParam = $pluginsDir;
        }

The long term fix is coming in the 1.3 release of Fuel’s parser package https://github.com/fuel/parser/pull/48. The devs were very good about accepting this patch which bodes well for future contributions to the project.

Spain’s Finalists

Spain 1 - 0 Germany 2008
Spain 1 - 0aet Netherlands 2010
Spain 4 - 0 Italy 2012
Casillas (F F F)
Sergio Ramos (F F F)
Xavi (F F F)
Iniesta (F F* t87)
Alonso (f63 t87 F)
Farbregas (t63 f87 t75)
Torres (t78* f105 f75*)
Capdevila (F F _)
Puyol (F F _)
Busquets (_ F F)
Silva (t56 S t59*)
Fabregas (_ f87 t75)
Pedrito (_ t60 f59)
Arbeloa (S S F)
Marchena (F S _)
Senna (F _ _)
Pique (_ _ F)
Alba (_ _ F*)
Jesus Navas (_ f60 S)
Santi Cazorla (f66 _ S)
Mata (_ S f87*)
Villa (S t105 _)
Guiza (f78 _ _)
Reina (S S S)
Albiol (S S S)
Llorente (_ S S)
Javi Martinez (_ S S)
Juanfran (_ _ S)
Negredo (_ _ S)
Palop (S _ _)
Fernando Navarro (S _ _)
Sergio Garcia (S _ _)
Juanito (S _ _)
De la Red (S _ _)
Valdes (_ S _)

F = full match played, t = subbed off, f = subbed on, S = unused substitute, _ = not present, * = goal.

Using Mustache with FuelPHP

  • Add ‘parser’ to the ‘packages’ array in config.php
  • Name your views ‘foo.mustache’ not ‘foo.php’
  • Call your views with View::forge(‘bar/foo.mustache’) not View::forge(‘bar/foo’)
  • Still call your ViewModels with ViewModel::forge(‘bar/foo’) but add a public $_view = ‘bar/foo.mustache’ variable to your ViewModel