View
Repeats

Take care of indentation and blank lines when using .erb for plain text emails

Building plain text emails with an .erb template doesn't allow you to indent code like you normally do in HTML mails.

DON'T

<%= 'foo' if bar %>

"\n" if bar is false

"foo\n" if bar is true


<%= nil %>

"\n"


<% if true %>
  <%= 'foo' %>
<% end %>  

" foo"


<%= 'foo' %>

<%= 'bar' %>

"foo\n\nbar\n"

DO

Write unindented code to get the expected result.

<% if bar %>
<%= 'bar' %>
<% end %>
<%= 'foo' %>
<%= 'bar' %> 
  • Use [Form Models](https://github.com/makandra…
Repeats

HTML file inputs support picking directories

HTML's <input type="file"> accepts a single file. You can allow multiple files via <input type="file" multiple>.
But sometimes, selecting multiple files is not enough and can be cumbersome for the user. Enter webkitdirectory:

<input type="file" webkitdirectory multiple>

Using webkitdirectory switches the browser's file picker to select a directory. All files inside that directory, and inside any nested subdirectories, will be selected for the file input.

This can be useful when users want to upload all files from a nested dire…

Repeats

HTML forms with multiple submit buttons

Most forms have a single submit button that will save the record when pressed.

Sometimes a form needs additional submit buttons like "accept" or "reject". Such buttons usually attempt a state transition while updating the record.

To process a form with multiple buttons, your server-side code will need to know which button was pressed. To do so you can give each submit button a different [formaction] attribute. This will override the …

Haml: Generating a unique selector for an element

Having a unique selector for an element is useful to later select it from JavaScript or to update a fragment with an Unpoly.

Haml lets you use square brackets ([]) to generate a unique class name and ID from a given Ruby object. Haml will infer a class attribute from the given object's Ruby class. It will also infer an id attribute from the given object's Ruby class and #id method.

This is especially useful with ActiveRecord instances, which have a persisted #id and will hence **generate the same selector o…

Introduction to Google Tag Manager (for web developers who know Google Analytics)

As a web developer, you know Google Analytics (GA). Probably you've dropped the GA snippet into more than one website, maybe you've even used its Javascript API to implement tracking at the event level.

Google Tag Manager (GTM) is a related tool, but on a higher level and thus with much more power. GTM is not a replacement for GA. Rather, it can make GA configurable without changing anything in the application's code base (and much more beyond, see below).

Only prefer GTM if the customer requests it, or if he is updating his tracking r…

Using the Ruby block shortcut with arguments

Ruby has this handy block shortcut map(&:to_i) for map { |x| x.to_i }. However, it is limited to argument-less method invocations.

To call a method with an argument, you usually need to use the full block form. A common case is retrieving values from a list of hashes (imagine using a JSON API):

users = [ { name: 'Dominik', color: 'blue' }, { name: 'Stefan', color: 'red'} ]
names = users.collect do |user|
  user['name']
end

But with a little extension, you can do better.

Block shortcut with arguments

By defining `Symbol#c…

Repeats

Debugging cucumber feature with javascript + firefox vnc

TL;DR Debugging problems with javascript errors in cucumber tests is sometimes easier in the browser. Run the test, stop at the problematic point (with Then pause from Spreewald 1.7+) and open VNC for Firefox.

Features:

Repeats

Do not use "flex: 1" or "flex-basis: 0" inside "flex-direction: column" when you need to support IE11

Flexbox is awesome. Most of it even works in IE11, but flex: 1 won't work reliably in Internet Explorer.
This it because implicitly sets flex-basis: 0 which IE fails to support properly.

Example

Consider the following HTML and CSS.

<div class="container">
  <div class="child">
    foo
  </div>
  <div class="bar">
    bar
  </div>
</div>
.container {
  display: flex;
  flex-direction: column;
}

.child {
  flex: 1;
}

See it in action at Plunker.

Background

Repeats

Trigger native mouse events with Javascript

The attached Coffeescript helper will let you create mouse events:

$element = $('div')
Trigger.mouseover($element)
Trigger.mouseenter($element)
Trigger.mousedown($element)
Trigger.mouseup($element)
Trigger.mouseout($element)
Trigger.mouseleave($element)
Trigger.click($element)

The dispatched events are real DOM events, which will trigger both native and jQuery handlers.
jQuery's .trigger is simpler, but will only trigger event handlers that were bound by jQuery's .on.

Real user actions t…

Haml: Prefixing a group of attributes

Haml lets you prefix a group of attributes by wrapping them in a hash. This is only possible with the {} attribute syntax, not with the () attribute syntax.

Example: HTML5 data attributes

HTML5 allows you to use arbitrary attributes like data-method and data-confirm. You can prefix a group of data- attributes like this:

%a{href: '/path', data: { method: 'delete', confirm: 'Really delete?' }} Label

This compiles to:

<a data-confirm='Really delete?' data-method='delete' href='/path'>Label</a>

Exa…

Repeats

Designing HTML email

The 90s are calling: they want their tables back. Unfortunately, you'll need them all for laying out your HTML emails. (It is really that bad.)

Email client HTML rendering is way more scattered than browser HTML. While you might have a pretty good understanding of what features and patterns you can use to support all major browsers, I doubt anyone masters this craft for HTML email clients.

The only way to ensure your email looks good (acceptable, at least) in all mail clients, is to check it. Litmus is your go-to solu…

Repeats

How to make your application assets cachable in Rails

Note: Modern Rails has two build pipelines, the asset pipeline (or "Sprockets") and Webpacker. The principles below apply for both, but the examples shown are for Sprockets.


Every page in your application uses many assets, such as images, javascripts and stylesheets. Without your intervention, the browser will request these assets again and again on every request. There is no magic in Rails that gives you automatic caching for assets. In fact, if you haven't been paying attention to this, your application is probabl…

Repeats

Everything you know about html_safe is wrong

Back in the war, Rails developers had to manually HTML-escape user-supplied text before it was rendered in a view. If only a single piece of user-supplied text was rendered without prior escaping, it enabled XSS attacks like injecting a <script> tag into the view of another user.

Because this practice was so error-prone, the rails_xss plugin was developed and later integrated into Rails 3. rails_xss follows a different approach: Instead of relying…

Repeats

Project management best practices: The story tracker

In general, the tracker should always be the definitive source of truth of what needs to be done as part of a project. If you identify a task that needs to be done, you should create a story. If you learn something that contradicts an existing story, change it.

The tracker can contain two types of stories: Developer stories, and non-developer stories.

Non-developer stories

Non-developer stories should be clearly marked. They usually belong to the PM (or maybe people from the operations team). Those story can take all forms, could just…

Chrome bug: Wrong stacking order when transitioning composited elements

Google Chrome has a subtle rendering bug that hits me once in a while. It usually occurs in sliders with HTML content.

The issue

When a slider contains a composited[1] element, the element will overlap any other element when sliding, being rendered as frontmost element. After the slider has settled, stacking order jumps back to normal.

It seems like Chrome is doing its compositing wrong. This doesn't happen in Firefox.

The cause

The issue only occurs if:

  • two elements A and B are nested inside an element C
  • A overlaps B (part…
Repeats

ActiveRecord: When aggregating nested children, always exclude children marked for destruction

When your model is using a callback like before_save or before_validation to calculate an aggregated value from its children, it needs to skip those children that are #marked_for_destruction?. Otherwise you will include children that have been ticked for deletion in a nested form.

Wrong way

class Invoice
  has_many :invoice_items
  accepts_nested_attributes_for :invoice_items, :allow_destroy => true # the critical code 1/2
  before_save :calculate_and_store_amount                              # the critical code 2/...

Heads up: Rails offers two similar means for text truncation

Rails defines a #truncate helper as well as a method String#truncate.

= truncate("my string", length: 5)
= "my string".truncate(5)

Both are really similar; in fact, the helper invokes the method and improves it with two niceties: support for passing a block (which could e.g. render a "read on" link), and html_safe knowledge.

Prefer the truncate() helper

The method knows nothing about html_safe and will always return an unsafe string. FWIW, an HTML string may easily become invalid when truncated, e.g. when a closing ta…

Repeats

Stretching an HTML page to full height

This card existed before, but was outdated due to browser implementation changes. The information below is validated for the current list of browsers we support.


By default your html and body elements are only as high as the actual page content. If you only have two lines of text in your page, your html and body elements will only be around 40 pixels high, regardless of the size of your browser window.

You might be surprised by this, since setting a background on either html and body does cover the enti…

This website uses cookies to improve usability and analyze traffic.
Accept or learn more