The nitty-gritty of compile and link functions inside AngularJS 1 directives

Use the compile function to change the original DOM (template element) before AngularJS creates an instance of it and before a scope is created.

Use the pre-link function to implement logic that runs when AngularJS has already compiled the child elements, but before any of the child element's post-link functions have been called.

Use the post-link function to execute logic, knowing that all child elements have been compiled and all pre-link and post-link functions of child elements have been executed.

Bash script to list commits by Pivotal Tracker ID

The main benefit of our convention to prefix commits by their corresponding Pivotal Tracker ID is that we can easily detect commits that belong to the same story. You can either do that manually or use the bash script below by copying it somewhere to your .bashrc.

# Usage: ptcommits 123456
function ptcommits {
  if test "$1"
  then
    local PTID=$(echo "$1" | grep "[0-9]*" -o) # Allow URLs
    git log --onel...

Convert SCSS to SASS

The ruby sass gem also installs a command line tool to convert to and from SCSS. Use it for a directory of .scss-files like

sass-convert -R assets/stylesheets --from scss --to sass

CSS-Style

Richard Powell presents a collection of CSS styling advice that's mainly taken from SMACSS. Although at makandra we're using BEM instead of SMACSS, here's my favorites.

Do not use ID's in CSS Selectors

It is never safe to assume there will only ever be one of something on a page so do not use ID's for CSS. Id's are much better used as javascript hooks so use them for this instead.

.list {…} instead of #list {…}

Animate an interface using classes not inline styles

Inline styles added by javascript are h...

Powerful favicon generator

This favicon generator will guide you to a perfect set of favicon files, suitable for all devices and situations (browser, homescreen icon for iOS/Android/Windows, MacBook Touch Bar etc.)

How to

Open the Favicon generator and upload a square image:

  • either an SVG
  • or a PNG/JPG/… with more than 260px size

Then follow the steps it guides you. In the result window, stick to the HTML5 tab. It is just fine.

More

Haml: Prevent whitespace from being stripped in production

Disclaimer

This is not an issue in newer versions of HAML (starting with 5.0.0), as the ugly-option was removed so that in development everything is rendered ugly, too.

Problem

When HTML is rendered from HAML in production or staging environment, whitespace is removed to reduce the download size of the resulting pages. Therefore it might happen that whitespace you see in development is missing in production or staging.

Here is an example of two inlined bootstrap buttons in a t...

How to mount a legacy database to migrate data

There are many approaches out there how you can import data from a legacy application to a new application. Here is an approach which opens two database connections and uses active record for the legacy system, too:

1. Add you database information to you config/database.yml.

data_migration:
  database: your_application_data_migration

2. Create a separate application record for the data migration, e.g. in app/data_migration/migration_record.rb. You will need to create an app/data_migration.rb class first.

class DataMig...

Joining PDFs with Linux command line

There are several ways to merge two (or more) PDF files to a single file using the Linux command line.

If you're looking for graphical tools to edit or annotate a PDF, we have a separate card for that.

PDFtk (recommended)

PDFtk is a great toolkit for manipulating PDF documents. You may need to install it first (sudo apt install pdftk).
Merging multiple files works like this:

pdftk one.pdf two.pdf cat output out.pdf

Unlike pdfjam, PDFtk should not mess with page sizes but simply joins pages as they are.

...

IE11 ignores calc() functions in the flex shorthand

Example (broken in IE):

flex: 0 1 calc(50% - 20px)

Workaround:

flex-basis: calc(50% - 20px)

flex-grow: 0 // Default, can be omitted for this example
flex-shrink: 1 // Default, can be omitted for this example

Class methods in Coffeescript

How to define and call class methods in CoffeeScript classes:

class Foo

  @classMethod: -> 
    @otherClassMethod()
  
  instanceMethod: ->
    @otherInstanceMethod()
    @constructor.classMethod()

Take care of existing users when upgrading Clearance

When upgrading Clearance, pay attention whether the password hashing strategy might have changed. Old clearance versions (< 1.0) used SHA1-encrypted passwords by default. Current versions default to BCrypt.

If you simply upgrade without taking this into account, users will get a BCrypt::Errors::InvalidHash when trying to sign in. Your tests will not notice this, since they create new users for each scenario.

To fix it, you'll either have to force all users to reset their passwords, or you can allow old users to keep signing in with t...

Known MariaDB version incompatibilities

MariaDB (and MySQL) is released in different versions with different behaviors. For backwards compatibility this can be managed with the sql_mode option.

Following you can find behavior differences which cannot be changed by this option. This can cause a regression in an existing application. There is no workaround available. The application needs to be adapted.

Queries with aggregated date types

For a database instance of MariaDB-10...

Fix for "Rails assets manifest file not found" in Capistrano deploy

If you use webpacker in your Rails application, and you have completely disabled Sprockets, you might get the following error when trying to deploy: Rails assets manifest file not found. This happens inside the deploy:assets:backup_manifest task.

This task comes from capistrano-rails. It is build for Sprockets and does not work with Webpacker out of the box.

Solution

Configure capistrano-rails to work with Webpacker

Alternative

If you are using capistrano-rails, but...

Capistrano: Finding out who deployed which revision of your application and when

Capistrano automatically logs each (successful) deployment into a file on your application servers.

It is located at the root of your server's project folder, i.e. the parent of releases and current, like so:

/var/www/your-project$ ls
current
log
releases
repo
revisions.log  <---  here
shared

Each line in that file contains the deployed branch, commit, release ID, and username (was read from the deploying user's machine):

$ tail -n3 revisions.log 
Branch master (at da45511bea63002ac2ff002d1692e09d0dd7cb88) deployed as rel...

DOM API for jQuery users

General hints on the DOM

  • the root of the DOM is document
  • custom elements inherit from HTMLElement. They need a - (dash) in their name, e.g. <notification-box>.
  • event listeners don't have event delegation à la .on('click', cssSelector, handler)

Comparison

Action jQuery DOM API equivalent
Find descendant(s) by CSS selector .find(selector) one: `.querySelector(selecto...

Restore changes, even from deleted files, with RubyMines "Local History"-Feature

Sometimes, due to git or other "accidents", important files get deleted or overwritten.

At a state when even Ctrl+Z doesn't work anymore, you maybe can rescue your files with RubyMines "Local History"-Feature!

To do this try the following:

  • If the file got deleted, recreate a new empty file with the same name on the exact same place
  • Open that file in the editor
  • Go to RubyMine and click on VCS -> Local History -> Show History
  • In the now open window, you should see all greater changes made to the File, even before it got deleted/temp...

CSS font metrics in detail

Line-height and vertical-align are simple CSS properties. So simple that most of us are convinced to fully understand how they work and how to use them. But it’s not. They really are complex, maybe the hardest ones, as they have a major role in the creation of one of the less-known feature of CSS: inline formatting context.

For example, line-height can be set as a length or a unitless value 1, but the default is normal. OK, but what normal is? We often read that it is (or should be) 1, or maybe 1.2, even the CSS spec is unclear on that...

Installing Ruby 2.3 or below on Ubuntu 17 and above

From Ubuntu 17, rbenv fails to install Ruby below 2.4 because of a mismatching OpenSSL dependency: it needs libssl1.0-dev for the installation process, but recent Ubuntus come with libssl-dev.

From the linked StackOverflow comment:

As far as I know (and tested), Ruby versions < 2.4 requires libssl1.0, while >2.4 libssl1.1+. The two libssl packages conflict with each other, so you can't have both of them, so I had to juggle the libs in order to install the required ruby version. To make things even funnier (or more complicated),...

How to inspect the HTML of an email in Thunderbird

Inspecting the source of an email does not always reveal the plain HTML source, but some encoded byte mess. In order to inspect the HTML anyways, you can use a little trick:

While composing a message, select all (Ctrl + A), then navigate to Insert > HTML on the message window.

If you need to inspect a received message, hit "Reply" to turn it into composition mode.

Git: Apply a diff

git apply allows you to apply a diff onto your HEAD. Most often you can achieve the same result with a rebase & merge.

Example:

master                commit1 - commit3
feature-branch                \ commit2 - commit4
git checkout feature-branch
git reset --hard commit3
git diff ..commit4 | git apply
master                commit1 - commit3
feature-branch                          \ Unstaged commit 2 & 4

You can also [create a patch and apply it afterwards](https://makandracards.com/makandra/2521-git-how-to...

Adding Jasmine JavaScript specs to a Webpack(er) project

The goal is to get Jasmine specs running in a Rails project using Webpacker, with the browser based test runner. Should be easily adaptable to a pure Webpack setup.

Image

Step 1: Install Jasmine

yarn add jasmine-core

Step 2: Add two separate packs

Since we do not want to mix Jasmine into our regular Javascript, we will create two additional packs. The first only contains Jasmine and the test runner. The second will contain our normal application code and the specs themselves.

We cannot...

How to get a backtrace if rspec (or any other ruby process) hangs with no output

If rspec hangs with no output and you dont get a backtrace neither with --backtrace nor by just killing it with crtl-c,
you can put the following in your spec/spec_helper.rb:

puts "rspec pid: #{Process.pid}"

trap 'USR1' do
  threads = Thread.list

  puts
  puts "=" * 80
  puts "Received USR1 signal; printing all #{threads.count} thread backtraces."

  threads.each do |thr|
    description = thr == Thread.main ? "Main thread" : thr.inspect
    puts
    puts "#{description} backtrace: "
    puts thr.backtrace.join("\n")
  end

...

Cucumber: Clear localStorage after each scenario

Capybara clears cookies before each scenario, but not other client-side data stores. If your app is using localStorage or sessionStorage, contents will bleed into the next scenario.

Use this hook to remove all site data after each scenario:

After do
  if Capybara.current_driver == :selenium && !Capybara.current_url.starts_with?('data:')
    page.execute_script <<-JAVASCRIPT
      localStorage.clear();
      sessionStorage.clear();
    JAVASCRIPT
  end
end

Unpoly: Testing values for presence or blankness

In Ruby on Rails, all objects have a useful blank? method. It returns true for nil but also for empty strings or empty arrays. There is also a universal method present? which returns true for all values that are not blank?.

In JavaScript you need to roll your own implementation of blank? and present?.

If your application uses [Unpoly](...