dotject

After yesterday’s post about dotject, it quickly became apparent that although some people may find it useful, they wanted the dotject functionality to be part of an IDE. This was always my intention and it’s now available as an Atom plugin.

Atom

Titled as “a hackable text editor for the 21st Century”, GitHub’s Atom has created some controversy about being a closed-source open-source text editor (yes you read that right). Although the core isn’t open source, developers have the ability to develop plugins and themes to completely change or enhance the way the editor works.

The Plugin

I found it easy to create an Atom plugin for dotject, mainly due to it’s familiarity with npm (it also has a root package.json file etc). Under the hood, it even uses my dotject node package, so there’s no duplication of the dotject code whatsoever.

Installation

Use the Atom package manager, which can be found in the Settings view or run apm install dotject from the command line.

Usage

The default keymapping is shift-cmd-J (although this can be configured). You simply highlight your dotject string and press shift-cmd-J to perform the conversion.

Example

Highlighting a.b.c,d.e then pressing shift-cmd-J will replace a.b.c,d.e with:

1
{"a":{"b":{"c":{}}},"d":{"e":{}}}

The code

It’s essentially 2 lines of code, with a little glue and keymapping:

1
2
3
4
// convert the current text selection
var converted = dotject(editor.getSelection().getText());
// insert the stringified json in place of the selection
editor.getSelection().insertText(JSON.stringify(converted));

This would all be perfect, if it was not for CoffeeScript (I’ve written in JavaScript above).

dotject

dotject provides a quick and simple way to compose JavaScript objects using familiar dot notation.

The code supports object creation at n levels (nesting) along with same level objects. There’s also functionality to support (multiple) value assignment and value overriding. It might sound complicated but it’s designed to make life easier, the examples below will showcase this.

dotject harnesses the power of functional.js and it’s λ.reduce function to achieve the “dot notation to object” implementation in very few lines of code.

Getting started

Install via npm:

1
npm install dotject # --save

Require the module in the usual way:

1
var dotject = require("dotject");

Using dotject

There is a comprehensive list of programatic examples in the specs, for the project, but I’ll run through examples here:

Simple object composition

Separating property names with dots (like JavaScript dot notation) will create nested objects:

1
2
3
4
5
6
7
8
9
dotject("a.b.c");
{
"a": {
"b": {
"c": {}
}
}
}

Separating property names with a comma (similar to JavaScript objects) will create properties at the same level:

1
2
3
4
5
6
dotject("a,b");
{
"a": {},
"b": {}
}

This notation can be combined with the dot style notation:

1
2
3
4
5
6
7
8
dotject("a,b.c");
{
"a": {},
"b": {
"c": {}
}
}

Extend an existing object

Extend an existing object with new properties by passing the existing object as a second (optional) argument:

1
2
3
4
5
6
7
8
dotject("b.c", {"a":{}});
{
"a": {},
"b": {
"c": {}
}
}

Existing object values are retained:

1
2
3
4
5
6
7
8
dotject("b.c", {"a": true});
{
"a": true,
"b": {
"c": {}
}
}

Existing nested object properties are retained:

1
2
3
4
5
6
7
8
dotject("a.c", {"a":{"b":{}}});
{
"a": {
"b": {},
"c": {}
}
}

Assign a value

You can assign a value to the last nested property:

1
2
3
4
5
6
7
dotject("a.b", {}, 10);
{
"a": {
"b": 10
}
}

Assign multiple values

You can assign a values to the last nested properties:

1
2
3
4
5
6
7
8
9
dotject("a,b.c,d", {}, true, 10, "test");
{
"a": true,
"b": {
"c": 10
},
"d": "test"
}

Assign multiple values and override existing

You can assign a values to the last nested properties:

1
2
3
4
5
6
dotject("a,b", {"a": false}, true, "test")
{
"a": true,
"b": "test"
}

“Real world” example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var camera = {isEnabled: true};
camera = dotject("settings.encoding.format,output.data.base64", camera, "JPEG", true);
{
"isEnabled": true,
"settings": {
"encoding": {
"format": "JPEG"
}
},
"output": {
"data": {
"base64": true
}
}
}

Other thoughts

I did consider not implementing the ability to extend existing objects, as this would provide cleaner usage and the base library (functional.js) does already have support for this with the λ.assign (λ.extend) function. I’d be interested to hear your feedback on this, as personally I’m almost always passing a new object, which seems silly.

Issues and pull requests

Please raise any issues / pull requests directly on github.

JSON5

I get excited by new tech, especially when it’s JavaScript related. It usually makes me do a little dance.

The proposed extension to JSON, “JSON5“ unfortunately makes me die a little inside. My blog posts rarely adopt this tone, but I feel very strongly about this.

You can read more about JSON5 on the official site but I’m going to have a whinge about why it’s completely pointless and unimaginative poppycock.

The reason behind JSON5

To quote the proposal:

“JSON isn’t the friendliest to write and maintain by hand. Keys need to be quoted; objects and arrays can’t have trailing commas; comments aren’t supported.”

- aseemk

From that you can deduce the following main proposed features:

  • Inline comments
  • Trailing commas in arrays
  • Trailing commas for object properties

The benefits

There isn’t one. Not one. If anything, this is teaching bad programming techniques:

1
2
3
4
5
6
7
8
{
why: [
"is",
"this",
"better",
],
// (it isn't)
}

Inline comments

Property names should be descriptive enough to be obvious without comments, otherwise what you’re doing is probably wrong.

Don’t say “we need to comment our config files”. If your config file requires explanation, do it in the documentation with examples, not inline in your JSON!

Commas

This isn’t me getting hung up on old Internet Explorer 6 and 7 parsing, there is simply no need for trailing commas on objects or arrays. Is it worthy of a new spec to add this as a feature?

Conclusion

If it isn’t broken, don’t try to fix it. The approach of the proposal appears to be “what could we add” and seems mainly be suited to less technical people who modify config files.

Of course, I’d love for you to challenge my views…

Maps with directions

Today I wrote a Cordova “Directions” Plugin to utilise native maps apps for “sat nav” style direction purposes (using latitude and longitude). You can view the source code here.

Install the plugin

1
$ cordova plugin add https://github.com/leecrossley/cordova-plugin-directions.git

That’s all the installation steps thanks to Cordova’s fantastic CLI and streamlined plugin architecture. You do not need to reference any JavaScript, the build command will add a directions object to your root automatically.

Get directions

After the deviceready event has been fired, pass latitude and longitude to the navigateTo function:

1
directions.navigateTo("51.50722", "-0.12750"); // latitude, longitude

That’s it! Really, it’s that simple. The Google maps app will open on Android and give directions from the device’s current location. Similarly, Bing maps will open on Windows Phone 8.

Platforms

I only needed support for Android and Windows Phone 8, it would be easy to add support for iOS too if anyone needs it. As usual, issues and pull requests on GitHub.

Note: I managed to write this entire post without making any one direction jokes.

The .guru top level domain

The “.guru” top level domain (TLD) became available for public registration this week. More than 20,000 .guru domain names have already been snapped up, proving it to be the most popular of the new public TLDs.

dot guru

Going, going…

Are you considered an expert in a particular field, product or category? If you are a guru, there might still be time to register your .guru domain name.

Take a quick search on iwantmyname to see what’s available.

I’m a dot guru

I quickly registered a couple of .guru domain names. I plan to utilise them as opposed to selling them, although someone has listed 3dprinting.guru for $7500 and mine are better than that.. so we’ll see.

There are also others listed for silly prices (and unlikely to sell?), I’ve seen one on ebay for $20K (or best offer, admittedly).

Trademarks

As you’d expect, most companies have registered their trademarks as domains (e.g. Apple have registered iphone.guru and pretty much all their products). There are however some registrations that do not belong to the trademark holders :) … opens popcorn

Other TLDs

Other popular TLDs now available include:

  • .bike
  • .clothing
  • .singles
  • .ventures
  • .plumbing
  • .holdings
  • .equipment
  • .lighting
  • .estate
  • .graphics
  • .camera
  • .gallery

Note that .guru is more popular than all of the above put together.

Is this the end of .com?

No. To put things into perspective, there have been more than five times as many .com registrations than .guru registrations since Wednesday.

Even skype and twitter (at the time of writing this) aren’t picking up that domain.guru is a URL, even with a protocol prefix!

The .com TLD isn’t going anywhere. Past new TLDs such as .co didn’t replace the .com and neither will any of the proposed future new TLDs.

The new TLDs do have their place and are needed in the overcrowded .com world.

Windows Phone 8

Developing or porting a Cordova / PhoneGap app to WP8 can be particularly tricky. There are lots of gotchas, which are usually difficult to identify without experience. Today I reported an issue that prevents the WP8 platform from even being used with the latest stable version of Cordova. It really does get less attention that iOS and Android.

One of the main issues making the platform difficult to develop for is the inability to easily see errors as they occur using the default setup. In contrast, on the Android platform, you’re able to get an extremely verbose output of everything using logcat.

Show me the errors

I discovered a neat trick over 8 months ago when I was developing a WP8 app in anger. Simply place this code in your app (so that it is executed before any potential errors):

1
2
3
4
window.onerror = function (message, file, line) {
window.external.Notify("Error in Application: " +
message + ". Source File: " + file + ", Line: " + line);
}

This code allows you to not only see any thrown errors in the Visual Studio output window, but also the error message itself and the file / line number of the offending code! A bit better than splurging console.logs everywhere :)

You can see the original gist I wrote here.

New features of “grunt-timer”

I’m pleased to announce the v0.3 release of grunt-timer! The best part about this release is that it’s entirely down to the efforts of the open source community.

What’s new

There are 3 new features, implemented as interchangeable options:

friendlyTime

Initialising grunt-timer with this option outputs durations in a friendly hours/minutes/seconds format (as opposed to just milliseconds, which is the default). e.g:

1
2
module.exports = function (grunt) {
timer.init(grunt, { friendlyTime: true });

deferLogs

Initialising grunt-timer with this option outputs a summary of all task timings at the end of the grunt process (as opposed to between tasks, which is the default). e.g:

1
2
module.exports = function (grunt) {
timer.init(grunt, { deferLogs: true });

deferLogs can be used in conjunction with friendlyTime.

1
2
module.exports = function (grunt) {
timer.init(grunt, { friendlyTime: true, deferLogs: true });

totalOnly

Initialising grunt-timer with this option only the total time all tasks took to complete. This is useful for having many small, insignificant tasks that would generate considerable output even with deferLogs. e.g:

1
2
module.exports = function (grunt) {
timer.init(grunt, { totalOnly: true });

totalOnly can be used in conjunction with friendlyTime.

1
2
module.exports = function (grunt) {
timer.init(grunt, { friendlyTime: true, totalOnly: true });

Credits

Contributors

  • Thanks to Dave Cadwallader for the implementation of the friendlyTime and deferLogs options.
  • Thanks to Carl Herbst for the implementation of the totalOnly option.

Pull requests

The full source code is available here and you can create pull requests here.

It’s time

We’re in the year 2014, people know what the world wide web is (and have known for quite some time), yet may organisations still insist on using a www subdomain for their primary website instead of a pretty subdomain-less url.

Keep it simple

I don’t use, link to, or promote the url www.ilee.co.uk - I always use ilee.co.uk. It’s prettier, simpler and still obviously a url.

Use a permanent (301) redirect

I do redirect www.ilee.co.uk to ilee.co.uk, for completeness and SEO reasons. Serving the same content for each url could be considered duplicate content without a redirect. GitHub pages automatically handles this and it’s GitHub’s preferred format (you’ll never see www.github.com, it’s always github.com).

Expressjs

To my horror I realised yesterday that www.plugreg.com, didn’t redirect to plugreg.com. plugreg is written in node.js and uses the expressjs framework, so I wrote a handy little function to handle the www redirect scenario:

1
2
3
4
5
6
7
8
9
10
11
var redirect = function (req, res, next) {
var baseUrl = req.protocol + "://" + req.host,
wwwUrl = req.protocol + "://www.";
if (baseUrl.substring(0, wwwUrl.length) === wwwUrl) {
res.redirect(301, baseUrl.replace("://www.", "://") + req.url);
} else {
next();
}
};
app.all("*", redirect);

Configure webmaster tools

Under “site settings” of Google Webmaster Tools, you also have the option to set your preferred domain:

  • Don’t set a preferred domain
  • Display URLs as www.ilee.co.uk
  • Display URLs as ilee.co.uk

Here’s to a www-less 2014.

Optimise for mobile

With huge numbers of internet users using mobiles and tablet devices to browse the web, it’s more important than ever to optimise your website for these devices.

Creating a mobile website is not enough

If you truly want to engage users on mobile devices, you’ve got to consider their experience, not just how the website looks. Touch interfaces, varying resolutions / density and gestures are among just a few of the challenges technology advancements have brought.

What exactly is UX?

UX stands for User eXperience, which is the comprehensive experience of a user interacting with a product (in this case a website and more specifically, a website on mobile devices). It encompasses factors such as ease-of-use and user gratification.

UX is hard

There’s no completely right answer but there are better answers. Google are starting to analyse the mobile user experience of websites using some set tangible metrics, so this is a good quantifiable place to start.

Why UX?

It’s all about the users and they are ultimately going to result in conversions (if that’s your aim) usually through improved productivity or satisfaction though a good user experience. Although Google looks to start weighting search results based on their perceived automated user experience, the focus should still be primarily on real users. After all, web traffic on its own means nothing.

PageSpeed insights

The PageSpeed Insights tool is now reporting mobile user experience, in addition to page speed. This is a great place to start to give you instant feedback on some tangible metrics. The tool currently analyses:

  • Use of plugins
  • Viewport metatag and content size within the viewport
  • Size of touch/tap “clickable” interactions
  • Font sizes

The website provides more info on these. This blog passed all of the user experience first time, except for the sizing of anchor tags. To fix this, I added the following css to my article (content) section:

1
2
3
4
5
6
7
8
@media screen and (max-width: 600px) {
article a {
display: inline-block;
padding: 3px 7px;
background-color: #ecf0f1;
margin: 5px 0px;
}
}

That’s not the end

The PageSpeed Insights are a great place to start for existing mobile websites, but it’s not the end of the road, there are many other considerations (every UX designer and every website will have their own particulars). Consider split A/B testing and responding to user feedback too.

If you have the luxury of a starting your mobile website from scratch or a rewrite, consider user experience right from the outset and get users involved in the process as early as possible.

The year of the node

If you haven’t already (shame on you), it really is time to sit down and have a play with node.js. So that you have absolutely no excuses, I’ve put together a super quick start guide to kick you off.

Nodejs was first released back in May 2009 but has gathered huge momentum over the past year or so.

Super quick start

Install

Download the installer for your OS and install.

Create

Create a new directory for your app (optional) and a blank app.js JavaScript file.

1
2
3
$ mkdir nodeapp
$ cd nodeapp
$ touch app.js

Code

In your newly created JavaScript file, add the following code:

1
2
3
4
5
6
var http = require("http");
http.createServer(function(req, res) {
res.writeHead(200, {"Content-Type": "text/html"});
res.end("I know node.js!");
}).listen(4000);

Run

Ensure you’re in the directory of your app.js JavaScript file and run:

1
$ node app

Now visit http://localhost:4000/ to see your newly created node.js http server in action!

Packages

You’ll notice in the example above that we’re using http, which is part of the node core. There are over 50,000 3rd party packages available on the node package manager registry, that should keep you busy for the rest of the year :)

Happy new year!