• Get Review Board
  • What's New
  • Products
  • Review Board Code review, image review, and document review
  • Documentation
  • Release Notes
  • Power Pack Enterprise integrations, reports, and enhanced document review
  • Try for 60 Days
  • Purchase
  • RBCommons Review Board as a Service, hosted by us
  • Pricing
  • RBTools Command line tools and Python API for Review Board
  • Documentation
  • Release Notes
  • Review Bot Automated code review, connecting tools you already use
  • Documentation
  • Release Notes
  • RB Gateway Manage Git and Mercurial repositories in your network
  • Documentation
  • Release Notes
  • Learn and Explore
  • What is Code Review?
  • Documentation
  • Frequently Asked Questions
  • Support Options
  • Third-Party Integrations
  • Demo
  • Review Board RBTools Power Pack Review Bot Djblets RB Gateway
    1. Review Board 1.7
    2. Version 7.x
    3. Version 6.x
    4. Version 5.0
    5. Version 4.0
    6. Version 3.0
    7. Version 2.5
    8. Version 2.0
    9. Version 1.7
    10. Version 1.6
    11. Version 1.5
    12. Version 1.0
    13. Writing Review Board Extensions
  • Home
  • Users Guide
  • Getting Started
  • Introduction
  • What is Code Review?
  • General Workflow
  • Account Settings
  • Dashboard
  • Searching
  • Quick Search
  • Full-Text Search
  • Working with Review Requests
  • Creating Review Requests
  • Editing Fields
  • Uploading Diffs
  • Uploading File Attachments
  • Publishing Review Requests
  • Closing Review Requests
  • Reviewing
  • Reviewing Diffs
  • Reviewing File Attachments
  • Reviewing Images
  • Issue Tracking
  • Review Draft Banner
  • Creating and Editing Reviews
  • Publishing Reviews
  • Approving Changes (Ship It!)
  • Replying to Comments
  • Tools
  • post-review
  • Administration Guide
  • Installation
  • Installing on Linux
  • Installing on Windows
  • Installing Development Releases
  • Creating a Review Board Site
  • Upgrading
  • Upgrading Review Board
  • Upgrading Sites
  • Optimization
  • General Optimization Tips
  • Optimizing Memcached
  • Optimizing MySQL
  • Administration UI
  • Overview of the Administration UI
  • Administrator Dashboard
  • Database Management
  • Configuration
  • Site Settings
  • General Settings
  • Authentication Settings
  • E-Mail Settings
  • Diff Viewer Settings
  • Logging Settings
  • SSH Settings
  • File Storage Settings
  • Access Control
  • E-Mail
  • Default Reviewers
  • Permission Groups
  • Repositories
  • Review Groups
  • Users
  • Extensions
  • Site Maintenance
  • The rb-site Tool
  • Search Indexing
  • Advanced Management Commands
  • Web API Guide
  • Overview
  • Authenticating
  • Resource Tree
  • Resources
  • Change List Resource
  • Change Resource
  • Change Resource
  • Diff List Resource
  • Diff Resource
  • File Diff List Resource
  • File Diff Resource
  • Diff Resource
  • File Diff List Resource
  • File Diff Resource
  • File Diff Comment List Resource
  • Original File Resource
  • Patched File Resource
  • Default Reviewer List Resource
  • Default Reviewer Resource
  • Default Reviewer Resource
  • Draft File Attachment List Resource
  • Draft File Attachment Resource
  • Draft File Attachment Resource
  • Draft Screenshot List Resource
  • Draft Screenshot Resource
  • Draft Screenshot Resource
  • Extension List Resource
  • Extension Resource
  • Extension Resource
  • File Attachment Comment List Resource
  • File Attachment Comment Resource
  • File Attachment List Resource
  • File Attachment Resource
  • File Attachment Comment List Resource
  • File Attachment Resource
  • File Attachment Comment List Resource
  • File Diff Comment List Resource
  • File Diff List Resource
  • File Diff Resource
  • File Diff Comment List Resource
  • Original File Resource
  • Patched File Resource
  • File Diff Resource
  • File Diff Comment List Resource
  • Original File Resource
  • Patched File Resource
  • Hosting Service Account List Resource
  • Hosting Service Account Resource
  • Hosting Service Account Resource
  • Original File Resource
  • Patched File Resource
  • Repository Info Resource
  • Repository List Resource
  • Repository Resource
  • Repository Info Resource
  • Repository Resource
  • Repository Info Resource
  • Review Diff Comment List Resource
  • Review Diff Comment Resource
  • Review Diff Comment Resource
  • Review Draft Resource
  • Review File Attachment Comment List Resource
  • Review File Attachment Comment Resource
  • Review File Attachment Comment Resource
  • Review Group List Resource
  • Review Group Resource
  • Review Group User List Resource
  • Review Group User Resource
  • Review Group Resource
  • Review Group User List Resource
  • Review Group User Resource
  • Watched List Resource
  • Review Group User List Resource
  • Review Group User Resource
  • Watched List Resource
  • Watched Review Group List Resource
  • Watched Review Request List Resource
  • Review Group User Resource
  • Watched List Resource
  • Watched Review Group List Resource
  • Watched Review Group Resource
  • Watched Review Request List Resource
  • Watched Review Request Resource
  • Review List Resource
  • Review Resource
  • Review Diff Comment List Resource
  • Review Diff Comment Resource
  • Review File Attachment Comment List Resource
  • Review File Attachment Comment Resource
  • Review Reply List Resource
  • Review Reply Resource
  • Review Reply Draft Resource
  • Review Screenshot Comment List Resource
  • Review Screenshot Comment Resource
  • Review Draft Resource
  • Review Reply Diff Comment List Resource
  • Review Reply Diff Comment Resource
  • Review Reply Diff Comment Resource
  • Review Reply Draft Resource
  • Review Reply File Attachment Comment List Resource
  • Review Reply File Attachment Comment Resource
  • Review Reply File Attachment Comment Resource
  • Review Reply List Resource
  • Review Reply Resource
  • Review Reply Diff Comment List Resource
  • Review Reply Diff Comment Resource
  • Review Reply File Attachment Comment List Resource
  • Review Reply File Attachment Comment Resource
  • Review Reply Screenshot Comment List Resource
  • Review Reply Screenshot Comment Resource
  • Review Reply Draft Resource
  • Review Reply Screenshot Comment List Resource
  • Review Reply Screenshot Comment Resource
  • Review Reply Screenshot Comment Resource
  • Review Reply Resource
  • Review Reply Diff Comment List Resource
  • Review Reply Diff Comment Resource
  • Review Reply File Attachment Comment List Resource
  • Review Reply File Attachment Comment Resource
  • Review Reply Screenshot Comment List Resource
  • Review Reply Screenshot Comment Resource
  • Review Request Draft Resource
  • Draft File Attachment List Resource
  • Draft File Attachment Resource
  • Draft Screenshot List Resource
  • Draft Screenshot Resource
  • Review Request Last Update Resource
  • Review Request List Resource
  • Review Request Resource
  • Change List Resource
  • Change Resource
  • Diff List Resource
  • Diff Resource
  • File Attachment List Resource
  • File Attachment Resource
  • Review List Resource
  • Review Resource
  • Review Draft Resource
  • Review Request Draft Resource
  • Draft File Attachment List Resource
  • Draft Screenshot List Resource
  • Review Request Last Update Resource
  • Screenshot List Resource
  • Screenshot Resource
  • Review Request Resource
  • Change List Resource
  • Change Resource
  • Diff List Resource
  • Diff Resource
  • File Diff List Resource
  • File Attachment List Resource
  • File Attachment Resource
  • File Attachment Comment List Resource
  • Review List Resource
  • Review Resource
  • Review Diff Comment List Resource
  • Review File Attachment Comment List Resource
  • Review Reply List Resource
  • Review Screenshot Comment List Resource
  • Review Draft Resource
  • Review Request Draft Resource
  • Draft File Attachment List Resource
  • Draft File Attachment Resource
  • Draft Screenshot List Resource
  • Draft Screenshot Resource
  • Review Request Last Update Resource
  • Screenshot List Resource
  • Screenshot Resource
  • Screenshot Comment List Resource
  • Review Screenshot Comment List Resource
  • Review Screenshot Comment Resource
  • Review Screenshot Comment Resource
  • Review Resource
  • Review Diff Comment List Resource
  • Review Diff Comment Resource
  • Review File Attachment Comment List Resource
  • Review File Attachment Comment Resource
  • Review Reply List Resource
  • Review Reply Resource
  • Review Reply Diff Comment List Resource
  • Review Reply File Attachment Comment List Resource
  • Review Reply Screenshot Comment List Resource
  • Review Reply Draft Resource
  • Review Screenshot Comment List Resource
  • Review Screenshot Comment Resource
  • Root List Resource
  • Default Reviewer List Resource
  • Default Reviewer Resource
  • Extension List Resource
  • Extension Resource
  • Hosting Service Account List Resource
  • Hosting Service Account Resource
  • Repository List Resource
  • Repository Resource
  • Repository Info Resource
  • Review Group List Resource
  • Review Group Resource
  • Review Group User List Resource
  • Review Request List Resource
  • Review Request Resource
  • Change List Resource
  • Diff List Resource
  • File Attachment List Resource
  • Review List Resource
  • Review Request Draft Resource
  • Review Request Last Update Resource
  • Screenshot List Resource
  • Search Resource
  • Server Info Resource
  • Session Resource
  • User List Resource
  • User Resource
  • Watched List Resource
  • Screenshot Comment List Resource
  • Screenshot List Resource
  • Screenshot Resource
  • Screenshot Comment List Resource
  • Screenshot Resource
  • Screenshot Comment List Resource
  • Search Resource
  • Server Info Resource
  • Session Resource
  • User List Resource
  • User Resource
  • Watched List Resource
  • Watched Review Group List Resource
  • Watched Review Request List Resource
  • User Resource
  • Watched List Resource
  • Watched Review Group List Resource
  • Watched Review Group Resource
  • Watched Review Request List Resource
  • Watched Review Request Resource
  • Watched Review Group List Resource
  • Watched Review Group Resource
  • Watched Review Group Resource
  • Watched Review Request List Resource
  • Watched Review Request Resource
  • Watched Review Request Resource
  • Watched List Resource
  • Watched Review Group List Resource
  • Watched Review Group Resource
  • Watched Review Request List Resource
  • Watched Review Request Resource
  • Errors
  • 100 - Does Not Exist
  • 101 - Permission Denied
  • 103 - Not Logged In
  • 104 - Login Failed
  • 105 - Invalid Form Data
  • 203 - Invalid Change Number
  • 204 - Change Number In Use
  • 205 - Missing Repository
  • 206 - Invalid Repository
  • 207 - Repository File Not Found
  • 208 - Invalid User
  • 209 - Repository Action Not Supported
  • 210 - Repository Information Error
  • 212 - Empty Changeset
  • 213 - Server Configuration Error
  • 214 - Bad Host Key
  • 215 - Unverified Host Key
  • 216 - Unverified Host Certificate
  • 217 - Missing User Key
  • 218 - Repository Authentication Error
  • 219 - Diff Empty
  • 220 - Diff Too Big
  • 221 - File Retrieval Error
  • 222 - Hosting Service Authentication Error
  • 223 - Group Already Exists
  • Glossary
  • REST API 2.0
  • Overview
  • Authenticating
  • Resources
  • Change List Resource
  • Change Resource
  • Change Resource
  • Diff List Resource
  • Diff Resource
  • File Diff List Resource
  • Diff Resource
  • File Diff List Resource
  • File Diff Resource
  • Default Reviewer List Resource
  • Default Reviewer Resource
  • Default Reviewer Resource
  • Draft File Attachment List Resource
  • Draft File Attachment Resource
  • Draft File Attachment Resource
  • Draft Screenshot List Resource
  • Draft Screenshot Resource
  • Draft Screenshot Resource
  • Extension List Resource
  • Extension Resource
  • Extension Resource
  • File Attachment Comment List Resource
  • File Attachment Comment Resource
  • File Attachment List Resource
  • File Attachment Resource
  • File Attachment Comment List Resource
  • File Attachment Resource
  • File Attachment Comment List Resource
  • File Diff Comment List Resource
  • File Diff List Resource
  • File Diff Resource
  • File Diff Comment List Resource
  • Original File Resource
  • Patched File Resource
  • File Diff Resource
  • File Diff Comment List Resource
  • Original File Resource
  • Patched File Resource
  • Hosting Service Account List Resource
  • Hosting Service Account Resource
  • Hosting Service Account Resource
  • Original File Resource
  • Patched File Resource
  • Repository Info Resource
  • Repository List Resource
  • Repository Resource
  • Repository Info Resource
  • Repository Resource
  • Repository Info Resource
  • Review Diff Comment List Resource
  • Review Diff Comment Resource
  • Review Diff Comment Resource
  • Review Draft Resource
  • Review File Attachment Comment List Resource
  • Review File Attachment Comment Resource
  • Review File Attachment Comment Resource
  • Review Group List Resource
  • Review Group Resource
  • Review Group User List Resource
  • Review Group Resource
  • Review Group User List Resource
  • Review Group User Resource
  • Review Group User List Resource
  • Review Group User Resource
  • Watched List Resource
  • Review Group User Resource
  • Watched List Resource
  • Watched Review Group List Resource
  • Watched Review Request List Resource
  • Review List Resource
  • Review Resource
  • Review Diff Comment List Resource
  • Review File Attachment Comment List Resource
  • Review Reply List Resource
  • Review Screenshot Comment List Resource
  • Review Draft Resource
  • Review Reply Diff Comment List Resource
  • Review Reply Diff Comment Resource
  • Review Reply Diff Comment Resource
  • Review Reply Draft Resource
  • Review Reply File Attachment Comment List Resource
  • Review Reply File Attachment Comment Resource
  • Review Reply File Attachment Comment Resource
  • Review Reply List Resource
  • Review Reply Resource
  • Review Reply Diff Comment List Resource
  • Review Reply File Attachment Comment List Resource
  • Review Reply Screenshot Comment List Resource
  • Review Reply Draft Resource
  • Review Reply Screenshot Comment List Resource
  • Review Reply Screenshot Comment Resource
  • Review Reply Screenshot Comment Resource
  • Review Reply Resource
  • Review Reply Diff Comment List Resource
  • Review Reply Diff Comment Resource
  • Review Reply File Attachment Comment List Resource
  • Review Reply File Attachment Comment Resource
  • Review Reply Screenshot Comment List Resource
  • Review Reply Screenshot Comment Resource
  • Review Request Draft Resource
  • Draft File Attachment List Resource
  • Draft File Attachment Resource
  • Draft Screenshot List Resource
  • Draft Screenshot Resource
  • Review Request Last Update Resource
  • Review Request List Resource
  • Review Request Resource
  • Change List Resource
  • Diff List Resource
  • File Attachment List Resource
  • Review List Resource
  • Review Request Draft Resource
  • Review Request Last Update Resource
  • Screenshot List Resource
  • Review Request Resource
  • Change List Resource
  • Change Resource
  • Diff List Resource
  • Diff Resource
  • File Attachment List Resource
  • File Attachment Resource
  • Review List Resource
  • Review Resource
  • Review Draft Resource
  • Review Request Draft Resource
  • Draft File Attachment List Resource
  • Draft Screenshot List Resource
  • Review Request Last Update Resource
  • Screenshot List Resource
  • Screenshot Resource
  • Review Screenshot Comment List Resource
  • Review Screenshot Comment Resource
  • Review Screenshot Comment Resource
  • Review Resource
  • Review Diff Comment List Resource
  • Review Diff Comment Resource
  • Review File Attachment Comment List Resource
  • Review File Attachment Comment Resource
  • Review Reply List Resource
  • Review Reply Resource
  • Review Reply Draft Resource
  • Review Screenshot Comment List Resource
  • Review Screenshot Comment Resource
  • Root List Resource
  • Default Reviewer List Resource
  • Default Reviewer Resource
  • Extension List Resource
  • Extension Resource
  • Hosting Service Account List Resource
  • Hosting Service Account Resource
  • Repository List Resource
  • Repository Resource
  • Review Group List Resource
  • Review Group Resource
  • Review Request List Resource
  • Review Request Resource
  • Search Resource
  • Server Info Resource
  • Session Resource
  • User List Resource
  • User Resource
  • Screenshot Comment List Resource
  • Screenshot List Resource
  • Screenshot Resource
  • Screenshot Comment List Resource
  • Screenshot Resource
  • Screenshot Comment List Resource
  • Search Resource
  • Server Info Resource
  • Session Resource
  • User List Resource
  • User Resource
  • Watched List Resource
  • User Resource
  • Watched List Resource
  • Watched Review Group List Resource
  • Watched Review Request List Resource
  • Watched Review Group List Resource
  • Watched Review Group Resource
  • Watched Review Group Resource
  • Watched Review Request List Resource
  • Watched Review Request Resource
  • Watched Review Request Resource
  • Watched List Resource
  • Watched Review Group List Resource
  • Watched Review Group Resource
  • Watched Review Request List Resource
  • Watched Review Request Resource
  • Errors
  • 100 - Does Not Exist
  • 101 - Permission Denied
  • 103 - Not Logged In
  • 104 - Login Failed
  • 105 - Invalid Form Data
  • 203 - Invalid Change Number
  • 204 - Change Number In Use
  • 205 - Missing Repository
  • 206 - Invalid Repository
  • 207 - Repository File Not Found
  • 208 - Invalid User
  • 209 - Repository Action Not Supported
  • 210 - Repository Information Error
  • 212 - Empty Changeset
  • 213 - Server Configuration Error
  • 214 - Bad Host Key
  • 215 - Unverified Host Key
  • 216 - Unverified Host Certificate
  • 217 - Missing User Key
  • 218 - Repository Authentication Error
  • 219 - Diff Empty
  • 220 - Diff Too Big
  • 221 - File Retrieval Error
  • 222 - Hosting Service Authentication Error
  • 223 - Group Already Exists
  • Glossary
  • Extending Review Board
  • Writing Review Board Extensions
  • Writing Authentication Backends
  • Writing Legacy Authentication Backends
  • Frequently Asked Questions
  • General Index
  • Release Notes
  • This documentation covers Review Board 1.7. You can select a version above or view the latest documentation.

    Writing Review Board Extensions¶

    New in version 1.7: Many of the features described here are new in Review Board 1.7.

    Overview¶

    Review Board’s functionality can be enhanced by installing a Review Board extension. Writing and installing an extension is an excellent way to tailor Review Board to your exact needs. Here are a few examples of the many things you can accomplish by writing an extension:

    • Modify the user interface, providing new links or buttons.
    • Generate statistics for report gathering.
    • Interface Review Board with other systems (e.g. an IRC bot).

    Extension Structure¶

    Extensions must follow a certain structure to be recognized and loaded by Review Board. They are distributed inside Python Eggs following a few conventions. See Python Egg for more information.

    Note

    The Review Board extension system has been designed to follow many of Django’s conventions. The structure of an extension package tries to mirror that of Django apps.

    The main constituent of an extension is a class which inherits from the Extension base class reviewboard.extensions.base.Extension.

    The Review Board repository contains a script for generating the initial code an extension requires. See Extension Boilerplate Generator for more information.

    Minimum Extension Structure¶

    At minimum, an extension requires the following files:

    • setup.py
    • extensiondir/__init__.py
    • extensiondir/extension.py

    The following are a description and example of each file. In each example extensiondir has been replaced with the extension’s package, ‘sample_extension’:

    setup.py

    This is the file used to create the Python Egg. It defines the Entry Point along with other meta-data. See Python Egg for a description of features relevant to Review Board extensions. Example:

    from setuptools import setup
    
    
    PACKAGE = "sample_extension"
    VERSION = "0.1"
    
    setup(
        name=PACKAGE,
        version=VERSION,
        description="description of extension",
        author="Your Name",
        packages=["sample_extension"],
        entry_points={
            'reviewboard.extensions':
                '%s = sample_extension.extension:SampleExtension' % PACKAGE,
        },
    )
    

    See Python Egg and the setuptools documentation for more information.

    sample_extension/__init__.py

    This file indicates the sample_extension is a Python package.

    sample_extension/extension.py

    This is the main module of the extension. The Extension subclass should be defined here. Example:

    from reviewboard.extensions.base import Extension
    
    
    class SampleExtension(Extension):
        def __init__(self, *args, **kwargs):
            super(SampleExtension, self).__init__(*args, **kwargs)
    

    Other Structure¶

    Review Board also expects extensions to follow a few other conventions when naming files. The following files serve a special purpose:

    models.py
    An extension may define Django models in this file. The corresponding tables will be created in the database when the extension is loaded. See Models for more information.
    models/
    As an alternative to using models.py, a Python package may be created in models/, which may define models in its modules.
    admin_urls.py
    An extension may define urls for configuration in the admin panel. It is only used when is_configurable is set True. For more information, see Admin URLs.
    admin.py
    This file allows an extension to register models in its own Django admin site. It is only used when has_admin_site is set True. For more information, see extension-admin-sites.

    Extension Class¶

    The main component of an extension is a class inheriting from reviewboard.extensions.base.Extension. It can optionally set the following attributes:

    • is_configurable
    • has_admin_site
    • default_settings
    • requirements

    The base class also provides the following attributes:

    • settings
    class reviewboard.extensions.base.Extension¶
    is_configurable¶

    A Boolean indicating whether the extension supports configuration in the Review Board admin panel. The default is False. See Configuration for more information.

    has_admin_site¶

    A Boolean that indicates whether a Django admin site should be generated for the extension. The default is False. See Admin Site for more information.

    default_settings¶

    A Dictionary which acts as a default for settings. The default is {}, an empty dictionary. See Default Settings for more information.

    requirements¶

    A list of strings providing the names of other extensions the extension requires. An extension may only be enabled if all other extensions in its requirements list are also enabled. See Dependencies for more information.

    settings¶

    An instance of djblets.extensions.base.settings. This attribute gives each extension an easy-to-use and persistent data store for settings. See Settings for more information.

    Models¶

    Extensions are able to define Django Models to expand the database schema. When an extension is loaded, it is added to INSTALLED_APPS automatically. New Models are then written to the database by Review Board, which runs syncdb programmatically.

    Note

    Review Board is also able to evolve the database programmatically. This allows a developer to make changes to an extension’s models after release.

    Extensions use the same convention as Django applications when defining Models. In order to define new Models, a models.py file, or a models/ directory constituting a Python package should be created.

    Here is an example models.py file:

    from django.db import models
    
    
    class MyExtensionsSampleModel(models.Model):
        name = models.CharField(max_length=128)
        enabled = models.BooleanField()
    

    Note

    When an extension is disabled, tables for its models are not dropped. For a development installation, an evolution to drop these tables may be generated using:

    ./reviewboard/manage.py evolve --purge

    Alternativley, when developing against a Review Board install, rb-site may be used:

    rb-site manage /path/to/site evolve -- --purge

    Settings¶

    Each extension is given a settings dictionary which it can load from the database using load() and save to the database using save(). This is found in the settings attribute and is an instance of the djblets.extensions.base.settings class.

    A set of defaults may be provided in default_settings to make initialization of the dictionary simple. See Default Settings for more information.

    class djblets.extensions.base.settings¶
    load()¶

    Retrieves the dictionary entries from the database.

    save()¶

    Stores the dictionary entries to the database.

    Here is an example of how to save settings:

    settings['mysetting'] = "New Setting Value"
    settings.save()  # Store the settings in the database.
    

    And an example of how to load settings:

    settings.load()  # Retrieve the settings from the database.
    mysetting = settings['mysetting']  # Read the setting value.
    

    Default Settings¶

    To provide defaults for the settings dictionary, an extension may use the default_settings attribute. If a key is not found in settings, default_settings will be checked. If neither dictionary contains the key, a KeyError exception will be thrown.

    Here is an example extension setting default_settings:

    class SampleExtension(Extension):
       default_settings = {
          'mysetting': 1,
          'anothersetting': 4,
          'stringsetting': "I'm a string setting",
       }
    
       def __init__(self, *args, **kwargs):
         super(SampleExtension, self).__init__(*args, **kwargs)
    

    Configuration¶

    For administrative configuration, extensions are able to hook into the Review Board admin panel.

    By setting is_configurable to True, an extension is assigned a URL namespace under the admin path. New URLs are added to this namespace using an admin_urls.py file. See Admin URLs for more information.

    Review Board also supplies views, templates, and forms, making management of Settings painless. See Settings Form for more information.

    Admin URLs¶

    If an extension has is_configurable set to True, it will be assigned a URL namespace under the admin path. A button labeled Configure will appear in the list of installed extensions, linking to the base path of this namespace.

    To specify URLs in the namespace, an admin_urls.py file should be created, taking the form of a Django URLconf module. This module should follow Django’s conventions, defining a urlpatterns variable.

    urlpatterns¶

    Used to specify URLs. This should be a Python list, in the format returned by the function django.conf.urls.patterns().

    The following is an example admin_url.py file:

    from django.conf.urls.defaults import patterns, url
    
    
    urlpatterns = patterns('sample_extension.views',
        url(r'^$', 'configure')
    )
    

    This would direct the base URL of the namespace to the configure view.

    For a more in depth explanation of URLconfs please see the Django URLs documentation.

    Settings Form¶

    Review Board supplies the views, templates, and a base Django form to make creating a configuration UI for Settings painless. To take advantage of this feature, do the following:

    • Define a new form class inheriting from djblets.extensions.forms.SettingsForm
    • Create a new URL pattern to reviewboard.extensions.views.configure_extension, providing the extension class and form class. See Admin URLs for more information on creating URL patterns.

    Here is an example form class:

    from django import forms
    from djblets.extensions.forms import SettingsForm
    
    
    class SampleExtensionSettingsForm(SettingsForm):
        field1 = forms.IntegerField(min_value=0, initial=1, help_text="Field 1")
    

    Here is an example URL pattern for the form:

    from django.conf.urls.defaults import patterns
    
    from sample_extension.extension import SampleExtension
    from sample_extension.forms import SampleExtensionSettingsForm
    
    
    urlpatterns = patterns('',
        (r'^$', 'reviewboard.extensions.views.configure_extension',
         {'ext_class': SampleExtension,
          'form_class': SampleExtensionSettingsForm,
         }),
    )
    

    Admin Site¶

    By setting has_admin_site to True, an extension will be given its own Django admin site. A button labeled Database will appear in the list of installed extensions, linking to the base path of the admin site.

    The extension’s instance of django.contrib.admin.sites.AdminSite will exist in the admin_site attribute of the Extension.

    Models should be registered to the Admin site in an admin.py file. Here is an example admin.py file:

    from reviewboard.extensions.base import get_extension_manager
    
    from sample_extension.extension import SampleExtension
    from sample_extension.models import SampleModel
    
    
    # You must get the loaded instance of the extension to register to the
    # admin site.
    extension_manager = get_extension_manager()
    extension = extension_manager.get_enabled_extension(SampleExtension.id)
    
    # Register the Model to the sample_extensions admin site.
    extension.admin_site.register(SampleModel)
    

    For more information on Django admin sites, please see the Django Admin Site documentation.

    Useful Hooks¶

    Extensions hooks are the primary mechanism for customizing Review Board’s appearance and behavior.

    Hooks need only be instantiated for Review Board to “notice” them, and are automatically removed when the extension shuts down.

    The following hooks are available for use by extensions.

    URLHook¶

    reviewboard.extensions.hooks.URLHook are used to extend the URL patterns that Review Board wil recognize and respond to.

    URLHook requires two arguments for initialization: the extension instance and the URL patterns.

    Example usage in an Extension:

    class SampleExtension(Extension):
        def __init__(self, *args, **kwargs):
            super(SampleExtension, self).__init__(*args, **kwargs)
            pattern = patterns('', (r'^sample_extension/',
                                    include('sample_extension.urls')))
            self.url_hook = URLHook(self, pattern)
    

    Notice how sample_extension.urls was included in the patterns. In this case, sample_extension is the package name for the extension, and urls is the module that contains the patterns:

    from django.conf.urls.defaults import patterns, url
    
    
    urlpatterns = patterns('sample_extension.views',
        url(r'^$', 'dashboard'),
    )
    

    DashboardHook¶

    reviewboard.extensions.hooks.DashboardHook can be used to define a custom dashboard page for your Extension. DashboardHook requires two arguments for initialization: the extension instance and a list of entries. Each entry in this list must be a dictionary with the following keys:

    • label: Label to appear on the dashboard’s navigation pane.
    • url: URL for the dashboard page.

    If the extension needs only one dashboard, then it needs only one entry in this list. (See NavigationBarHook)

    Example usage in an Extension:

    class SampleExtension(Extension):
        def __init__(self, *args, **kwargs):
            super(SampleExtension, self).__init__(*args, **kwargs)
            self.dashboard_hook = DashboardHook(
                self,
                entries = [
                    {
                        'label': 'A SampleExtension Label',
                        'url': settings.SITE_ROOT + 'sample_extension/',
                    }
                ]
            )
    

    Corresponding code in views.py:

    def dashboard(request, template_name='sample_extension/dashboard.html'):
        return render_to_response(template_name, RequestContext(request))
    

    Corresponding template dashboard.html:

    {% extends "base.html" %}
    {% load djblets_deco %}
    {% load i18n %}
    
    {% block title %}{% trans "sample_extension Dashboard" %}{% endblock %}
    
    {% block content %}
    {%  box "reports" %}
     <h1 class="title">{% trans "sample_extension Dashboard" %}</h1>
    
     <div class="main">
      <p>{% trans "This is my new Dashboard page for Review Board" %}</p>
     </div>
    {%  endbox %}
    {% endblock %}
    

    NavigationBarHook¶

    reviewboard.extensions.hooks.NavigationBarHook can be used to introduce additional items to the main navigation bar.

    NavigationBarHook requires two arguments: the extension instance and a list of entries. Each entry represents an item on the navigation bar, and is a dictionary with the following keys:

    • label: The label to display.
    • url: The URL to point to.
    • url_name: The name of the URL to point to.

    Only one of url or url_name is required. url_name will take precedence.

    If your extension needs to access the template context, you can define a subclass from NavigationBarHook to override get_entries and return results from there.

    Example usage in an Extension:

    class SampleExtension(Extension):
        def __init__(self, *args, **kwargs):
            super(SampleExtension, self).__init__(*args, **kwargs)
            self.navigationbar_hook = NavigationBarHook(
                self,
                entries = [
                    {
                        'label': 'An Item on Navigation Bar',
                        'url': settings.SITE_ROOT + 'an_item_url_a/',
                    },
                    {
                        'label': 'Another Item on Navigation Bar',
                        'url': settings.SITE_ROOT + 'an_item_url_b/',
                    },
                    {
                        'label': 'Yet Another Item on Navigation Bar',
                        'url': settings.SITE_ROOT + 'an_item_url_c/',
                    },
                ]
            )
    

    Review UI Integration¶

    Review UIs are used in reviewing file attachments of particular mimetypes. For example, an Image Review UI is used to render image files and allow comments to be attached to specific areas of an image. Similarly, a Markdown Review UI renders the raw text from a .md file into a corresponding HTML.

    Extensions can integrate custom Review UIs into Review Board by defining a hook that subclasses ReviewUIHook. Each extension may define and register zero or more Review UIs. When the extension is enabled through the admin page, the hook registers its list of Review UIs. Likewise, the hook unregisters these Review UIs when the extension is disabled.

    We use a simple XMLReviewUI that performs syntax highlighting as an example to demonstrate the key anatomical points for integrating ReviewUIs through extensions.

    Subclassing ReviewUIHook¶

    extension.py must use a Review UI Hook to register its list of Review UIs. This can be using reviewboard.extensions.hooks.ReviewUIHook directly, using a subclass of it. ReviewUIHook expects a list of Review UIs as argument in addition to the extension instance.

    Example: XMLReviewUIExtension:

    class XMLReviewUIExtension(Extension):
        def __init__(self, *args, **kwargs):
            super(XMLReviewUIExtension, self).__init__(*args, **kwargs)
            self.reviewui_hook = ReviewUIHook(self, [XMLReviewUI])
    

    ReviewUI Class¶

    Each Review UI must be defined by its own ReviewUI class that subclasses reviewboard.reviews.ui.base.FileAttachmentReviewUI. It must also define the following class variables:

    • supported_mimetypes: a list of mimetypes of the files that this Review UI will be responsible for rendering.
    • template_name: where to find the html template used when rendering this Review UI
    • object_key: a unique name to identify this Review UI

    Example: XMLReviewUI:

    import logging
    
    from django.utils.encoding import force_unicode
    import pygments
    
    from reviewboard.reviews.ui.base import FileAttachmentReviewUI
    
    
    class XMLReviewUI(FileAttachmentReviewUI):
        """ReviewUI for XML mimetypes"""
        supported_mimetypes = ['application/xml', 'text/xml']
        template_name = 'xml_review_ui_extension/xml.html'
        object_key = 'xml'
    

    The class should also have some function to render the particular mimetype(s) that it is responsible for. There are no restrictions on the name of the function or what it returns, but it should be in agreement with logic specified in its corresponding template.

    Example: render() in XMLReviewUI. This simply uses the pygments API to convert raw XML into syntax-highlighted HTML:

    def render(self):
        data_string = ""
        f = self.obj.file
    
        try:
            f.open()
            data_string = f.read()
        except (ValueError, IOError), e:
            logging.error('Failed to read from file %s: %s' % (self.obj.pk, e))
    
        f.close()
    
        return pygments.highlight(
            force_unicode(data_string),
            pygments.lexers.XmlLexer(),
            pygments.formatters.HtmlFormatter())
    

    ReviewUI Template¶

    Here is the template that corresponds to the above Review UI:

    xml_review_ui_extension/templates/xml_review_ui_extension/xml.html:

    {% extends base_template %}
    {% load i18n %}
    {% load reviewtags %}
    
    {% block title %}{{xml.filename}}{% if caption %}: {{caption}}
    {% endif %}{% endblock %}
    
    {% block scripts-post %}
    {{block.super}}
    
    <script language="javascript"
    src="{{MEDIA_URL}}ext/xml-review-ui-extension/js/XMLReviewableModel.js">
    </script>
    
    <script language="javascript"
    src="{{MEDIA_URL}}ext/xml-review-ui-extension/js/XMLReviewableView.js">
    </script>
    
    <script language="javascript">
        $(document).ready(function() {
            var view = new RB.XMLReviewableView({
                model: new RB.XMLReviewable({
                    attachmentID: '{{xml.id}}',
                    caption: '{{caption|escapejs}}',
                    rendered: '{{review_ui.render|escapejs}}'
                })
            });
            view.render();
            $('#xml-review-ui-container').append(view.$el);
        });
    </script>
    {% endblock %}
    
    {% block review_ui_content %}
    <div id="xml-review-ui-container"></div>
    {% endblock %}
    

    ReviewUI JavaScript¶

    Here are the corresponding JavaScript used in the above template.

    xml_review_ui_extension/htdocs/js/XMLReviewableModel.js:

    /*
     * Provides review capabilities for XML files.
     */
    RB.XMLReviewable = RB.FileAttachmentReviewable.extend({
        defaults: _.defaults({
            rendered: ''
        }, RB.FileAttachmentReviewable.prototype.defaults)
    });
    

    xml_review_ui_extension/htdocs/js/XMLReviewableView.js:

    /*
     * Displays a review UI for XML files.
     */
    RB.XMLReviewableView = RB.FileAttachmentReviewableView.extend({
        className: 'xml-review-ui',
    
        /*
         * Renders the view.
         */
        renderContent: function() {
            this.$el.html(this.model.get('rendered'));
    
            return this;
        }
    });
    

    Python Egg¶

    Extensions are packaged and distributed as Python Eggs. This allows for automatic detection of installed extensions, packaging of static files, and dependency checking.

    The setuptools module is used to create a Python Egg. A setup.py file is created for this purpose. See the setuptools documentation for a full description of features.

    Entry Point¶

    To facilitate the auto-detection of installed extensions, a reviewboard.extensions entry point must be defined for each Extension Class. Here is an example entry point definition:

    entry_points={
         'reviewboard.extensions':
             'sample_extension = sample_extension.extension:SampleExtension',
    },
    

    This defines an entry point for the SampleExtension class from the sample_extension.extension module. Here is an example of a full setup.py file defining this entry point:

    from setuptools import setup
    
    
    PACKAGE = "sample_extension"
    VERSION = "0.1"
    
    setup(
        name=PACKAGE,
        version=VERSION,
        description="Description of extension",
        author="Your Name",
        packages=["sample_extension"],
        entry_points={
            'reviewboard.extensions':
                'sample_extension = sample_extension.extension:SampleExtension',
        },
    )
    

    Static Files¶

    Any static files (such as css, html, and javascript) the extension requires must be added to the package data of the Python Egg. Here is an example of how this is done in the setup.py file:

    package_data={
        'sample_extension': [
            'htdocs/css/*.css',
            'htdocs/js/*.js',
            'templates/rbreports/*.html',
            'templates/rbreports/*.txt',
        ],
    }
    

    Here is an example of a full setup.py file including the static files:

    from setuptools import setup
    
    
    PACKAGE = "sample_extension"
    VERSION = "0.1"
    
    setup(
        name=PACKAGE,
        version=VERSION,
        description="Description of extension",
        author="Your Name",
        packages=["sample_extension"],
        entry_points={
            'reviewboard.extensions':
                'sample_extension = sample_extension.extension:SampleExtension',
        },
        package_data={
            'sample_extension': [
                'htdocs/css/*.css',
                'htdocs/js/*.js',
                'templates/rbreports/*.html',
                'templates/rbreports/*.txt',
            ],
        }
    )
    

    Dependencies¶

    Any dependencies of the extension are defined in the setup.py file using install_requires. Here is an example of a full :file`setup.py` file including a dependency:

    from setuptools import setup
    
    
    PACKAGE = "sample_extension"
    VERSION = "0.1"
    
    setup(
        name=PACKAGE,
        version=VERSION,
        description="Description of extension",
        author="Your Name",
        packages=["sample_extension"],
        entry_points={
            'reviewboard.extensions':
                'sample_extension = sample_extension.extension:SampleExtension',
        },
        install_requires=['PythonPackageIDependOn>=0.1']
    )
    

    This will ensure any packages the extension requires will be installed. See the Setuptools documentation for more information on install_requires.

    In addition to requiring python packages when installing, an extension can declare a list of additional extensions it requires. This requirements list gives the name of each extension that must be enabled before allowing the extension itself to be enabled. This list is declared by setting the requirements attribute. Here is an example of an extension defining a requirements list:

    class SampleExtension(Extension):
        requirements = ['other_extension.extension.OtherExtension']
    
        def __init__(self, *args, **kwargs):
            super(RBWebHooksExtension, self).__init__(*args, **kwargs)
    

    Developing With a Python Egg¶

    In order for Review Board to detect an extension, the Python Egg must be generated using the setup.py file, and installed. During development this can be done by installing a link in the Python installation to the source directory of your extension. This is accomplished by running:

    python setup.py develop

    If changes are made to the setup.py file this should be executed again.

    See the Setuptools documentation for more information.

    Extension Boilerplate Generator¶

    The Review Board repository contains a script for generating the boilerplate code for a new extension. This script is part of the Review Board tree and is located here:

    ./contrib/tools/generate_extension.py

    Keep up with the latest Review Board releases, security updates, and helpful information.

    About
    News
    Demo
    RBCommons Hosting
    Integrations
    Happy Users
    Support Options
    Documentation
    FAQ
    User Manual
    RBTools
    Administration Guide
    Power Pack
    Release Notes
    Downloads
    Review Board
    RBTools
    Djblets
    Power Pack
    Package Store
    PGP Signatures
    Contributing
    Bug Tracker
    Submit Patches
    Development Setup
    Wiki
    Follow Us
    Mailing Lists
    Reddit
    Twitter
    Mastodon
    Facebook
    YouTube

    Copyright © 2006-2025 Beanbag, Inc. All rights reserved.

    Terms of Service — Privacy Policy — AI Ethics Policy — Branding

    On this page

    • [Top]
    • Overview
    • Extension Structure
      • Minimum Extension Structure
      • Other Structure
    • Extension Class
    • Models
    • Settings
      • Default Settings
    • Configuration
      • Admin URLs
      • Settings Form
    • Admin Site
    • Useful Hooks
      • URLHook
      • DashboardHook
      • NavigationBarHook
    • Review UI Integration
      • Subclassing ReviewUIHook
      • ReviewUI Class
      • ReviewUI Template
      • ReviewUI JavaScript
    • Python Egg
      • Entry Point
      • Static Files
      • Dependencies
      • Developing With a Python Egg
    • Extension Boilerplate Generator