While I really want this to be my tablet, I’m wary of whether it will have a WiFi only version (I don’t need another monthly fee, thanks), it’s price (rumored significantly higher than the iPad), and how well it plays movies from Netflix and Hulu.
The intertubes all have Gmail’s Priority Inbox in mind. I find people’s reactions to be quite surprising. I don’t get the tidal waves of email as some people do. In fact, I get very little email. Yet, I was excited at the idea of trying to make email better.
Some people were nervous about it. Nervous as in paranoid. I wonder, why? Google isn’t actually “reading” your email. It’s just some algorithms running on your read and reply history. Some Bayesian statistics applied. Anyone worried that their email is now being read should realize that Google could have been reading your email long before now. Really, if anyone is that concerned with privacy, they should consider using their own hosted email server, and an email certificate. Then you can be sure the only people seeing your email are you and your sender/receiver.
Other people don’t want to change their system. They have rules set up to filter a lot of junk already, or they use a speedy Inbox Zero routine to quickly weed out the crap. I can appreciate that. I like to process my email all at once, and leave nothing left in the inbox. I also use a set of filters, mostly to apply labels to certain things so I can have a context when I open them. But I still appreciate what this Priority Inbox can do. Rules can change. You may add a new mailing list, or find a new friend that sends you chain letters, and instead of adding yet another rule manually, why not just let a computer figure that out for you quickly? Or for those processing every single message themselves, I have to wonder why you would want to spend the time and mental energy on so much junk.
As a programmer, I look at everything and think: “Can’t a computer do that for me?”
Now, I just got Priority Inbox enabled, and the excitement died a little. Not because I think it’s useless, but because I don’t get a lot of email. When it turned on, it helped sort 2 emails for me. I can see people getting included in emails by being added to the carbon copy a lot, or if they’re in a position facing the public, like a community manager. But looking at people’s rules, I don’t see how people can accept getting so much junk mail in the first place.
Pretty much all the email I get I would classify as “important”. Almost everything is directed at me. The few mailing lists I subscribe to, I do so because I want to read every single message. I don’t allow applications like Facebook or Twitter1 or whatever to send me useless notification emails. Any time any service sends me email that I don’t want, I scour the footer for the unsubscribe link, and make a liberal use of that spam button. I can’t imagine allowing myself to receive email that I would want a filter to automatically archive for me. What use was that email for me, then? I never look in the archive. I don’t store information in my email for later reference. How some of you people even allow so much junk is beyond me.
Basecamp has no ability inside the app to disable emails, and when posting a new message, the easiest email options is to selected “Everyone” instead of checking everyone but myself. I’ve wanted to hit the spam button for Basecamp so many times, but I always stop myself in case I get message from another Basecamp account that I need to see. Grrrr. ↩
While I really want this to be my tablet, I’m wary of whether it will have a WiFi only version (I don’t need another monthly fee, thanks), it’s price (rumored significantly higher than the iPad), and how well it plays movies from Netflix and Hulu.
“Text and email are polite invitations to a conversation. They happen at the speed and leisure of both the sender and the receiver. In stark contrast, when you get a phone call, it’s almost always a convenient time for the caller and a bad time for the recipient, who I refer to as the “victim” because I insist on accuracy.
—Scott Adams Blog: Phone
This is another installment about how my MooTools MVC framework rocks. Check it out. If you’re interested in the first part, check out my write-up on using Models.
After you make the building blocks of your application, using Models, Views are how you display that information to a user. Having written a lot of JavaScript that adds content to the page, I know just how much it can suck. You typically have two options:
innerHTML of a div.document.createElement and el.appendChild, ad infinitum.Both are equally unappetizing. Wouldn’t it be so much nicer to write your views like we do in other languages?
Here’s a nice mix of HTML and JavaScript. No tricky string concatenation1. You just have to put your JavaScript inside tags like you would in PHP.
<ul id="Tasks">
<% tasks.forEach(function(task) { %>
<li class="task">
<input type="checkbox" />
<%= task.get('title') %>
<% if(tag.get('tags').length) {
print(view('tasks/inline_tags', { tags: task.get('tags') }));
} %>
</li>
<% }); %>
</ul>
Besides print, which does exactly what you think it does, there are a bunch of other functions that are sort of “globally” accessible from a View. And these are functions defined on View.Helpers. The most basic version of the helpers only includes a view function, which let’s you nest views inside each other, like I used above. If you include the View.Helpers file, you get more functions, such as excerpt (truncates to a certain length) and date (allows date formating similar to PHP’s date method). As I find more basic functions that you would want in a templating system, I’ll add more, such as possibly something like escape.
These are saved as .html files. You don’t need to manually include them like Models or Controllers; the View class will first check to see if they’ve been included, and if not, go and fetch them over the wire. And they go in you app’s views folder. The example above would have a structure like so:
js/
views/
tasks/
list.html
The View Class is what converts templates into views for your application. You can instantiate a View, and then pass it data and ask for it to process itself using the passed data.
var myView = new View('tasks/list').render({ tasks: myTasks });
myEl.grab(myView);
myOtherEl.set('html', myView);
Views have both a toElement and toString function defined to return the processed mark-up in the proper format. This means you can simply pass the view as a parameter to most MooTools Element methods, and it just works2.
Good news, though: Controllers have a convenience method called view that really makes this a joy to use. I’ll have more to say about Controllers in my next report.
The string concatenation is done internally. Everything in the template is turned into a string using John Resig’s micro-templating suggestion. ↩
Regular DOM methods might not though. appendChild expects an Element, and since it’s not part of MooTools, it’s not rigged up to called toElement. Also, because of the way toString works with Classes in Internet Explorer, this feature doesn’t work in those browsers. MooTools 1.3 repairs that problem. ↩
Chrome started it.

Firefox is following along in version 4. The browser in Android does this too.
There is only one bar to enter text. You can enter a URL, and it will work as you’d expect. Or you can enter some terms, and it will send you to your default search engine.
Google has done the same with the default browser in Android. Apparently, it can be confusing in the iPhone’s Safari.
To think that most users of a browser are going to know the difference between a URL and search term would be wrong thinking. To make users care about the difference, for those that do know it, is not caring about your users. All the users should care about is:
How can I find what I’m looking for? Ah yes, the browser bar. I’ll just type what I’m looking for here. It will tell me.
When will all browsers finally combine the location bar with the search bar?
It’s always cool to learn new systems to productivity and work. Patrick Rhone asks people to share what they keep in their Simplenote, and so I join in:
I quite like Patrick’s Yay me! idea, and Randy’s elevator pitch/bio idea.
This is a fantastic extension for Chrome. This lets you easily edit the styles of a web page, and have them be saved and applied next time you visit.
The demo shows one excellent use: improving a site you frequent. I did that for Kotaku/Lifehacker. I never use the Share box, and always mistake it for a search box. So, share box hidden, search box moved into place.
Also, I have refrained from Adblockers in the past because I don’t want to block all ads. I respect websites’ needs to make money. But I don’t respect the need to make a website that is more about the ads than the content. So, certain websites that cover their articles in flash ads, or have far too many ads in the sidebar, have their ads hidden.
Yes, I know. Shame on me, etc.
Considering how awesome my phone is, this gives me hope of an Android tablet that will perform well. Only disappointing spec on paper is its 7-inch screen.
It’s really bugged me when writing large JavaScript applications, organization of code never really seems to be considered. We use frameworks for all the server-side stuff we do, but everyone seems content writing JavaScript in one big mess.
Granted, that’s why I was attracted to MooTools in the first place: the idea of organizing your code is built into the framework. If you don’t predominantly write classes with MooTools, you might as well be writing jQuery. But even with classes, in a JavaScript application1 you write a lot of code that works with those classes and fiddles with the DOM. It can get to be a real mess.
A year ago, I got fed up with it. I was also interested in Adobe AIR at the time, and liked the idea of being able to copy over as much of my code as possible to make an AIR version of an application. Hopefully, the only changes would be the way data was stored and received. I feel pretty good when using the MVC paradigm on the server-side, and I felt it made sense in the browser as well. So I started a MooTools MVC framework.
I started with making various sub-classes of Model2 that interacted with specific data storage concepts. In Adobe AIR, a SQLite database would likely be used. In the browser, you’d likely have you’re data stored on the server, and need to access it via ajax. I wanted to be able to have the same model class, and just change its subclass based on need. Certainly, the Model.SQL could be used in newer browsers, as well, if you wished.
It didn’t take look for me to give up for the time being on AIR, but I still felt that the organization that such a framework provided was beneficial. Therefore, I spent more time on Model.Ajax and Model.Browser, since most of my use of the framework has been for the browser. Model.Browser uses a combination of localStorage, userData, and cookies, depending on support, to allow a web application to function entirely on the client side. I did much of this just to allow myself to work out an example application, without needing a back-end.
Model.Ajax is what I use the most, now. Let me show you an example model:
var Task = new Class({
Extends: Model.Ajax,
fields: {
id: Model.Fields.AutoField({ write: false }),
title: Model.Fields.TextField(),
created_at: Model.Fields.DateField(),
tags: Model.Fields.ManyToManyField(Tag)
is_done: Model.Fields.BooleanField({ default: true })
}
});
By extending Model.Ajax, Task will make some default assumptions about the back-end API. For instance, Task.find will call /tasks/find, Task.get(5) will call /tasks/5, and myTask.save() will call /tasks/insert or /tasks/5/update depending on if it’s new or not. And of course, because of the asynchronous nature of all these function calls, a callback can be passed, which will receive the instances as it’s only parameter upon completion. Such as:
Task.get('123', function(task) {
console.log(task); //the returned data, cast as an instance of Task already
});
A model also declares its fields, so that every time a new Task is made with a hash of properties, it only extracts the ones it cares about, and converts them to the proper type if it can. Specifically, I’ve set id to read only, since I don’t want something accidentally changing the id of a task and sending it.
An instance of a Model can access it’s properties through getter and setter functions. These are similar to the Element getter and setters, and they allow each individual field type to cast to the proper type, or return a default. For example:
var myTask = new Task;
myTask.set('is_done', 'true');
console.log(myTask.get('is_done')); //will return the boolean true, not the string.
This also allows Fields that provide relationships to other models cast ids to instances and back again. Task.tags will store an array of tag ids internally, and submit those to the server upon a save. But if you get the tags, the ManyToManyField will convert them into the existing Tag instances.
The point of using Models in this framework is to have a single location that is responsible for abstracting data retrieval3, and providing a central place to handle any data conversion. You shouldn’t have any Ajax requests or data validation any where else in your application.
From here on out, my use of a JavaScript application is one where a large amount of it is written in JavaScript. Sure, your requests still need to interact with a server-side technology, but on the client side, most of the application functions without page refreshes. ↩
The assumption is made that you know what MVC is. If not, read up. ↩
Whether the Model or the Controller should do the ajax requests has been argued both ways when used in a JavaScript MVC framework, . Since the primary reason for a Model is to abstract the data storage system, it makes sense to me that only the Model should know if it needs to access a web server via ajax, or use localStorage, or use SQLite. ↩