Fork me on GitHub

THE SITE HAS MOVED TO Sammyjs.org. YOU ARE BEING REDIRECTED

Sammy

Documentation

API

Handlebars.SafeString ( string )

Build out our basic SafeString type

Sammy ( )

Sammy (also aliased as $.sammy) is not only the namespace for a number of prototypes, its also a top level method that allows for easy creation/management of Sammy.Application instances. There are a number of different forms for Sammy() but each returns an instance of Sammy.Application. When a new instance is created using Sammy it is added to an Object called Sammy.apps. This provides for an easy way to get at existing Sammy applications. Only one instance is allowed per element_selector so when calling Sammy('selector') multiple times, the first time will create the application and the following times will extend the application already added to that selector.

Example

      // returns the app at #main or a new app
      Sammy('#main')

      // equivilent to "new Sammy.Application", except appends to apps
      Sammy();
      Sammy(function() { ... });

      // extends the app at '#main' with function.
      Sammy('#main', function() { ... });
    

Sammy.Application ( app_function )

Sammy.Application is the Base prototype for defining 'applications'. An 'application' is a collection of 'routes' and bound events that is attached to an element when run() is called. The only argument an 'app_function' is evaluated within the context of the application.

Attributes


APP_EVENTS = ['run'

An array of the default events triggered by the application during its lifecycle

ROUTE_VERBS = ['get','post','put','delete']

the four route verbs

any = _routeWrapper('any')

Alias for route('any', ...)

debug = false

When set to true, logs all of the default events using log()

del = _routeWrapper('delete')

Alias for route('delete', ...)

element_selector = 'body'

Defines what element the application is bound to. Provide a selector (parseable by jQuery()) and this will be used by $element()

get = _routeWrapper('get')

Alias for route('get', ...)

post = _routeWrapper('post')

Alias for route('post', ...)

put = _routeWrapper('put')

Alias for route('put', ...)

raise_errors = false

When set to true, and the error() handler is not overriden, will actually raise JS errors in routes (500) and when routes can't be found (404)

run_interval_every = 50

The time in milliseconds that the URL is queried for changes

template_engine = null

The default template engine to use when using partial() in an EventContext. template_engine can either be a string that corresponds to the name of a method/helper on EventContext or it can be a function that takes two arguments, the content of the unrendered partial and an optional JS object that contains interpolation data. Template engine is only called/refered to if the extension of the partial is null or unknown. See partial() for more information

Methods


$element ( )

returns a jQuery object of the Applications bound element.

after ( callback )

A shortcut for binding a callback to be run after a route is executed. After callbacks have no guarunteed order.

around ( callback )

Adds an around filter to the application. around filters are functions that take a single argument callback which is the entire route execution path wrapped up in a closure. This means you can decide whether or not to proceed with execution by not invoking callback or, more usefuly wrapping callback inside the result of an asynchronous execution.

Example

The most common use case for around() is calling a possibly async function and executing the route within the functions callback:

        var app = $.sammy(function() {

          var current_user = false;

          function checkLoggedIn(callback) {
            // /session returns a JSON representation of the logged in user
            // or an empty object
            if (!current_user) {
              $.getJSON('/session', function(json) {
                if (json.login) {
                  // show the user as logged in
                  current_user = json;
                  // execute the route path
                  callback();
                } else {
                  // show the user as not logged in
                  current_user = false;
                  // the context of aroundFilters is an EventContext
                  this.redirect('#/login');
                }
              });
            } else {
              // execute the route path
              callback();
            }
          };

          this.around(checkLoggedIn);

        });
      

before ( options, callback )

Takes a single callback that is pushed on to a stack. Before any route is run, the callbacks are evaluated in order within the current Sammy.EventContext

If any of the callbacks explicitly return false, execution of any further callbacks and the route itself is halted.

You can also provide a set of options that will define when to run this before based on the route it proceeds.

Example

        var app = $.sammy(function() {

          // will run at #/route but not at #/
          this.before('#/route', function() {
            //...
          });

          // will run at #/ but not at #/route
          this.before({except: {path: '#/route'}}, function() {
            this.log('not before #/route');
          });

          this.get('#/', function() {});

          this.get('#/route', function() {});

        });
      

See contextMatchesOptions() for a full list of supported options

bind ( name, data, callback )

Works just like jQuery.fn.bind() with a couple noteable differences.

  • It binds all events to the application element
  • All events are bound within the eventNamespace()
  • Events are not actually bound until the application is started with run()
  • callbacks are evaluated within the context of a Sammy.EventContext

See http://code.quirkey.com/sammy/docs/events.html for more info.

bindToAllEvents ( callback )

Will bind a single callback function to every event that is already being listened to in the app. This includes all the APP_EVENTS as well as any custom events defined with bind().

Used internally for debug logging.

clearTemplateCache ( )

clear the templateCache

contextMatchesOptions ( context, match_options, positive )

Matches an object of options against an EventContext like object that contains path and verb attributes. Internally Sammy uses this for matching before() filters against specific options. You can set the object to only match certain paths or verbs, or match all paths or verbs except those that match the options.

Example

       var app = $.sammy(),
           context = {verb: 'get', path: '#/mypath'};

       // match against a path string
       app.contextMatchesOptions(context, '#/mypath'); //=> true
       app.contextMatchesOptions(context, '#/otherpath'); //=> false
       // equivilent to
       app.contextMatchesOptions(context, {only: {path:'#/mypath'}}); //=> true
       app.contextMatchesOptions(context, {only: {path:'#/otherpath'}}); //=> false
       // match against a path regexp
       app.contextMatchesOptions(context, /path/); //=> true
       app.contextMatchesOptions(context, /^path/); //=> false
       // match only a verb
       app.contextMatchesOptions(context, {only: {verb:'get'}}); //=> true
       app.contextMatchesOptions(context, {only: {verb:'post'}}); //=> false
       // match all except a verb
       app.contextMatchesOptions(context, {except: {verb:'post'}}); //=> true
       app.contextMatchesOptions(context, {except: {verb:'get'}}); //=> false
       // match all except a path
       app.contextMatchesOptions(context, {except: {path:'#/otherpath'}}); //=> true
       app.contextMatchesOptions(context, {except: {path:'#/mypath'}}); //=> false
      

error ( message, original_error )

The base error handler takes a string message and an Error object. If raise_errors is set to true on the app level, this will re-throw the error to the browser. Otherwise it will send the error to log(). Override this method to provide custom error handling e.g logging to a server side component or displaying some feedback to the user.

eventNamespace ( )

A unique event namespace defined per application. All events bound with bind() are automatically bound within this space.

getLocation ( )

Delegates to the location_proxy to get the current location. See Sammy.HashLocationProxy for more info on location proxies.

helper ( name, method )

Helper extends the event context just like helpers() but does it a single method at a time. This is especially useful for dynamically named helpers

Example

       // Trivial example that adds 3 helper methods to the context dynamically
       var app = $.sammy(function(app) {

         $.each([1,2,3], function(i, num) {
           app.helper('helper' + num, function() {
             this.log("I'm helper number " + num);
           });
         });

         this.get('#/', function() {
           this.helper2(); //=> I'm helper number 2
         });
       });
      

Arguments

  • name The name of the method
  • method The function to be added to the prototype at name

helpers ( extensions )

Helpers extends the EventContext prototype specific to this app. This allows you to define app specific helper functions that can be used whenever you're inside of an event context (templates, routes, bind).

Example

      var app = $.sammy(function() {

        helpers({
          upcase: function(text) {
           return text.toString().toUpperCase();
          }
        });

        get('#/', function() { with(this) {
          // inside of this context I can use the helpers
          $('#main').html(upcase($('#main').text());
        }});

      });
      

Arguments

  • extensions An object collection of functions to extend the context.

isRunning ( )

Returns true if the current application is running.

lookupRoute ( verb, path )

Given a verb and a String path, will return either a route object or false if a matching route can be found within the current defined set.

mapRoutes ( route_array )

mapRoutes takes an array of arrays, each array being passed to route() as arguments, this allows for mass definition of routes. Another benefit is this makes it possible/easier to load routes via remote JSON.

Example

      var app = $.sammy(function() {

        this.mapRoutes([
            ['get', '#/', function() { this.log('index'); }],
            // strings in callbacks are looked up as methods on the app
            ['post', '#/create', 'addUser'],
            // No verb assumes 'any' as the verb
            [/dowhatever/, function() { this.log(this.verb, this.path)}];
          ]);
      })
      

notFound ( verb, path )

This thows a '404 Not Found' error by invoking error(). Override this method or error() to provide custom 404 behavior (i.e redirecting to / or showing a warning)

refresh ( )

Reruns the current route

routablePath ( path )

Returns a copy of the given path with any query string after the hash removed.

route ( verb, path, callback )

route() is the main method for defining routes within an application. For great detail on routes, check out: http://code.quirkey.com/sammy/doc/routes.html

This method also has aliases for each of the different verbs (eg. get(), post(), etc.)

Arguments

  • verb A String in the set of ROUTE_VERBS or 'any'. 'any' will add routes for each of the ROUTE_VERBS. If only two arguments are passed, the first argument is the path, the second is the callback and the verb is assumed to be 'any'.
  • path A Regexp or a String representing the path to match to invoke this verb.
  • callback A Function that is called/evaluated whent the route is run see: runRoute(). It is also possible to pass a string as the callback, which is looked up as the name of a method on the application.

run ( start_url )

Actually starts the application's lifecycle. run() should be invoked within a document.ready block to ensure the DOM exists before binding events, etc.

Example

      var app = $.sammy(function() { ... }); // your application
      $(function() { // document.ready
          app.run();
       });
      

Arguments

  • start_url Optionally, a String can be passed which the App will redirect to after the events/routes have been bound.

runRoute ( verb, path, params, target )

First, invokes lookupRoute() and if a route is found, parses the possible URL params and then invokes the route's callback within a new Sammy.EventContext. If the route can not be found, it calls notFound(). If raise_errors is set to true and the error() has not been overriden, it will throw an actual JS error.

You probably will never have to call this directly.

Arguments

  • verb A String for the verb.
  • path A String path to lookup.
  • params An Object of Params pulled from the URI or passed directly.

Returns

Either returns the value returned by the route callback or raises a 404 Not Found error.

setLocation ( new_location )

Delegates to the location_proxy to set the current location. See Sammy.HashLocationProxy for more info on location proxies.

Arguments

  • new_location A new location string (e.g. '#/')

setLocationProxy ( new_proxy )

Sets the location proxy for the current app. By default this is set to a new Sammy.HashLocationProxy on initialization. However, you can set the location_proxy inside you're app function to give your app a custom location mechanism. See Sammy.HashLocationProxy and Sammy.DataLocationProxy for examples.

setLocationProxy() takes an initialized location proxy.

Example

          // to bind to data instead of the default hash;
          var app = $.sammy(function() {
            this.setLocationProxy(new Sammy.DataLocationProxy(this));
          });
      

swap ( content )

Swaps the content of $element() with content You can override this method to provide an alternate swap behavior for EventContext.partial().

Example

      var app = $.sammy(function() {

        // implements a 'fade out'/'fade in'
        this.swap = function(content) {
          this.$element().hide('slow').html(content).show('slow');
        }

        get('#/', function() {
          this.partial('index.html.erb') // will fade out and in
        });

      });
      

templateCache ( key, value )

a simple global cache for templates. Uses the same semantics as Sammy.Cache and Sammy.Storage so can easily be replaced with a persistant storage that lasts beyond the current request.

toString ( )

//=> Sammy.Application: body

trigger ( name, data )

Triggers custom events defined with bind()

Arguments

  • name The name of the event. Automatically prefixed with the eventNamespace()
  • data An optional Object that can be passed to the bound callback.
  • context An optional context/Object in which to execute the bound callback. If no context is supplied a the context is a new Sammy.EventContext

unload ( )

The opposite of run(), un-binds all event listeners and intervals run() Automaticaly binds a onunload event to run this when the document is closed.

use ( )

use() is the entry point for including Sammy plugins. The first argument to use should be a function() that is evaluated in the context of the current application, just like the app_function argument to the Sammy.Application constructor.

Any additional arguments are passed to the app function sequentially.

For much more detail about plugins, check out: http://code.quirkey.com/sammy/doc/plugins.html

Example

        var MyPlugin = function(app, prepend) {

          this.helpers({
            myhelper: function(text) {
              alert(prepend + " " + text);
            }
          });

        };

        var app = $.sammy(function() {

          this.use(MyPlugin, 'This is my plugin');

          this.get('#/', function() {
            this.myhelper('and dont you forget it!');
            //=> Alerts: This is my plugin and dont you forget it!
          });

        });
      

If plugin is passed as a string it assumes your are trying to load Sammy."Plugin". This is the prefered way of loading core Sammy plugins as it allows for better error-messaging.

Example

        $.sammy(function() {
          this.use('Mustache'); //=> Sammy.Mustache
          this.use('Storage'); //=> Sammy.Storage
        });
      

Sammy.Cache ( app, options )

Sammy.Cache provides helpers for caching data within the lifecycle of a Sammy app. The plugin provides two main methods on Sammy.Application, cache and clearCache. Each app has its own cache store so that you dont have to worry about collisions. As of 0.5 the original Sammy.Cache module has been deprecated in favor of this one based on Sammy.Storage. The exposed API is almost identical, but Sammy.Storage provides additional backends including HTML5 Storage. Sammy.Cache will try to use these backends when available (in this order) LocalStorage, SessionStorage, and Memory

Sammy.DataLocationProxy ( app, data_name, href_attribute )

The DataLocationProxy is an optional location proxy prototype. As opposed to the HashLocationProxy it gets its location from a jQuery.data attribute tied to the application's element. You can set the name of the attribute by passing a string as the second argument to the constructor. The default attribute name is 'sammy-location'. To read more about location proxies, check out the documentation for Sammy.HashLocationProxy

An optional href_attribute can be passed, which specifies a DOM element attribute that holds "links" to different locations in the app. When the proxy is bound, clicks to element that have this attribute activate a setLocation() using the contents of the href_attribute.

Example

      var app = $.sammy(function() {
        // set up the location proxy
        this.setLocationProxy(new Sammy.DataLocationProxy(this, 'location', 'rel'));

        this.get('about', function() {
          this.partial('about.html');
        });

      });
    

In this scenario, if an element existed within the template:

      <a href="/about" rel="about">About Us</a>
    

Clicking on that link would not go to /about, but would set the apps location to 'about' and trigger the route.

Sammy.EventContext ( app, verb, path, params, target )

Sammy.EventContext objects are created every time a route is run or a bound event is triggered. The callbacks for these events are evaluated within a Sammy.EventContext This within these callbacks the special methods of EventContext are available.

Example

$.sammy(function() {

    // The context here is this Sammy.Application
    this.get('#/:name', function() {
      // The context here is a new Sammy.EventContext
      if (this.params['name'] == 'sammy') {
        this.partial('name.html.erb', {name: 'Sammy'});
      } else {
        this.redirect('#/somewhere-else')
      }
    });
    

});

Initialize a new EventContext

Arguments

  • app The Sammy.Application this event is called within.
  • verb The verb invoked to run this context/route.
  • path The string path invoked to run this context/route.
  • params An Object of optional params to pass to the context. Is converted to a Sammy.Object.
  • target a DOM element that the event that holds this context originates from. For post, put and del routes, this is the form element that triggered the route.

Methods


$element ( )

A shortcut to the app's $element()

engineFor ( engine )

Look up a templating engine within the current app and context. engine can be one of the following:

  • a function: should conform to function(content, data) { return interploated; }
  • a template path: 'template.ejs', looks up the extension to match to the ejs() helper
  • a string referering to the helper: "mustache" => mustache()

If no engine is found, use the app's default template_engine

eventNamespace ( )

A shortcut to app's eventNamespace()

interpolate ( content, data, engine )

using the template engine found with engineFor(), interpolate the data into content

json ( string )

Default JSON parsing uses jQuery's parseJSON(). Include Sammy.JSON plugin for the more conformant "crockford special".

load ( location, options, callback )

create a new Sammy.RenderContext calling load() with location and options. Called without interpolation or placement, this allows for preloading/caching the templates.

notFound ( )

Raises a possible notFound() error for the current path.

partial ( location, data )

render() the the location with data and then swap() the app's $element with the rendered content.

redirect ( )

Changes the location of the current window. If to begins with '#' it only changes the document's hash. If passed more than 1 argument redirect will join them together with forward slashes.

Example

        redirect('#/other/route');
        // equivilent to
        redirect('#', 'other', 'route');
      

render ( location, data, callback )

Create and return a Sammy.RenderContext calling render() on it. Loads the template and interpolate the data, however does not actual place it in the DOM.

Example

        // mytemplate.mustache <div class="name"></div>
        render('mytemplate.mustache', {name: 'quirkey'});
        // sets the `content` to <div class="name">quirkey</div>
        render('mytemplate.mustache', {name: 'quirkey'})
          .appendTo('ul');
        // appends the rendered content to $('ul')
      

renderEach ( location, name, data, callback )

Create and return a Sammy.RenderContext calling renderEach() on it. Loads the template and interpolates the data for each item, however does not actual place it in the DOM.

Example

        // mytemplate.mustache <div class="name"></div>
        renderEach('mytemplate.mustache', [{name: 'quirkey'}, {name: 'endor'}])
        // sets the `content` to <div class="name">quirkey</div><div class="name">endor</div>
        renderEach('mytemplate.mustache', [{name: 'quirkey'}, {name: 'endor'}]).appendTo('ul');
        // appends the rendered content to $('ul')
      

send ( )

create a new Sammy.RenderContext calling send() with an arbitrary function

swap ( contents )

A shortcut to app's swap()

toString ( )

//=> Sammy.EventContext: get #/ {}

trigger ( name, data )

Triggers events on app within the current context.

Sammy.Form ( app )

Sammy.Form is a Sammy plugin that adds form building helpers to a Sammy.Application

Attributes


simple_element = simple_element

simple_element is a simple helper for creating HTML tags.

Arguments

  • tag the HTML tag to generate e.g. input, p, etc/
  • attributes an object representing the attributes of the element as key value pairs. e.g. {class: 'element-class'}
  • content an optional string representing the content for the the element. If ommited, the element becomes self closing

Methods


formFor ( name, object, content_callback )

formFor creates a Sammy.Form builder object with the passed name and object and passes it as an argument to the content_callback. This is a shortcut for creating FormBuilder objects for use within templates.

Example

        // in item_form.template

        <% formFor('item', item, function(f) { %>
          <%= f.open({action: '#/items'}) %>
          <p>
            <%= f.label('name') %>
            <%= f.text('name') %>
          </p>
          <p>
            <%= f.submit() %>
          </p>
          <%= f.close() %>
        <% }); %>
      

Sammy.FormBuilder ( name, object )

Sammy.FormBuilder is based very closely on the Rails FormBuilder classes. Its goal is to make it easy to create HTML forms for creating and editing JavaScript objects. It eases the process by auto-populating existing values into form inputs and creating input names suitable for parsing by Sammy.NestedParams and other backend frameworks.

You initialize a Sammy.FormBuilder by passing the 'name' of the object and the object itself. Once initialized you create form elements with the object's prototype methods. Each of these methods returns a string of HTML suitable for appending through a template or directly with jQuery.

Example

      var item = {
        name: 'My Item',
        price: '$25.50',
        meta: {
          id: '123'
        }
      };
      var form = new Sammy.FormBuilder('item', item);
      form.text('name');
      //=> <input type='text' name='item[form]' value='My Item' />
    

Nested attributes can be accessed/referred to by a 'keypath' which is basically a string representation of the dot notation.

      form.hidden('meta.id');
      //=> <input type='hidden' name='item[meta][id]' value='123' />
    

Methods


checkbox ( keypath, value, attributes )

creates a checkbox input for keypath with the value value. Multiple checkboxes can be created with different value, if value equals the current value of the key of the form builder's object the attribute checked='checked' will be added.

By default checkbox() also generates a hidden element whose value is the inverse of the value given. This is known hack to get around a common gotcha where browsers and jQuery itself does not include 'unchecked' elements in the list of submittable inputs. This ensures that a value should always be passed to Sammy and hence the server. You can disable the creation of the hidden element by setting the hidden_element attribute to false

close ( )

closes the form

hidden ( keypath, attributes )

creates a hidden input for keypath with an optional attributes object

label ( keypath, content, attributes )

creates a label for keypath with the text content with an optionalattributes` object

open ( attributes )

creates the open form tag with the object attributes

password ( keypath, attributes )

creates a password input for keypath with an optional attributes object

radio ( keypath, value, attributes )

creates a radio input for keypath with the value value. Multiple radios can be created with different value, if value equals the current value of the key of the form builder's object the attribute checked='checked' will be added.

select ( keypath, options, attributes )

creates a select element for keypath with the option elements specified by an array in options. If options is an array of arrays, the first element in each subarray becomes the text of the option and the second becomes the value.

Example

       var options = [
         ['Small', 's'],
         ['Medium', 'm'],
         ['Large', 'l']
       ];
       form.select('size', options);
       //=> <select name='item[size]'><option value='s'>Small</option> ...
      

submit ( attributes )

creates a submit input for keypath with an optional attributes object

text ( keypath, attributes )

creates a text input for keypath with an optional attributes object

textarea ( keypath, attributes )

creates a textarea for keypath with an optional attributes object

Sammy.GoogleAnalytics ( app, tracker )

A simple plugin that pings Google Analytics tracker every time a route is triggered. Originally by Brit Gardner (britg), with updates from Aaron Quint (quirkey).

=== Arguments

+tracker+:: the Google Analytics pageTracker object. Defaults to the default object defined by the GA snippet, or pass your own if you have a custom install

=== Example

Install Google Analytics to your site as you normally would. Be sure that the 'pageTracker' global variable exists.

Then, simply add the plugin to your Sammy App and it will automatically track all of your routes in Google Analytics. They will appear as page views to the route's path.

      $.sammy(function() {
        this.use('GoogleAnalytics');

        ...
      });
    

If you have routes that you do not want to track, simply call noTrack within the route.

      $.sammy(function() {
        this.use('GoogleAnalytics')

        get('#/dont/track/me', function() {
          this.noTrack();  // This route will not be tracked
        });
      });
    

Methods


noTrack ( )

Disable tracking for the current route. Put at the begining of the route's callback

track ( path )

send a page view to the tracker with path

Sammy.Haml ( app, method_alias )

Sammy.Haml provides a quick way of using haml style templates in your app. The plugin itself includes the haml-js library created by Tim Caswell at at http://github.com/creationix/haml-js

Haml is an alternative HTML syntax that is really great for describing the structure of HTML documents.

By default using Sammy.Haml in your app adds the haml() method to the EventContext prototype. However, just like Sammy.Template you can change the default name of the method by passing a second argument (e.g. you could use the hml() as the method alias so that all the template files could be in the form file.hml instead of file.haml)

Example

The template (mytemplate.haml):

       %h1&= title

       Hey, #{name}! Welcome to Haml!
    

The app:

       var $.app = $.sammy(function() {
         // include the plugin
         this.use(Sammy.Haml);

         this.get('#/hello/:name', function() {
           // set local vars
           this.title = 'Hello!'
           this.name = this.params.name;
           // render the template and pass it through haml
           this.partial('mytemplate.haml');
         });

       });
    

If I go to #/hello/AQ in the browser, Sammy will render this to the body:

       <h1>Hello!</h1>

       Hey, AQ! Welcome to HAML!
    

Note: You dont have to include the haml.js file on top of the plugin as the plugin includes the full source.

Attributes


pathPatterns = {}

spot to memoize paths to speed up loops and subsequent parses

Methods


filterOutput ( value, escape )

Escapes output and converts empty values to empty strings

parsePath ( path )

returns a two element array containing the numbers of contexts to back up the stack and the properties to dig into on the current context

for example, if the path is "../../alan/name", the result will be [2, ["alan", "name"]].

Sammy.Handlebars ( app, method_alias )

Sammy.Handlebars provides a quick way of using Handlebars templates in your app. The plugin itself includes the handlebars.js library created by Yehuda Katz at at http://github.com/wycats/handlebars.js

Handlebars.js is an extension to the Mustache templating language created by Chris Wanstrath. Handlebars.js and Mustache are both logicless templating languages that keep the view and the code separated like we all know they should be.

By default using Sammy.Handlbars in your app adds the handlebars() method to the EventContext prototype. However, just like Sammy.Template you can change the default name of the method by passing a second argument (e.g. you could use the hbr() as the method alias so that all the template files could be in the form file.hbr instead of file.handlebars)

Example #1

The template (mytemplate.hb):

       <h1>\{\{title\}\}<h1>

       Hey, ! Welcome to Handlebars!
    

The app:

       var $.app = $.sammy(function() {
         // include the plugin and alias handlebars() to hb()
         this.use(Sammy.Handlebars, 'hb');

         this.get('#/hello/:name', function() {
           // set local vars
           this.title = 'Hello!'
           this.name = this.params.name;
           // render the template and pass it through handlebars
           this.partial('mytemplate.hb');
         });

       });
    

If I go to #/hello/AQ in the browser, Sammy will render this to the body:

       <h1>Hello!</h1>

       Hey, AQ! Welcome to Handlebars!
    

Example #2 - Handlebars partials

The template (mytemplate.hb)

       Hey, ! 
    

The partial (mypartial.hb)

       Say hello to your friend !
    

The app:

       var $.app = $.sammy(function() {
         // include the plugin and alias handlebars() to hb()
         this.use(Sammy.Handlebars, 'hb');

         this.get('#/hello/:name/to/:friend', function() {
           var context = this;

           // fetch handlebars-partial first
           $.get('mypartial.hb', function(response){
             context.partials = response;

             // set local vars
             context.name = this.params.name;
             context.hello_friend = {name: this.params.friend};

             // render the template and pass it through handlebars
             context.partial('mytemplate.hb');
           });
         });

       });
    

If I go to #/hello/AQ/to/dP in the browser, Sammy will render this to the body:

       Hey, AQ! Say hello to your friend dP!
    

Note: You dont have to include the handlebars.js file on top of the plugin as the plugin includes the full source.

Sammy.HashLocationProxy ( app, run_interval_every )

The HashLocationProxy is the default location proxy for all Sammy applications. A location proxy is a prototype that conforms to a simple interface. The purpose of a location proxy is to notify the Sammy.Application its bound to when the location or 'external state' changes. The HashLocationProxy considers the state to be changed when the 'hash' (window.location.hash / '#') changes. It does this in two different ways depending on what browser you are using. The newest browsers (IE, Safari > 4, FF >= 3.6) support a 'onhashchange' DOM event, thats fired whenever the location.hash changes. In this situation the HashLocationProxy just binds to this event and delegates it to the application. In the case of older browsers a poller is set up to track changes to the hash. Unlike Sammy 0.3 or earlier, the HashLocationProxy allows the poller to be a global object, eliminating the need for multiple pollers even when thier are multiple apps on the page.

Methods


bind ( )

bind the proxy events to the current app.

getLocation ( )

get the current location from the hash.

setLocation ( new_location )

set the current location to new_location

unbind ( )

unbind the proxy events from the current app

Sammy.JSON ( app )

Sammy.JSON is a simple wrapper around Douglas Crockford's ever-useful json2.js (http://www.json.org/js.html]) Sammy.JSON includes the top level JSON object if it doesn't already exist (a.k.a. does not override the native implementation that some browsers include). It also adds a json() helper to a Sammy app when included.

Methods


json ( object )

json is a polymorphic function that translates objects aback and forth from JSON to JS. If given a string, it will parse into JS, if given a JS object it will stringify into JSON.

Example

        var app = $.sammy(function() {
          this.use(Sammy.JSON);

          this.get('#/', function() {
            this.json({user_id: 123}); //=> "{\"user_id\":\"123\"}"
            this.json("{\"user_id\":\"123\"}"); //=> [object Object]
            this.json("{\"user_id\":\"123\"}").user_id; //=> "123"
          });
        })
      

Sammy.Meld ( app, method_alias )

Sammy.Meld is a simple templating engine that uses the power of jQuery's DOM manipulation to easily meld JSON data and HTML templates very quickly.

The template can either be a string (i.e. loaded from a remote template) or a DOM Element/jQuery object. This allows you to have templates be DOM elements as the initial document load.

Example

The simplest case is a nested <div> whose class name is tied to a property of a JS object.

Template:

        &lt;div class="post"&gt;
          &lt;div class="title"&gt;&lt;/div&gt;
          &lt;div class="entry"&gt;&lt;/div&gt;
          &lt;div class="author"&gt;
            &lt;span class="name"&gt;&lt;/span&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    

Data:

        {
          "post": {
            "title": "My Post",
            "entry": "My Entry",
            "author": {
              "name": "@aq"
            }
          }
        }
    

Result:

        &lt;div class="post"&gt;
          &lt;div class="title"&gt;My Post&lt;/div&gt;
          &lt;div class="entry"&gt;My Entry&lt;/div&gt;
          &lt;div class="author"&gt;
            &lt;span class="name"&gt;@aq&lt;/span&gt;
          &lt;/div&gt;
        &lt;/div&gt;
    

Templates can be much more complex, and more deeply nested. More examples can be found in test/fixtures/meld/

If you don't think the lookup by classes is semantic for you, you can easily switch the method of lookup by defining a selector function in the options

For example:

      meld($('.post'), post_data, {
        selector: function(k) {
          return '[data-key=' + k + ']';
        }
      });
    

Would look for template nodes like <div data-key='entry'>

Methods


create_context ( _context )

by @langalex, support for arrays of strings

Sammy.Mustache ( app, method_alias )

Sammy.Mustache provides a quick way of using mustache style templates in your app. The plugin itself includes the awesome mustache.js lib created and maintained by Jan Lehnardt at http://github.com/janl/mustache.js

Mustache is a clever templating system that relys on double brackets for interpolation. For full details on syntax check out the original Ruby implementation created by Chris Wanstrath at http://github.com/defunkt/mustache

By default using Sammy.Mustache in your app adds the mustache() method to the EventContext prototype. However, just like Sammy.Template you can change the default name of the method by passing a second argument (e.g. you could use the ms() as the method alias so that all the template files could be in the form file.ms instead of file.mustache)

Example #1

The template (mytemplate.ms):

       &lt;h1&gt;\{\{title\}\}&lt;h1&gt;

       Hey, ! Welcome to Mustache!
    

The app:

       var $.app = $.sammy(function() {
         // include the plugin and alias mustache() to ms()
         this.use(Sammy.Mustache, 'ms');

         this.get('#/hello/:name', function() {
           // set local vars
           this.title = 'Hello!'
           this.name = this.params.name;
           // render the template and pass it through mustache
           this.partial('mytemplate.ms');
         });

       });
    

If I go to #/hello/AQ in the browser, Sammy will render this to the body:

       &lt;h1&gt;Hello!&lt;/h1&gt;

       Hey, AQ! Welcome to Mustache!
    

Example #2 - Mustache partials

The template (mytemplate.ms)

       Hey, ! 
    

The partial (mypartial.ms)

       Say hello to your friend !
    

The app:

       var $.app = $.sammy(function() {
         // include the plugin and alias mustache() to ms()
         this.use(Sammy.Mustache, 'ms');

         this.get('#/hello/:name/to/:friend', function() {
           var context = this;

           // fetch mustache-partial first
           $.get('mypartial.ms', function(response){
             context.partials = response;

             // set local vars
             context.name = this.params.name;
             context.hello_friend = {name: this.params.friend};

             // render the template and pass it through mustache
             context.partial('mytemplate.ms');
           });
         });

       });
    

If I go to #/hello/AQ/to/dP in the browser, Sammy will render this to the body:

       Hey, AQ! Say hello to your friend dP!
    

Note: You dont have to include the mustache.js file on top of the plugin as the plugin includes the full source.

Sammy.NestedParams ( app )

Sammy.NestedParams overrides the default form parsing behavior to provide extended functionality for parsing Rack/Rails style form name/value pairs into JS Objects. In fact it passes the same suite of tests as Rack's nested query parsing. The code and tests were ported to JavaScript/Sammy by http://github.com/endor

This allows you to translate a form with properly named inputs into a JSON object.

Example

Given an HTML form like so:

     &lt;form action="#/parse_me" method="post"&gt;
       &lt;input type="text" name="obj[first]" /&gt;
       &lt;input type="text" name="obj[second]" /&gt;
       &lt;input type="text" name="obj[hash][first]" /&gt;
       &lt;input type="text" name="obj[hash][second]" /&gt;
     &lt;/form&gt;
    

And a Sammy app like:

     var app = $.sammy(function(app) {
       this.use(Sammy.NestedParams);

       this.post('#/parse_me', function(context) {
         $.log(this.params);
       });
     });
    

If you filled out the form with some values and submitted it, you would see something like this in your log:

     {
       'obj': {
         'first': 'value',
         'second': 'value',
         'hash': {
           'first': 'value',
           'second': 'value'
         }
       }
     }
    

It supports creating arrays with [] and other niceities. Check out the tests for full specs.

Sammy.Object ( obj )

Sammy.Object is the base for all other Sammy classes. It provides some useful functionality, including cloning, iterating, etc.

Attributes


escapeHTML = _escapeHTML

Escape HTML in string, use in templates to prevent script injection. Also aliased as h()

Methods


has ( key )

Checks if the object has a value at key and that the value is not empty

join ( )

convenience method to join as many arguments as you want by the first argument - useful for making paths

keys ( attributes_only )

Returns an array of keys for this object. If attributes_only is true will not return keys that map to a function()

log ( )

Shortcut to Sammy.log

toHTML ( )

Renders a simple HTML version of this Objects attributes. Does not render functions. For example. Given this Sammy.Object:

      var s = new Sammy.Object({first_name: 'Sammy', last_name: 'Davis Jr.'});
      s.toHTML() //=&gt; '&lt;strong&gt;first_name&lt;/strong&gt; Sammy&lt;br /&gt;&lt;strong&gt;last_name&lt;/strong&gt; Davis Jr.&lt;br /&gt;'
      

toHash ( )

Returns a copy of the object with Functions removed.

toString ( include_functions )

Returns a string representation of this object. if include_functions is true, it will also toString() the methods of this object. By default only prints the attributes.

Sammy.PathLocationProxy ( app )

Sammy.PathLocationProxy is a simple Location Proxy that just gets and sets window.location. This allows you to use Sammy to route on the full URL path instead of just the hash. It will take a full refresh to get the app to change state.

To read more about location proxies, check out the documentation for Sammy.HashLocationProxy

Sammy.Pure ( app, method_alias )

Sammy.Pure is a simple wrapper around the pure.js templating engine for use in Sammy apps.

See http://beebole.com/pure/ for detailed documentation.

Sammy.RenderContext ( event_context )

Sammy.RenderContext is an object that makes sequential template loading, rendering and interpolation seamless even when dealing with asyncronous operations.

RenderContext objects are not usually created directly, rather they are instatiated from an Sammy.EventContext by using render(), load() or partial() which all return RenderContext objects.

RenderContext methods always returns a modified RenderContext for chaining (like jQuery itself).

The core magic is in the then() method which puts the callback passed as an argument into a queue to be executed once the previous callback is complete. All the methods of RenderContext are wrapped in then() which allows you to queue up methods by chaining, but maintaing a guarunteed execution order even with remote calls to fetch templates.

Methods


appendTo ( selector )

Same usage as jQuery.fn.appendTo() but uses then() to ensure order

collect ( array, callback, now )

itterates over an array, applying the callback for each item item. the callback takes the same style of arguments as jQuery.each() (index, item). The return value of each callback is collected as a single string and stored as content to be used in the next iteration of the RenderContext.

interpolate ( data, engine, retain )

uses the previous loaded content and the data object to interpolate a template. engine defines the templating/interpolation method/engine that should be used. If engine is not passed, the next_engine is used. If retain is true, the final interpolated data is appended to the previous_content instead of just replacing it.

load ( location, options, callback )

Load a template into the context. The location can either be a string specifiying the remote path to the file, a jQuery object, or a DOM element.

No interpolation happens by default, the content is stored in content.

In the case of a path, unless the option {cache: false} is passed the data is stored in the app's templateCache().

If a jQuery or DOM object is passed the innerHTML of the node is pulled in. This is useful for nesting templates as part of the initial page load wrapped in invisible elements or <script> tags. With template paths, the template engine is looked up by the extension. For DOM/jQuery embedded templates, this isnt possible, so there are a couple of options:

  • pass an {engine:} option.
  • define the engine in the data-engine attribute of the passed node.
  • just store the raw template data and use interpolate() manually

If a callback is passed it is executed after the template load.

next ( content )

Resume the queue, setting content to be used in the next operation. See wait() for an example.

partial ( location, data )

render() the the location with data and then swap() the app's $element with the rendered content.

prependTo ( selector )

Same usage as jQuery.fn.prependTo() but uses then() to ensure order

render ( location, data, callback )

load() a template and then interpolate() it with data.

Example

        this.get('#/', function() {
          this.render('mytemplate.template', {name: 'test'});
        });
      

renderEach ( location, name, data, callback )

loads a template, and then interpolates it for each item in the data array. If a callback is passed, it will call the callback with each item in the array after interpolation

replace ( selector )

Replaces the $(selector) using html() with the previously loaded content

send ( )

defers the call of function to occur in order of the render queue. The function can accept any number of arguments as long as the last argument is a callback function. This is useful for putting arbitrary asynchronous functions into the queue. The content passed to the callback is passed as content to the next item in the queue.

=== Example

          this.send($.getJSON, '/app.json')
              .then(function(json) {
                $('#message).text(json['message']);
              });
      

swap ( )

executes EventContext#swap() with the content

then ( callback )

The "core" of the RenderContext object, adds the callback to the queue. If the context is waiting (meaning an async operation is happening) then the callback will be executed in order, once the other operations are complete. If there is no currently executing operation, the callback is executed immediately.

The value returned from the callback is stored in content for the subsiquent operation. If you return false, the queue will pause, and the next callback in the queue will not be executed until next() is called. This allows for the guarunteed order of execution while working with async operations.

If then() is passed a string instead of a function, the string is looked up as a helper method on the event context.

Example

        this.get('#/', function() {
          // initialize the RenderContext
          // Even though `load()` executes async, the next `then()`
          // wont execute until the load finishes
          this.load('myfile.txt')
              .then(function(content) {
                // the first argument to then is the content of the
                // prev operation
                $('#main').html(content);
              });
        });
      

trigger ( name, data )

trigger the event in the order of the event context. Same semantics as Sammy.EventContext#trigger(). If data is ommitted, content is sent as {content: content}

wait ( )

Pause the RenderContext queue. Combined with next() allows for async operations.

Example

          this.get('#/', function() {
            this.load('mytext.json')
                .then(function(content) {
                  var context = this,
                      data    = JSON.parse(content);
                  // pause execution
                  context.wait();
                  // post to a url
                  $.post(data.url, {}, function(response) {
                    context.next(JSON.parse(response));
                  });
                })
                .then(function(data) {
                  // data is json from the previous post
                  $('#message').text(data.status);
                });
          });
      

Sammy.Session ( app, options )

Sammy.Session is an additional plugin for creating a common 'session' store for the given app. It is a very simple wrapper around Sammy.Storage that provides a simple fallback mechanism for trying to provide the best possible storage type for the session. This means, LocalStorage if available, otherwise Cookie, otherwise Memory. It provides the session() helper through Sammy.Storage#store().

See the Sammy.Storage plugin for full documentation.

Sammy.Storage ( app )

Sammy.Storage is a plugin that provides shortcuts for creating and using Sammy.Store objects. Once included it provides the store() app level and helper methods. Depends on Sammy.JSON (or json2.js).

Sammy.Store ( options )

Sammy.Store is an abstract adapter class that wraps the multitude of in browser data storage into a single common set of methods for storing and retreiving data. The JSON library is used (through the inclusion of the Sammy.JSON) plugin, to automatically convert objects back and forth from stored strings.

Sammy.Store can be used directly, but within a Sammy.Application it is much easier to use the Sammy.Storage plugin and its helper methods.

Sammy.Store also supports the KVO pattern, by firing DOM/jQuery Events when a key is set.

Example

      // create a new store named 'mystore', tied to the #main element, using HTML5 localStorage
      // Note: localStorage only works on browsers that support it
      var store = new Sammy.Store({name: 'mystore', element: '#element', type: 'local'});
      store.set('foo', 'bar');
      store.get('foo'); //=&gt; 'bar'
      store.set('json', {obj: 'this is an obj'});
      store.get('json'); //=&gt; {obj: 'this is an obj'}
      store.keys(); //=&gt; ['foo','json']
      store.clear('foo');
      store.keys(); //=&gt; ['json']
      store.clearAll();
      store.keys(); //=&gt; []
    

Arguments

The constructor takes a single argument which is a Object containing these possible options.

  • name The name/namespace of this store. Stores are unique by name/type. (default 'store')
  • element A selector for the element that the store is bound to. (default 'body')
  • type The type of storage/proxy to use (default 'memory')

Extra options are passed to the storage constructor. Sammy.Store supports the following methods of storage:

  • memory Basic object storage
  • data jQuery.data DOM Storage
  • cookie Access to document.cookie. Limited to 2K
  • local HTML5 DOM localStorage, browswer support is currently limited.
  • session HTML5 DOM sessionStorage, browswer support is currently limited.

Methods


clear ( key )

Removes the value at key from the current store

clearAll ( )

Clears all the values for the current store.

each ( callback )

Iterates over each key value pair passing them to the callback function

Example

        store.each(function(key, value) {
          Sammy.log('key', key, 'value', value);
        });
      

exists ( key )

Checks for the existance of key in the current store. Returns a boolean.

fetch ( key, callback )

Returns the value at key if set, otherwise, runs the callback and sets the value to the value returned in the callback.

Example

      var store = new Sammy.Store;
      store.exists('foo'); //=&gt; false
      store.fetch('foo', function() {
        return 'bar!';
      }); //=&gt; 'bar!'
      store.get('foo') //=&gt; 'bar!'
      store.fetch('foo', function() {
        return 'baz!';
      }); //=&gt; 'bar!
      

filter ( callback )

Filters the store by a filter function that takes a key value. Returns an array of arrays where the first element of each array is the key and the second is the value of that key.

Example

        var store = new Sammy.Store;
        store.set('one', 'two');
        store.set('two', 'three');
        store.set('1', 'two');
        var returned = store.filter(function(key, value) {
          // only return
          return value === 'two';
        });
        // returned =&gt; [['one', 'two'], ['1', 'two']];
      

first ( callback )

Works exactly like filter except only returns the first matching key value pair instead of all of them

get ( key )

Returns the set value at key, parsing with JSON.parse and turning into an object if possible

isAvailable ( )

Checks for the availability of the current storage type in the current browser/config.

keys ( )

Returns the all the keys set for the current store as an array. Internally Sammy.Store keeps this array in a 'meta_key' for easy access.

load ( key, path, callback )

loads the response of a request to path into key.

Example

In /mytemplate.tpl:

      My Template
      

In app.js:

      var store = new Sammy.Store;
      store.load('mytemplate', '/mytemplate.tpl', function() {
        s.get('mytemplate') //=&gt; My Template
      });
      

set ( key, value )

Sets the value of key with value. If value is an object, it is turned to and stored as a string with JSON.stringify. It also tries to conform to the KVO pattern triggering jQuery events on the element that the store is bound to.

Example

        var store = new Sammy.Store({name: 'kvo'});
        $('body').bind('set-kvo-foo', function(e, data) {
          Sammy.log(data.key + ' changed to ' + data.value);
        });
        store.set('foo', 'bar'); // logged: foo changed to bar
      

Sammy.Store.Cookie ( name, element, options )

.Cookie ('cookie') storage uses browser cookies to store data. JavaScript has access to a single document.cookie variable, which is limited to 2Kb in size. Cookies are also considered 'unsecure' as the data can be read easily by other sites/JS. Cookies do have the advantage, though, of being widely supported and persistent through refresh and close/open. Where available, HTML5 DOM Storage like LocalStorage and SessionStorage should be used.

.Cookie can also take additional options:

  • expires_in Number of seconds to keep the cookie alive (default 2 weeks).
  • path The path to activate the current cookie for (default '/').

For more information about document.cookie, check out the pre-eminint article by ppk: [http://www.quirksmode.org/js/cookies.html]

Sammy.Store.Data ( name, element )

Data ('data') stores objects using the jQuery.data() methods. This has the advantadge of scoping the data to the specific element. Like the 'memory' store its data will only last for the length of the current request (data is lost on refresh/etc).

Sammy.Store.LocalStorage ( name, element )

LocalStorage ('local') makes use of HTML5 DOM Storage, and the window.localStorage object. The great advantage of this method is that data will persist beyond the current request. It can be considered a pretty awesome replacement for cookies accessed via JS. The great disadvantage, though, is its only available on the latest and greatest browsers.

For more info on DOM Storage: [https://developer.mozilla.org/en/DOM/Storage] [http://www.w3.org/TR/2009/WD-webstorage-20091222/]

Sammy.Store.Memory ( name, element )

Memory ('memory') is the basic/default store. It stores data in a global JS object. Data is lost on refresh.

Sammy.Store.SessionStorage ( name, element )

.SessionStorage ('session') is similar to LocalStorage (part of the same API) and shares similar browser support/availability. The difference is that SessionStorage is only persistant through the current 'session' which is defined as the length that the current window is open. This means that data will survive refreshes but not close/open or multiple windows/tabs. For more info, check out the LocalStorage documentation and links.

Sammy.Store.isAvailable ( type )

Tests if the type of storage is available/works in the current browser/config. Especially useful for testing the availability of the awesome, but not widely supported HTML5 DOM storage

Sammy.Template ( app, method_alias )

Sammy.Template is a simple plugin that provides a way to create and render client side templates. The rendering code is based on John Resig's quick templates and Greg Borenstien's srender plugin. This is also a great template/boilerplate for Sammy plugins.

Templates use <% %> tags to denote embedded javascript.

Examples

Here is an example template (user.template):

      &lt;div class="user"&gt;
        &lt;div class="user-name"&gt;&lt;%= user.name %&gt;&lt;/div&gt;
        &lt;% if (user.photo_url) { %&gt;
          &lt;div class="photo"&gt;&lt;img src="&lt;%= user.photo_url %&gt;" /&gt;&lt;/div&gt;
        &lt;% } %&gt;
      &lt;/div&gt;
    

Given that is a publicly accesible file, you would render it like:

       $.sammy(function() {
         // include the plugin
         this.use(Sammy.Template);

         this.get('#/', function() {
           // the template is rendered in the current context.
           this.user = {name: 'Aaron Quint'};
           // partial calls template() because of the file extension
           this.partial('user.template');
         })
       });
    

You can also pass a second argument to use() that will alias the template method and therefore allow you to use a different extension for template files in partial()

      // alias to 'tpl'
      this.use(Sammy.Template, 'tpl');

      // now .tpl files will be run through srender
      this.get('#/', function() {
        this.partial('myfile.tpl');
      });
    

Sammy.Title ( )

Sammy.Title is a very simple plugin to easily set the document's title. It supplies a helper for setting the title (title()) within routes, and an app level method for setting the global title (setTitle())

Attributes


_default = { $1: "$data" }

Encoded expression evaluation. Abbreviated form is ${}.

Methods


complete ( items )

This stub can be overridden, e.g. in jquery.tmplPlus for providing rendered events

template ( name, tmpl )

Get: Use $.template( name ) to access a cached template. Also $( selectorToScriptBlock ).template(), or $.template( null, templateString ) will return the compiled template, without adding a name reference. If templateString includes at least one HTML tag, $.template( templateString ) is equivalent to $.template( null, templateString )

template ( name )

Consider the first wrapped element as a template declaration, and get the compiled template or store it as a named template.

tmpl ( tmpl, data, options, parentItem )

Return wrapped set of template items, obtained by rendering template against data.

tmpl ( data, options, parentItem )

Use first wrapped element as template markup. Return wrapped set of template items, obtained by rendering template against data.

tmplItem ( )

Find which rendered template item the first wrapped DOM element belongs to

tmplItem ( elem )

Return rendered template item for an element.

Sammy.addLogger ( logger )

Add to the global logger pool. Takes a function that accepts an unknown number of arguments and should print them or send them somewhere The first argument is always a timestamp.

Sammy.log ( )

Sends a log message to each logger listed in the global loggers pool. Can take any number of arguments. Also prefixes the arguments with a timestamp.