Variable fonts for web developers

This card is mainly an explanation how variable fonts work in CSS, not necessarily a recommendation to actually use them.

What is a variable font?

Designing and rendering fonts are two highly complex topics. For an arbitrary text to appear properly on your screen, its font must be created multiple times for different "settings" like stroke width (boldness) and style (e.g. italic).

Now as web developers, we usually ship these variants of the same font via multiple @font-faces of the same font-family:

@font-face
  font-family...

Improving browser rendering performance

As the web is being used for more and more tasks, expectations rise. Not only should web pages offer rich interaction, they must be responsive in both size and interaction.

This imposes a paradoxon that needs to be solved by building performing applications. It's not enough any more to have your web site do crazy stuff, it is also required to do it crazy fast. This card is intended to give you an introduction to this emerging aspect of web development.

Read this introductory [performance study on Pinterest](http://www.smashingmagazine.com/...

Vortrag: Elasticsearch Grundlagen und Rails-Integration mit searchkick

Was ist Elastic?

  • Suchmaschine, basierend auf Apache Lucene
  • größtenteils Open-Source
  • einige kommerzielle Features ("Elastic Stack", früher "X-Pack")
    • Zugriffsrechte (bis vor kurzen)
    • Monitoring
    • Reporting
    • Graph-Unterstützung
    • Machine Learning
  • REST-Api (JSON über HTTP)

Grundlagen

Elastic antwortet per Default auf Port 9200

http GET :9200
{
  "name": "ntK2ZrY",
  "cluster_name": "elasticsearch",
  "cluster_uuid": "Bbc-ix5bQZij5vfFU29-Cw",
  "version": {
    "number": "6.7.1",
    "build_flavor": "...

How to make changes to a Ruby gem (as a Rails developer)

At makandra, we've built a few gems over the years. Some of these are quite popular: spreewald (> 1M downloads), active_type (> 1M downloads), and geordi (> 200k downloads)

Developing a Ruby gem is different from developing Rails applications, with the biggest difference: there is no Rails. This means:

  • no defined structure (neither for code nor directories)
  • no autoloading of classes, i.e. you need to require all files yourself
  • no active_support niceties

Also, their scope...

Check that an element is hidden via CSS with Spreewald

If you have content inside a page that is hidden by CSS, the following will work with Selenium, but not when using the Rack::Test driver. The Selenium driver correctly only considers text that is actually visible to a user.

Then I should not see "foobear"

This is because the Rack::Test driver does not know if an element is visible, and only looks at the DOM.

Spreewald offers steps to check that an element is hidden by CSS:

Then "foo" should be hidden

You can also check that an el...

Minidusen: Filtering associated records

Minidusen lets you find text in associated records.

Assume the following model where a Contact record may be associated with a Group record:

class Contact < ApplicationRecord
  belongs_to :group

  validates_presence_of :name, :street, :city, :email
end

class Group < ApplicationRecord
  has_many :contacts

  validates_presence_of :name
end

We can filter contacts by their group name by joining the groups table and filtering on a joined column.
Note how the joined column is qualified as groups.name (rather than just `na...

Show/Hide Rubocop marking in RubyMine

If you have installed Rubocop in your project, RubyMine can show you Rubocop violations immediately in your editor. You probably already know this feature.

Example

Image

Enable/Disable marking

If your RubyMine does not show you any violations, although there are some, you may have to enable the setting first.

To do so, open Navigate -> Search Everywhere -> Actions (Or use the shortcut CTRL + SHIFT + A) and type in "rubocop", then you should see some...

How to configure file watchers in RubyMine

Installation

You need to install the official plugin, it is not bundled with RubyMine by default.

Example: Setup a watcher to verify rubocop integrity

First, open Settings -> Tools -> File Watchers. Then, configure rubocop to check every change to the VCS:

Image

Note that the "program" argument must be part of your $PATH. I worked around this constraint by using b as a shim for bundle exec.

Resources

  • [File watchers documen...

Convert curl commands to ruby code

curl-to-ruby is a handy tool that converts your curl command to ruby code that uses the Net::HTTP library.

Example

curl -X POST -d
  "grant_type=password&email=email&password=password"
  localhost:3000/oauth/token

will output to:

require 'net/http'
require 'uri'

uri = URI.parse("http://localhost:3000/oauth/token")
request = Net::HTTP::Post.new(uri)
request.set_form_data(
  "email" => "email",
  "grant_type" => "password",
  "password" => "password",
)

req_options =...

Using ffmpeg as a HLS streaming server

A practical and detailed walk-through tutorial on using ffmpeg for live-streaming HLS, filled with real-world examples.

  • Using FFmpeg as a HLS streaming server (Part 1) – HLS Basics
  • Using FFmpeg as a HLS streaming server (Part 2) – Enhanced HLS Segmentation
  • Using FFmpeg as a HLS streaming server (Part 3) – Multiple Bitrates
  • Using FFmpeg as a HLS streaming server (Part 4) – Multiple Video Resolutions
  • Using FFmpeg as a HLS streaming server (Part 5) – Folder Structure
  • Using FFmpeg as a HLS streaming server (Part 6) – Independent Seg...

Tailwind versus BEM

The linked article compares two approaches for writing CSS:

  • A component library (like BEM)
  • Utility classes (like Tailwind)

It's good to know the pros and cons of each approach. Although we default to BEM, you might encounter a utility approach in a client project.

Terminator: do not broadcast to other windows

Terminator has a cool feature that allows you to split your terminal into many panels and type in all of them at the same time. It's called broadcasting and can be enabled by pressing Alt+a (and disabled by Alt+o).

However, in some circumstances it will also be broadcasted to other running instances of Terminator. This probably is not what you want and could be very dangerous (e.g. if you're logged in to a production server in a terminal that is on another workspace).

To prevent the broadcast from affecting other windows, go to `Prefer...

IIFEs in Coffeescript

In JavaScript we often use Immediately Invoked Function Expessions (or IIFEs) to prevent local variables from bleeding into an outside scope:

(function() {
  var foo = "value"; // foo is scoped to this IIFE
})();

In Coffeescript an IIFE looks like this:

(->
  foo = "value" # foo is scoped to this IIFE
)()

There is also a shorthand syntax with do:

do ->
  foo = "value" # foo is scoped to this IIFE

You can also use do with arguments t...

Ruby: Comparing a string or regex with another string

In Rubocop you might notice the cop Style/CaseEquality for e.g. this example:

def foo(expected, actual)
  expected === actual
end

In case expected is a Regex, it suggests to change it to the following pattern:

def foo(expected, actual)
  expected.match?(actual)
end

In case expected is a Regex or a String, you need to keep ===. Otherwise the actual expression is always converted to a regular expression.

# For expected === actual
foo('Test(s)', 'Test(s)') #=> true

# For expected.match?(actual)
foo('Test(...

Passive event listeners may speed up your scroll and touch events

Scroll and touch event listeners tend to be computationally expensive as they are triggered very often. Every time the event is fired, the browser needs to wait for the event to be processed before continuing - the event could prevent the default behavior. Luckily there is a concept called passive event listeners which is supported by all modern browsers.

Below are the key parts quoted from WICG's explainer on passive event listeners. See [this demo video](https://www.youtube.com/watch?v=NPM6172...

Ruby: A short summary of available hooks in Cucumber

Here is a short summary of Cucumber hooks in Ruby taken from https://github.com/cucumber/cucumber-ruby. Note that the BeforeStep is currently not existing in the Ruby implementation of Cucumber.

Before hooks run before the first step of each scenario.

Before do |scenario|
  ...
end

After hooks run after the last step of each scenario, even when the step result is failed, undefined, pending or skipped.

...

Manage Linux services on the command line (Ubuntu)

Ubuntu 18.04 uses systemd to manage services.

There are basically two commands for listing all services and manipulating the state of a certain service: service and systemctl:

  • service manages System V init scripts
  • systemctl controls the state of the systemd system and service manager. It is backwards compatible to System V and includes the System V services

Therefore I prefer to use systemctl.


See which services are there

>systemctl list-units -a --type=service
  UNIT                                 LOAD     ...

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...

CarrierWave: How to remove GIF animation

When accepting GIF images, you will also accept animated GIFs. Resizing them can be a time-consuming task and will block a Rails worker until the image is processed.

Save yourself that trouble, and simply tell ImageMagick to drop any frames but the first one.

Add the following to your uploader class:

process :remove_animation

private

def remove_animation
  if content_type == 'image/gif'
    manipulate! { |image| image.collapse! }
  end
end

You may also define that process for specific versions only (e.g. only for thum...

Migrate gem tests from Travis CI to Github Actions with gemika

We currently test most of our gems on Travis CI, but want to migrate those tests to Github Actions. This is a step-by-step guide on how to do this.

Note that this guide requires the gem to use gemika.

  1. Go to a new "ci" branch:
    git checkout -b ci
    
  2. Update gemika to version >= 0.5.0 in all your Gemfiles.
  3. Have gemika generate a Github Actions workflow definition by running
    mkdir -p .github/workflows; bundle exec rake gemika:generate_github_actions_workflow > .github/workf...
    

How to downgrade Google Chrome in Ubuntu

If you're experiencing problems with your Google Chrome installation after an update, it might help downgrading Chrome to check if the problem disappears. Keep in mind though that running outdated software, especially web browsers, is in most cases not a good idea. Please verify periodically if you still need to run the old version or if an even more recently updated version fixes the problems introduced in your version.

Here's how to get old versions of Chrome for your Ubuntu installation:

First, go to [UbuntuUpdates](https://www.ubuntuup...

Installing old versions of mysql2 on Ubuntu 20.04+

On some of our older projects, we use the mysql2 gem. Unfortunately, versions 0.2.x (required for Rails 2.3) and versions 0.3.x (required for Rails 3.2) can no longer be installed on Ubuntu 20.04. Trying this either leads to errors when compiling the native extension, or a segfaults when using it.

For Rails 4.2, mysql2 version 0.4.10 seems to work okay. If you still have issues, upgrade to 0.5.x, which should be compatible.

To install it, you have to switch the mysql2 gem to our fork. In your Gemfile, ...

Installing Ruby <= 2.3 on Ubuntu 20.04+

Installing old Rubies (<= 2.3) with a standard rbenv + ruby-build is no longer possible on Ubuntu 20.04. This is because those Rubies depend on OpenSSL 1.0 which is no longer shipped with current Ubuntus.

We have forked ruby-build with a workaround that makes it compile and statically link the latest OpenSSL 1.0 version. This works on Ubuntu 20.04, as well as on Ubuntu 18.04.

To switch to our fork of ruby-build, update ruby-build like this

git -C ~/.rbenv/plugins/ruby-build remote add makandra...

How to fill in multiple lines in a textarea with cucumber

If you want to fill in textareas with multiple lines of text (containing line breaks / new lines) you can use Cucumber's docstrings:

And I fill in "Comment" with:

"""
This is a long comment.
With multiple lines.

And paragraphs.
"""

The step definition is part of the spreewald gem