Skip to content

Commit

Permalink
Merge pull request #319 from paulmillr/topics/chaplin
Browse files Browse the repository at this point in the history
Add Chaplin application.
  • Loading branch information
sindresorhus committed Dec 12, 2012
2 parents faa859e + 00ca042 commit 07898f7
Show file tree
Hide file tree
Showing 41 changed files with 9,188 additions and 0 deletions.
6 changes: 6 additions & 0 deletions labs/dependency-examples/chaplin-brunch/.editorconfig
@@ -0,0 +1,6 @@
# editorconfig.org
root = true

[*.coffee]
indent_style = space
indent_size = 2
5 changes: 5 additions & 0 deletions labs/dependency-examples/chaplin-brunch/.gitignore
@@ -0,0 +1,5 @@
# NPM packages folder.
node_modules/

# Brunch folder for temporary files.
tmp/
15 changes: 15 additions & 0 deletions labs/dependency-examples/chaplin-brunch/README.md
@@ -0,0 +1,15 @@
# Brunch with Chaplin TODOMVC
Brunch with Chaplin is a skeleton (boilerplate) for [Brunch](http://brunch.io)
based on [Chaplin](https://github.com/chaplinjs/chaplin) framework.

The application is based on the skeleton.

## Getting started
* Install [Brunch](http://brunch.io) if you hadn’t already (`npm install -g brunch`).
* Execute `npm install` in the root directory once.
* Execute `brunch build` in the root directory to build app every time. That’s all.
* Execute `brunch watch` if you want to continiously rebuild the app
on every change. To run the app then, you will need to open `public/index.html` in your browser (assuming the root is `/todomvc/` root or so).

## Author
The stuff was made by [@paulmillr](http://paulmillr.com).
67 changes: 67 additions & 0 deletions labs/dependency-examples/chaplin-brunch/app/application.coffee
@@ -0,0 +1,67 @@
Chaplin = require 'chaplin'
mediator = require 'mediator'
routes = require 'routes'
HeaderController = require 'controllers/header-controller'
FooterController = require 'controllers/footer-controller'
TodosController = require 'controllers/todos-controller'
Todos = require 'models/todos'
Layout = require 'views/layout'

# The application object
module.exports = class Application extends Chaplin.Application
# Set your application name here so the document title is set to
# “Controller title – Site title” (see Layout#adjustTitle)
title: 'Chaplin • TodoMVC'

initialize: ->
super

# Initialize core components
@initDispatcher controllerSuffix: '-controller'
@initLayout()
@initMediator()

# Application-specific scaffold
@initControllers()

# Register all routes and start routing
@initRouter routes, pushState: no
# You might pass Router/History options as the second parameter.
# Chaplin enables pushState per default and Backbone uses / as
# the root per default. You might change that in the options
# if necessary:
# @initRouter routes, pushState: false, root: '/subdir/'

# Freeze the application instance to prevent further changes
Object.freeze? this

# Override standard layout initializer
# ------------------------------------
initLayout: ->
# Use an application-specific Layout class. Currently this adds
# no features to the standard Chaplin Layout, it’s an empty placeholder.
@layout = new Layout {@title}

# Instantiate common controllers
# ------------------------------
initControllers: ->
# These controllers are active during the whole application runtime.
# You don’t need to instantiate all controllers here, only special
# controllers which do not to respond to routes. They may govern models
# and views which are needed the whole time, for example header, footer
# or navigation views.
# e.g. new NavigationController()
new HeaderController()
new FooterController()
new TodosController()

# Create additional mediator properties
# -------------------------------------
initMediator: ->
# Create a user property
mediator.user = null
# Add additional application-specific properties and methods
mediator.todos = new Todos()
mediator.todos.fetch()
# Seal the mediator
mediator.seal()
36 changes: 36 additions & 0 deletions labs/dependency-examples/chaplin-brunch/app/assets/index.html
@@ -0,0 +1,36 @@
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Chaplin • TodoMVC</title>
<link rel="stylesheet" href="../../../../assets/base.css">
<!--[if IE]>
<script src="../../../assets/ie.js"></script>
<![endif]-->
<link rel="stylesheet" href="stylesheets/app.css">

<!-- Usually all these files are concatenated automatically
by brunch and you need just to import `vendor.js` -->
<script src="../../../../assets/base.js"></script>
<script src="../../../../assets/jquery.min.js"></script>
<script src="../../../../assets/lodash.min.js"></script>
<script src="../../../../assets/handlebars.min.js"></script>

<script src="javascripts/vendor.js"></script>
<script src="javascripts/app.js"></script>
<script>require('initialize');</script>
</head>
<body>
<section id="todoapp">
<header id="header"></header>
<section id="main"></section>
<footer id="footer"></footer>
</section>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://paulmillr.com">Paul Miller</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
</body>
</html>
@@ -0,0 +1,3 @@
Chaplin = require 'chaplin'

module.exports = class Controller extends Chaplin.Controller
@@ -0,0 +1,8 @@
Controller = require 'controllers/base/controller'
FooterView = require 'views/footer-view'
mediator = require 'mediator'

module.exports = class FooterController extends Controller
initialize: ->
super
@view = new FooterView collection: mediator.todos
@@ -0,0 +1,8 @@
Controller = require 'controllers/base/controller'
HeaderView = require 'views/header-view'
mediator = require 'mediator'

module.exports = class HeaderController extends Controller
initialize: ->
super
@view = new HeaderView collection: mediator.todos
@@ -0,0 +1,7 @@
Controller = require 'controllers/base/controller'

module.exports = class IndexController extends Controller
title: 'Todo list'

list: (options) ->
@publishEvent 'todos:filter', options.filterer?.trim() ? 'all'
@@ -0,0 +1,8 @@
Controller = require 'controllers/base/controller'
TodosView = require 'views/todos-view'
mediator = require 'mediator'

module.exports = class TodosController extends Controller
initialize: ->
super
@view = new TodosView collection: mediator.todos
6 changes: 6 additions & 0 deletions labs/dependency-examples/chaplin-brunch/app/initialize.coffee
@@ -0,0 +1,6 @@
Application = require 'application'

# Initialize the application on DOM ready event.
$ ->
app = new Application()
app.initialize()
13 changes: 13 additions & 0 deletions labs/dependency-examples/chaplin-brunch/app/lib/support.coffee
@@ -0,0 +1,13 @@
Chaplin = require 'chaplin'
utils = require 'lib/utils'

# Application-specific feature detection
# --------------------------------------

# Delegate to Chaplin’s support module
support = utils.beget Chaplin.support

# _(support).extend
# someMethod: ->

module.exports = support
12 changes: 12 additions & 0 deletions labs/dependency-examples/chaplin-brunch/app/lib/utils.coffee
@@ -0,0 +1,12 @@
Chaplin = require 'chaplin'

# Application-specific utilities
# ------------------------------

# Delegate to Chaplin’s utils module
utils = Chaplin.utils.beget Chaplin.utils

# _(utils).extend
# someMethod: ->

module.exports = utils
39 changes: 39 additions & 0 deletions labs/dependency-examples/chaplin-brunch/app/lib/view-helper.coffee
@@ -0,0 +1,39 @@
mediator = require 'mediator'
utils = require 'chaplin/lib/utils'

# Application-specific view helpers
# ---------------------------------

# http://handlebarsjs.com/#helpers

# Conditional evaluation
# ----------------------

# Choose block by user login status
Handlebars.registerHelper 'if_logged_in', (options) ->
if mediator.user
options.fn(this)
else
options.inverse(this)

# Map helpers
# -----------

# Make 'with' behave a little more mustachey
Handlebars.registerHelper 'with', (context, options) ->
if not context or Handlebars.Utils.isEmpty context
options.inverse(this)
else
options.fn(context)

# Inverse for 'with'
Handlebars.registerHelper 'without', (context, options) ->
inverse = options.inverse
options.inverse = options.fn
options.fn = inverse
Handlebars.helpers.with.call(this, context, options)

# Evaluate block with context being current user
Handlebars.registerHelper 'with_user', (options) ->
context = mediator.user?.serialize() or {}
Handlebars.helpers.with.call(this, context, options)
@@ -0,0 +1 @@
module.exports = require('chaplin').mediator
@@ -0,0 +1,9 @@
Chaplin = require 'chaplin'
Model = require 'models/base/model'

module.exports = class Collection extends Chaplin.Collection
# Use the project base model per default, not Chaplin.Model
model: Model

# Mixin a synchronization state machine
# _(@prototype).extend Chaplin.SyncMachine
@@ -0,0 +1,5 @@
Chaplin = require 'chaplin'

module.exports = class Model extends Chaplin.Model
# Mixin a synchronization state machine
# _(@prototype).extend Chaplin.SyncMachine
16 changes: 16 additions & 0 deletions labs/dependency-examples/chaplin-brunch/app/models/todo.coffee
@@ -0,0 +1,16 @@
Model = require 'models/base/model'

module.exports = class Todo extends Model
defaults:
title: ''
completed: no

initialize: ->
super
@set 'created', Date.now() if @isNew()

toggle: ->
@set completed: not @get('completed')

isVisible: ->
isCompleted = @get('completed')
18 changes: 18 additions & 0 deletions labs/dependency-examples/chaplin-brunch/app/models/todos.coffee
@@ -0,0 +1,18 @@
Collection = require 'models/base/collection'
Todo = require 'models/todo'

module.exports = class Todos extends Collection
model: Todo
localStorage: new Store 'todos-chaplin'

allAreCompleted: ->
@getCompleted().length is @length

getCompleted: ->
@where completed: yes

getActive: ->
@where completed: no

comparator: (todo) ->
todo.get('created')
3 changes: 3 additions & 0 deletions labs/dependency-examples/chaplin-brunch/app/routes.coffee
@@ -0,0 +1,3 @@
module.exports = (match) ->
match ':filterer', 'index#list'
match '', 'index#list'
@@ -0,0 +1,7 @@
Chaplin = require 'chaplin'
View = require 'views/base/view'

module.exports = class CollectionView extends Chaplin.CollectionView
# This class doesn’t inherit from the application-specific View class,
# so we need to borrow the method from the View prototype:
getTemplateFunction: View::getTemplateFunction
@@ -0,0 +1,7 @@
Chaplin = require 'chaplin'
require 'lib/view-helper' # Just load the view helpers, no return value

module.exports = class View extends Chaplin.View
# Precompiled templates function initializer.
getTemplateFunction: ->
@template
@@ -0,0 +1,40 @@
View = require 'views/base/view'
template = require 'views/templates/footer'

module.exports = class FooterView extends View
autoRender: yes
el: '#footer'
template: template

initialize: ->
super
@subscribeEvent 'todos:filter', @updateFilterer
@modelBind 'all', @renderCounter
@delegate 'click', '#clear-completed', @clearCompleted

render: =>
super
@renderCounter()

updateFilterer: (filterer) =>
filterer = '' if filterer is 'all'
@$('#filters a')
.removeClass('selected')
.filter("[href='#/#{filterer}']")
.addClass('selected')

renderCounter: =>
total = @collection.length
active = @collection.getActive().length
completed = @collection.getCompleted().length

@$('#todo-count > strong').html active
countDescription = (if active is 1 then 'item' else 'items')
@$('.todo-count-title').text countDescription

@$('#completed-count').html "(#{completed})"
@$('#clear-completed').toggle(completed > 0)
@$el.toggle(total > 0)

clearCompleted: ->
@publishEvent 'todos:clear'
@@ -0,0 +1,18 @@
View = require 'views/base/view'
template = require 'views/templates/header'

module.exports = class HeaderView extends View
autoRender: yes
el: '#header'
template: template

initialize: ->
super
@delegate 'keypress', '#new-todo', @createOnEnter

createOnEnter: (event) =>
ENTER_KEY = 13
title = $(event.currentTarget).val().trim()
return if event.keyCode isnt ENTER_KEY or not title
@collection.create {title}
@$('#new-todo').val ''
10 changes: 10 additions & 0 deletions labs/dependency-examples/chaplin-brunch/app/views/layout.coffee
@@ -0,0 +1,10 @@
Chaplin = require 'chaplin'

# Layout is the top-level application ‘view’.
module.exports = class Layout extends Chaplin.Layout
initialize: ->
super
@subscribeEvent 'todos:filter', @changeFilterer

changeFilterer: (filterer = 'all') ->
$('#todoapp').attr 'class', "filter-#{filterer}"

0 comments on commit 07898f7

Please sign in to comment.