Pete Forde talks at TWG’s, “Good People drinking wine” event July 23rd

Posted by Andrés on August 5, 2010

Pete Forde talks about the importance of Open Data at TWG’s, “Good People drinking wine and talking to each other” on July 23rd. Check out the video below (The darkness clears up at 3:50).

JSONimal – Elegant DOM construction with jQuery

Posted by jamie on July 16, 2010

As part of my co-op term here at TWG, I’ve had the opportunity to try out new technology, approach interesting technical problems, and develop useful bits of code outside of client work. JSONimal was created on one of my ‘lab days’ focused on innovation and experimentation.

The purpose of JSONimal is to take the pain out of constructing HTML using Javascript.

What’s it do? This example should demonstrate my goal fairly well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$(function() {
    $.mktag("#demo").jsonimal([
        ["h1", {text: "JSONimal!"}],
        ["table",{style: 'border: 1px solid black'},[
            ["thead",[
                ["tr",{style: 'text-transform: uppercase'},[
                    ["th", {text: "one"}],
                    ["th", {text: "two"}],
                    ["th", {text: "three"}]
                ]]
            ]],
            ["tbody", [
                ["tr",[
                    ["td", {html: "<u>a</u>"}],
                    ["td", {text: "b"}],
                    ["td", {text: "c"}]
                ]],
                ["tr",[
                    ["td",[
                        ["a", {href: "http://www.google.ca", text: "Google"}]
                    ]],
                    ["td", {text: "b"}],
                    ["td", {text: "c"}]
                ]],
                ["tr",[
                    ["td", {text: "a"}],
                    ["td", {text: "b"}],
                    ["td", {text: "c"}]
                ]]
            ]]
        ]]
    ]).appendTo("body");
});

Which will add this to the body:

JSONimal!

one two three
a b c
Google b c
a b c

For more information and examples, check out the github page: JSONimal @ github.

I also posted it as on the jQuery plugins page – but that just points to the github page anyway. JSONimal @ plugins.jquery.com

Rails Web Developer Quiz

Posted by Dominic on July 13, 2010

Here’s a quiz we ran last year, at Employment.nil, Toronto first Ruby job fair.

See if you can get them all, I’ll post the answers in a couple weeks, and if you have your own favorite trick questions, post them here.

Javascript

1. An external JavaScript must contain the <script> tag, true or false?

2. What is the purpose of the the SWFObject javascript library?

Ruby

3. Given:

a = ‘foo’
b = nil

first = a && b
second = a and b

Are first and second equal?

4. True or false?

1
1/2 == 0.5

5. If ('1'..'10').to_a returns:

["1", "2", "3", "4", ..... "10"]

What does ('2'..'10').to_a return?

Rails

6. Given the following class:

1
2
class Monkey &lt;&lt; ActiveRecord::Base
has_many :bananas, :order =&gt; 'size ASC'

named_scope :starting_from_massive, :order => ‘size DESC’
end

What SQL is generated for the following queries:

1
2
3
@monkey.bananas
@monkey.bananas.starting_from_massive
@monkey.bananas.all(:order =&gt; nil)

XHTML:

7. The DOCTYPE declaration has no closing tag, true or false?

8. All XHTML tags and attributes must be in lower case, true or false?

9. There is a way of describing XML data, how?

10. What does DTD stand for?

AJAX:

11. AJAX functionality is achieved by using what object?

CSS:

12. Should you clear floats?

13. How do you properly clear floats?

14. How do you write IE specific css?
Bonus: what is the problem with this?

Everything – Multiple Choice

15. Rails: Which of the following is not a form helper method?

a. text_field_tag
b. text_input_tag
c. text_area_tag
d. hidden_field_tag

16. What’s the default REST HTTP action verb for updating an existing record?

a. PUT
b. UPDATE
c. POST
d. PUSH

17. Which of the following is not a core Rails package?

a. ActionMailer
b. ActionController
c. ActiveRecord
d. ActiveResource

18. Which of the following is not an instance method of Object?

a. to_a
b. to_i
c. taint
d. hash

19. Which of the following is not a valid render option?

a. :update
b. :partial
c. :string
d. :file

20. Which of the following is not a valid ActionController filter declaration?

a. before_filter
b. clear_filter
c. after_filter
d. around_filter

21. Which of the following is not a valid ActiveRecord callback type?

a. before_create
b. before_validation_on_create
c. after_destroy
d. before_validation_on_destroy

22. XML is to XHTML as this is to HTML.

23. The keys of a model’s attributes are stored using this data type.

24. This is the RFC 2324 definition for HTTP status code 418.

24. Bonus: what does this do???

1
data.gsub(/[^\d]/, '').split('').reverse.enum_with_index.collect{|x, i|  (i%2!=0)? (x.to_i*2).to_s.split('').inject(0){|sum, i| sum + i.to_i} :  x.to_i}.inject(0){|sum, i| sum + i}%10 != 0

R or RoR:
—-

1. Ruby:
Given:
a = ‘foo’
b = nil

first = a && b
second = a and b
Are first and second equal?
No. first one equals nil, second equals foo

2. Ruby:
True or false: 1/2 == 0.5
false 1/2 is int, .5 is float
1/2 is equal to zero because it is an int divided by an int, they don’t have the precision to give the correct answer

3. Ruby:
If (’1′..’10′).to_a returns :

["1", "2", "3", "4", ..... "10"]

what does (’2′..’10′).to_a return?

answer: empty array because ’10′ precedes ’2′

It’s ordering by string representation, not integer

4. Rails:

class Monkey << ActiveRecord::Base has_many :bananas, :order => ‘size ASC’

named_scope :starting_from_massive, :order => ‘size DESC’
end

What is the SQL for

@monkey.bananas
@monkey.bananas.starting_from_massive
@monkey.bananas.all(:order => nil)

Answer:
1: select * from monkeys order size ASC
2. select * from monkeys order size ASC, size DESC
3. select * from monkeys order size ASC

5. What does the H in DHH stand for? Spell it?
Hein

—-
4. XHTML:
The DOCTYPE declaration has no closing tag
False

5. All XHTML tags and attributes must be in lower case
true

6. There is a way of describing XML data, how?
Document Type Definition

7. What does DTD stand for?
Document Type Definition

Javascript:
—-
8. What is the purpose of the the swf object javascript library?
To work around the judgement against Microsoft regarding the Eolas patent defining “Embedded Objects Linked Across Systems”.

Ajax:
A little bit tougher now: AJAX functionality is achieved by using what object?
XMLHttpRequest

CSS:
—-
1.
Should you clear floats?
yes

2.
How do you properly clear floats?
overflow: hidden;
_height: 1%;

3.
How do you write ie specific css?
_element are for ie6
*element are for ie7

Bonus: what is the problem with this?

Multiple Choice

Which of the following is not a form helper method?

text_field_tag
text_input_tag
text_area_tag
hidden_field_tag

What’s the default REST HTTP action verb for updating an existing record?

PUT
UPDATE
POST
PUSH

Which of the following is not a core Rails package?

ActionMailer
ActionController
ActiveRecord
ActiveResource

Which of the following is not an instance method of Object?

to_a
to_i
taint
hash

Which of the following is not a valid render option?

:update
:partial
:string
:file

Which of the following is not a valid ActionController filter declaration?

before_filter
clear_filter
after_filter
around_filter

Which of the following is not a valid ActiveRecord callback type?

before_create
before_validation_on_create
after_destroy
before_validation_on_destroy

Simple Answers

This is the “H” in “DHH”.

What is Heinemeier?
(Spelling can count)

XML is to XHTML as this is to HTML.

What is SGML?

The keys of a model’s attributes are stored using this data type.

What is String?
or
What are Strings?

This is the RFC 2324 definition for HTTP status code 418.

What is “I’m a teapot”?
// ]]>

We’re big in Japan!

Posted by Georges on March 15, 2010

Well, PostageApp is. We were very happy to wake up this morning to see that PostageApp has spread to Japan!

The folks over at 100shiki.com posted a little introduction and overview (here it is in English) of PostageApp and helped to introduce us to our first overseas audience. Thanks guys!

For any of you who are new to PostageApp, it’s the easier way to send email from web apps. You can use it from any Rails or PHP app, or you can use our JSON API directly from the framework of your choice.

TWG Kicks Off 2010 with Scrum!

Posted by todd on February 18, 2010

TWG would like to formally welcome you to 2010 and talk a little bit about something we’ve decided to kick off the new year with: Scrum!

Scrum is an agile framework that allows teams to become self organizing and focus on delivering high business value.

In 2010, TWG is committed to delivering working, high business value, high quality software, faster.  This is something Scrum enables us to do.

Why Change?

While TWG has previously used plenty of agile practices, the time has come to formalize the process so that we can get all the benefits of being an agile organization.

How Is Agile Different?

Many agencies and web development companies typically insist on gathering every single requirement up front, locking them down, forcing the client to sign off, swearing that these requirements will never change.  We now know better.  Requirements will change, we learn as we go, and we will inevitably discover new and more valuable features as the project comes together.  TWG is using Scrum to build partnering relationships with our clients, so that we can see and adapt to requirements as they emerge, and deliver better and more useful websites and software.

Build Less Software…

So how do you build high value, high quality software, quickly?  Build less, but build it better!

This may seem unusual, but remember, when you start a project, application or a web site, you don’t really know what you or your users want until you get your hands on it and start playing with it.  This is normal.  So instead of trying to plan it all up front, we’re going to be working on building the things you know right now, and get them done, Done, DONE!

Nothing gets feedback better than working software, so why wait until the end of your project to see it?  Once you’ve seen it and learned from it, you can add to it, change it or even scrap it!

At TWG, we’re starting Scrum with 1 week sprints.  These are time boxed working periods where at the end, our goal is to deliver working software, as opposed to things like documents, mock-ups or in-progress features.  This is a tough, aggressive process that we’re working on, but we feel in the end it will enable us to deliver better, more valuable software, faster.

…Get more value (rather than a laundry list).

Many web development companies will work with you to look around at all the sites that are out there, collect a large laundry lists of  possible features that you might want your system to do, and then give a quote on building that.  You sign off, and the work gets started.  You wait potentially months until all the features are built, the schedule might slip two or three times, and when you finally get it, you discover you really didn’t end up with the software you really hoped for or needed.

Not only that, but while the software was being built, the market changed and some features became irrelevant or new features became more critical.  Too late to change now.  I guess you’re stuck.

What if you had your list of features prioritized in order of importance/ROI and what if you got the most important features first each iteration – say every week?  Maybe you’d find out you didn’t need to build those last few features since they weren’t all that valuable anyway, or maybe you’d find you could swap some of those less valuable ones out for new ones.  Who wouldn’t want that kind of flexibility?

What Comes Next?

This transition is a work in progress and we’re going to give you regular updates and insights into our experiences with Scrum.  You’ll get to see some of the nitty-gritty details like our task board, and burn up charts, as well as some of the struggles and discoveries we make as we go down this road.  We hope you’ll keep your eye on our blog and provide us with any feedback or experiences you’ve had.

Remember Rcov?

Posted by Oleg on December 16, 2009

Rcov helps to identify code that is not being being hit by your tests (or maybe some functions left behind after refactoring). It’s very easy to get it running as well:

$ sudo gem install rcov

Plug this rake task into /lib/tasks/rcov.rake

require 'rcov/rcovtask'

namespace :rcov do
  desc 'Measures test coverage using rcov'
  Rcov::RcovTask.new(:test) do |rcov|
    rcov.pattern    = %w(test/unit/**/*_test.rb test/functional/**/*_test.rb test/integration/**/*_test.rb)
    rcov.output_dir = 'rcov'
    rcov.verbose    = true
    rcov.rcov_opts << '--exclude "gems/*"'
    rcov.rcov_opts << '--rails'
  end
end

And finally run it:

$ rake rcov:test

It’s so easy you have no excuse not to have it.

Harnessing Ruby Enumerable

Posted by Scott Tadman on December 8, 2009

You’re probably afraid to ask about some of the methods in the Ruby Enumerable mixin. Not only are there a whole bunch of them, 41 in Ruby 1.9 to be exact, but selecting the right one for the problem can be an exercise in frustration. Part of the problem is there’s no easy way to identify what method might suit your requirements. While the names are usually self-explanatory, it can be tricky to remember block arguments or if they return an Array or a particular element.

Any toolbox needs to be organized, so it’s probably best to sort the various Enumerable methods into groups based on the kind of result you want to get. Grouped together like this, the methodology within Ruby becomes more apparent.

Conventions

In this description, “true / false” refers to values that are equivalent to true, or equivalent to false. In practical terms this means that nil and false are both considered false, and everything else is non-false, (or in general terms, true). Note: things that evaluate as true include what might be considered false in other languages such as 0, empty strings, and empty Array or Hash structures.

When describing the blocks, e refers to an element in the set. For an Array, this is simply the element at a particular index. For a Hash this is a key/value pair, so the block semantics should be expanded to { |(k,v)| } or e.first and e.last will need to be used within the block.

Assessment

One of the simplest features of Enumerable is the methods that provide a quick true/false assessment based on the content involved. Often these will be used to decide how to handle an Array or Hash, or if its in a condition that can be utilized.

Method Arguments Block Definition Return
all? { |e| … } => true / false
* Optional
true / false
Runs each element through the given block with and returns true if all of the block results evaluate true, otherwise false. Without a block returns true if all the elements evaluate as true, otherwise false.
any? { |e| … } => true / false
* Optional
true / false
Runs each element through the given block with and returns true if any of the block results evaluate true, otherwise false. Without a block returns true if any the elements evaluate as true, otherwise false.
none? { |e| … } => true / false
* Optional
true / false
Runs each element through the given block with and returns true if none of the block results evaluate true, otherwise false. Without a block returns true if none the elements evaluate as true, otherwise false.
one? { |e| … } => true / false
* Optional
true / false
Runs each element through the given block with and returns true if one of the block results evaluate true, otherwise false. Without a block returns true if one the elements evaluate as true, otherwise false.

Single Element

Often you’ll want to extract a single element from a set. In this case there are many ways to get what you want, each with their particular quirks.

Method Arguments Block Definition Return
detect ifnone = nil { |e| … } => true / false element / nil
Runs each element through the given block with and returns the first element for which the block result is true. If all return false, the result is nil.
find ifnone = nil { |e| … } => true / false element / nil
The same as detect, this runs each element through the given block with and returns the first element for which the block result is true. If all return false, the result is nil.
first element / nil
Returns the first element in the set, of if the set is empty then nil.
max { |a,b| … } => -1 / 0 / 1
* Optional
element / nil
Returns the largest element in the set, of if the set is empty then nil. The result of the optional block should be compatible with Comparable and return -1, 0, or 1.
max_by { |e| … } element / nil
Returns the largest element in the set where comparisons are performed on the result of the block, of if the set is empty then nil. Anything returned by the block must be compatible with Comparable.
min { |a,b| … } => -1 / 0 / 1
* Optional
element / nil
Returns the smallest element in the set, of if the set is empty then nil. The result of the optional block should be compatible with Comparable and return -1, 0, or 1.
min_by { |e| … } element / nil
Returns the smallest element in the set where comparisons are performed on the result of the block, of if the set is empty then nil. Anything returned by the block must be compatible with Comparable.

Filtering

Method Arguments Block Definition Return
grep regexp { |e| … }
* Optional
Array
Matches each element against the supplied regexp and returns all that match in an Array. If a block is supplied, all matching elements are transformed by the block before being inserted into the result Array, which avoids having to chain the result through a map call.
reject { |e| … } => true / false Array
Runs all elements through the supplied block and excludes those from the result array where the block evaluates as true.
select { |e| … } => true / false Array
The inverse of , this runs all elements through the supplied block and includes those from the result array where the block evaluates as true.
select { |e| … } => true / false Array
The inverse of , this runs all elements through the supplied block and includes those from the result array where the block evaluates as true.

Transformation

There are a few powerful methods for transforming the content of one set into an Array.

Method Arguments Block Definition Return
collect { |e| … } Array
Runs each element through the provided block and puts each block result in the Array that is returned.
map { |e| … } Array
The same as collect, runs each element through the provided block and puts each block result in the Array that is returned.
inject memo = first { |memo, e| … } last block result / nil
This is perhaps the most understood and under-utilized method in the Enumerable toolkit. In general terms, this method takes a seed “memo” value, and runs that through the block in conjunction with each element. The result of the first block call is supplied to the second, and so on, which leaves the door wide open as to what this method can do. For instance, every other Enumerable method can be expressed as a form of inject.

Active state for link_to == active_link_to. A solution for building navigation systems in Rails.

Posted by Oleg on November 27, 2009

I have a question for you. How do you deal with the logic of setting links as active in your navs?

Actually, I don’t want to know. It’s probably awful. I might have a pretty good solution for you. Let’s take a look at a very simple nav. These examples all use HAML:

%ul
  %li= link_to 'Home', home_path
  %li= link_to 'Puppies', puppies_path
  %li= link_to 'Kittens', kittens_path
  %li= link_to 'Froggies', froggies_path

Right, that’s great. But how do I insert logic as to what link gets marked as active? To begin, let’s quickly install this random gem:

sudo gem install active_link_to

And then change our nav a bit:

%ul
  %li= active_link_to 'Home', home_path
  %li= active_link_to 'Puppies', puppies_path
  %li= active_link_to 'Kittens', kittens_path
  %li= active_link_to 'Froggies', froggies_path

And that’s pretty much it.

So, for example, if you navigate to /kittens/1-my-fluffy-kitten navigation link for ‘Kittens’ will have ‘active’ class attached to it. It’s almost like magic.

You probably noticed that ‘Home’ is highlighted as well. It happened because whatever URL you are currently on is a child of the home_path. I guess we want to mark it as active only if we find ourselves on the home page and not anywhere else. We can fix this:

%ul
  %li= active_link_to 'Home', home_path, :active => {:when => :self_only}
  %li= active_link_to 'Puppies', puppies_path
  %li= active_link_to 'Kittens', kittens_path
  %li= active_link_to 'Froggies', froggies_path

Hey, wanna render a sub nav when you find yourself browsing /puppies or any page under that URL? It’s just sooo easy:

%ul
  %li= active_link_to 'Home', home_path, :active => {:when => :self_only}
  %li
    = active_link_to 'Puppies', puppies_path
    - if is_active_link?(puppies_path)
      %ul
        %li= active_link_to 'Big', big_puppies_path
        %li= active_link_to 'Small', small_puppies_path
  %li= active_link_to 'Kittens', kittens_path
  %li= active_link_to 'Froggies', froggies_path

And that’s the skinny of what active_link_to is for.

For more documentation on more functionality checkout project on GitHub: http://github.com/theworkinggroup/active_link_to

Making a world of difference with 0.05em

Posted by Vivian on November 3, 2009

Typographic sensibility can make or break a design, both in print pieces and online. In web design, attention to typography is especially important since the majority of online content is written information. It is often said that the strength of a web designer can be judged through their ability to create an engaging UI with just text.

There are many tools and tricks available to web designers when it comes to styling type: size, colour, alignment, line-height (leading), word-spacing (don’t do it), but an important one I find most often ignored by developers is letter-spacing (tracking). Letter-spacing is literally the space between the letters… and it can make a big difference in terms of legibility and the overall feel of a site.

letter-spacing-importance

“Don’t blame me; you forgot the letter-spacing…”

As a designer, it feels like I am often getting flack from developers for type that is “too small”. Ninety-nine percent of the time after I hand off an Illustrator file or PSD of a design, the coded page comes back to me without any letter-spacing included in the CSS. Letter-spacing is like air: you don’t really notice it, but it makes a difference whether it is there or not.

It’s easy, just do it.

I’m really bad at math, but the other day it dawned on me how to figure out the CSS letter-spacing measurement from my AI (or PSD) file. Tracking in Adobe programs is measured in 1/1000em so when the design file specifies “50″ or “100″ in the tracking character palette, it is 100/1000 = 0.1em. That 0.1em can take a 10px all caps style from “too small” to “completely awesome”. See below:

EXAMPLE WITHOUT ANY LETTER-SPACING, OMG SO TIGHT, NOT IN A GOOD/SEXY WAY.

ADDED 0.1EM OF LETTER-SPACING. LOOK HOW AMAZING IT IS NOW.

2PX OF LETTER-SPACING? CRAZYTOWN! GET THE EFF OUT OF HERE!

Of course there are issues…

Like in many cases, basically Firefox is the only browser that does letter-spacing right. Depending on your product/audience, this may not be an issue, but it is definitely something to keep in mind when specifying sub-pixel measurements that may be rounded up or down in browsers other than Firefox.

Negative letter-spacing: it’s just a fad, right?

This is so tight, yo! I can’t even read it!

Over the last couple years a big web typography trend has been the bold sans type with negative letter-spacing, “all the cool kids are doing it.” While I can see the appeal (in that it speaks to the whole web 2.0 design aesthetic), I expect that this trend will soon remedy itself. Letter-spacing is meant to be applied with a gentle touch, and when heavy-handed negative (or positive) tracking occurs, it can definitely affect the legibility, as some of those examples clearly show.

The bottom line

Always use letter-spacing to your advantage and not to your own detriment, just because it’s “in”. Yell at developers when they omit it from the CSS and then decide to blame you, the designer. And if that doesn’t work, do what I had to do: get the keys to the site or app, then tweak to your heart’s content.

geeks + beer + friday = ?

Posted by Georges on October 16, 2009

Every so often a text editor war will flare up in the office. We all have our favourites, but no one likes vi the way Scott likes vi.

Here’s the first in Dr. Tadman‘s twelve part lecture series on how vi will make your life better:

TWGtadman-viforbeginners_thumb

Click For Full-Size Image