Backbone subviews with non-uniform layout I have a “featured projects” view that requires its subviews conform to a non-uniform grid: one narrow column with 3 items, then one wide column with 2 items, followed by another narrow column with 3 items. The width that is used for each subview is determined by the model’s display attribute. If there are any extra items in the collection, they are disregarded for the purposes of this view.

Here's the relevant portion of the code:

class App.Views.FeaturedProjects extends Backbone.View
  el: '#featured'
  template: '&lt;div class="column"&gt;&lt;/div&gt;'

  initialize: -&gt;
    ...
    @collection.on 'reset', @addAll, this

  addOne: (item, el) =&gt;
    view = new App.Views.Project model: item
    el.append view.render().el

  addAll: -&gt;
    # … clear out existing subviews, then …

    # separate collection into wide &amp; narrow
    narrow = @collection.where display: 'narrow'
    wide = @collection.where display: 'wide'

    # only display the grid if there are enough items to fill it
    if narrow.length &gt;= 6 and wide.length &gt;= 2
      column1 = $(@template).addClass('column-narrow')  
      column2 = $(@template).addClass('column-wide')    
      column3 = $(@template).addClass('column-narrow')  

      # 3 narrow / 2 wide / 3 narrow
      @addOne(item, column1) for item in narrow[0..2]
      @addOne(item, column2) for item in wide[0..1]
      @addOne(item, column3) for item in narrow[3..5]

      @$el.append(column1).append(column2).append(column3)


My current approach works, but is there a better way of handling something like this?

EDIT

I took Marco's suggestions a bit further and ended up with the following:

class App.Views.FeaturedProjects extends Backbone.View
  columnTemplate: '&lt;div class="column"&gt;&lt;/div&gt;'

  defaults: -&gt;
    columns: [
      { type: 'narrow', itemsPer: 3 }
      { type: 'wide', itemsPer: 2 }
      { type: 'narrow', itemsPer: 3 }
    ]

  initialize: (options) -&gt;
    @options = _.extend({}, @defaults(), options)
    ...
    @collection.on 'reset', @addAll, this

  addAll: -&gt;
    # … clear out existing subviews, then …
    items = {}
    valid = true
    # get unique column types
    uniqueColTypes = _.uniq _.pluck @options.columns, 'type'

    # separate collection by column type and verify there are enough items of each type
    for type in uniqueColTypes
      items[type] = @collection.where display: type
      valid = false if items[type].length &lt; @minItems type

    # display the grid
    if valid
      for column in @options.columns
        columnHtml = $(@columnTemplate).addClass "column-#{column.type}"
        itemsPer = column.itemsPer
        @addOne items[column.type].shift(), columnHtml while itemsPer--
        @$el.append(columnHtml)

  # returns number of items with specified column type required to fill the grid
  minItems: (type) -&gt;
    minItems = 0
    minItems += col.itemsPer for col in _.where @options.columns, {type: type}
    return minItems
This looks pretty good. My main suggestion for improvement would be we how you set and create the columns. I would try and make this more dynamic so the amount of columns can more easily change, and can be set from code using this view. 

To do this I'd create an array to represent the columns. Each column would have information about whether its narrow, or wide and then how many items it should have in it:

columns = [{type: 'narrow', itemsPer: 3}, {type: 'wide', itemsPer: 2}, 
  {type: 'narrow', itemsPer: 3}]


And then process the array rather then have variables named for each column. This would also add the items to the columns so it can be done it one loop. I used "shift" to remove the first element of the array so the narrow collection could be used without referencing exact indexes, which would allow it to work for any amount of items per column. I also changed the structure of the narrow and wide variables so they are properties on a items object, which makes the referenced with the same column.type name. 

items[narrow] = @collection.where display: 'narrow'
items[wide] = @collection.where display: 'wide' 

if narrow.length &gt;= 6 and wide.length &gt;= 2
  for column in columns    
    columnHtml = $(@template).addClass('column-' + column.type)
    for i in range(column.itemsPer)
      @addOne(items[column.type].shift(), columnHtml)

    @$el.append(columnHtml)


Another thing, I found the template property to be confusing, because it was the template for each of the three columns where I expected it to be the template for the whole view (which would only be created once). I suggest naming it to something like "columnTemplate" 

columnTemplate: '&lt;div class="column"&gt;&lt;/div&gt;',


My code examples are in pseudo code, as I'm less familiar with CoffeeScript, but I think you can understand generally what I'm saying.