Fork me on GitHub

Getting Started

In order to use, an integration package must be created. This package contains the application code and configuration. extensions are organized as Plugins. Thus, the integration package may contain the Plugin code directly, or the Plugin is created as seperate package.

In this documentation a package named cone.example is created, which contains both the integration and plugin code.


The example package created in this documentation can be found in the Github repository.

Create Python Package

First thing to do is to create a Python Package.

Create a directory named cone.example with the following structure:

├── example.ini
└── src
    └── cone
        ├── example
        │   ├── browser
        │   │   ├──
        │   │   ├── static
        │   │   │   ├── example.css
        │   │   │   └── example.js
        │   │   └── templates
        │   │       └──
        │   ├── configure.zcml
        │   ├──
        │   └──

The package must depend on and waitress as installation dependency. Add the following to

from setuptools import find_packages
from setuptools import setup

version = '0.1'
shortdesc = 'Example cone plugin'

    package_dir={'': 'src'},

The package hooks up to the namespace package cone, so src/cone/ must contain:


Bootstrap Script

Virtualenv is used to setup the application. Add a script, which creates the isolated python environment, and installs the dependencies.

set -e

for dir in lib include local bin share; do
    if [ -d "$dir" ]; then
        rm -r "$dir"

python3 -m venv .
./bin/pip install pyramid==1.9.4
./bin/pip install repoze.zcml==1.1
./bin/pip install repoze.workflow==1.1
./bin/pip install -e .

Make this script executable.

chmod +x

Application Configuration uses PasteDeploy for application configuration. PasteDeploy defines a way to declare WSGI application configuration in an .ini file.

Create example.ini and add:

debug = true

use = egg:waitress#main
host =
port = 8081

use =

# pyramid related configuration useful for development
pyramid.reload_templates = true

pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.debug_templates = true

# default language
pyramid.default_locale_name = en

# admin user and password
cone.admin_user = admin
cone.admin_password = admin
#cone.authenticator =

# auth tkt settings
cone.auth_secret = 12345
#cone.auth_cookie_name =
#cone.auth_secure =
#cone.auth_include_ip =
#cone.auth_timeout =
#cone.auth_reissue_time =
#cone.auth_max_age =
#cone.auth_http_only =
#cone.auth_path =
#cone.auth_wild_domain =

# application main template
#cone.main_template = package.browser:templates/

# plugins to be loaded
cone.plugins = cone.example

# application root node settings
cone.root.title = cone.example
cone.root.default_child = example
#cone.root.default_content_tile =
#cone.root.mainmenu_empty_title = false

pipeline =

Details about the available dedicated configuration options can be found in the Application Configuration documentation.

ZCML Configuration

Plugins may contain a ZCML configuration which contains ZCML configuration directives. If desired, add src/cone/example/configure.zcml containing:

<?xml version="1.0" encoding="utf-8" ?>
<configure xmlns="">
  <!-- configuration directives goes here -->

Static Resources

Delivering static resources is done by registering a directory for serving the assets and telling the application which files to deliver to the browser.

Create src/cone/example/browser/static directory containing example.css and example.js.

Create a static view for the static directory in src/cone/example/browser/

from pyramid.static import static_view

static_resources = static_view('static', use_subpath=True)

Register the static view and tell the application to deliver the CSS and JS file to the browser. This is done inside the Plugin main hook function.

Add the plugin main hook function in src/cone/example/ containing.

from import main_hook
from cone.example.browser import static_resources

def example_main_hook(config, global_config, local_config):
    """Function which gets called at application startup to initialize
    this plugin.
    # register static resources view
    config.add_view(static_resources, name='example-static')

    # register static resources to be delivered'example-static/example.css')'example-static/example.js')

Application Model uses the traversal mechanism of Pyramid and utilize node package for publishing.

Publishable nodes are expected to implement A basic application node is shipped with which can be used to start implementing the application model from.

Detailed information about the application model can be found in the Application Model documentation.

Create plugin entry node in src/cone/example/

from import BaseNode

class ExamplePlugin(BaseNode):

The application needs to know about the application model entry node. This is done by registering it with register_entry inside the Plugin main hook function.

Extend the main hook function in src/cone/example/ and register the model.

from import main_hook
from import register_entry
from cone.example.model import ExamplePlugin

def example_main_hook(config, global_config, local_config):
    # register plugin entry node
    register_entry('example', ExamplePlugin)

UI Widgets follows the concept of tiles in it’s UI. Each part of the application is represented by a tile, i.e. main menu, navigation tree, site content area, etc.

The implementation and more documentation about tiles can be found here.

Detailed information about the available UI elements can be found in the UI Widgets documentation.

To render the Content Area of the UI for the ExamplePlugin node, a tile named content must be created. Add src/cone/example/browser/ and register it like so:

from import ProtectedContentTile
from cone.example.model import ExamplePlugin
from cone.tile import tile

class ExamplePluginContent(ProtectedContentTile):

Also create the corresponding page template in src/cone/example/browser/templates/ containing:

   Example app content.

Tell your plugin to scan the browser package inside the Plugin main hook function to ensure tile registration gets executed.

from import main_hook

def example_main_hook(config, global_config, local_config):
    # scan browser package

Working with JavaScript utilizes bdajax for it’s user interface. The documentation how to properly integrate custom JavaScript can be found here.


To install the application, run


Run Application

./bin/pserve serve example.ini

The application is now available at localhost:8081.