Matthew Connelly's developer page

Self-Hosting Git Repos and Installing GitList for a Web Interface

Hosting your git repositories yourself is as simple as git init --bare (or git clone --bare for existing repos) in a directory on your server, and then adding the remote to your local repo: git remote add myServer ssh://me@server.address/path/to/repo/project.git.

Having your repos on GitHub too makes for a nice redundancy (or on any other git server), and a remote on your server, on GitHub and a local copy makes for three redundancies. You can push to multiple remotes by adding a few lines in your project's git config.

In your local copy of the repo, edit .git/config and add a new block:

[remote "all"]
    url = ssh://me@server.address/path/to/repo/project.git
    url =

That would be the url for your server and for GitHub's. And so now when you're ready to push, git push all <branch_name> will push your changes to both repositories. It should be noted that you can name this remote whatever you want.

Installing GitList for a Git Web Interface (and Troubleshooting)

(Using Nginx server on Debian 9)

For a nice way to show your code and commits much like GitHub does, there are many git web interfaces out there, but I chose GitList because it looked pretty good and seemed pretty easy to set up.

I used Nginx for my server, so I followed GitList's instructions for Nginx, copying their provided configuration.
Here are some issues I encountered and their solutions:

Getting a 500 error when trying to view repos:

Assuming you’re using php-fpm, you’ll need to note the address in GitList’s Nginx config, within the php location block, listed as fastcgi_pass:

location ~ ^/index.php.$ {

Then open /etc/php/7.0/fpm/pool.d/www.conf and find the line listen = /run/php/php7.0-fpm.sock; here you’re going to change the listed socket to the address in our Nginx location block above so that it reads as: listen =

After restarting php-fpm, you should no longer receive a 500 error when viewing repos.

Getting blank screen (500 error) when trying to view commits:

This error persisted for a bit longer than the above for me, but looking at the error log (always check the error log!), I noticed this:

FastCGI sent in stderr: “PHP message: PHP Fatal error:  Uncaught Error: Class ‘SimpleXmlIterator’ not found in /var/www/gitlist/vendor/klaussilveira/gitter/lib/Gitter/PrettyFormat.php:22

Searching for ‘SimpleXmlIterator’ not found online lead me to find that I needed to install php7.0-xml, which I was able to do with apt-get, which solved the issue.

Game Development – Text-based Level Editing and Phaser JS

If you are familiar with roguelikes (turn-based dungeon crawlers) such as Nethack, then you are no doubt familiar with the idea of a game’s elements being displayed entirely as ASCII characters.

Here I will explain how I use a similar approach to create the layout of rooms in a game I am working on and how I use Phaser (JS game engine) to render the rooms based on my layouts.

The following array of strings represents a single room:

    //1         12             25
    'ppppppppppppppppppppppppp' //19

“E” represents an enemy, and “p” represents an immovable block that can be used as a platform or wall. A dash represents empty space, simply because I find it easier to read than whitespace, although I am not exactly counting dashes to find any kind of distance.

The commented-out numbers on top and on the right represent columns and rows respectively; I have divided a canvas 800 pixels wide and 600 pixels high into 25-by-19 32-pixel squares.

How and when a room is rendered

  1. The player collides with the edge of the world (canvas)

  2. The player’s x-position is then changed to the position of the edge opposite of the collision (right edge collision, player moved to far-left of canvas; left edge collision, player moved to far-right of canvas); this gives the appearance of entering a new room

  3. The room is then cleared, using Phaser’s sprite.kill() method

  4. A variable integer is then increased or decreased by 1 depending on the edge of collision (right, +1; left, -1), and this integer is then used as our room’s index in our level array.

    • So if our current room’s index is 0 (the first room in the level array), and the player collides with the right edge of the canvas, our integer increases to 1, and we render the room who’s index is 1 (our second room in the level array)
  5. After getting the room we want by index, we check each string within the room array; each of these strings can be looked at as a row of things that can be rendered onto the canvas, from the top of the canvas to the bottom.

  6. For each row (string) in the room array, we check each character by its index using String.charAt().

  7. Using a switch statement, the character can be matched to a case; if and after being matched, we will call Phaser’s group.create() method to render the matched sprite or image.

So using the room layout above, level1[0][8].charAt(4) would match a case of p in our switch statement: - 0 is the index of the room (it is the only room shown, but typically there would be multiple rooms), 8 is the index of the row, and the 4th character of the 8th row is a p.

The room-rendering function (abridged)

(To be called on collision.)

function renderRoom(room){
    for(var row in room){
        for(var column=0; column <=  room[row].length; column++){
            switch (room[row].charAt(column)){
                case 'p':
                    platform = platforms.create(column*32, row*32, 'platform-image');

This room-rendering function currently only works with one level but should scale to accommodate multiple levels and work similarly if not identically.

The room system works as detailed in pseudo-code below, with each “column” actually representing a single character in a string:

level1 [
    room1 [ 
        row1 'column1 column2 column3',
        row2 'column1 column2 column3',
        row3 'column1 column2 column3'
    room2 [ 
        row1 'column1 column2 column3',
        row2 'column1 column2 column3',
        row3 'column1 column2 column3'

Chromebook Linux – From Crouton to GalliumOS

I love my Chromebook (as evidenced in this post); I bring it everywhere as it comes in handy for long commutes and, weighing in at around 3 pounds, isn’t the least bit cumbersome.

However, the restrictions ChromeOS placed on me had been noticeable since the beginning; and I knew I would be restricted to Chrome Apps, extensions, and Play store applications, but didn’t count on how annoying this restriction would wind up being. Fortunately, there were workarounds.

Crouton: An Early Solution

Crouton proved to be very easy to install and useful from the start. By creating a chroot and installing my distro of choice in it, I could run Ubuntu either by switching over to the chroot or accessing it from the Crosh command line.

There was a problem, however; Ubuntu didn’t have the greatest driver support for my Chromebook’s trackpad and keyboard. So I found myself running Linux programs from the command line that ChromeOS typically wouldn’t allow (such as PHP, Python, and naturally, apt-get), but actually working in the ChromeOS environment, as it was just that much more supportive of the machine (Samsung Chromebook 3).

But now if I wanted to play a game in an emulator such as Mupen64plus or WINE, I could not run that from the command line while in ChromeOS; it would throw an error in regards to X-server, forcing me to switch over to the chroot just for one program.

GalliumOS: My Current (And Best, So Far) Solution

Finally I thought I would consider GalliumOS; a distro made specifically for Chromebooks. I made a ChromeOS recovery image and made a GalliumOS bootable USB and gave it a try.

It worked nicely; it was a complete Linux environment that supported my machine’s brightness and volume keys, and with better “palm detection” (think Macbook trackpads and your resting thumb) out of the box without messing about with Synaptics.

Initially, there was no sound support for my model. This stopped from installing it for a bit, but after trying a few other options, one including running a chroot off an SD card (for extra space for packages; it gets ejected when the machine sleeps unfortunately), I figured I’d deal with the sound issue. (At the time, the bug was that no internal sound was supported, but Bluetooth sound was.)

After a full install, made easy thanks to GalliumOS’s excellent documentation, and then finally a GalliumOS update, to my surprise, internal audio worked, and so I’m now using my Chromebook as I please, with the ability to install my favorite programs such as Visual Studio Code (a program I wanted on my Chromebook from the very start), WINE, and all the rest; with that update came the patch that fixed my model’s sound issue.

As I find myself installing and re-installing Linux pretty often, as with the example of setting up chroots mentioned earlier, I began tracking my environment’s packages, as well as Visual Studio Code extensions, which you can check out in a repository here.

Enabling In-line PHP Parsing With Nginx

My Environment

  • Nginx version
    • 1.10.0
  • PHP version
    • 7.0
  • FastCGI processor
    • php7.0-fpm
  • Kernel
    • Ubuntu 16.04

The First And More Obvious Step

To enable parsing of PHP in HTML files, editing a server block’s location block to include files with an HTML extension should be sufficient.
For example:

# /etc/nginx/sites-available/
location ~ \.(php|html)$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;

However, since I am working with PHP 7, whose full name is “php7.0” (which is usefully descriptive but makes things tricky when initially looking for related directories or daemons), I had an extra step in order to make this work. And apparently, all PHP versions, from late php5.* to php7.0, will require this extra step.

The Final And Not-So-Obvious Step

You’ll now have to edit php-fpm.conf, or preferrably one of its included files; namely, www.conf.
For me, php-fpm.conf lives at /etc/php/7.0/, with www.conf in directory pool.d.

The line we are looking for in www.conf (or the line you can add to php-fpm.conf if you want) is security.limit_extensions, which, in conjunction with our Nginx configuration, will permit our specified file types to be parsed as PHP. You may have to uncomment it, and for me it read as such by default:

security.limit_extensions = .php .php3 .php4 .php5 .php7

Here we can add .html or .htm, or even .js (but then we’d have to add .js to our Nginx location block as we did with .html earlier).

Finally, we must now restart the php-fpm daemon, and of course, our Nginx server, for all changes to take effect.

For me, signaling Nginx to reload works:
nginx -s reload
(You will need root permissions for this.)

For php-fpm, I use the service wrapper:
service php7.0-fpm restart
(Root permissions needed again.)

Now you should be all set to write in-line PHP in HTML files, or even JavaScript files, if your heart so desires.

Chromebook Web Development

Quick Rundown

  • Machine:
    • Samsung Chromebook 3
  • Environment:
    • ChromeOS for a GUI and native drivers
    • Lubuntu for server-side programs and scripts (treated as headless)
  • Text Editor/IDE

I recently purchased a Samsung Chromebook 3 so I could work on projects during my long commute or at my local coffee shop without worrying about losing or breaking my other more expensive portable machine. It’s really nice and light, and with a little configuration, makes for a great portable web development environemnt. After all, ChromeOS is itself a linux distro, but things are a little hidden in this environment as ChromeOS is meant to be easily accessible and to leave the user as little room as possible to screw things up.

First, Enable Developer Mode

Enabling developer mode is very easy and necessary to get things started. This will allow you to access ChromeOS’s native shell, or “Crosh”, which runs in Chrome as an extension which is really cool; ctrl+alt+t will bring you there. From Crosh, we can then access our typical unix shell by simply typing “shell.”

But now lets say we want another distro to run along side ChromeOS?

Creating A Chroot For Running Another Distro

A chroot, or change root, gives us the ability to run this second distro, without partitioning the disk or using a virtual machine, while still being able to access the same files across both environments. I installed LXDE because the Chromebook I purchased had only 2 gigs of RAM, and used Crouton to create the chroot.

This second distro is nice because if you are familiar with the Linux environment, you can proceed to work as you normally would, with Aptitude, Python, PHP and everyhing else already installed, and without all the limitations of ChromeOS.

ChromeOS Is Still Very Nice, And An Integral Part Of This Setup

ChromeOS makes for a very friendly desktop environment despite the red tape, and handles keyboard and trackpad input with its native drivers; I access the chroot via terminal to run scripts and install programs, but work with the ChromeOS GUI. For a text editor, I use Caret-T, which is installed as a Chrome extension, and comes with intellisense-like auto-completion for JavaScript.

Quick and Custom AddThis Setup

Getting AddThis sharing set up exactly how I wanted took some digging the first time around. Maybe, like me, you wanted AddThis’s functionality but with your own styles, and not the AddThis brand buttons. Here’s how I set it up, allowing for full customization.


Before going further, here’s a short list of things to consider before working with AddThis:

You should have included AddThis’s script before your document’s closing body tag. AddThis’s script will only work remotely; host locally or on a server. AddThis links will not work when certain adblock browser extensions are enabled; I’ve found adblock plus gave me no problems, but ublock origin did.

The Code And Setup


<a class="sharing addthis_button_mailto">mailto</a>
<a class="sharing addthis_button_email">email</a>
<a class="sharing addthis_button_tumblr">tumblr</a>
<a class="sharing addthis_button_google">google</a>
<a class="sharing addthis_button_twitter">twitter</a>
<a class="sharing addthis_button_facebook">facebook</a>
<a class="sharing addthis_button_linkedin">linkedin</a>

For the HTML, we use anchors each with a class that the AddThis scripts and stylesheets recognize, such as “addthis_button_facebook”. Sharing will be fully functional when clicking on an anchor with this class for the corresponding platform. Meaning, these classes are required, or at least in this setup.

The first class of “sharing” is a custom one that I use to denote that these anchors are for AddThis functionality, and to be styled as such. The JavaScript will point to the “sharing” class as well, but these are not required.

When you first create these anchors with the “addthis_button_socialplatform” class, AddThis will create a span as well that will contain a small image; I simply style that span with a “display: none”, and carry on with my own styles.

The JavaScript:

var share = document.getElementsByClassName('sharing');
for(var i=0; i<share.length; i++){
    share[i].setAttribute('addthis:description','Check out my cool post!');

For the JavaScript, we simply set the attributes of our AddThis anchors (all with the class of “sharing”) so that when sharing content, they automatically populate any text fields with the appropriate content. There’s no need to set an href, as the AddThis script will automatically set it equal to #.

The AddThis anchor attributes are the following:

addthis:url - field will be populated with this url. In this case, I set it equal to our document’s url, as I want the shared content to link back to my post or page. Of course, this url can be whatever you want. addthis:title - The title that will appear before the description in your shared content. addthis:description - this will be the copy that appears below the title in your shared content. This really only applies to platforms like Facebook and LinkedIn that allow for more copy when sharing. There won’t be any bugs when this attributed is applied to an anchor where not applicable (such as twitter); the description simply will not appear in that platform’s shared content, so there’s no need to worry about that. How you set any of these attributes is entirely up to you; I use JavaScript because I thought it was the easiest solution and I like JavaScript, but of course you could do it manually. Where you get your “addthis:description” is up to you as well; maybe an especially important paragraph’s innerHTML?

Considerations For Facebook And Email

Email (not mailto, but AddThis’s email sharing) and Facebook sharing stand out amongst all the other platforms here in that they both require a little extra.

If you change the content you want to share to Facebook and it isn’t updating, you’ll want to paste the url of the page you’re sharing into Facebook’s sharing debugger. While mailto will open your device’s default mail client, then populate the subject based on the mailto attributes, “addthis_button_email” populates its fields based on the AddThis config variable (seen below).

var addthis_config = addthis_config||{};
addthis_config.ui_email_to = '';
addthis_config.ui_email_from = '';
addthis_config.ui_email_note = 'The copy that makes up the body of the email.';

Only one of these will work per page. Also, in case you’re familiar with the old AddThis email modal, I feel I should warn you that they’ve done away with that and instead AddThis email opens a new window.

Alternatively, you could create an email template in your AddThis dashboard. I’ll admit AddThis has good documentation for this.

Finally, you may want to “display: none” on “#at-cv-lightbox”; this modal can popup after first visit to a page using AddThis.

Animating With GreenSock

Originally written for The Charles NYC.

I’ve recently been introduced to animating with the powerful JavaScript library GreenSock. It’s quite impressive, notably for how manageable its animations are. Unlike CSS3, which measures its animations with percentages, GreenSock uses seconds for timing. GreenSock is also capable of applying multiple animations to a single element, each running either consecutively or simultaneously, which is something CSS3 is not capable of either.

The real beauty of GreenSock is how much control it affords. Much like the animations they control, tweens (the animations between two keyframes) can be controlled with a timeline. This is essentially a container for tweens, and timelines themselves can be nested in other timelines, affording even more control.

After building out a complex sequence of animations, you’ll find GreenSock’s afforded control becomes especially important when changing the animation or timing of your sequence. Whether it be within a single tween or an entire timeline, making changes is easy and painless, and will not affect adjacent animations.

Using GreenSock, I made a brief animation (above) detailing the interaction between PacMan and a ghost. To create these two characters, I styled and positioned multiple divs, essentially “building” them. To make them “interact,” I placed all of their actions (tweens) into their own respective timelines in order to control the timing of each action.

For example: to animate PacMan biting, there is a rotation tween on PacMan’s upper and lower jaw. These two tweens are both timed to occur simultaneously within a timeline. This timeline, containing all of Pacman’s animations, is then nested in my master timeline. This timeline is then timed to happen first, with my ghost’s timeline timed to happen shortly after.

The learning curve for animating with GreenSock was relatively low with all the available resources online. GreenSock has their own active forum where often the creator of GreenSock himself answers questions in detail with code examples or an occasional proof of concept on Codepen. I’m excited to be working more in-depth with GreenSock in the future. In the absence of Flash, GreenSock seems to be the runner-up as the standard for creating engaging animations on the web.