– we create awesome web applications

I had a lot of things to do last Thursday, Feb-17. I met a friend from abroad 3am at Ben Gurion Airport and spent several hours talking before we went to sleep, signed a contract for developing killer web app at 1:30am, and finally gave a presentation at The Junction at 4:30pm.

Late evening I found myself thinking (again) about having at least 32 hours days to have enough time to accomplish all the planned tasks. As a developer I always kept a lot of todo tasks in a queue: some ideas about adding new cool features, some ideas about improving existing ones, some thoughts about refactoring. Unfortunately the queue tends to overflow and todo tasks get lost.

There are two ways to solve that.

  1. Have a large manageable queue by using modern project management tools and write everything down naively thinking you would get back to these task later.
  2. Adopt adaptive development approaches and use the right tools to develop web applications like Ruby on Rails, stay productive and happy.

Back to the presentation at The Junction. It has 3 parts:

  1. The Modern Approach: The modern approach of building applications. Creating products using adaptive development methodology allows getting faster to the market while keeping highly maintainable code. Methodology and technology aspects of creating awesome applications in a modern environment.

    Slides are here.

  2. Introduction to Ruby On Rails, a web development that doesn’t hurt. Why Ruby On Rails is so popular among startup founders and developers. What’s so special in web applications framework and general purpose language that makes them the ultimate choice for the next killer application.

    Slides are here.

  3. Case study: thounds.com

    Slides are here.

I hope that those who attended the meetup enjoyed it, and those who didn’t would take a look at the slides.

Vitaly gave an interesting presentation about MongoDB at Database 2011 Conference.

MongoDB. NoSQL for SQL addicts.

Slides are here.

We presented on IGTCloud Ruby On Rails Day today.

Agenda was a bit different this time, not only technical presentations but also a few words about modern approach of building web applications.

Find the slides below.

  1. The Modern Approach - Michael Mazyar

    The modern approach of building applications. Creating products using adaptive development methodology allows getting faster to the market while keeping highly maintainable code. Methodology and technology aspects of creating awesome applications in a modern environment. Slides

  2. Introduction to Ruby On Rails - Boris Nadion

    Web development that doesn’t hurt. Why Ruby On Rails is so popular among startup founders and developers. What’s so special in web applications framework and general purpose language that makes them the ultimate choice for the next killer application. Slides

  3. Ruby Basics - Vitaly Kushner

    General overview of Ruby language.

  4. Rails Basics - Vitaly Kushner

    General overview of Rails framework. Slides for both presentations

  5. Case study - Michael Mazyar

    Adaptive development and Ruby On Rails - real world examples.

Startup Weekend comes to Israel.

The event will take place at IBM offices in Petch Tikva from Dec-16 to Dec-18. We are going to participate and also sponsor the event.

Startup weekends are known to be a good place to network with all those startup people, like enterpreneurs, VCs, lawyers, developers and designers.

Israeli event seems to be kosher, so it's not exactly a weekend: Wed - Fri :-) Grab your discounted ticket using discount code swearlybird, and as they say you should bring "laptop, good attitude, and creative energy" there.

Follow Startup Weekend Israel tweets to stay updated.

We will tweet our impressions and blog about them here.

Looking forward to have some geek fun.

This is going to be the first part of a blog post series about javascript widgets.

First type I'm going to cover is Popup Widget. Sometimes it's called Popin Widget because there is no actually new window that pops up, instead the content is shown IN-side a current page. The idea is quite simple: you provide some html/js snippet to other sites. They put it into relevant place, and you have some functionality of your site running there.

I'm going to explain how exactly it works, what should be done to achieve this, and what common mistakes i see once and again.

At the end of the blog post you will get a link to complete javascript library, grab it, play with it, and use it for fun or profit.

Content.

  1. Layout

  2. Cross-browser support.

  3. Global namespace.

  4. Loading javascript.

  5. UI problem with WEDJE.

  6. Never slow down target site.

  7. Using of js frameworks.

  8. Random div ids.

  9. Passing parameters to the script.

  10. Loading, please wait…

  11. Pop up the popup.

  12. HTML/JS snippet.

  13. Passing referrer.

  14. YUI compressor

  15. Getting things together.

  16. Example

Ok, less talk, more work. If you don't have a time and strong will to read my thoughts about the approach, scroll to the last part 15. Getting things together.

1. Layout.

The main idea is very simple. Let's call a site that have your widget - "target".

You add one or more divs to the end of target document, and they hold an iframe. Ifame content comes from your site. Once user clicks some button you show a div and bring relevant iframe content. Once user click some "close" link, you hide this div together with iframe. Actually it's likely to remove iframe completely, I will talk about this later.

2. Cross-browser support.

Well, there is nothing more to say about it. Your code should work with all grade-A browsers, meaning FF, Safari, IE7/8 and Opera.

3. Global namespace.

Since we're going to put our javascript into 3rd party website, we should not spam javascript namespace with our own variables and functions. That's why I personally dislike Google approach with setting global variables like

google_ad_client = "12345";

4. Loading javascript.

It's good idea to have static javascript that can be cached, or even loaded from Amazon S3. If you think you have to generate javascript dynamically, most probably you're doing smth wrong and have to review your architecture.

There are 2 different ways to load external javascript: syncronous, and asyncronous (which sometimes called WEDJE ‐ Widget Enabled DOM Javascript Embedding).

5. UI problem with WEDJE.

WEDJE approach is the right one for most cases because your javascript doesn't slow down the target site. But since we have to bind some button click event with our code, there is a chance that user will click this button before our js code is loaded in a asyncronous way. And that's not good. That's why this approach is not applicable here, at least it's not applicable without modifications.

6. Never slow down target site.

Since WEDJE approach is not applicable here, we have to go with syncronous way of loading assets. Once you include javascript into a web page, browser stops loading everything else until it loads and runs this javascript.

It means that if your site is down and doesn't respond to requests, target site will be frozen until the browser figures this out and times out. In other words, if your site is down - you hurt the target site.

It might be tempting to put your javascript on some cloud storage solution, like Amazon S3 together with all your other assets.

But there is a problem with it. See, S3 doesn't support HTTPS protocol. And if someone will want to use your widget on secure site it will work, but with nasty "secure/insecure content" message.

Not nice.

So please allow HTTP and HTTPS access to your widget, it's really annoying to find useful widget and not use because of lack of support for HTTPS (Feedburner, i'm looking at you).

Update: see Dubek's comment below about S3 and HTTPS.

7. Using of js frameworks.

Short answer is: no.

Long answer is: never ever even try.

Since we're writing a widget, we are doing something that adds a value to a target site.

Target site worked without our widget before and will keep working without it in a future. That's why we should be modest here. Modest as in NOT bringing 100K of framework to use 3.5 functions from it.

We have no choice - need to implement these functions by ourselves.

Here is the short list of functions we need:

  • get element by id
  • show element
  • hide element
  • remove element

Right, DOM has it, but who will write document.getElementById serveral times? It takes time to write and takes bytes to load :-)

8. Random div ids.

To avoid problems with similar ids on a page, I'd suggest to generarte random ids for the elements we're going to add to the page. Check out rnd(...) function in the example code.

9. Passing parameters to the script.

As i mentioned above, I think it's a good idea to avoid spamming the javascript namespace.

So, to pass parameters to the script we need to add them into script URL, and than parse from the script itself, e.g.:

.../mywidget.js?key1=value1&key2=value2

Once script is loaded, it finds itself in a DOM tree, parses parameters and passes them as-is to the iframe URL defined in opts.iframe_base_url.

See "detecting protocol and parameters" section of the code for more detalis.

10. Loading, please wait...

Some of the widgets we see on internet doesn't provide a visual feedback to users about what's going on.

While iframe is being loaded users see only dark backgorund, when browser starts loading the iframe users see some white background.

That's not good.

We need to provide some visual feedback like "Loading, please wait..." until the iframe is completely loaded. That's is done by binding to onload event of the iframe and switching the iframe's and "loading..." div's "display" styles.

Please pay attention to opts.close_image and opts.loading_image parameters at the beginning of the script.

11. Pop up the popup.

There are serveral approaches here.

  1. user put a link/button in any place he likes, and passes it's DOM id to the script to allow us binding to its click-event;

  2. we create a link/button in a place that user includes the script.

The first one is a quite rare approach because it requires more coding on a user side. But you can still use it If you're a writing a widget for your own site. In such a case you could pass parameter to the javascript as mentioned in "Passing parameters to the script.", parse it in jasvascript and call bind(...) function:

bind("my_parsed_elelemt_id", "click", function(){show_widget(); return false});

The second one is the one we're going to implement and use.

We create fancy image that will serve as a link to show the popup and define it in opts.button_image, don't forget to avoid defining protocol there.

12. HTML/JS snippet.

You should share with your users a snippet. Here it is:

<script type='text/javascript'>
  document.write(unescape("%3Cscript src='" + ("https:" == document.location.protocol ? "https" : "http") + "://assets.astrails.com/popup-assests/astrails-widget.js?q=wow' type='text/javascript'%3E%3C/script%3E"));
</script>

The snippet will actually embed a button and bind all the events.

Pay attention that we pass q=wow parameter to the script, your server-side part of a widget will get this parameter. You can pass anything you want in those parameters.

13. Passing referrer.

Since we open server-side part of a widget in a iframe, sever-side script will not obtain HTTP_REFERRER value.

We need to pass it manually in request URL. Take a look at "detecting protocol and parameters" section of the code for more details.

14. YUI compressor

To finally distribute your code use YUI Compressor, it could reduce a downloadable code size.

15. Getting things together.

  1. Grab the code from github.

  2. Open astrails-widget.js, and change values of hash "opts" to point to your URLs and adjust iframe sizes.

  3. Read "6. Never slow down target site." if you haven't already. If you will take only one thing from this article, make it this one.

  4. Compress the script with YUI compressor.

  5. Upload compressed script to the location defined in opts.js_url.

  6. Copy-paste a snippet from "12. HTML/JS snippet.", add parameters you need on the server side to the javascript URL.

  7. Write the server part refered by opts.iframe_base_url.

  8. Give this snippet to your users.

  9. Enjoy.

16. Example

Click the button below to see it in action.


In a next part i will try cover so called Embedded Widgets.

RRDtool is the OpenSource industry standard, high performance data logging and graphing system for time series data. Use it to write your custom monitoring shell scripts or create whole applications using its Perl, Python, Ruby, TCL or PHP bindings.

Let's run it with Ruby on Leopard.

sudo port install rrdtool

Default ports installation comes without ruby bindings.

Thanks a lot to Amit Hurvitz for providing a file of Virtual Disk Image (VDI) of VirtualBox, containing an up and running JRuby on Rails on Glassfish with Mysql. Image also contains some examples (actually solutions to the code camp exercises), all running on top of an OpenSolaris guest OS (can be run on many host systems).

Grab the image ~1.5GB archive.

Grab the exercises ~9.7MB archive.

We participated in JRuby on Rails with GlassFish Code Camp hosted by Sun Microsystems Inc. I was speaking about the framework in general trying to infect Java developers with Ruby On Rails. Slides are available.

Amit Hurvitz gave exciting presentation about GlassFish and short introduction into DTrace. Find out more details about the Code Camp.

I was the last person in our company working with ERB to render templates. While all the rest switched to HAML. At the beginning it was quite hard for me to read HAML comparing to ERB. HAML looked for me like some completely alien thing with weird percent marks all over the place and the significant whitespace never did it for me. On the other hand ERB felt like warm home after years we spent together.

Until I did the switch.

2008 was the year when we finally switched to full time consulting. And like all consulters we faced the problem of correct pricing. There are two well-known ways to charge a customer: per-hour rate and fixed bid quote, and several combinations of them.