Everything tagged misc (25 posts)

On Leaving Sencha

As some of you may know, I left Sencha last week to move to another startup just up the road in San Mateo. Leaving the company was a hugely difficult thing to do for lots of reasons, some obvious, some less so. I'd like to share a few thoughts on my time there and look forward a little to the future.

I first came across Sencha's products when I saw an early preview of Ext JS 2 way back in 2007. I thought it was amazing stuff, and I started using it all over the place despite being a Ruby guy at the time. As time went by and I got deeper into the language and the framework, it became clear that JavaScript was the future, even though most people at the time still thought that was a little crazy.

I didn't really intend to join the company. I was having fun writing components and exploring the framework from the outside already, but a chance meeting in San Francisco with the team changed all that. What I found was a small but immensely talented group of people who loved what they did - writing awesome frameworks all day. Underqualified though I felt, being invited into that group was an honor I couldn't really refuse.

Continue reading

Anatomy of a Sencha Touch 2 App

At its simplest, a Sencha Touch 2 application is just a small collection of text files - html, css and javascript. But applications often grow over time so to keep things organized and maintainable we have a set of simple conventions around how to structure and manage your application's code.

A little while back we introduced a technology called Sencha Command. Command got a big overhaul for 2.0 and today it can generate all of the files your application needs for you. To get Sencha Command you'll need to install the SDK Tools and then open up your terminal. To run the app generator you'll need to make sure you've got a copy of the Sencha Touch 2 SDK, cd into it in your terminal and run the app generate command:

sencha generate app MyApp ../MyApp

This creates an application called MyApp with all of the files and folders you'll need to get started generated for you. You end up with a folder structure that looks like this:

Sencha Touch 2 Directory Overview

This looks like a fair number of files and folders because I've expanded the app folder in the image above but really there are only 4 files and 3 folders at the top level. Let's look at the files first:

Continue reading

What do you want from Sencha Touch 2.1?

Disclaimers: this is the most unofficial, non-Sencha-backed poll of all time. There's no guarantee we'll ever do any of it, yada yada.

Touch 2.0 went GA last week to easily the best product launch reception I've seen. It was great and the feedback's wonderful but honeymoons are boring - I want to know what's wrong with it :)

So, what do you want to see in Sencha Touch 2.1? I asked on Twitter just now and got a bunch of responses so here are some ideas. Even if what you want is on this list already drop a reply in the comments so I know more than one person cares about it:

Some replies to my Twitter poll

We do of course have a few ideas up our sleeves too, but why spoil the surprise?

Continue reading

Sencha Touch 2 GA Released!

The last few months have flown by faster than almost any before them. The first Sencha Touch 2 release went out in October as a Developer Preview, coinciding with SenchaCon 2011, sparking a huge wave of interest from all over the HTML5 community. Today marks the GA release of Sencha Touch 2.0.0, and we couldn't be happier with how far we've come.

See the announcement on sencha.com

It was only 18 months ago that we released the first version of Sencha Touch 1. It ushered in a brave new world, bringing tried and true approaches from the desktop together with the exciting new capabilities of the mobile web. But it was, to many of us, very much a version 1 product. ST2 is as big a step up from ST1 as ST1 was from everything that went before it.

Similar themes, great execution

For me, there are three core themes that go into any game-changing software release: Performance, Stability and Ease of Use. These themes come up again and again, especially for products at the bleeding edge of what's possible. With the mobile web, each year can bring game changing developments - that's one of the reasons developing Sencha Touch is so exciting.

Continue reading

Building a data-driven image carousel with Sencha Touch 2

This evening I embarked on a little stellar voyage that I'd like to share with you all. Most people with great taste love astronomy and Sencha Touch 2, so why not combine them in a fun evening's web app building?

NASA has been running a small site called APOD (Astronomy Picture Of the Day) for a long time now, as you can probably tell by the awesome web design of that page. Despite its 1998-era styling, this site incorporates some pretty stunning images of the universe and is begging for a mobile app interpretation.

We're not going to go crazy, in fact this whole thing only took about an hour to create, but hopefully it's a useful look at how to put something like this together. In this case, we're just going to write a quick app that pulls down the last 20 pictures and shows them in a carousel with an optional title.

Here's what it looks like live. You'll need a webkit browser (Chrome or Safari) to see this, alternatively load up http://code.edspencer.net/apod on a phone or tablet device:

The full source code for the app is up on github, and we'll go through it bit by bit below.

Continue reading

Sencha Touch 2 PR4 - Big Improvements in Data and MVC

Today we released Sencha Touch 2.0 PR4 - the fourth and final preview release before we hit beta. While we're technically calling this one a preview release, we're pretty happy with the performance, stability and overall quality of this release and consider it exceptionally close to beta quality.

As well as a good number of enhancements and bug fixes PR4 brings a couple of long-awaited improvements to two of the most important parts of Sencha Touch - the data package and the application architecture.

First up, the data package has been ported to use the new config system, which normalizes all of the configuration options for every class in the data package, providing a clean and predictable way to configure and update your data classes. We're still cleaning up some of the data package documentation and given the scope of some of the changes we're expecting a few bugs to appear as a result but overall we're very happy with the improved capabilities of Ext.data.

MVC Improvements

The second big improvement in PR4 is to the application architecture. The MVC classes have also been upgraded to use the new config system, again yielding big improvements in the API and general flexibility of your code.

Continue reading

SenchaCon 2011: The Best Bits

SenchaCon 2011 is drawing to a close and it's been another awesome ride. We were joined by 600 of the best and brightest of the Sencha community and I think it's pretty safe to say we had an awesome time. Day 3 is just drawing to a close so here's a few highlights from the week.

Ext JS 4.1 Performance Preview Released

There were a number of big announcements on day 1. Probably the most exciting one for me was the release of Ext JS 4.1 Performance Preview. We've been working like fiends to improve Ext JS's performance profile on older browsers (IE6, IE7 and IE8 in particular) and on Monday we were able to share some of what we've achieved.

Page load, render and layout times are all enormously improved and have been the focus of our optimizations so far. Since 4.0 we've been building up a performance benchmarking rig that tests all of our 100+ examples (and a number of real-world customer apps) on consumer grade hardware with a range of browsers. We've seen massive improvements in loading time on these older browsers - for example the Themes Viewer example with its 300 Components all rendered at load time now starts up twice as fast as it did in 4.0.7.

Continue reading

Ext JS 4.0.7 Released

I'm very happy to report that we released Ext JS 4.0.7 to the public today. This is the seventh patch release to the 4.0.x series and contains several hundred improvements and bug fixes compared to the last public version, 4.0.2a.

4.0.7 is all about robustness - we've found that our support subscribers have had a lot of success with the newer builds of Ext JS 4 so I'm really pleased that we can share this with you. We're releasing this publicly earlier than we would usually do because it has taken us longer than we expected to get Ext JS 4.1 into your hands.

Michael put out a post on our blog last week with some updates on 4.1 and our desires around releases and communications with the community. Not being able to ship 4.1 to you yet has been a frustrating experience but I think that once you see it you'll enjoy the vast improvements it brings.

In the meantime, I'm happy to answer questions in the comments, via twitter or email (ed @ sencha). You can download the build here and see the full release notes for 4.0.7 all the way back to 4.0.0.

Continue reading

SourceDevCon 2011 - an awesome conference

The inaugural SouceDevCon just wrapped up in Split, Croatia so I'd like to share a few thoughts on the last few days. The conference was an enormous success, featuring some great speakers, inspiring presentations and a fantastic group of attendees. Split itself is beautiful, and the weather was equally equitable. More than a few of us are returning a lot browner/redder than we came.

Photo of the Adriatic

Day 1

The conference was spread across 3 days - the first two were spent listening and learning across the three concurrent tracks, the third on a boat sailing around the Adriatic Sea. Day one kicked off with my colleagues Aditya and James setting out a little of what to expect from Sencha in 2011 in the opening keynote.

Straight after that I took to the stage to introduce a few of the features of Ext JS 4. My session started a little late and I forgot what I was talking about a couple of times (sorry guys :) ) but I think it turned out well enough. I spliced together the deadly combination of sleep deprivation and live coding but with a little help from the audience we were able to stumble through. I think it would make for a good screencast.

Continue reading

Proxies in Ext JS 4

One of the classes that has a lot more prominence in Ext JS 4 is the data Proxy. Proxies are responsible for all of the loading and saving of data in an Ext JS 4 or Sencha Touch application. Whenever you're creating, updating, deleting or loading any type of data in your app, you're almost certainly doing it via an Ext.data.Proxy.

If you've seen January's Sencha newsletter you may have read an article called Anatomy of a Model, which introduces the most commonly-used Proxies. All a Proxy really needs is four functions - create, read, update and destroy. For an AjaxProxy, each of these will result in an Ajax request being made. For a LocalStorageProxy, the functions will create, read, update or delete records from HTML5 localStorage.

Because Proxies all implement the same interface they're completely interchangeable, so you can swap out your data source - at design time or run time - without changing any other code. Although the local Proxies like LocalStorageProxy and MemoryProxy are self-contained, the remote Proxies like AjaxProxy and ScriptTagProxy make use of Readers and Writers to encode and decode their data when communicating with the server.

Ext.data.Proxy Reader and Writer

Whether we are reading data from a server or preparing data to be sent back, usually we format it as either JSON or XML. Both of our frameworks come with JSON and XML Readers and Writers which handle all of this for you with a very simple API.

Continue reading

Introduction to Ext JS 4

At the end of last 2010 we capped off an incredible year with SenchaCon - by far the biggest gathering of Sencha developers ever assembled. We descended on San Francisco, 500 strong, and spent an amazing few days sharing the awesome new stuff we're working on, learning from each other, and addressing the web's most pressing problems.

Now, we're proud to release all of the videos from the conference completely free for everyone. You can see a full list on our conference site, where you'll find days worth of material all about Ext JS 4, Sencha Touch and all of the other treats we're working on at the moment.

Some of the videos in particular stand out for me - Jamie's Charting and Layouts talks were spectacular, as was Rob's Theming Ext JS 4 talk. On the Touch side, Tommy's talks on Performance and Debugging are required viewing, as is Dave Kaneda's characteristically off the cuff Theming talk.

My personal high point was standing in front of all of you and introducing Ext JS 4 and its three core goals - speed, stability and ease of use. I think you're going to love what we've done with the framework in version 4.

Continue reading

Ext JS 4: The Class Definition Pipeline

Last time, we looked at some of the features of the new class system in Ext JS 4, and explored some of the code that makes it work. Today we're going to dig a little deeper and look at the class definition pipeline - the framework responsible for creating every class in Ext JS 4.

As I mentioned last time, every class in Ext JS 4 is an instance of Ext.Class. When an Ext.Class is constructed, it hands itself off to a pipeline populated by small, focused processors, each of which handles one part of the class definition process. We ship a number of these processors out of the box - there are processors for handling mixins, setting up configuration functions and handling class extension.

The pipeline is probably best explained with a picture. Think of your class starting its definition journey at the bottom left, working its way up the preprocessors on the left hand side and then down the postprocessors on the right, until finally it reaches the end, where it signals its readiness to a callback function:

The distinction between preprocessors and postprocessors is that a class is considered ‘ready’ (e.g. can be instantiated) after the preprocessors have all been executed. Postprocessors typically perform functions like aliasing the class name to an xtype or back to a legacy class name - things that don't affect the class' behavior.

Continue reading

Classes in Ext JS 4: Under the hood

Last week we unveiled a the brand new class system coming in Ext JS 4. If you haven’t seen the new system in action I hope you’ll take a look at the blog post on sencha.com and check out the live demo. Today we’re going to dig a little deeper into the class system to see how it actually works.

To briefly recap, the new class system enables us to define classes like this:

Ext.define('Ext.Window', {
    extend: 'Ext.Panel',
    requires: 'Ext.Tool',
    mixins: {
        draggable: 'Ext.util.Draggable'
    },
    
    config: {
        title: "Window Title"
    }
});

Here we’ve set up a slightly simplified version of the Ext.Window class. We’ve set Window up to be a subclass of Panel, declared that it requires the Ext.Tool class and that it mixes in functionality from the Ext.util.Draggable class.

There are a few new things here so we’ll attack them one at a time. The ‘extend’ declaration does what you’d expect - we’re just saying that Window should be a subclass of Panel. The ‘requires’ declaration means that the named classes (just Ext.Tool in this case) have to be present before the Window class can be considered ‘ready’ for use (more on class readiness in a moment).

Continue reading

Writing Compressible JavaScript

Writing a library is a balancing act between the (sometimes competing) interests of API clarity, code clarity, performance and compressibility. In this article I'm going to detail three of the approaches we take to meet this balance and suggest them for your own usage.

1. Collecting var statements

Every time we declare variables we add 4 bytes to the compressed file size. Variables are declared sufficiently often that this can really add up, so instead of this:

var myFirstVar = 'something'; 
var myOtherVar = 'another thing'; 
var answer = 42; 
var adama = true;

One should use this form:

var myFirstVar = 'something', 
    myOtherVar = 'another thing', 
    answer = 42, 
    adama = true;

When this code is compressed, each variable name above is turned into a single-letter name, meaning that the wasted 4 bytes per useless additional 'var ' in the first example would have contributed significantly to code size with no benefit.

2. Local variable pointers to object properties

The following code (pruned from a previous version of Ext JS) is not as compressible as it could be:

Continue reading

Answering Nicholas Zakas' JavaScript quiz

A current meme that's floating around the JavaScript geek corner of the internet is setting quizzes on some of the more unusual aspects of JavaScript. This time round Nicholas Zakas is providing the entertainment, so I thought I'd provide some answers. Let's get started:

Question 1

Question 1 looks like this:


var num1 = 5,
    num2 = 10,
    result = num1+++num2;

We're asked what the values of result, num2 and num1 are. First, let's deconstruct what that +++ is doing. There is no +++ operator in JavaScript - instead we have a num1++ followed by a + num2.

JavaScript has two ways of incrementing a number by 1 - we can either put the ++ before the variable or after it. The variable is incremented either way - the only difference is what is returned. ++10 returns 11, whereas 10++ returns 10:


var a = 10;

var b = a++; //a is set to 11 now, but b is set to 10
var c = ++a; //a is set to 12 now, c is also set to 12

So 'result' is the sum of num1++ (which is 5) and num2, which is 10, so result equals 15. num2 remains at 10 as it was not modified. num1 is now equal to 6 because we incremented it by 1, though the incrementation did not affect the sum passed to result.

Continue reading

Ext JS is looking for a QA rockstar

This has been cross-posted from our Open Discussion Forum.

As part of our ambition of creating the world's best JavaScript framework, we're looking to hire a special somebody to help maintain the high quality of our components.

While we have one eye on implementing new features and improving Ext JS's performance, the other is on making sure what we already have still works well.

This is a difficult job and we need someone smart, focused and well versed in Ext JS. Somebody who will:

  • Use our existing systems to test components as new builds of the library are landed
  • Maintain a strong presence in the forums and be the first to know of any reported issues
  • Respond to bug tickets such as rendering issues and broken functionality
  • Totally own the Quality Assurance of Ext JS - we want your ideas and your initiative as well as your expertise with Ext
  • Liaise with the core team on a daily basis

This is a full-time position, though allowances can be made for the right person. If you think you would enjoy working with Ext JS, and have what it takes to help us keep Ext at the forefront of our field, drop me a private message with the following information:

Continue reading

JavaScript FizzBuzz in a tweet

The FizzBuzz challenge has been around a while but I stumbled across it again after reading another unique Giles Bowkett post.

If you're not familiar with FizzBuzz, it's a little 'challenge' designed to test a candidate programmer's ability to perform a simple task. In this case, you just have to print out the numbers from 1 to 100, unless the number is a multiple of 3, when you should instead print "Fizz", 5 in which case you print "Buzz", or both 3 and 5 in which case you print "FizzBuzz".

Here's a trivial JavaScript implementation:

for (var i=1; i <= 100; i++) {
  if (i % 3 == 0) {
    if (i % 5 == 0) {
      console.log('FizzBuzz');
    } else {
     console.log('Fizz');
   }
  } else if (i % 5 == 0) {
    console.log('Buzz');
  } else {
    console.log(i);
  }
};

Pretty simple stuff, but a bit verbose. I wanted something that would fit into a tweet. It turns out that's pretty simple - this is 133 characters including whitespace, 7 within tolerance for a twitter message:

Continue reading

Using the ExtJS Row Editor

The RowEditor plugin was recently added to the ExtJS examples page. It works a lot like a normal Grid Editor, except you can edit several fields on a given row at once before saving.

This neatly solves the problem of adding a new row to an editor grid, entering data into the first field and finding it save itself straight away, which is rarely desired. In this fashion we can provide full CRUD for simple models in a single page.

Installation

You'll need to get a copy of the javascript, css and images from the server. This is a bit of a pain. If you still have the ExtJS SDK around you can find these in the examples folder, if not you can get each file as follows:

Grab the plugin JS file below and put it where you usually put your .js files: http://www.extjs.com/deploy/dev/examples/ux/RowEditor.js

This needs to go with your other stylesheets, usually in a directory called 'css': http://www.extjs.com/deploy/dev/examples/ux/css/RowEditor.css

Download these two images and put them into your existing 'images' folder (the same place the other ExtJS images live): http://www.extjs.com/deploy/dev/examples/ux/images/row-editor-bg.gif http://www.extjs.com/deploy/dev/examples/ux/images/row-editor-btns.gif

Include the .js and .css files on your page and you should be ready to go.

Continue reading

Moving from Blogger to Wordpress

Over the weekend I migrated from Blogger (hosted by Google) to Wordpress (hosted by me). Overall, Wordpress feels far superior, but the migration was not without problems. Here's a short guide to what I had to do:

Get Wordpress

First, grab the latest version of Wordpress. Being a PHP application, it just drops into a directory and works :)

Create a database, set config

Wordpress has a setup script but being a bit of a noob I couldn't give it write permission to my filesystem. If you are also afflicted by such inadequacies the following steps may help you. For clarity I'll call my DB 'wordpress'. First, set up your database:

  • mysql -u root
  • CREATE DATABASE wordpress;
  • GRANT ALL on wordpress.* TO 'wordpress'@'localhost' identified by 'wordpress';

You'll need a wp-config.php file - Wordpress comes with a default one which you can copy thusly (in the root directory of your wordpress directory):

cp wp-config-sample.php wp-config.php

Now edit wp-config.php, and fill in the details to make it look a little like this:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');

/** MySQL database username */
define('DB_USER', 'wordpress');

/** MySQL database password */
define('DB_PASSWORD', 'wordpress');

/** MySQL hostname */
define('DB_HOST', 'localhost');
Continue reading

Read my BDD article in this month's JS Magazine

I have an article on Behaviour Driven Development for JavaScript in June's edition of the excellent JavaScript Magazine.

If you haven't seen or read the magazine before (it's quite new), it's well worth the few dollars charged. The magazine format allows for in-depth articles that require more space, time and effort to write than a typical blog post, and which therefore often go unwritten.

The thrust of my article is that too much of our JavaScript goes untested, but that nowadays it's easy to fix that. I go through an example of a client side shopping cart, using the JSpec BDD library. Even if you don't buy/read the magazine, I highly recommend checking out JSpec and other libraries like it. As JavaScript powered applications become the norm, BDD will only become more important in ensuring our applications work properly, so now is a good time to start.

Also in this month's issue is a guide to using the Canvas tag, tips on how to use build scripts to optimise your JavaScript for each environment, AJAX security pointers and a roundup of community news.

Continue reading

Darwin, Humanism and Science

On Saturday I had the good fortune to be able to attend a conference entitled "Darwin, Humanism and Science", held at London's Conway Hall. For those not able to attend here is a short roundup of what happened:

Richard Dawkins starts us off

The conference kicked off with a quick introduction from BHA President Polly Toynbee, after which Professor Dawkins took to the stage. His lecture revolved around the concluding paragraph of Darwin's On the Origin of Species, which can be read online for free here (the relevant passage starts "Thus, from the war of nature ..."). Dawkins analysed each segment of the text in turn, giving us his insights into its meaning and slipping in some fascinating information about our modern-day understanding of evolution, such as how we know that all species in the world today must be descended from a single progenitor.

The professor left some time for questions at the end of his lecture. He had commented on the lamentable state of the public's understanding of science, proffering the alarming statistic that some 18% of the British population believes that the Earth orbits the Sun once a month (presumably we go around faster in February), which lead me to ask him what we can do to combat this. His answer was to "get out more".

Continue reading

ExtJS Textmate bundle

** Update 2:** I've recently cleaned up the bundle, removing stale snippets. It's now located at https://github.com/edspencer/Sencha.tmbundle

** Update:** Added extra instructions when downloading the bundle instead of git cloning it. Thanks to TopKatz for his help

I develop on both OSX and Windows machines, and my editors of choice are Textmate and the excellent Windows clone E. One of the great things about Textmate is its bundle support, which allows you to create reusable code snippets (among other things).

I've got a good collection of these built up so thought I'd make them available on Github. You can install it like this:

Mac OSX:

cd ~/Library/Application Support/TextMate/Bundles
git clone git://github.com/edspencer/Sencha.tmbundle.git

Windows:

cd C:Documents and Settings{YOUR USERNAME}Application DataeBundles
git clone git://github.com/edspencer/Sencha.tmbundle.git

If you don't have git installed you can simply download the bundle as a zip file, and extract it into the directory as above. You need to rename the extracted directory to something like extjs.tmbundle or it won't show up. If you do go the git route you can of course cd into that git directory at any point and use git pull to update to the latest bundle version.

I'll give one example of the usefulness of snippets like these; here's the Ext.extend snippet from the bundle:

Continue reading

Don't forget the wurst

So it came to be realised during Rails Camp 08 that the world was sadly lacking in William Shatner based list apps. Thankfully, the Railslove guys (plus Rany) have come to the rescue with don't forget the wurst. If you're looking for something delightfully random in your life, you may have just found it.

Check out my Shatner's greatest hits list and Ask William about a few of the items - he will furnish you with compelling and thoughtful answers.

Continue reading

DRYing up your CRUD controller RSpecs

A lot of what we do in Rails boils down to simple Crud. If you're in the habit of developing admin sections to allow your clients to control the front end of their site, you'll probably have noticed that these controllers in particular tend to all look the same. There are quite a few ways to DRY up the controller itself - using something like make_resourceful, for example, but what about your RSpec files?

Robby Russell recently posted a short article about RSpec's Shared Example Groups. Take a look at his post or at the RSpec documentation (it's not scary) to see how they work in more detail, but they basically allow you to share your it "should" do ..... end blocks, enabling them to be reused multiple times.

When you think about it, every time we spec a basic CRUD controller, we're doing the same thing - we should be able to just do something like this:

require File.dirname(__FILE__) + '/../../spec_helper'

describe Admin::ContactsController do
 before(:each) do
   @model = 'Contact'
   login_as_admin
 end

 it_should_behave_like "CRUD GET index"
 it_should_behave_like "CRUD GET show"
 it_should_behave_like "CRUD POST create"
 it_should_behave_like "CRUD PUT update"
 it_should_behave_like "CRUD DELETE destroy"
 it_should_behave_like "CRUD GET edit"
end
Continue reading

Git clone vs Git submodule

Having recently made the switch from svn to git, I wanted to achieve what svn externals did (and what Piston did better). Turns out this is pretty simple, for example to get rails on edge:

cd your_git_dir
git submodule add git://github.com/rails/rails.git vendor/rails

A couple of other default submodules you'll want:

git submodule add git://github.com/dchelimsky/rspec.git vendorpluginsrspec
git submodule add git://github.com/dchelimsky/rspec-rails.git vendorpluginsrspec-rails

What submodule does is to check out the submodules as their own repositories, so they are tracked independently of the repository you made them submodules of. The submodules you have are tracked in the .gitmodules file, which might look something like this:

[submodule "vendorrails"]
 path = vendor/rails
 url = git://github.com/rails/rails.git
[submodule "vendor/plugins/rspec"]
 path = vendor/plugins/rspec
 url = git://github.com/dchelimsky/rspec.git
[submodule "vendor/plugins/rspec-rails"]
 path = vendor/plugins/rspec-rails
 url = git://github.com/dchelimsky/rspec-rails.git

Or at least that's how it should look, Windows seems to mess this up into looking something like the following:

[submodule "vendorrails"]
 path = vendor\rails
[submodule "vendorrails"]
 url = git://github.com/rails/rails.git
[submodule "vendorpluginsrspec"]
 path = vendor\plugins\rspec
[submodule "vendorpluginsrspec"]
 url = git://github.com/dchelimsky/rspec.git
[submodule "vendorpluginsrspec-rails"]
 path = vendor\plugins\rspec-rails
[submodule "vendorpluginsrspec-rails"]
 url = git://github.com/dchelimsky/rspec-rails.git

Note especially that you need to remove the 's and replace all 's with /'s. If you don't git will give a fail message like:

Continue reading