As explained in the Getting Started documentation, applications are organized by Plugins, shipping with related application Models, Tiles and Resources.
cone.app
provides a set of hooks for plugins to extend and customize the
application which are explained in the following sections.
For each plugin registered in the
Application Configuration .ini
file, a
configure.zcml
file can be provided containing ZCML directives,
e.g.
<?xml version="1.0" encoding="utf-8" ?>
<configure xmlns="http://pylonshq.com/pyramid">
<!-- directives go here -->
</configure>
ZCML Configuration of plugins are loaded after cone.app
basics are
initialized properly at application creation time.
For more Information about ZCML take a look at the ZCML Documentation and the Pyramid ZCML Integration
Plugin initialization code goes into the main hook function.
The main hook function of all plugins is executed after all ZCML files
are loaded. This happens in defined plugin registration order in application
.ini
file.
The hook gets passed the
pyramid.config.Configurator
object and the global_config
and local_config
dictionaries.
Configuration .ini
file settings are contained in local_config
. Thus
plugin related custom settings can be added to the application .ini
file
and read inside the main hook.
Following tasks shall be implemented in the main hook function:
The main hook function is normally implemented and registered in the plugin
package __init__.py
module.
from cone.app import main_hook
@main_hook
def example_main_hook(config, global_config, local_config):
"""Initialization code goes here.
"""
A plugin may provide resources like JavaScipt and CSS files, images, and so forth. Such resources are located in a seperate folder, which gets provided as pyramid static resource.
from pyramid.static import static_view
static_resources = static_view('static', use_subpath=True)
The static view gets registered in the plugin main hook.
from cone.app import main_hook
from cone.example.browser import static_resources
@main_hook
def example_main_hook(config, global_config, local_config):
# static resources
config.add_view(static_resources, name='example-static')
This configuration makes the resources available to the browser by URL, but no CSS or JS files are delivered yet on page load. CSS and JS files can be published for authenticated users only or for all users.
Resource registries are simple lists on the global application config object
cone.app.cfg
. Resources can be delivered either as is, or merged with
other resources in one file.
For delivering resources as is, register them in cone.app.cfg.css
respective cone.app.cfg.js
.
Resources which can be merged to one file are registered in
cone.app.cfg.merged.css
respective cone.app.cfg.merged.js
.
To register the resources for all users of the site, authenticated or not, add them
to the public
resources list, e.g. cone.app.cfg.css.public
. If
resources should only be delivered for authenticated users, add them to the
protected
list, e.g. cone.app.cfg.css.protected
.
Note
If you need to depend on resources delivered by another plugin make sure to
register the resources inside the main hook function and that the plugin
containing the dependencies are placed before your plugin is loaded at
cone.plugins
in the ini configuration.
If you provide a plugin which is desired to be used as dependency for other plugins this also applies.
from cone.app import main_hook
import cone.app
@main_hook
def example_main_hook(config, global_config, local_config):
# public CSS
cone.app.cfg.css.public.append('example-static/public.css')
# protected CSS
cone.app.cfg.css.protected.append('example-static/protected.css')
# public JavaScript
cone.app.cfg.js.public.append('example-static/public.js')
# protected javaScript
cone.app.cfg.js.protected.append('example-static/protected.js')
Plugin root node factories are registered to the application via
cone.app.register_entry
inside the main hook function.
from cone.app import main_hook
from cone.app import register_entry
import cone.example.model import ExamplePlugin
@main_hook
def example_main_hook(config, global_config, local_config):
# register plugin entry node
register_entry('example', ExamplePlugin)
This makes the plugin model available to the browser via traversal.
Plugin Settings are realized as well as application nodes. They are located
at app_root['settings']
and can be registered to the application via
cone.app.register_config
.
from cone.app import main_hook
from cone.app import register_config
from cone.app.model import BaseNode
class ExampleSettings(BaseNode):
"""Plugin settings are provided by this node.
"""
@main_hook
def example_main_hook(config, global_config, local_config):
register_config('example', ExampleSettings)