Compiling non-digest assets with asset_sync gem in Rails 4.0

In Rails 4, non-digest asset compilation has been disabled. If you ask me, I think this decision make Rails too opinionated.

For some of my applications (The Feedback Button) there is a strong need to compile non-digest versions of assets, as they are referenced outside of the application. Digest version of the assets have a hash of the content in the name. There is no easy way to figure out the proper name of the compiled assets, so there is a strong need to also compile the non-digest version (without the MD5 in the name) of the asset.

There are some monkey-patches or rake tasks available, but they all fail to address the issue when having to put your assets on the Amazaon S3 with CloudFront using the asset_sync gem.

Luckily there is a gem to fix this, and the name of this hero is non-stupid-digest-assets. Simply by adding this gem, you are no longer required to monkey-patch or create a rake task. Just one line in your Gemfile. Beautiful!

There is actually one more thing you need to do, and that is to set your manifest option to false like so:


AssetSync.configure do |config|
config.manifest = false
end

This is to prevent the asset_sync gem from reading the manifest file, which would cause to exclude non-digest assets. This line will prevent the upload from ignoring the assets we actually want to upload.

So, the fix actually took two lines of code in the Gemfile and in config/initilizers/asset_sync.rb.

Also as an extension, I also added an option to overwrite existing files because the default setup ignores the files if they are already present in the bucket (this works on initial upload, but you want your code to stay updated!).


config.existing_remote_files = 'ignore'

The final initialiser should look like this:

Read more...

Printing from iframe when CSS is limiting

Traditional approach to printing HTML pages was to separate the stylesheets into print and screen like so:

Alternatively, you could have embedded all the styles in one stylesheet using the media queries like so:

Unfortunately, there are occasional needs to print a webpage that looks different from the main page in print.

The Solution

Instead of struggling with CSS and media queries, there is a third way; a better way: printing from an iframe.

By placing an iframe and giving it a hidden property, it will not be visible to the user, but accessible through javascript.

<iframe id="print_me" src="iframe_print_source.html" style="display: none;"></iframe>

With this in mind, we add a button that will trigger the printing of this iframe.

<button id="print_button" onclick="javascript:window.frames['print_me'].print();">Print Me</button>

This approach is made possible because each iframe is treated as a separate webpage. The iframe has its own DOM structure which you can access and manoeuvre around. The javascript that does heavy lifting is placed in the onclick handler and is triggered when the "Print Me" button is pressed.

This approach has three downsides:

  1. Two requests made to the server.
  2. Print must be triggered with javascript.
  3. Double loading of the same data.

This hack works and can be extended to fix the problems listed above in several ways.

The first downside can be resolved by creating the iframe dynamically and loading the content to print only when the print button is pressed. This fix becomes a strong positive when printing involves heavy styling. You don't want to waste any bandwidth on print styling -- assuming the user does not print that often.

The second point can be partially resolved by adding a listener on the keyboard and trigger the print action when 'Cmd + P' or 'Ctrl + P' is pressed on the keyboard.

The third point is actually an advantage that we are utilising in this case by changing the content. This means that you can place a completely different stylesheet (or even a different content) within the iframe without breaking the parent page.

Also, here is why you should avoid media queries:
Peter Griffin demonstrates CSS

Read more...

How is Dropbox's Mailbox app any different from LinkedIn Intro app?

I was having a drink with a friend, who saw me use the Dropbox's Mailbox App. After explaining him how this thing worked, I realized that the mechanism is not so different from LinkedIn's Intro app, which has been bashed and mashed around for it's privacy implications.

Then I asked him a question: how is Mailbox any different from Intro?

Here is an except from Mailbox's website:

In order to deliver email as quickly as possible, send push notifications, and keep an accurate badge count on your home screen, Mailbox checks your email from the cloud.

It does not seem to be too different. The biggest difference I see is in the press -- mainly company's track record. But then again, Dropbox? LinkedIn? It's a seesaw of privacy policies and practices, deteriorating little by little on each side (not to say that these are the only companies).

It is a fact that some of my close friends have begun deactivating their LinkedIn accounts. Is it a matter of time until people stop using Mailbox? stop using GMail all together?

Needless to say, Mailbox is a quality app, and I will probably not give up using it for a while. I love the app. But again, I ask the question: how is Mailbox any different from LinkedIn Intro app?

Read more...

Improve your Github + Pivotal workflow with git_tracker

Pivotal Tracker has a cool feature where it adds your git commit messages related to your story as comments. If the commit message contains a corresponding story number, that commit will show up as a comment.

This is the format of the commit message. Notice that the ticket number is inside the brackets with a hashtag.


$ git commit -m "My awesome commit. [#39731421]"

Usually when you work on a story, it will be on a separate branch with a ticket number in the name of the branch. Something like:


feature/39731421_make_it_more_awesome

When you are working on a feature with multiple commits, it becomes redundant to enter the same ticket number in your commit every time. This is where git_tracker can help you out.

git_tracker is a tool that will look at your branch and automatically insert the ticket number in the format specified above.

Installation is quite simple. Follow these steps.

$ cd my_project
$ brew install git-tracker
$ git tracker init

That is it! The tracker will install git commit hooks that will do the magic and add the number to your commit message.

Lastly, if you are not sure how to name your branch here is a list of supported branch formats by git_tracker listed below:

  • best_feature_ever_#8675309
  • best-feature-ever-8675309
  • 8675309_best_feature_ever
  • #8675309-best-feature-ever
  • your_name/8675309_best_feature_ever
  • your_name/#8675309_best_feature_ever

Read more...

Passing multiple multi-line strings as arguments to a ruby method

Ever had a need to pass not just one, but two or even multiple multiline strings to a method in one go?

Read more...

Percent Notation and Symbols in Ruby 2.0

Ruby is nice because it has the percent notation for working with different base elements such as strings, arrays, and symbols. You can create different objects by replacing the character after the '%' mark.

Read more...

Reset iOS Simulator With a Rake Task

A slight annoyance while developing with RubyMotion is having to reset the iOS Simulator. It is quite frustrating to use a mouse sometimes to perform a repetitive task, so I thought it would be nice to simplify that to run it in a command line.

By executing AppleScript using the osascript command, we can call the "Reset Content and Settings" menu item in the simulator and have it reset by running the following rake task:

rake simulator:reset

Read more...

Time to Market

In the world of software development, time-to-market is the driving force of the business.

via OmniTI ~ Your Code May Be Elegant.

Read more...

Ember Example Applications

Here is a list of Ember's example applications. I will be updating this list as I find new prototypes.

Read more...

Twitter Weekly Updates for 2012-09-02

Read more...