Today I Learned

A collection of useful bits & bobs I'd rather not forget
Edit processing sketches in Vim

Since I last used processing many moons ago, it's become possible to use other text editors rather than their default IDE. Here's how to edit and run processing sketches, straight from Vim.

  1. Install Vim Processing.
  2. Install "processing-java" by opening the Processing IDE, then clicking "Tools > 'processing-java'"
  3. Run sketches from within vim with the :make command. I've mapped leader-m to this command to speed things up a bit:
" Run :make in processing sketches
map <Leader>m :make<cr>
VIM
PROCESSING
Compare a single file between Git branches

You've been working on a file for hours, and can't remember what change you've made. If the original version you'd like to look at is on a different branch, a simple git diff won't cut it. However, you can easily compare files across branches with:

git diff mybranch..otherbranch -- /path/to/file.ext

If you're actually on the branch and want to compare with another branch, there's a simpler way still:

git diff otherbranch.. -- /path/to/file.ext
Scaling a CSS container within bounds

In CSS constraining an element within the bounds of it's parent whilst maintaining it's aspect ratio is harder than you might imagine. This little JS Fiddle from danield770 was just the ticket:

div#constrained-element {
  width:       100vw;
  height:      56.25vw; /* 100/56.25 = 1.778 */
  max-height:  100vh;
  max-width:   177.78vh; /* 16/9 = 1.778 */
  margin:      auto;
  position:    absolute;
  top:         0;
  bottom:      0; 
  left:        0;
  right:       0;
}

Effectively it uses the CSS3 viewport width/height property to calculate the proper size (in this case 16:9).

Access clipboard image data, cross browser (even Safari)

Allowing users to paste images from their clipboards directly into a web app is a great way of bringing a desktop-like experience to the web. However browser support for this functionality is a little all over the place (Safari, I'm looking at you).

Happily as is so often the case on the internet, a kindly soul (in this case Michael Yin) has done the hard work for you and wrapped it up in a neat little jQuery plugin. Just drop it in and cross browser image pasting is yours. My only regret is not finding this sooner.

Paste.js on Github

// Capture paste event on the whole document 
$('html').pastableNonInputable();
$('*').on('pasteImage', function (ev, data){
  // Do something with the image (data.dataURL)
}.bind(this)).on('pasteImageError', function(ev, data){
  // Do something with the error
}).on('pasteText', function (ev, data){
  // Do something with text
});
JAVASCRIPT
Ruby Decorators

Callbacks in active record can, even with the best intentions, quickly become a tangled web of despair. Decorators are a neat way of layering functionality in a more specific way.

For example, let's say you have a class which generates an image.

class GenerateImage
  def call
    # do some image processing stuff
  end
end

GenerateImage.new.call

Simple enough, but perhaps you also want to send an alert when the image processing is complete. You could do this with an active record callback, but using a decorator provides a nice declarative way of doing the same thing:

class GenerateImage
  def call
    # do some image processing stuff
  end
end

class ImageProcessingDecorator < SimpleDelegator
  def call
    if __getobj__.call
      # Send alerts after the call method
      # of GenerateImage is complete
    end
  end
end

ImageProcessingDecorator.new(
  GenerateImage.new("params")
).call

Effectively whatever arguments you pass to GenerateImage then "fall" through to the ImageProcessingDecorator after processing has successfully completed. Using this pattern you can layer functionality together in a way that's easier to unpick at a later date.

Big thanks to the mighty Ben Orenstein for his video on the subject. If you write ruby code, you should check out his upcoming course.

RUBY
RAILS
Vim Spellcheck

I love Vim, and do most of my writing in it. However, it's not set up for copy so much as it is code. Little luxuries like spell checking aren't enabled by default.

Thankfully, turning it on and off it is as easy as:

" Enable spellcheck
set spell
" Disable spellcheck
set nospell

I generally find it less distracting to not have spell check on most of the time, hence why I don't just set this in my .vimrc file.

Copying Rails console output to clipboard on Mac

From time to time I want to work with information which is from rails console output outside of the command line. Helpfully, ruby provides a neat way to pipe console output into the mac system clipboard using IO:

IO.popen("pbcopy", "w") do |pipe| 
  # Get users without subscriptions as CSV and add them to the clipboard
  pipe.puts User.includes(:subscription).where(subscriptions: {user_id: nil}).pluck(:email).to_csv
end
RUBY
RAILS
A very basic goroutine example

In Golang, moving CPU intensive tasks into a Goroutine is a very easy way to process heavy tasks concurrently but synchronously. Imagine you're uploading a file to S3. Written as below, this would run in the main channel:

func main() {
  // ...
  imageUrl := HeavyImageUpload(imageData)
  return imageUrl
}
func HeavyImageUpload(imageData ImageData) {
  //... image processing stuff
  return imageUrl
}

This will work, but it won't scale well. However, you can easily move this into it's own channel away from the main channel, meaning they can be processed at the same time, but remain in sync.

func main() {
  // ...
  imageChannel := make(chan string)
  // Run function within a goroutine
  go HeavyImageUpload(imageData, imageChannel)
  // Wait for the channel
  imageUrl := <- imageChannel 
  return imageUrl
}
func HeavyImageUpload(imageData ImageData, imageChannel chan string) {
  //... image processing stuff
  imageChannel <- imageUrlString
}

The <- pointers are key. They ensure that the channel has finished processing before moving on to the next part of the program.

This is a great way of still performing everything synchronously, but moving the processing into parallel threads so they can be processed concurrently.

GOLANG
Deploy a subfolder as a GitHub pages site

Static sites on github must be deployed to the gh-pages branch. Sometimes you may want to deploy a sub folder within your repository to be at the root of your site. For example:

-- / 
---- build/ << contains built site
---- source/
---- README.md
---- etc..

You can deploy the /build/ folder from the master branch to the root of gh-pages using the subtree command:

git subtree push --prefix build origin gh-pages

As a bonus, if you're using a custom domain you need to ensure there's a CNAME file in the root of the /build/ folder with the domain name in it. You can wrap this up in a shell command like so:

touch build/CNAME
echo \"domainname.co\" >> build/CNAME
GITHUB
Sending client events with Pusher

Pusher is an amazing service for quickly integraing realtime behaviour into an app.

When publishing events from a server things are simple enough, but there are a couple of ideosyncracies to get up and running when publishing events via Javascript.

All client events have to be authenticated on your server before they'll send any data. Then (and this is the gotcha which held me hostage for more than a little while), you have to ensure that all client events (i.e. events you send from the browser), start with a client- prefix. Without this, it's not going to work.

As usual, it's all in the documentation.

JAVASCRIPT
How to renew an SSL certificate on Heroku

Renewing SSL certificates is one of those jobs which I end up researching for half an hour every time I try and do it. These instructions are geared towards SSL on Heroku.

Step 1. Buy a new SSL cert from Namecheap

Step 2. Generate a new key / crt pair

On your local machine, create a new key pair:

openssl req -nodes -new -key server.key -out server.csr

Step 3. Upload the crt to namecheap

Step 4. Download the bundle from namecheap

Step 5. Update the certificate on heroku with the BUNDLE.crt file you just downloaded

heroku certs:update server.crt server.key -a app-name

Step 6. Test SSL with:

Check everything is wired up properly with

curl -kvI https://www.example.com

SERVER
Lesser used git commands

Most of these don't see much action day to day, but they're useful when they're useful.

# See a list of recent commits
git log --stat --pretty=short --graph

# Disregard uncommited changes to a file
git checkout -- /PATH/TO/FILE

# Checkout a specific past commit as a new branch
git checkout -b NEW_BRANCH_NAME COMMIT_HASH

# Amend a commit message before pushing
git commit --amend

# Add staged filed to the last commit (useful for assets)
git commit --amend -C HEAD

# List remote git branches
git branch -a

# See changes to files you've already committed 
git diff --cached