Documentation is hard. Like writing code, it is a delicate balancing act of packing information into a format that is both very dense and very readable. Going too far in either direction severely limits its usefulness.
While ramping down a client project recently, I was asked to provide documentation and guides for the JavaScript application stack the company was using. Talking such a broad topic in a useful and consumable way was a daunting challenge. Some of the problems I immediately saw were:
- The documentation would have to stand on its own; I wouldn’t be there to update or answer questions about it.
- It needed to be approachable for developers new to the technology, but also deep enough for more experienced developers to derive value.
- I only had a couple days to create the content, so it needed to be pretty concise.
After brainstorming several approaches, I decided that writing a cookbook was my best option. Cookbooks organize material into “recipes,” simple practical problems along with a described solution and short code sample. The most well-known examples are probably O’Reilly’s offerings, which cover a wide range of technologies.
Writing the cookbook content proved to be a fun and challenging exercise. I had frequently been consulting and pairing with other developers on this project, so I used questions they had frequently asked me as the basis for the content.
I also tried to place some additional limits on myself:
- Keep descriptions to no more than a single paragraph.
- Keep all the example code snippets small enough to fit entirely on one screen without scrolling.
I thought this would maximize the readability of the document. I also figured that examples that could not fit into these constraints were probably too complex and nuanced to effectively demonstrate in standalone documentation. Additionally, I hoped that the format would be lightweight enough that future developers would feel comfortable editing existing entries or adding new ones.
Below is an example from the cookbook I generated.
Data-binding To a Specific Model Property
Recipe – listen to the change:propertyName event on the model
You can use this to databind to a specific property in a view:
var View = Marionette.ItemView.extend({
ui: {
statusIndicator: '.app-status-indicator'
},
modelEvents: {
// Bind to the status property, and toggle an indicator whenever it changes
'change:status': 'toggleStatusIndicator'
},
toggleStatusIndicator: function(model, status) {
this.ui.statusIndicator.toggleClass('active', status);
}
});
Or to give your model computed properties:
var Model = Backbone.Model.extend({
initialize: function(options) {
// Bind to change events for the dependant properties
this.listenTo(this, 'change:firstName change:lastName', this.computeDisplayName);
// You have to compute the property once manually on startup to make
// sure the initial value is computed
this.computeDisplayName();
},
computeDisplayName: function() {
// Set computed property based on dependant properties
this.set('displayName', this.get('lastName') + ', ' + this.get('firstName'));
}
});
The whole recipe can fit onto a page without scrolling and provides some simple standalone examples. What other kinds of documentation have you found successful in a similar situation?