Apache, PHP5 and MySQL on El Capitan

Apache and PHP5

The Apache server works out of the box and can be controlled with the following commands:

Start Apache

$ sudo apachectl start

Stop Apache

$ sudo apachectl stop

Restart Apache

$ sudo apachectl restart

Once the server is running, you should be able to load the default page by going to http://localhost in a browser. You'll also need to set up the directory to host all your files, which requires a few steps:

  • Create a 'Sites' folder in your root (home) directory: mkdir ~/Sites
  • Create a 'username.conf' file (if your username is johndoe, then johndoe.conf) at /etc/apache2/users/: sudo touch /etc/apache2/users/username.conf

You then need to edit the config file you just created with your preferred editor to add the following (replace "username" in the first line with your own":

<Directory "/Users/username/Sites/">
AllowOverride All
Options Indexes MultiViews FollowSymLinks
Require all granted

Then open up /etc/apache2/httpd.conf in an editor to uncomment the following lines (first two should already be uncommented, and the last one enables PHP5):

LoadModule authz_core_module libexec/apache2/mod_authz_core.so
LoadModule authz_host_module libexec/apache2/mod_authz_host.so
LoadModule userdir_module libexec/apache2/mod_userdir.so
LoadModule include_module libexec/apache2/mod_include.so
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
Include /private/etc/apache2/extra/httpd-userdir.conf
LoadModule php5_module libexec/apache2/libphp5.so

We also need to open /etc/apache2/extra/httpd-userdir.conf and uncomment:

Include /private/etc/apache2/users/*.conf

save all edited files, and run the restart command mentioned earlier: sudo apachectl restart You'll now be able to access your Sites folder by going to http://localhost/~username/


OSX does not come with MySQL so it needs to be downloaded: Mac OS X 10.10 (x86, 64-bit), DMG Archive (no need to sign up, just click the tiny "no thanks" link at the bottom). Once you run the DMG installer, it'll give you a temporary root user password upon completion, which you should write down somewhere until it's changed. Open up your System Preferences and go to the newly added MySQL section to start the server.

The temporary password can be overwritten by running the following: /usr/local/mysql/bin/mysqladmin -u root -p 'temppassword' password 'newpassword' where you can replace temppass with the one provided by the installer, and newpass with your desired password.

Typing out the full path to mysql can get annoying, so we can add the mysql directory to the shell path by adding the following into your .bash_profile: export PATH="/usr/local/mysql/bin:$PATH"

There's also a known 2002 MySQL Socket error which can be fixed with the following:

sudo mkdir /var/mysql
sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock


First download phpMyAdmin and unzip contents into a folder named 'phpmyadmin' inside the root of the Sites folder. Create a 'config' folder inside of phpmyadmin folder, and change the permissions: chmod o+w ~/Sites/phpmyadmin/config and run the setup by going to http://localhost/~username/phpmyadmin/setup/

In the setup screen, click 'New Server' and select the 'Authentication' tab. User 'root' should be pre-filled, just type in the updated password we set previously and hit save.

Once returned to the previous screen, click the 'Save' button on the bottom, and a config.inc.php file will be saved into the 'config' folder we had created earlier. Move this file into the root of the phpmyadmin folder and delete the now empty 'config' directory.

You should now be able to interact with your databases by going to http://localhost/~username/phpmyadmin/

Framer Studio Tips


Framer uses Coffeescript which is a shorthand sytnax that compiles to Javascript. I've outlined some of the basics on how to write loops and conditionals, but a more comprehensive overview can be found here.


CoffeeScript uses significant whitespace, meaning tabs help define the structure of what's written in place instead of the default { and } which denote the beginning and end of a block of code.

# This will work 
if 1 + 1 == 2
    console.log "hello"

# This won't work 
if 1 + 1 == 2
console.log "hello" 


Functions are chunks of reusable code, which can take in arguments (or parameters) to make them extremely versatile.

# JS function
function myFunction(argument1, argument2) {
    output =  argument1 + argument2;
    return output;
myFunction(1, 10); # outputs 11

# Coffeescript function
myFunction = (argument1, argument2) ->
    output = argument1 + argument2
    return output
myFunction(1, 10) # outputs 11


A loop allows for iterating over a collection of items such as an Array or Object. There are several types of loops, but the most commonly used one is the for loop:

# Looping through an array
myArray = [1, 2, 3, 4, 5]

for number in myArray
    number + 1

# Output: 2, 3, 4, 5, 6 

We can also loop through an Object to access and manipulate its properties and values:

# Looping through an object
myObject =
    name: "Dave"
    city: "NYC"
    age: "Unknown"

for prop, value of myObject
    key, ":", value

# name:Dave, city:NYC, age:Unknown 


Conditionals use if, else if, and else keywords to help define logic.

if age < 25
    console.log "Young"
else if age > 25 and age < 65
    console.log "Old"
    console.log "Dinosaur"


Comparators are used to compared things, such as greater than (>) or less than or equal to (<=)

1 is 1 # Output: true 
1 isnt 1 # Output: false 
1 < 2 # Output true 
1 > 2 # Output false 


A collection of tips to help you solve seemingly simple interactions that usually end up more complex than they seem.

Importing from Sketch

Any layer or layer group you wish to manipulate within Framer needs to be grouped. It's recommended that you name your layer groups (using camelCase, don't use - or _ as Framer will strip them), otherwise Framer will name your layers for you and it will be a nightmare to try to keep track of what's what.

Once the Sketch file is set up, you can go to the import button in the upper left toolbar – the currently open file's artboard will automatically be imported.

Getting scrollComponent to work with imported layouts

To scroll imported layers, you need to wrap them in a ScrollComponent – I'd also recommend wrapping the scrollable area in it's own group within Sketch to make manipulating it easier upon import:

# Sketch Import 
sketch = Framer.Importer.load "sketchFile"

# Wrap the imported content layers 
scroll = ScrollComponent.wrap(sketch.content)

Clipping masks (and animating them)

This one took awhile to figure out, but you can mask layers as well as animate the mask in Framer. To do so, the masking layer's background needs to be set to 'transparent' and you need to set force2d property to 'true' on the layer that's being masked. This bypasses the GPU accelerated rendering which as a result allows for advanced masking to work.

maskContent = new Layer
    width: 400
    height: 400
    backgroundColor: 'blue'

mask = new Layer
    width: 200
    height: 200
    backgroundColor: 'transparent'

maskContent.force2d = true
maskContent.parent = mask

Full width/height elements

Framer doesn't allow for percent based widths, but you can easily replicate the behavior by basing your measurements off of the Screen dimensions (which equates to the viewport dimensions).

layerA.width = Screen.width # 100% Of viewport width
layerB.width = Screen.width/2 # 50% of viewport width

Adding a video layer

You can add video into your prototype using the following code:

videoLayer = new VideoLayer
    video: "video.mp4"

To control video and listen for playback events:

videoLayer.player.autoplay = true

# Play the video 

# Jump to 5 seconds 

# Listen to paused playback 
Events.wrap(videoLayer.player).on "pause", ->
    print "Video paused"

Reusable code snippets (modules)

Framer modules allow for reusable blocks of code that you can import into any project. Facebook's Cemre Güngör put together several useful shortcuts that makes working in Framer extra convenient which can be accessed here.

Once downloaded, you need to copy over shortcuts.coffee into the modules folder of your project, and add the following to the beginning of your Framer document editor: shortcuts = require "shortcuts"

Creating global variables for imported PSD/Sketch layers

When working with an imported PSD or Sketch file, you normally need to access each layer within the scope of the variable which stores the imported data:

sketch = Framer.Importer.load "fileName"
sketch.layerA.width = 100 # or sketch['layerA'].width = 100

Using the module, we can now conveniently target layers using just the layer name like so:

sketch = Framer.Importer.load "fileName"
shortcuts.initialize(myLayers) # load in FB's module
layerA.width = 100

Animating layers

The standard syntax for writing animations can get quite verbose, but FB's module makes it a lot more compact as it's based on jQuery's syntax:

layer.animateTo({x: 100}, [time], [curve], [callback])

We can also easily slide layers to emulate fullscreen viewport transitions using the following methods: layer.slideFromLeft() or layer.slideToLeft() (available for left, right, top and bottom)

Layers can easily be hidden or shown using layer.hide() or layer.show(), and we can animate fades using layer.fadeIn() and layer.fadeOut() (it even works with custom duration: layer.fadeIn(.5). Hide, show, fadeIn and fadeOut can take layers or arrays containing layers.

Targeting layers by name

Traversing the layer heirarchy becomes painless thanks to layers.getChild('layerName) and layers.getChildren('layerName').

For an overview on everything that's contained in the module, refer to this article.

Noteworthy modules

[Fluid Framer[(https://github.com/stakes/fluid-framer) Adds the flexibiity to dynamically scale and float elements in the browser window or within their superLayer. Demo Docs

Input Framer A module to easily turn the inputs in your designs into real inputs.

TextLayer for Framer A module that simplifies the process of adding text to your prototypes.

TabBarModule A module that makes it super easy to set up a tab bar navigation.

Slider Library A module to easily set up mutliple sliders with a single line of code. (tutorial below)

iOS Notification A framer module that mimics an iOS notification.

Simple Android Keyboards Easily add a static Android Keyboard to your Framer Studio project with just one line of code. Keyboards types include: default, numbers, symbols, dialpad, and voice.

Simple Android Toast Module to easily add Android toasts.

Simple Android Snackbar Module to easily add Android Snackbars.

Additional Resources

Thankfully, there's a wealth of information available to help you get better acquainted with Framer:


Framer's example tutorials

Creating your first prototype with Framer

Sliders with Framer

Codepen Framer workshop

Framer Vimeo channel

CoffeeScript for Framer Book

Code samples, and tips:


Prototype viewers

Framer viewer for Android

Frameless browser for iOS

Discovering Meteor


I had first come across Meteor a little more than a year ago – and for someone who looks for the quickest and most efficient way to build something from soup to nuts, sounded like the perfect solution. Like many things I've wanted to explore, it had been put off for some time due to day-to-day distractions, but recently resurfaced as it reached v1 release. Given that it's had time to mature and for community and resources to properly have taken shape, I've decided to dive in and see exactly how interesting and useful it's been made out to be.

I've spent my 45min commute playing around and trying to grasp the fundamentals for the past week, and I must admit, so far I'm extremely impressed with the ease and approachability Meteor brings to use javascript to build both client and server ends of the experience, primarily for a novice wannabe developer.

Diving In


Deployment using MUP (Meteor Up)

MUP seemed to be the ideal tool for deploying to a Digital Ocean droplet based on the articles I came across.

The first step was to install MUP using npm install -g mup. Next up, you need to create a folder to hold the configuration files (ideally adjacent to your project folder to prevent it from being pushed up and exposing things). Specifically in my case, I had a folder microscope and microscope-deploy sitting in the same parent folder. Next up is to run the command mup init which will then create two files: mup.json (Meteor configuration file) and settings.json (settings for Meteor's settings API). We'll then need to edit mup.json and follow the comments to populate it with the correct server information and preferences.

After that's done, running mup setup will install everything needed which will take a few minutes. The final step to push up your Meteor project to your server is to run mup deploy and voilà, it should now be live!

In reality I hit a few errors that took me about 4 hours to get to the bottom of, but mostly consisted of misconfigured paths and issues with the version of node installed on my server (which I had to step down to 0.10.36 to get things to work). However, once MUP was setup, deploying updates to my server became as easy as running mup deploy which to be honest still feels like magic :)

Setting up web development environment on a Mac


Now that Yosemite and all the essentials are installed, next up is setting up my environment. When I first started out, the easiest way to get things set up was installing MAMP and calling it a day, but I've since decided to get my hands dirty and use nginx as my HTTP server, which will be covered in this guide. In addition, I'll be installing Node.js, Homebrew, MySQL, and a few other things that I use on occasion as part of my workflow.

Command Line Tools for Xcode

First up, I'll be installing Command Line Tools for Xcode to have access to common Linux-based utilities, tools, and compilers. This allows more awesome stuff to be installed (many of the Unix tools require GCC which Command Line Tools makes available). Mavericks and above allows you to install via the command line whereas older versions of OS X requires you to install Xcode.

$ xcode-select --install

The $ character shouldn't be typed, as it's just a cue to enter a shell command.

Once you agree to the license agreement it'll take a couple minutes to download and install (~130mb).

A few things I've found useful:

  • Copy large sets of data with rsync: When moving thousands of files from one location to another, I've found this to be a godsend and crushes cp or finder drag-dropping in terms of transfer speed. I've been using rsync -vaP Volumes/Source Volumes/Target wherev increases verbosity, a for archive mode which mirrors symlinks and permissions, P for partial transfer resume and progress. I've also seen suggestions for rsync --ignore-existing -raz Volumes/Source Volumes/Target.

  • Search your command line history by using `history | grep 'string to search for' to get a list of matches.

  • 'ls -lrt Directory >> filetosaveresults.log' will list the contents of Directory into a text file named filetosaveresults.log

  • Get the total file size of a directory by using du -hs FOLDER/PATH where h outputs human-readable numbers and s summarizes only the size of the folder rather than all of its contents.

NVM + node

I want to avoid having to use sudo for installing NPM or packages so I'll be installing node version manager first, which can be done by running the following command:

$ curl https://raw.githubusercontent.com/creationix/nvm/v0.12.1/install.sh | bash

I actually ran into the following error message which was asking me to create a profile and add the NVM directory path:

$ => nvm is already installed in /Users/USERNAME/.nvm, trying to update
$ => HEAD is now at 68574cc... v0.12.1
$ error: branch 'master' not found.

It offers 2 options to fix this problem in the output – I opted for the first which asks you to create a bash profile and run the command again. To create the file, I ran $ touch ~/.bash_profile before running the curl command above again.

Nano is the command line editor, once you add the above lines you can save and exit by hitting ctrl + X, Y to save changes and 'enter' to confirm selection

After restarting terminal, running the $ nvm command confirmed it's been installed by it's output of usage instructions. I also ran into an issue where the nvm current version wouldn't stick on a new terminal window, so i had to set the default version by running $ nvm alias default 0.10.33.

Since node version manager is now working, I went ahead and installed the latest version of Node (v0.10.33 at time of writing) by running $ nvm install 0.10.33. The latest version number of Node can be found at nodejs.org. $ node -v should now return the current installed version of node, $ npm -v the version of node package manager, and '$ which node` the path node has been installed to (the home directory).

$ node -v
$ npm -v
$ which node

With node and NPM installed, I can now install my essentials:

$ npm install -g bower #[Bower](http://bower.io/) - package manager for the web
$ npm install -g grunt #[Grunt](http://gruntjs.com/) - javascript task runner
$ npm install -g gulp #[Gulp](http://gulpjs.com/) - a streaming build system

# is a comment and can be ignored when entering commands

So fresh and so clean: Installing Yosemite + toolchain on a retina Macbook Pro

As part of preparing for the new year, I've set the goal of cleaning up my entire digital life by bringing order to what is currently a chaotic mashup of files and services floating around across the many devices I own. My library of photos are drifting around in various places, as are the fonts and resources I depend on daily to do my work. With the official release of Yosemite, it seemed like the perfect opportunity to do a clean install and document the setup of my toolchain as the first step towards a better organized, and hopefully more productive life. Once complete, I'll be moving onto cleaning up all my files and setting up a centralized structure on my NAS with portions of it replicated on Dropbox, but I may be getting ahead of myself.

Installing Yosemite

Wiping my rMBP and getting a clean install of Yosemite was a breeze, thanks to the Mavericks installer I had ready on a USB key. I'd recommend creating your own bootable Installer with Yosemite rather than doing a 2-step upgrade like I've done.

--edit It looks like since OS X Lion there's been a recovery feature that has a partition with all necessary tools to repair or reinstall OS X without requiring bootable media. More info here

Terminal / Command Line

iTerm 2

I've recently switched over to iTerm 2 from Terminal after hearing that it adds a few conveniences. The main ones I appreciate are the shortcut cmd+; for autocompletion, paste history which stores all copy or pasted text which can also be stored on disk, as well as it's super robust preferences panel which has a million and one ways to customize your experience.

One thing I found to be strange was the shortcut key to skip words (alt+← or alt+→) no longer worked in iTerm. This got that fixed up in no time.

Zsh + oh-my-zsh

Using Zsh adds many conveniences if you find yourself dabbling in the command line often. A quick example is the shared history across your tabs – the normal bash behavior is to keep the history contained within each tab which I've found to be frustrating at times. Depending on the theme you're using (which there are plenty of), you can also get extremely verbose in what you show in the prompt: such as current user, directory, branch, repo, and more.

You can install oh-my-zsh by running the following command in the command line: sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

Git Aliases

Setting up a few choice aliases for git saves strain on your precious fingers by reducing the amount of characters you need to repeatedly type throughout the day. Here's what I'm currently using:

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.cb 'checkout -b' #create and checkout to branch (needs branch name)
$ git config --global alias.cm '!git add . && git commit -am' #adds all untracked files and commits (needs commit message)
$ git config --global alias.st status
$ git config --global alias.a 'add .' #adds all untracked files
$ git config --global alias.last 'log -l HEAD' #display last commit
$ git config --global alias.unstage 'reset HEAD --' #unstage a file 

If you want to list out all your aliases, you can do so with $ git config --get-regexp alias

Sublime Text 3

ST probably requires no introduction, if you don't currently use it then do yourself a favor and try it out. I've experimented with a few different editors and never looked back since making the switch.

Enabling Package Control

Open the ST console with ctrl + ' and paste in the following command:

import urllib.request,os,hashlib; h = '2915d1851351e5ee549c20394736b442' + '8bc59f460fa1548d1514676163dafc88'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)

Essential Packages

Once Package Control is installed, you can easily install packages by launching the command palette cmd + shift + P and typing install to auto complete Package Control: Install Package

  • SFTP - Manage file transfers from within ST, I've used it to map my server locally and it makes syncing and publishing remotely stupid simple.

  • Emmet - Supercharge your HTML and CSS workflow. More information

  • ColorHighlighter - Preview color values from within ST.

  • ColorPicker - Update color values with the native color picker with cmd + shift + C (best used with Skala Color as the native OSX color picker is a bit clunky)

  • AlignTab - Align lines of code by character (highlighting lines to align then right-click context menu) or by regex (via the command palette)

  • Gist - Pull the content of a gist into your file, useful if you store boilerplate code as gists that you can then use as a starting point for new files

  • HTMLPrettify - Cleans up HTML/CSS/JS/JSON using Einar Lielmanis' beautifier scripts.

User Preferences

I use the following values for my preferences which you can access through the command palette and typing in user.

    "caret_extra_width": 1,
    "caret_style": "phase",
    "close_windows_when_empty": false,
    "color_scheme": "Packages/Theme - Spacegray/base16-ocean.dark.tmTheme",
    "drag_text": false,
    "draw_minimap_border": true,
    "enable_tab_scrolling": false,
    "font_face": "Source Code Pro",
    "font_options": ["no_round"],
    "font_size": 13,
    "highlight_line": true,
    "highlight_modified_tabs": true,
    "ignored_packages": ["Vintage"],
    "line_padding_bottom": 4,
    "line_padding_top": 4,
    "open_files_in_new_window": false,
    "overlay_scroll_bars": "enabled",
    "preview_on_click": false,
    "draw_indent_guides": true,
    "rulers": [80],
    "scroll_past_end": true,
    "scroll_speed": 5.0,
    "show_full_path": false,
    "tab_size": 2,
    "theme": "Spacegray Eighties.sublime-theme",
    "translate_tabs_to_spaces": true,
    "trim_trailing_white_space_on_save": true,
    "word_wrap": true

Launching Sublime from the Command Line

Sublime comes with a CLI to launch the editor from the command line. In order to get this to work, you first need to set up a symbolic link to it. Before we do that, we should first check if Sublime is in the place we expect it to be by running $ open /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl. That should open up Sublime 3, meaning we can run the following to set up the symlink: $ sudo ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/subl. If you get an error about a non-existing directory you can first create the set of folders using sudo mkdir -p /usr/local/bin/, then running the command to create the symlink. Once that's done, try running $ subl . and it should open up the current command line directory in Sublime!


I've also grown fond of the Spacegray theme in the Eighties flavor, which I highly recommend.

Sublime Text - Space Gray Eighties Theme

Alfred 2

Alfred's workflows make finding and launching things only a few keystrokes away, and will do wonders in raising productivity. I'm currently using the following workflows:

  • Can I Use - Easily check on browser compatibility using the caniuse + property trigger

  • Encode/Decode - Encode/decode strings (URL/HTML/Base64/etc) using encode or decode + string

  • Network Info - Grab your internal/external IP address and Mac addresses using mac or ip

  • Open with ST - Open files and folders in ST3 using subl

Essential Apps

The following are a bunch of additional apps and tools that I've come to love and rely on.

  • FileShuttle Basically a self-hosted Droplr or CloudApp. Great for automating the process of capturing and sharing screenshots.

  • Skala Color Being used to the Adobe color pickers, I've always found the native Mac ones annoying and clunky to use. Bjango's take on the color picker is a lot more useful for day-to-day design & development work and will save you a lot of hassle.

  • Sip I'm a huge fan of the color picker shortcut key for Sketch, and Sip does the same but brings it to the OS level. You can set your hotkey and tweak the settings to grab color values in the format preferred, and it even keeps a history of the colors you've "sipped".

  • QuickCast Allows you to quickly create screencasts that are up to 3 minutes long, that can be published online for sharing or stored locally. Requires you to register for an account but it's the most efficient app for this purpose that I've found and well worth the minor hassle of signing up.

  • Wallpaper by Behance A convenient little way to set your wallpaper from a collection of Behance submissions. You can set it to shuffle automatically or manually select and change it yourself. Minor quibble is that the collections don't seem to be updated often enough and there is no sync between devices, but a great way to keep your desktop looking fresh, nonetheless.

  • Imageoptim Crunch your images to make them as lean as possible. I mainly use this on JPG and GIFs, because TinyPNG is ridiculously amazing with PNGs and nothing comes close.

  • Caffeine This nifty little app overrides your energy settings when you activate it via the menubar icon and keeps your mac from going to sleep.