Elf Sternberg

Done, and gets things smart.

Wordpress or Joomla? Mutter mutter mutter…

Wow, talk about a niche market ready for exploitation.

I was talking a client today, and my first question to her was the first question I try to get most of my clients to answer: “If you don’t do this, if you don’t spend the money and the time, what’s the worst that could happen?”

“The worst that could happen is that I keep getting dumped on by my tech-savvy members who know we can do better. The site is awful.” And, to be fair, she’s right: it’s done with Front Page 1999, and it looks it: Frames, 256-color palette, poor tiling of the background for wide-screen monitors, no content management.

I’m still debating between putting them on Joomla and Wordpress. Or MediaWiki, but I’m not a sadist. While I like Joomla, it’s probably more than they need, but Wordpress is less. And learning how to make a Joomla template, like a Wordpress theme or a MediaWiki skin, would be a heck of a saleable asset.

That said, 99.99% of Joomla templates are just re-arrangement of the standard layouts with art, and the art is simple to modify in-line after you’ve found a freebie that comes close.

I spent the day looking through the various websites of various labor unions and brotherhoods and so forth, and y’know what?  They’re all tragic. Not just my client’s (and she admits that her site is tragic), but all of them.   This is a niche market just the same way that election websites are a niche market: get the images and the art right, and you could sell themes to just about anyone.  And generally, unions– at least those not currently pressing a strike– tend to have some money.

One thing that gets my attention, though, is that a lot of these people keep their sites in-house.  They’d rather run it on their IIS server than trust a third party hosting solution.  Which means that I’d better get used to using the WAMP or XAMPP stacks.

Rails 3: Django with a funny syntax

From the announcements for Rails 3:

The upcoming version 3 of Ruby on Rails will feature a sexy new querying API from ActiveRecord. Here is an example:

User.order('users.id DESC').limit(20).includes(:items)

In other words, Rails is now Django.

Also:

  • Each application now has it’s own name space, application is started with YourAppName.boot for example, makes interacting with other applications a lot easier.
  • Rails 3.0 now provides a Rails.config object, which provides a central repository of all sorts of Rails wide configuration options.

In other words, Rails is now Django.

To be fair, these are huge improvements to Rails. They’ve needed to do these things for a long, long time. The separation of application namespaces is especially powerful– it’s what gives Django a massive chunk of it’s dynamism. It’s good to see that these great ideas, which have been in Django since version 2, have now made it into Rails, just as the Django people start grappling with their own version of Capistrano (Fabric) and their own deployment issues. Rails’ migration path has always been obvious, a pythonic value, while Django has two migration tools (South and Evolution), which is more a rubyish value, and the Django team has decided to leave migration tracks up to outside development teams may-the-best-solution-win.

So, we’ll see. I’m installing Rails 3 this morning, and who knows?  Maybe it’ll seduce me back to working with Rails again.

Cheesy law firm website templates are multi-colored, busy, poorly laid-out, and tend to go for light-on-dark themes where the seriousness of the business is emphasized by leather and wood textures, spot lighting, and so forth.

A review of the websites of the largest law firms in the US shows two things: a lot of them don’t have their Internet stuff together. Those that do go for very clean designs, solid color schemes, and traditional dark-on-white themes where readability is at a premium.

I’ve been trying to do a design thing every week.  I doodle a lot, and make lots of scratches, and I might show you a few of those, but as a web developer I have to keep my hand into the design side of things.  Recently, the magazine Photoshop User had an article on doing “Multi-colored Box Tiles”, an effect they consider “a classic.”  It turned out to be significantly more difficult with the Gimp, but I did finally manage it.

Take your subject in front of a neutral background.  Here, I’ve put my daughter, Kouryou-chan in front of  a medium blue background with a slight lighting gradient.  Open the Layers dialog (Windows -> Dockable Dialogs -> Layers, or CTRL-L).  Now create four new layers (Layer -> New Layer) above your subject.  Select the first new layer, set the pen to color #cccccc.  Create a couple of random boxes, making sure that one encapsulates the head completely (otherwise it’ll just look weird).   In the second layer, do the same thing, but using pen color #999999. It’s okay if the boxes overlap.  In the third, again but this time with color #666666, and in the fourth with color #333333.  You should by now have completely obscured your subject.

For each layer, set the Mode to Overlap (On the layer dialog, Mode -> Overlap), and play with the opacities, and you’ll get a nifty mosaic effect.

Now for the 3D effect, here’s the fun part.  Create a new image, transparent background, big enough to hold your subject.  Go back to your working image, pull up the selection editor (Select -> Selection Editor).  Pick one layer and click on the selection editor.  You should see that layer’s boxes highlited– but the selection is inverted, so Select -> Invert Selection.  Now copy the selection and what it contains (Edit -> Copy Visible).

Now go to your blank image and Edit -> Paste As -> As New Layer.    If you’ve got a complete copy of Gimp, you should have Layer Effects installed, so you can just Layer -> Layer Effects -> Drop Shadow, but if not, drop shadows are simple: Duplicate the layer, go to the new layer and fill it with a dark grey, blur the edges (Filters -> Blur -> Gaussian Blur), then position in behind your existing layer as you like.  Once your drop shadows are nice, merge down the existing collection of boxes on top of its drop shadow layer, so you get a few random boxes and their drop shadows.

Do this with all four layers.  Now that you’ve got all four layers on your new canvas, it’s time to play puzzle, moving the four layers to construct the whole image again.  You can set the upper layer to 50% opacity; that’ll help make sure you’ve merged the textures correctly.  It’s just a lot of fiddling; up the magnification to 400% or 800%, that’ll also help a lot.  Once you’re done, set all four layers to 100% opacity again.

For the new background, I just picked a nice grey with a gradient, the glow centered behind the subject’s heart.

Stupid Gawk Trick

This morning, for no reason that I’d care to discuss in public, I needed to rename every file in a directory to the index number of its position in the directory in asciibetical order, and add an extension.

The harmless version of this was:

ls | gawk 'BEGIN { c = 0; } c += 1 { print "mv", $0, c".jpg" }'

The version that actually does the work:

ls | gawk 'BEGIN { c = 0; } c += 1 { print "mv", $0, c".jpg" }' | bash

Better version (harmless):

ls | gawk '{ printf ("mv \"%s\" %02d.jpg\n", $0, NR) }'

Don’t use the second unless, well, you know, you intend on doing it.

Rails re-affirms my love for Django…

I have a contract that I’m working on that requires I work with rails.  That, in itself, isn’t so bad.  But I think what bothers me most about rails can be summed up in one word: partials. For example, let’s say I have the following:

render :partial => 'employee', :collection => @employees

What this means is that the files _employee.rhtml, using the internal variable employee, will iterate multiple times over the collection employees. The “magic” here is that the internal variable and the partial name coincide. This is called, in rails, using convention over configuration.  And while it makes perfect sense, it is in some sense straitjacketing.  Yes, I know, people will tell me that the internal variable name can be changed with the :as symbol; that’s not the point.  Ruby is such a malleable language that rails almost seems anathemic to ruby in the first place: why use what is just about the most flexible language in the first place, and then create a set of conventions which must be memorized in order to make the thing go?

I kinda like ruby and rails, but they don’t seem to belong to one another.   It feels very much like a marriage with a mail-order bride.

I had a job interview today, and one of the “challenges” with which I was presented was this: “We own several sites. We would like our user to be able to log into the central site as a subscriber, and then all the other sites will know what permissions that user has.”

The sites are cooperative, so getting content onto each one to support this idea isn’t difficult. Also, all of the sites belong to the same user, so getting a regular framework that you can deploy to all of them isn’t difficult either.

The scenario we want to support is this. We have two websites, the remote authentication server framework. Let’s call it “rasf.com” (which, sadly, does not go to rec.arts.sf.written), and let’s call the site that wants authentication “brandx.com.” (Sadly, this is a parked site that leads to a stock photography reseller.) The idea is that you’re a subscriber to rasf.com. You visit brandx.com, and Brand-X initially has no idea who you are. We want Brand-X to be able to say, “Hey, Rasf, who is this guy?” and have Rasf come back “Oh, he’s John Smith, he’s a legit user, and here are some details.”

The trick involves public key cryptography.  Both Rasf and Brand-X have public and private keys.  To understand the scenario, you must appreciate that much of the heavy lifting is done away from both sites on the browser.  The problem is that, on the browser, any windows opened between Rasf and Brand-X cannot communicate with each other; this is known as the sandbox, and it keeps malicious sites from using iframes or Ajax to either inject malware Javascript into the victim page or allow the nefarious iframe from ripping data (like username and password keystrokes) from the victim page.  We want to violate the sandbox, but how?

Assumption: You’ve visited Rasf recently, and have a cookie from Rasf saying “Yes, I, Joe Smith, and a valid user of Rasf and affiliated sites!”

You access a page from Brand-X.    Secretly, Brand-X creates a one-pixel-wide iframe and set the iframe’s src attribute to the “authenticate this user” page on Rasf, including in the request its public key as an argument.   After the iframe loads, the loaded page from Rasf now has the session information on the browser, and it has Brand-X’s public key.  The session information includes the Rasf cookie.    So now, Rasf knows two things: it knows who you are, and it knows that Brand-X wants to know who you are.

How does that who you are information get back to Brand-X?  Here’s where the cooperation comes from.  The iframe from Rasf, using the onload() event, creates yet another iframe, this time calling back to a specified page (the cross-domain receiver page) on Brand-X’s site, and that URL is loaded with your user ID, a cross-domain session key, and other information, all signed with the Rasf private key (so the Brand-X site can unpack with Rasf’s known public key).

Now, because both the containing page and the iframe two layers in are in the same domain, they’re in the same sandbox, and can communicate with one another via javascript.  The innermost iframe communicates with the cookies of the outermost page, the calls reload: all this information has now been pushed back to the Brand-X server, which can now use the signed cross-domain session key to make back-end requests of Rasf’s web services API and say, “Okay, now that I know he’s user 12345, and I have a session key validating this conversation, what else can you tell me about him?”

There are lots of other details here.  What if he’s not logged in to Rasf at all?  Well, enlarge the 1-pixel iframe to a size big enough to show a log-in within the Rasf domain, get his username and password, authenticate and proceed as before.

This is a generic description of what Facebook Connect does, and it’s how you can do it as well.

Java is Pass-By-Value, Dammit!

Quite possibly the most important article I’ve ever read, because it finally, finally explains to me what Java’s object-passing model is really all about. I’ve never understood it, and now I do: it’s exactly backwards from pass-by-reference, so it’s exactly backwards from the languages with which I grew up. The Object (and derivative) variables are pointers, not references, and calling them references only confuses people who grew up writing C (as I did).

Even more oddly, it explains to me what I’ve never quite understood about Python’s object model, because Python’s object model is exactly the same.   Reproducing the code in the article above in Python creates the same result:

class Foo(object):
    def __init__(self, x): self._result = x
    def _get_foo(self): return self._result
    def _set_foo(self, x): self._result = x
    result = property(_get_foo, _set_foo)

def twid(y):
    y.result = 7

def twid2(y):
    y = Foo(7)

r = Foo(4)
print r.result  # Should be 4
twid(r)
print r.result  # Should be 7

r = Foo(5)
print r.result  # Should be 5
twid2(r)
print r.result  # Still 5

This demonstrates that Python’s code remains pass-by-value, with pythonic “references” in fact being pointers-to-objects. In the case of twid2, we change what the pointer y, which exists in the frame of the call twid2, points to and create a new object that is thrown away at the end of the call.  The object to which y pointed when called is left unmolested.

This is important because it changes (it might even disrupt) the way I think about Python. For a long time, I’ve been using python calls out of habit, just knowing that sometimes objects are changed and sometimes they aren’t.  Now that the difference has been made clear to me, in language that I’ve understood since university, either I’m going to be struggling for a while incorporating this new understanding, or I’m going to be much more productive.

Like many designers, I’ve been enjoying Clients from Hell, a collection of various incidents freelance designers and developers have had working with customers over the years.  Oh, boy, do I know some of these.  But there’s one that stuck in my craw: “Slow It Down.”  The basic complaint is common to Ajax-based applications: if you’re close to the server when using Ajax for state management (send commands back to the server to change or save some detail), the transition from “working” to “done” can be so short that some users won’t realize that the action they committed has been saved.

I saw this on a project for an intranet deployment once.  The user was presented with a list of alert states, and if the alerts were being dealt with he could click on a checkbox to “silent” the alert and it would stop harassing his pager.  Since it was an intranet, the LAN was very fast and the server lightly loaded, so the “working” spinner would blink by so fast some people complained that they didn’t know if the action had been saved.  Where, they asked, was the submit button?

In “Slow it Down,” the developer says that he added a 1.5 second delay “on the server.”  He gives this as an example of a dumb client, but in this case, the client is right and the developer is wrong, and the developer is solving the problem the wrong way.  Using sleep() on the server blocks the thread, may slow down other transactions, and most importantly blocks the client from performing other actions.   The correct solution is to do it on the client, where you don’t use up server resources and the user can have many such transactions going on at the same time.

Here’s the whole solution, using jQuery. I create a function that clears the spinner out. Then I add an event handler that handles my data transaction and registers an on-end event handler. That event handler checks to see if the transaction took longer than the “display spinner” timeout. If it did, it clears the spinner.  If it did not, it creates a new setTimeout event to clear the spinner after the specified amount of time has passed.

(function() {
    var timeout = 500;

    function swapSpinner() {
        $('#spinner_container').html('');
    }

    $('#submit_button').click(function() {
            $('#spinner_container').html(
                '<img src="/assets/images/spinner.gif" alt="" />');
            var form = $('remote_form');
            var data = $(form).serialize();
            var action = $(form).attr('action');
            var started = new Date();

            $.post(action, data,
                   function(data, status) {
                       var when = new Date();
                       var inter = when.getTime() - started.getTime();
                       console.log(status, inter);
                       if (inter < timeout) {
                           setTimeout(swapSpinner, timeout - inter);
                       } else {
                           swapSpinner();
                       }
                   },
                   'text');
        });
        return false;
})();

This is the correct way to do this: a server thread is freed the moment the transaction is done, but the cognitive message the server is doing something has been successfully delivered to the user, and the (admittedly minimal, but as Google can tell you gazillions of minimal costs add up) CPU load has been distributed to the client. Because javascript is single-threaded and event modeled, many such events can be going on at once, so in the example I described above, the customer could click several boxes in a row and the system would do the right thing.

The developer might say that this is a case of educating the user.  I disagree: this is a case of unpleasant surprise.  There’s a rule in web design: exceed your client’s expectations gently.  If you’re going to make transactions instantaneous, you’re taking away the cognitive step submit the transaction.  You must replace that with some alternative acknowledgment.  A delay does that.  A delay done right does that and creates new opportunities for further exploration of the technique.

“And to think… I hesitated.”

I’ve always been a little leery of studies that show that somehow, a bigger monitor equals more productivity.  Well, count me as no longer leery.  I’ve been hacking on a 24″ monitor I bought at a Christmas sale yesterday, and already I’m going along significantly faster than I was before.  For one thing, I can now have both Firebug and the screen I’m interested in visible at the same time.  That alone makes me twice as effective as before.  Being able to do both and have the source code editor visible at the same time?  Priceless.

Seriously.  If you code at home and your monitor is still 19″, do yourself a favor and go buy a bigger one.  Or, as a cheap alternative, if your card supports it, buy a second monitor and dual-head.  Whatever you do, get the capacity to have all your work visible: output, product, debugging information in one glance.

(Yes, I know, the title is tragically bad SEO, but I couldn’t hold back from a Hellraiser quote.)

« Previous Entries  Next Page »

Recent Entries

    Recent Comments

      Most Commented