# Writing TurboGears Extensions

TurboGears provides a bunch of hook points and ways to extend the framework behavior to write extensions. Most of the needs can usually be satisfied by relying on `tg.configuration.AppConfig`, Configuration Milestones and Hooks.

## Creating an Extension

TurboGears extensions are identified by the `tgext.*` package name, since version 2.3.2 the devtools provide a command to quickly create a new TurboGears extension which can be both used by itself or plugged through `tgext.pluggable`.

To quickstart the extension run:

    $ gearbox tgext -n myextension -a "My Name" -e "my@email.com"

This will create a `tgext.myextension` directory which a simple sample extension inside. To tune the author, description, license of your extension have a look at the `tgext` command options using `gearbox help tgext`.

## Tuning on the Extension

If you created the `tgext.myextension` using the `tgext` command you can quickly turn it on by editing your application `config/app_cfg.py` and appending at the end the following lines:

    import tgext.myextension
    tgext.myextension.plugme(base_config)

of through the pluggable application interface if `tgext.pluggable` is available:

    from tgext.pluggable import plug
    plug(base_config, 'tgext.myextension')

By enabling the autogenerated extension and starting `gearbox serve` again, you will notice that it just provides a bunch of logging hooks and not much more:

    17:52:30,019 INFO  [tgext.myextension] Setting up tgext.myextension extension...
    17:52:30,023 INFO  [tgext.myextension] >>> Public files path is /home/USER/myapp/myapp/public
    17:52:30,023 INFO  [tgext.myextension] + Application Running!
    17:52:30,040 INFO  [gearbox] Starting server in PID 22484.
    Starting HTTP server on http://0.0.0.0:8080
    17:52:30,740 INFO  [tgext.myextension] Serving: /

## The Sample Extension

The sample extension created by the `tgext` command provides its actual setup inside the `__init__.py` file. This file showcases some of the extension points provided by TurboGears.

If you actually created `tgext.myextension` you should get a `tgext.myextension/tgext/myextension/__init__.py` file with the following content:

    from tg import config
    from tg import hooks
    from tg.configuration import milestones

    import logging
    log = logging.getLogger('tgext.myextension')

    # This is the entry point of your extension, will be called
    # both when the user plugs the extension manually or through tgext.pluggable
    # What you write here has the same effect as writing it into app_cfg.py
    # So it is possible to plug other extensions you depend on.
    def plugme(configurator, options=None):
        if options is None:
            options = {}

        log.info('Setting up tgext.myextension extension...')
        milestones.config_ready.register(SetupExtension(configurator))

        return dict(appid='tgext.myextension')

    # Most of your extension initialization should probably happen here,
    # where it's granted that .ini configuration file has already been loaded
    # in tg.config but you can still register hooks or other milestones.
    class SetupExtension(object):
        def __init__(self, configurator):
            self.configurator = configurator

        def __call__(self):
            log.info('>>> Plugin files path is %s' % config['paths']['static_files'])
            hooks.register('startup', self.on_startup)

            def echo_wrapper_factory(handler, config):
                def echo_wrapper(controller, environ, context):
                    log.info('Serving: %s' % context.request.path)
                    return handler(controller, environ, context)
                return echo_wrapper

            # Application Wrappers are much like easier WSGI Middleware
            # that get a TurboGears context and return a Response object.
            self.configurator.register_wrapper(echo_wrapper_factory)

        def on_startup(self):
            log.info('+ Application Running!')

The core parts of the previous example are:

> - plugme function, this is the function used to turn on your extension.

>     will be automatically called by `tgext.pluggable` when the extension is enabled using the pluggable application interface or by the user itself when manually enabling your extension. Inside this method the application configurator (AppConfig) object is available and the options the user specified for the extension, but not application configuration as it has not been loaded yet.

> - SetupExtension.__call__, this is a callable that is registered

>     by the plugme function for the `config_read` milestone so that it is executed when the .ini configuration has been loaded and merged with the options declared through the application configurator in config/app_cfg.py.

>     Here you can register additional milestones, functions or access and modify the application configurator through the `self.configurator` object.

> - SetupExtension.on_startup This is a sample hook registered on

>     application startup by `SetupExtension.__call__` that says hello when the application has started. Have at look at Hooks for a complete list of available hooks.

## Extensions with models and controllers

If your extension needs to expose models and controllers you probably want to have a look at Pluggable Applications which are meant to create reusable turbogears applications that can be plugged inside other applications to extend their features.

# Pluggable Applications with TurboGears

TurboGears 2.1.4 introduced support for pluggable applications using tgext.pluggable. `tgext.pluggable` is now the official supported way in TurboGears to create pluggable reusable applications. Currently only SQLAlchemy based applications are supported as pluggable applications.

Official documentation for `tgext.pluggable` can be found at: http://pypi.python.org/pypi/tgext.pluggable

## Supported Features

Pluggable applications can define their own:

> - controllers, which will be automatically mounted when the application is purged.
> - models, which will be available inside and outside of the plugged application.
> - helpers, which can be automatically exposed in `h` object in application template.
> - bootstrap, which will be executed when setup-app is called.
> - statics, which will be available at their own private path.

## Mounting a pluggable application

In your application config/app_cfg.py import `plug` from `tgext.pluggable` and call it for each pluggable application you want to enable.

The plugged package must be installed in your environment.

    from tgext.pluggable import plug
    plug(base_config, 'package_name')

## Creating Pluggable Applications

`tgext.pluggable` provides a quickstart-pluggable command to create a new pluggable applications:

    $ gearbox quickstart-pluggable plugtest
    ...

The quickstarted application will provide an example on how to use models, helpers, bootstrap, controllers and statics.