Ferris has a very simple global pubsub-style event system. Beyond the events emitted by Controllers and Views there’s also a way to globally emit and respond to events.

app/ is used to register global event listeners using on:[source]

Automatically called when the specified event occurs.

For example, to switch from the default theme:

def before_startup(controller, *args, **kwargs):
    controller.meta.view.theme = 'corny'

All controller events are prefixed with controller_ when broadcast globally.

Emitting Events

You can emit events on the global bus by using fire:, *args, **kwargs)[source]

Calls all of the registered event handlers for a given event. Passes through all arguments

For example:

def transmat(self, item):
    fire("item_transmat", item)


There are some very useful cases for using the global event bus.

Setting theme globally

As shown above this sets the theme for every controller:

def before_startup(controller, *args, **kwargs):
    controller.meta.view.theme = 'corny'

Injecting components

If you’d like every controller to contain a particular component:

def inject_components(controller, *args, **kwargs):
    if not MyComponent in controller.Meta.components:
        controller.Meta.components += (MyComponent,)

Injecting authorization chains

If you’d like every controller to have a particular authorization chain:

def inject_chains(controller, authorizations):
    if not my_chain in authorizations:

For example, if you’d like to lock down your application to a particular Google Apps domains:

def domain_chain(controller):
    user = controller.user
    if not user:
        return False, "You must be logged"

    email_domain ='@')[1]

    if not email_domain in ('', ''):
        return False, "Your domain does not have access"

    return True

def inject_authorization_chains(controller, authorizations):
    authorizations.insert(0, domain_chain)

Exposing template data

If you’d like every template to have access to some particular data:

def before_render(controller):
    controller.context['custom_data'] = something.get_data()