Bootstrap 4 is coming

What's new

  • Moved from Less to Sass. Bootstrap now compiles faster than ever thanks to Libsass, and we join an increasingly large community of Sass developers.
  • Improved grid system. We’ve added a new grid tier to better target mobile devices and completely overhauled our semantic mixins.
    Opt-in flexbox support is here. The future is now—switch a boolean variable and recompile your CSS to take advantage of a flexbox-based grid system and components.
  • Dropped wells, thumbnails, and panels for cards. Cards are a brand new co...

An auto-mapper for ARIA labels and BEM classes in Cucumber selectors

Spreewald comes with a selector_for helper that matches an English term like the user's profile into a CSS selector. This is useful for steps that refer to a particular section of the page, like the following:

Then I should see "Bruce" within the user's profile
                                 ^^^^^^^^^^^^^^^^^^

If you're too lazy to manually translate English to a CSS selector by adding a line to features/env/selectors.rb, we already have an [auto-mapper to translate English into ...

AWS Public IP Address Ranges Now Available in JSON Form

I am happy to announce that this information is now available in JSON form at https://ip-ranges.amazonaws.com/ip-ranges.json. The information in this file is generated from our internal system-of-record and is authoritative. You can expect it to change several times per week and should poll accordingly.

How to deal with 'parent id missing' error in nested forms

tl;dr

  • Use form models to handle this problem
  • Or soften the validation to validates_presence_of :parent

Usually you would validate presence of parent object id, like in this example:

class Parent < ActiveRecord::Base
  has_many :nested, :inverse_of => :parent
  accepts_nested_attributes_for :nested
end

class Nested < ActiveRecord::Base
  belongs_to :parent
  validates_presence_of :parent_id # <- 
end

With the parent already persisted creating nesteds still works fine.

But one will encounter a *'parent id missing' er...

Long cards: Directly jump from a paragraph to the same paragraph in the editor

If you hover over the text of a card, you will now see EDIT links at the top right corner of each block.

This link will open the card editor and scroll the editor to this very paragraph. The cursor caret will sit on the first character of that paragraph.

This should help making small changes to longer cards.

Using tig

tig is a command line explorer for Git that is just awesome. Install via apt-get or brew.

Handy commands

  • t ("tree"): Directory-structure based access. You'll see the current directory annotated with the latest change date and its author. Navigate with arrow keys or vim.
  • b ("blame"): Opens the file under the cursor and annotates each line with change date and author.
  • d ("diff"): Like ENTER on a commit, but arrow keys will scroll the diff!
  • /: Search current view (e.g. commit list, diff). Jump to next hit with n....

List of Helpful RubyMine Shortcuts

Navigation

CTRL + SHIFT + ALT + N

Search for any symbol in your application, like CSS classes, Ruby classes, methods, helpers etc.

CTRL + SHIFT + N

Search for filename in your application (also dependencies)

CTRL + E

Open a list of recently opened files

ALT + POS1

Open a the navigation bar as a context menu. Allows you to quickly navigate between files.

CTRL + G

Go to line

Actions

CTRL + SHIFT + A

:...

Pierce through Javascript closures and access private symbols

If you are writing any amount of Javascript, you are probably using closures to hide local state, e.g. to have private methods.

In tests you may find it necessary to inspect a variable that is hidden behind a closure, or to mock a private method using Jasmine spies.

You can use the attached Knife helper to punch a hole into your closure, through which you can read, write or mock local symbols:

klass = (->

 privateVariable = 0

 privateMethod = ->
   ...

Detecting N+1 queries with Bullet

The Bullet gem is designed to help you increase your application's
performance by reducing the number of queries it makes. It will watch
your queries while you develop your application and notify you when
you should add eager loading (N+1 queries), when you're using eager
loading that isn't necessary and when you should use counter cache.

Parallel Rspec with RTeX

Running projects parallel makes some trouble with PDF generation. Use geordi rspec spec to force sequential tests for the whole application or failed specs only.


geordi rspec
RTeX::Document::GenerationError in '...'
Could not find result PDF document.pdf after generation.
Check .../document.log

The document will show you, that RTeX tries to generate a PDF document out of a HTML file, which won't work.

Material Design Lite

CSS (+ some Javascript) framework, implementing Google's material design for static web pages.

Can be used for plain websites without requiring a full blown Javascript framework, unlike the (also excellent) Polymer paper elements, or Angular material.

Prelimiary impression:

I would recommend against using it at this stage, for a couple of reasons:

  • It is much less complete than you might expect from a CSS framewor...

How to disable auto-complete on login forms

Disabling auto-complete in login forms is probably a bad idea, since it encourages weak passwords.

If you are still forced to implement this (maybe due to legal or policy requirements), this is how:

Prevent browsers from saving the password in the first place. Disabling autocomplete does not improve security.

How to prevent password saving:

To prevent the browser from saving passwords (and usernames), you need to:

  • copy username and password to hidden form fields before submitting the login form
  • c...

CSS Support Guide for Email Clients

CSS support in major e-mail clients is horrible.

This will give you an overview what you will not be able to use across all clients.

See also

image-to-DataURI converter: Duri.me

Small web application where you can upload an image (PNG, JPEG, GIF) and generate a base64-encoded version of it.

You can copy the result as

  • HTML <img> tag with data URI,
  • CSS rule with background-image and data URI,
  • plain Base64-encoded data URI string.

A non-weird replacement for grouped_collection_select

Rails comes with grouped_collection_select that appears to be useful, but isn't.

As an alternative, consider the flat_grouped_collection_select found below. It takes a third argument that extracts the group from each element in the collection:

= form.flat_grouped_collection_select :user_id, users, :department, :id, :full_name

Here is the monkey-patch:

class ActionView::Helpers::FormBuilder

  def flat_grouped_collection_selec...

Rails 3 ActiveRecord::Persistence#becomes does not copy changed attributes

Note: ActiveRecord::Base#becomes has a lot of quirks and inconsistent behavior. You probably want to use ActiveType.cast instead.


This issue will be encountered when relying on attribute_was methods of ActiveModel::Dirty after casting a model which has defaults to a form model, for example.

In my case a record with an assignable_values legacy value beca...

Testing regular expressions visually

Developing complex regular expressions quickly blows my mind. Here are some online regex editors that help you by highlighting matching text and capture groups:

Reverse-proxying web applications with Apache 2.4+

Note: Making a reverse proxy with nginx is much more straightforward.


A reverse proxy is a "man in the middle" server that tunnels requests to another server. You can use for things like:

  • Expose a local service that you cannot directly reach over the internet
  • "Change" the domain or path of a web application by rewriting them on the fly
  • Instantly change servers that respond to a name or ...

Manually trigger a delegated DOM event

When you register a delegated event using on (or the deprecated delegate / live), it is somewhat hard to manually trigger these events manually, e.g. for testing.

After trying jQuery's trigger to no avail, I had success by using native Javascript methods to create and dispatch an event. For instance, to trigger a mousedown event:

element = $('...').get(0);
event = new MouseEvent('mousedown', { view: window, cancelable: true, bubbles: true }...

Upgrading from Capistrano 2 to 3

Capistrano 3 is a major rework of the framework and requires several adjustments to your deploy configuration files. The biggest change is that they moved away from their custom DSL and use Rake instead. For connecting with and operating on the servers, they bring a new gem SSHKit which does the heavy lifting. It's SSHKit's DSL that is used anywhere inside the Rake tasks. See #Resources at the bottom for examples.

Step 1: Upgrade guide

For migration from 2 to 3, follow this tutorial: [Capistrano 3 Upgrade Guide](https://semaphorec...

Cucumber step to pick a datetime in Rails' horrible datetime_select

Please don't use the horrible datetime_select helper. It has a terrible UI. Always prefer to use a visual time picker like Rome instead.

In case everything has failed and you do need a Cucumber step to pick a datetime datetime_select, here it is:

When(/^I select the time (\d+)\-(\d+)\-(\d+) (\d+):(\d+) from "(.*?)"$/) do |year, month, day, hour, minute, label_text|
  label = page.find('label', text: label_text)
  id = label[...

Savon testing: How to expect any message

When using Savon to connect a SOAP API, you may want to use Savon::SpecHelper to mock requests in your tests as described in their documentation.

When sending a message body, the savon mock object requires a message to be set, like this:

savon.expects(:action_name).with(message: { user_id: 123 }).returns('<some xml>')

If you want to stub only the returned XML and do not care about request arguments, you can not omit with as Savon's helper will complain:

savo...

Testing setTimeout and setInterval with Jasmine

Jasmine has a jasmine.clock() helper that you can use to travel through time and trigger setTimeout and setInterval callbacks:

beforeEach(function() {
  timerCallback = jasmine.createSpy("timerCallback");
  jasmine.clock().install();
});

afterEach(function() {
  jasmine.clock().uninstall();
});

it("causes a timeout to be called", function() {
  setTimeout(function() {
    timerCallback();
  }, 100);

  expect(timerCallba...

A solid and unobtrusive plugin for form field placeholders

jquery-placeholder is a simple jQuery plugin that enables form placeholders in browsers that do not support them natively, i.e. IE < 10.

Properties

  • Works in IE6.
  • Automatically checks whether the browser natively supports the HTML5 placeholder attribute for input and textarea elements. If this is the case, the plugin won’t do anything. If @placeholder is only supported for input elements, the plugin will leave those alone and apply to textareas exclusively. (This is the case for Safari 4, Opera 11.00, and possibly other browsers.)
    ...