Custom transclusion with Angular
Angular's directives have a transclude option, that allows for rendering an element's original content within the directive's template:
# HTML
<wrapping-directive>
Content ...
</wrapping-directive>
# Directive template
<div class="wrapper">
<ng-transclude></ng-transclude>
</div>
# Result
<div class="wrapper">
Content ...
</div>
However, if you need more control over the transcludable content you need heavier armor. For this case, Angular provides you with a transclusion function as the 5th argument of...
HTTP 302 redirects for PATCH or DELETE will not redirect with GET
A HTTP 302 Found redirect to PATCH and DELETE requests will be followed with PATCH or DELETE. Redirect responses to GET and POST will be followed with a GET. The Rails form_for helper will use a workaround to send POST requests with a _method param to avoid this issue for PATCH/DELETE.
If you make requests yourself, watch out for the following behavior.
When you make an AJAX request PATCH /foo and the /foo action redirects to /bar, browsers will request PATCH /bar. You probably expected the second requ...
Centering with CSS vertically and horizontally (all options overview)
There are a million ways to center <div>s or text in CSS, horizontally or vertically. All the ways are unsatisfying in their own unique way, or have restrictions regarding browser support, element sizes, etc.
Here are two great resources for finding the best way of aligning something given your use case and browser support requirements:
- How to center in CSS
-
A long form that lets you define your use case and browser support requirements, then shows you the preferred way of aligning.
[Centering CSS: A co...
ActiveRecord meets database views with scenic
Using Scenic, you can bring the power of SQL views to your Rails application without having to switch your schema format to SQL. Scenic provides a convention for versioning views that keeps your migration history consistent and reversible and avoids having to duplicate SQL strings across migrations. As an added bonus, you define the structure of your view in a SQL file, meaning you get full SQL syntax highlighting in the editor of your choice and can easily test your SQL in the database console during development.
[https://robots.thoughtb...
Showing a custom maintenance page while deploying
Note
The maintenance mode is enabled on all application server as soon as the file
/public/system/maintenance.htmlis present.
Installation
Add this line to your application's Gemfile:
gem 'capistrano', '~> 3.0'
gem 'capistrano-maintenance', '~> 1.0'
Add this line to you application's Capfile:
require 'capistrano/maintenance'
Enable task
Present a maintenance page to visitors. Disables your application's web interface by writing a #{maintenance_basename}.html file to each web server. The servers m...
How to render an html_safe string escaped
Once Rails knows a given string is html_safe, it will never escape it. However, there may be times when you still need to escape it. Examples are some safe HTML that you pipe through JSON, or the display of an otherwise safe embed snippet.
There is no semantically nice way to do this, as even raw and h do not escape html_safe strings (the former just marks its argument as html_safe). You need to turn your string into an unsafe string to get the escaping love from Rails:
embed = javascript_tag('var foo = 1337;') # This is an h...
Top 10 Email Developments of 2015
You know that layouting HTML e-mails is terrible.
For more fun, check Litmus' list of top 10 e-mail developments of 2015 that did not make things better.
Use jQuery's selector engine on vanilla DOM nodes
There are cases when you need to select DOM elements without jQuery, such as:
- when jQuery is not available
- when your code is is extremely performance-sensitive
- when you want to operate on an entire HTML document (which is hard to represent as a jQuery collection).
To select descendants of a vanilla DOM element (i.e. not a jQuery collection), one option is to use your browser's native querySelector and [querySelectorAll](https://developer.mozilla.org/de/docs/We...
Git: Keep your repository tidy
When you're using feature branches, they will stack up if you don't delete them after the merge to master. Here's how to tidy them up.
Delete feature branches
Find already-merged branches by running
# On branch master
git branch --merged
You may safely delete each of the listed branches, because they point to commits that are contained in the history of your current branch (i.e. master).
git branch -d my/feature-branch # Delete feature branch locally
git push origin :my/feature-branch # Push *nothi...
How to open a new tab with Selenium
Until recently, you could open a new tab via window.open when using execute_script in Selenium tests. It no longer works in Chrome (will show a "popup blocked" notification).
This is because browsers usually block window.open unless the user interacted with an element for security reasons. I am not sure why it did work via Selenium before.
Here is an approach that will insert a link into the page, and have Selenium click it:
path = "/your/path/here"
id = "helper_#{SecureRandom.hex(8)}"
execute_script <<-JAVASCRIPT
...
Make Nokogiri use system libxml2
The nokogiri gem provides different packages for several platforms. Each platform-specific variant ships pre-built binaries of libxml2, e.g. x86_64-linux includes binaries for 64bit Linux on Intel/AMD. This significantly speeds up installation of the gem, as Nokogiri no longer needs to compile libxml2.
However, this also means that for each security issue with libxml2, Nokogiri maintainers have to update their pre-built binaries and release a new version of the gem. Then, you need to update and ...
RSpec & Devise: How to sign in users in request specs
You know that Devise offers RSpec test helpers for controller specs. However, in request specs, they will not work.
Here is a solution for request specs, adapted from the Devise wiki. We will simply use Warden's test helpers -- you probably already load them for your Cucumber tests.
First, we define sign_in and sign_out methods. These will behave just like ...
Upgrade from Ruby 1.8.7 to 2.1.5 – an incomplete guide
I recommend to go straight to 2.1.5+ without intermediate steps. Otherwhise you burden yourself with unnecessary work of encoding problems.
Issues you may encounter:
- Set the ruby version within your
.ruby-versionfile to2.1.5 - Remove gem
ruby-debugand use e.g.byebug - Remove gem
oniguruma - Remove gem
fastercsv - Replace gem
mysqlwithmysql2 - Update gem capistrano
2.12.0to~>2.12when bound forRuby 1.8.7and remove obsolete explicite Gemfile entries fornet-scpandnet-sshif present. - Update gem `and...
Preconnect, Prefetch, Prerender ...
A very informative and interesting presentation about browsing performance, looking at efforts Google Chrome takes to increase it.
From those slides
There is a bunch of interesting pages in Chrome:
- chrome://dns - List of prefetched DNS
- chrome://predictors/ - Chrome knows where you'll go
Preconnect
With <link rel="preconnect" href="https://the-domain.com"> in an HTML head, you give the browser an early hint that it will need to access the mentioned domain. By setting up the connection in advance, page load performance gets im...
Test your application's e-mail spam scoring with mail-tester.com
You can use mail-tester.com to check your application's e-mails for issues that might cause e-mails to be classified as spam.
They provide a one-time e-mail addresses that you can use to sign up etc. You can then check for scoring results of SpamAssassin and other potential issues.
You don't need to hit 10/10. Something around 9/10 is perfectly fine.
Note:
- For password-protected staging sites you will get an error for links that can not be resolved. This is fine, simply check production once available.
- ...
Lazy-loading images
Note
This card does not reflect the current state of lazy loading technologies. The native lazy attribute could be used, which is supported by all major browsers since 2022.
Since images are magnitudes larger in file size than text (HTML, CSS, Javascript) is, loading the images of a large web page takes a significant amount of the total load time. When your internet connection is good, this is usually not an issue. However, users with limited bandwidth (i.e. on mobile) need to mine their data budget...
Thunderbird: How to compose an HTML e-mail (when plain-text messages are your default)
Nobody needs HTML e-mails. However, you occasionally might have to write an HTML message for some weird reason. Here is how:
- Hold the Shift-Key while clicking on "Write", "Reply", "Reply All", or "Forward".
That's it. :)
Check SSL certificates
Installing SSL certificates usually implies additionally using intermediate certificates. If one of them is missing, some SSL client implementations might fail with failures such as
curl
~ curl -v https://host-to-check
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
OpenSSL
~ openssl s_client -connect host-to-check:443
...
verify error:num=20:unable to get local issuer certificate
...
v...
Keeping web applications fast
Our applications not only need to be functional, they need to be fast.
But, to quote Donald Knuth,
premature optimization is the root of all evil (or at least most of it) in programming
The reasoning is that you should not waste your time optimizing code where it does not even matter. However, I believe there are some kinds of optimizations you should do right away, because
- they are either obvious and easy
- or they are very hard to do optimize later
This is an attempt to list some of those things:
On the server
...
Heads up: Ruby implicitly converts a hash to keyword arguments
When a method has keyword arguments, Ruby offers implicit conversion of a Hash argument into keyword arguments. This conversion is performed by calling to_hash on the last argument to that method, before assigning optional arguments. If to_hash returns an instance of Hash, the hash is taken as keyword arguments to that method.
Iss...
Escape a string for transportation in a URL
To safely transport an arbitrary string within a URL, you need to percent-encode characters that have a particular meaning in URLs, like & or =.
If you are using Rails URL helpers like movies_path(:query => ARBITRARY_STRING_HERE), Rails will take care of the encoding for you. If you are building URLs manually, you need to follow this guide.
Ruby
In Ruby, use CGI.escape:
# ✅ good
CGI.escape('foo=foo&bar=bar')
=> "foo%3Dfoo%26bar%3Dbar"
Do not ever use `URI.en...
Angular: Quick and easy animation on changed binding value
With ngAnimate, you can easily animate certain events (see directive support). We'll make use of ngClass animations to style an element on changed binding value.
Say we have a slider and a separate details container. Each time the slider changes, we want to "flash" the details container by hiding it and fading it back in.
HTML
Add a custom class to the element you want to animate, i.e. the details container:
<div class="details slide-index-{{ currentSlideIndex }}">
{{ co...
Project management best practices: Standup
If the project team consists of at least 2 members, do a daily standup. It should not take much longer than 15 minutes.
Format
Tell everyone else
- what you did yesterday
- what you intend to do today
- where you might need help or other input
- if there are new developments everyone needs to know about
A "still working on X, will probably be done today" is totally fine. No need to tell a long story.
If you are out of work, find a new story with the others.
If there are new stories in the backlog, look at them and
- make sure ev...
CSS has a well-supported :empty selector
All browsers + IE9 know the CSS :empty selector. It lets you hide an element when it has no content, i.e. not even white space.
(How to prevent whitespace in HAML)
For instance, you have a badge displaying the number of unread messages in a red bubble with white text:
.unread-messages-bubble {
background-color: red;
border-radius: 10px;
padding: 10px;
color: white;
}
To hide that bubble entirely ...