Posterous theme by Cory Watilo

Ruby 1.9.3 and ruby-debug

Hey eveyone,

 

If you are like us, you are pushing the cutting edge.  And so - you ran into the ruby 1.9 + ruby-debug issue.  (Maybe on OS X Lion too?).

 

A lot of the solutions I've seen online involve locally adding things to your gemset, then pulling them into your gemfile, etc.  

 

I work on a team of about 6 people, and having everyone hack their system to add these gems, and then if they ever change their gems they have to remember this... Additionally, a new person joins the team, and you have to 'relive' all this mess.

 

So - we posted them on our github account, and you can just do the following:

 

gem "ruby-core-source19", :git => "git://github.com/Ziplist/ruby_core_source19.git",  :require =>"ruby-core-source"
    gem "ruby-debug-base19",  :git => "git://github.com/Ziplist/ruby_debug_base19.git",   :require=>"ruby-debug-base"
    gem 'ruby-debug19'     ,  :git => "git://github.com/Ziplist/ruby_debug19.git",        :require=>"ruby-debug"
    gem 'linecache19'      ,  :git => "git://github.com/Ziplist/linecache19.git",         :require =>"linecache"

UPDATE: Boo -- looks like we got close, and it worked at times, but other times, bundle install would build it wrong. Spent a day on it already, just rolling back to 1.9.2... Drat!

Facet Search without Sphinx / Ferret / Ugliness

How cool -- just worked with a swell guy at work on this problem.

How can you take a query in active record, and find the facets for it - and their counts - all in 1 shot?

We can do that by grouping the query by all the things we want to facet on, then parsing the results.

 

Here's the ruby:

def self.db_facets(scope_conditions)
    facet_names = ['names','of','fields','to','facet']
    facet_values = self.find(:all, :select=>(facet_names + ['count(*) as count']).join(','), :group=> facet_names.join(","))
    facets = Hash.new do |h,k|
      h[k] = Hash.new do |sub_h, sub_k|
        sub_h[sub_k] = 0
      end
    end

    facet_values.each do |record|
      count = record.attributes['count'].to_i
      record.attributes.except('count').each_pair do |facet_name, facet_id|
        facets[facet_name.to_sym][facet_id.to_s] += count
      end
    end

 

New Little Tooltip Library

Just what the world needs -- yet another tooltip library.

 

But - I'm psyched because I built this one. 

 

It's posted on https://github.com/mx3/mx/blob/master/public/javascripts/jquery.mx-tooltip.js

Check it out.

 

Some goodies are that you can either load it up with a remote URL, or inline data.

It has a nifty CSS-only notch to show what was being tooltip'd.

Really simple and light - about 100 lines all told of actual code.

Drop the details into data-tooltip.

Extra code not shown in that file is the code to link it up with elements.  I did this:

$("*[data-tooltip]").mx_tooltip();

Wrote it in about 1 1/2 hours -- it's amazing how fast you can go when you know what you're doing.. I've done things similar to this a few times, so I was able to just knock out a few tricky areas - like making sure that you can mouseover the tooltip and it won't hide.  

We do that by: instead of calling hide() directly on mouseout, we do this:

 
hiding: false,
        hide_tooltip: function() {
          this.hiding = true;

          setTimeout(function() {
            if (this.hiding) {
              this.el.hide();
            }
          }.bind(this), 750);
        },

What that basically does, is queues up a 'hide' of the tooltip  when you mouseout of the link.  But we attach a mouse-in handler on the actual tooltip as well. If you mouse out of the tooltip link, we queue up the hide -- if we mousein to the tooltip before the timer fires (750ms), it sets the hiding to false, and we're good.

Anyway -- fun stuff... If you need a simple and clean tooltip - this may be the ticket, or maybe it'll be the start of something even cooler. 

 

Thanks!
Cary 

Why I Think Modals Totally Stink

Whoa. What a fun title eh?

 

Modals are this neat thing that new web designers use all the time, and yet.... I can't stand them.

I used to like them, like you used to like the idea of not doing the dishes... It was easier then, in the beginning. But now you know the truth, that it all catches up with you at some point.

I think the only places that modals can work is when you are doing something that is quick and does not affect the current page you are on.  Like - say you have a page and want to email that page to a friend - as long as there is nothing in the page recording how many times you have emailed something, I think a modal is a great construct for this.  It pops up, keeps you in context, the modal is a completely parallel workflow, and the amount of information needed is quite small.  Pulling up a full page would be silly in that - what would you put there? A huge page with a tiny bit of text asking for the email address to use? 

In fact, I would probably suggest that you design it such that it is a page, but then use JS to only pull a part of that page into the view as a modal.... (but I'm digressing..)

 

The point being, that is a great use for a modal.

A poor use for a modal (I think) is when it modifies the state of the current page. (And when it is a large amount of content).  Take the mint settings modal.

When you have a settings modal which modifies the current page's state you are left with page which may or may not be consistent with the server.  But the user has no idea of this.

You can either:

  1. Ignore the issue totally
  2. Put up some kind of message saying 'you may need to reload'
  3. Reload the entire page by default when the modal closes
  4. Add javascript to update certain parts of the page when certain things are changed.

Most people like mint do #1.

I think #2 is cheesy.

#3 is an area where I'm not sure that the user expects / wants their page to reload - and if you are doing a page reload anyway, why make it a modal.

#4 is just a bad road to go down for a site of any complexity.

 

 

Dynamic, Responsive Websites - The Easy(er) Way

Was working with cool co-worker Chris Sexton about how to solve a problem we'd been having at work.  That problem was trying to keep our site mobile-friendly, but not have to spend time designing for it, or doing special CSS.

The First Problem...

IThe first problem we worked through involved how to adjust the page's real HTML width on the fly depending on who was looking at it.  In addition, we wanted to make the devices 'viewport's be full.  So - if I had a mobile browser with a width of 350px and one with a width of 380px, it would always fill the entire screen.  Chris wrote up a cool explanation of the mechanics behind how we do it.

With that code, we can have the viewport adjust to preset sizes, which are aligned with preset sizes in our media screen CSS rules. It works like magic!  Each device 'class' has a defined screen size which fills their display.  And it's just so awesome.

 

But... Why?

 

So I wanted to get into a bit about why we decided to do things this way, and what it really leverages.  What it really buys you.

Our layout is a standard 3 column layout like this: 

Screen_shot_2011-06-15_at_10

We need a standard way to adjust things, at the column level, in order to make it magical.  We want to abide by a few design rules, and then it all just 'works'.

On our site, the right side is just ads, the left side is a set of filters / controls, and the center is the content.  The content is about 485px wide.

Our rules ended up being:

  1. Tablet view just drops the right column
  2. Mobile view drops the right column and then stacks the left column on top of the center one (expanding it a bit with CSS)
  3. Modals MUST always be the same width as the center column.

 

Now our modals are also a bit special, in that they are real pages, with only center column content, which are loaded into the page with JS. Very cool from a code perspective, since the JS is unnecessary, but it has really given structure to our site and consistency to what we do.  It also lets us do things like this.

Since the modals are never wider than the center column, they work on mobile just as well as on tablet and main site views.

For the mobile view we ended up having to do a bit of CSS for the headers.  And we also used CSS :before tags to inject some anchors into the page. Those anchors let us hide and show the filters with jQuery.

All in all - it's a really cool architecture, and as long as we stay within the rules we've set out, everything just 'works' so wonderfully....

We'll see how long the beauty lasts before a new requirement musses with us....

But until then... enjoying the design. :)

Starting Up The Engine

What a difference a few months makes!

 

Just a few months ago we were contemplating starting to work on a new website - but I am so glad we've waited a few months to get started.  

In that time we've learned so much about good design decisions and conventions that make developing a website so much faster and easier.  I'll share a few rules I've found really help to keep you on the fast track to features, and helps you avoid the craggy times where you are doing a lot of work but making no progress...

 

Rule #1 - make it consistent in the UI.

No need to custom cut each page - make a common layout element, like a center column, that is X px wide.  And use that same block all over the site.  Keep your h1, h2 h3's all the same.  If it looks a bit off, don't worry.  People will usually never notice - and the consistent feel gives them comfort and confidence on the site.  Things look familiar.  The best thing is, that creating a new UI form or page is *simple* since all those 'hard' decisions are done.  Where to put the label or the input...

Rule #2 - no more floats!

If I'm using a float for a common purpose, like floating an element to the right and then wrapping content around it. Or if I need it for layouts - I'm a happy camper.  That is what it was made for.  It was not made for emulating absolute positioning.  If you have float: left, width: X in your design... ugh.  it'll just screw you at some point.  And you can almost always do the same thing with inline-block.  And now you don't have to make all the containing containers 'float'd as well.  And there will be the day when you want to clear something (because you're using floats like you should be using blocks) and your whole page goes in the toilet.  Mark my words - it is almost always possible w/o floats and if you use floats be forewarned.

Rule #3 - clean up that HTML

I used to think it was worth it to put extra divs/spans into a design so that I could avoid doing 'dirty things' like relative positioning, absolute positioning, etc.  But I'm beginning to think that doing so only makes the ugliness spread.  For example, if you have a design that doesn't flow nicely on a page with standard floats & block elements, you're in for ugliness.  You can either make both the CSS AND the HTML ugly, or just consolidate the ugliness.  I've taken to just punting on the complicated layouts that come my way sometimes.  Wanting to use the standard divs with margins and paddings to acheieve what is basically a custom layout.  But now - I'm polluted with tons of extra markup.  So my HTML is dirty, and my CSS is dirty, with all these different classnames and such.

But the reason it is so messy is because we're basically hopping out of the normal HTML flow and positioning these elements in specific places inside a fixed size container.  You know what was designed to do that? Absolute positioning! :)  make that outer element relative, and drop those inner elements right where you want them.  If things need to grow and shrink when text is entered, I can almost guarantee you that unless the layout of the dialog is HTML-style - you're going to get into trouble anyway - so absolute positining is no worse than the alternative.  But - with clean HTML you can always move things about, transfer speed is slower, HTML really does become more like a data layer, and you can have teeny tiny comprehensible view files.

 

More to come -- someday. :)

How To Live In A World Like This

What a day of thoughts and ponderings.

Had the chance to sit down with someone and discuss some issues at work.  Nothing too huge and earthshattering, but walk through some things that have been causing friction.  At the end of it all it came down to this:

I believe that roles/responsibilities are orthogonal to how you treat people relationally

Imagine that you've got a small start up of 5 people, and you work every day in the coffeeshop.  All conversation is open.  You relate to each other respectfully.  Though one has the role of "CEO" and one may have the role as 'dev lead', people relate apart from their titles.  Or at least I wish that was the way it worked.

Once I use my title as an excuse to be rude, short, arrogant, angry, or any other thing that you couldn't see yourself doing to your co-worker, I think you've lost the battle to staying relational.  Now the co-workers have to be wary of when you are relating as an equal with a title, or as the one with the title.  That just causes people to drift apart.  I don't see (yet) any reason that you would have to be rude in most any situation.  Being rude or short, to me, says that you aren't willing to take the time to share what you are thinking in a constructive way that others can easily receive.  Be a rude subordinate and you'll get in hot water.  Be a rude boss and you have the excuse, 'I can because I am the boss'.  

At which point you've lost the battle for relationship.  In life, I believe, the moment you choose to excuse your behavior because of a title or a right, you have nothing left to stand on.  Your character is the core of who you are.  There are constructive and respectful ways to say most anything.  Now, if someone is being rude to you back it's a different ballgame, I'm not sure how to handle those situations just yet.  But most cases in a work environment are poop rolling down hill. No need.  You want a dev team to follow you and back you up, you need to lead by example.

Secure and Fast

Read some articles on how cookie-based systems are extremely insecure.  We all knew that.  It's not a suprise.  But the reason no one is going and putting https on their whole site is the expense in bandwidth and processing.  And the absurdity of encrypting a bunch of boilerplate HTML.  No reason to https your landing page, and yet if you start to pick and choose which pages are to be protected, you'll undoubtedly pick wrong at some point and get yourself in trouble.

A solution?

Something I'd been noodling about was the idea of splitting rendering of the views to the client with javascript.  This is nothing all that new.  Some cool technology is already out there doing this exact thing.  One library Bujagali (http://github.com/rdio/bujagali ) had an idea to pull the templates in individually and render them on the fly.  I kindof like that approach more and more as I think about it.  It's not heavy, it's not creating an abstraction layer you can't get around. It's simple and sweet.  Unlike what I percieve Sproutcore to be - which is a 'you will do it our new and improved way'.  I want to stay true to HTML/CSS/JS.  Keeping them separate and simple.  I'm not excited about making front-end GUIs which talk to the server through REST protocols. I kindof feel like that is a 1/2 solution.  We're taking what we do on mobile apps and desktops and then doing it all over again on the web.  But the web has a much clearer and cleaner approach.  I much rather would build a web-page than open up a GUI designer to lay out buttons.  I have this great technology in HTML and CSS - why go 'backwards' to a GUI paradigm?  Onward with progress!

So - Bujagali does what I like.  But it can be improved! (Like any good idea :))   In order to keep things secure, lets keep the page data in https.


Page data comes in over JSON and https - (you could even use Basic Auth to keep things *really* secure, no cookies here!).

Templates get loaded on-demand like Bujagali, over wide open, fast, cheap, http.

I'm a rails guy, and so thinking how I'd match it up with my wonderful active record and controller models.  And I think I'd go for this in the beginning:

Write a variant of HAML which generates js code targeting the templating javascript library of my choice (ecoTemplates / reisig microtemplates) - something that's fast and light.

All the HAML logic instead of Ruby is written in javascript. 

On the client javascript library, which just catches the JSON blobs from the server, finds the template to render, and renders it, with the data.

The default render for rails would be to take each instance variable and call to_json on it.  Models with data you don't want exposed can have to_json overridden. It's a bit inefficient to start with, but as you go you can optimize the data transfer.  Maybe specify for each controller action which data to send along the wire.

app helpers would convert to being written in javascript - and we'd bundle those and send them up to the client.

 

All those changes would give you (I think):

* secure data transfer

* much faster page rendering (since the page templates can be cached and the only thing transferred is the JSON data)

 

It's an idea, I'd love to try it out someday.  Who knows...

 

Peace!