Fork me on GitHub

UI Widgets

As mentioned in the Getting Started documentation, most UI Elements of cone.app are organized as tiles.

The use of tiles has the following advantages:

  • Abstraction of the site to several “subapplications” which act as views, widgets and/or controllers.
  • The possibility to create generic tiles expecting model nodes providing the contract of cone.app.interfaces.IApplicationNode.
  • AJAX is easily integrateable.

cone.app ships with several commonly needed tiles. One of this is registered by name content, which is reserved for rendering the Content Area of the page. A plugin must at least register a content tile for each application node it provides in order to display it in the layout.

The following sections explain the tiles shipped with this package. Some of them are abstract and can be used as base classes for custom tiles, while others are already registered and ready to be used.

Abstract tiles

Batch

A tile for rendering batches is contained at cone.app.browser.batch.Batch.

A subclass must at least implement vocab. The example below renders a batch for all children of model node.

from cone.app.browser.batch import Batch
from cone.app.browser.utils import make_query
from cone.app.browser.utils import make_url
from cone.tile import tile

@tile('examplebatch')
class ExampleBatch(Batch):
    slicesize = 10

    @property
    def vocab(self):
        count = len(self.model)
        pages = count / self.slicesize
        if count % self.slicesize != 0:
            pages += 1
        current = self.request.params.get('b_page', '0')
        for i in range(pages):
            query = make_query(b_page=str(i))
            href = make_url(
                self.request,
                path=path,
                resource='viewname',
                query=query
            )
            target = make_url(self.request, path=path, query=query)
            ret.append({
                'page': '{}'.format(i + 1),
                'current': current == str(i),
                'visible': True,
                'href': href,
                'target': target,
            })
        return ret

More customization options on Batch class:

  • display: Flag whether to display the batch.
  • batchrange: Number of batch pages displayed.
  • ellipsis: Ellipsis is number of pages exceeds batchrange.
  • firstpage: Overwrite with property returning None to suppress rendering first page link.
  • lastpage: Overwrite with property returning None to suppress rendering last page link.
  • prevpage: Overwrite with property returning None to suppress rendering previous page link.
  • nextpage: Overwrite with property returning None to suppress rendering next page link.

Batched Items

A tile for creating batched, searchable listings is contained at cone.app.browser.batch.

It consists of a listing header which displays a search field and a slice size selection, the actual listing slice and a listing footer which displays information about the currently displayed slice and the pagination Batch.

The listing slice is abstract and must be implemented while the listing header, footer and pagination batch are generic implementations.

Create a template for rendering the slice, e.g. at cone.example.browser:templates/example_slice.pt:

<tal:example_slice
    xmlns:tal="http://xml.zope.org/namespaces/tal"
    omit-tag="True">

  <div class="${context.slice_id}">
    <div tal:repeat="item context.slice_items">
      <span tal:content="item.metadata.title">Title</span>
    </div>
  </div>

</tal:example_slice>

The concrete tile implementation subclasses BatchedItems and must at least implement item_count and slice_items. To render the slice a template is provided at slice_template. Another option to render the slice is to overwrite rendered_slice or using a custom template for the entire BatchedItems implementation based on cone.app.browser:templates/batched_items.pt and render the slice there.

item_count returns the overall item count, slice_items returns the current items to display in the slice.

The subclass of BatchedItems gets registered under desired tile name. items_id is set as CSS id of the tile element and is used to bind JS events on the client side for rerendering the tile.

In the following example, filtered_items is used to compute the overall items based on given search term. This function is no part of the contract, but illustrates that filter criteria and current slice needs to be considered by the concrete BatchedItems implementation.

from cone.app.browser.batch import BatchedItems

@tile(name='example_items')
class ExampleBatchedItems(BatchedItems):
    items_id = 'example_items'
    slice_template = 'cone.example.browser:templates/example_slice.pt'

    @property
    def item_count(self):
        return len(self.filtered_items)

    @property
    def slice_items(self):
        start, end = self.current_slice
        return self.filtered_items[start:end]

    @property
    def filtered_items(self):
        items = list()
        term = self.filter_term
        term = term.lower() if term else term
        for node in self.model.values():
            if term and node.name.find(term) == -1:
                continue
            items.append(node)
        return items

More customization options on BatchedItems class:

  • path: Path to template used for rendering the tile. Defaults to cone.app.browser:templates/batched_items.pt. Can also be set by passing it as path keyword argument to tile decorator.
  • header_template: Template rendering the slice header. Defaults to cone.app.browser:templates/batched_items_header.pt.
  • footer_template: Template rendering the slice footer. Defaults to cone.app.browser:templates/batched_items_footer.pt.
  • slice_template: Template rendering the slice items. Defaults to None. Shall be set by subclass.
  • items_id: CSS ID of the batched items container DOM element.
  • items_css: CSS classes of the batched items container DOM element.
  • query_whitelist: Additional incoming request parameters to consider when creating URL’s. Defaults to [].
  • display_header: Flag whether to display the listing header. Defaults to True.
  • display_footer: Flag whether to display the listing footer. Defaults to True.
  • show_title: Flag whether to show title in the listing header. Defaults to True.
  • title_css: CSS classes to set on title container DOM element. Defaults to col-xs-4. Can be used to change the size of the title area.
  • default_slice_size: Default number of items displayed in slice. Defaults to 15.
  • num_slice_sizes: Number of available slice sizes in slice size selection.
  • show_slice_size: Flag whether to display the slice size selection in listing header. Defaults to True.
  • slice_size_css: CSS classes to set on slice size selection container DOM element. Defaults to col-xs-4 col-sm3. Can be used to change the size of the slice size selection.
  • show_filter: Flag whether to display the search filter input in listing header. Defaults to True.
  • filter_css: CSS classes to set on search filter input container DOM element. Defaults to col-xs-3. Can be used to change the size of the search filter input.
  • head_additional: Additional arbitrary markup rendered in listing header. Can be used to add additional listing filter aspects or similar.
  • title: Title in the listing header. Defaults to model.metadata.title.
  • bind_selectors: CSS selector to bind the batched items container DOM element to.
  • bind_events: JS events to bind the batched items container DOM element to.
  • trigger_selector: CSS selector to trigger JS event to when changing slice size or entering search filter term.
  • trigger_event: JS event triggered when changing slice size or entering search filter term.
  • pagination: BatchedItemsBatch instance.
  • page_target: Pagination batch page target.
  • slice_id: CSS ID of the slice container DOM element.
  • slice_target: Slice size selection target URL.
  • filter_target: Search filter input target URL.

Table

A tile for rendering sortable, batched tables is contained at cone.app.browser.table.Table.

A subclass of this tile must be registered under the same name as defined at table_tile_name and is normally bound to template cone.app:browser/templates/table.pt.

Futher the implementation must provide col_defs, item_count and sorted_rows.

from cone.app.browser.table import RowData
from cone.app.browser.table import Table

@tile(name='example_table', path='cone.app:browser/templates/table.pt')
class ExampleTable(Table):
    table_id = 'example_table'
    table_css = 'example_table'
    table_tile_name = 'example_table'
    col_defs = [{
        'id': 'column_a',
        'title': 'Column A',
        'sort_key': None,
        'sort_title': None,
        'content': 'string'
    }, {
        'id': 'column_b',
        'title': 'Column B',
        'sort_key': None,
        'sort_title': None,
        'content': 'string'
    }]

    @property
    def item_count(self):
        return len(self.model)

    def sorted_rows(self, start, end, sort, order):
        # ``sort`` and ``order`` must be considered when creating the
        # sorted results.
        rows = list()
        for child in self.model.values()[start:end]:
            row_data = RowData()
            row_data['column_a'] = child.attrs['attr_a']
            row_data['column_b'] = child.attrs['attr_b']
            rows.append(row_data)
        return rows

Column definitions:

  • id: Column ID.
  • title: Column Title.
  • sort_key: Key used for sorting this column.
  • sort_title: Sort Title.
  • content: Column content format:
    • string: Renders column content as is.
    • datetime: Expects datetime as column value and formats datetime.
    • structure: Renders column content as Markup.

More customization options on Table class:

  • default_sort: Default sort column by ID. Defaults to None.
  • default_order: Default sort order. Can be 'asc' or 'desc'. Defaults to None.
  • default_slicesize: Default table content slize size. Defaults to 15.
  • query_whitelist: List of URL query parameters considered when creating Links. Defaults to [].
  • show_title: Flag whether to display table title. Defaults to True.
  • table_title: Title of the table. Defaults to self.model.metadata.title.
  • show_filter: Flag whether to display table filter search field. Defaults to False. If used, server side implementation must consider self.filter_term when creating results.
  • show_slicesize: Flag whether to display the slize size selection. Defaults to True.
  • head_additional: Additional table header markup. Defaults to None.
  • display_table_header: Flag whether to display table header. Defaults to True.
  • display_table_footer: Flag whether to display table footer. Defaults to True.

Actions

Action are no tiles but behave similar. They get called with context and request as arguments, are responsible to read action related information from node and request and render an appropriate action (or not).

Actions are used in contexmenu and contents tiles by default, but they can be used elsewhere to render user actions for nodes.

There exist base objects Action, TileAction, TemplateAction, DropdownAction and LinkAction in cone.app.browser.actions which can be used as base classes for custom actions.

Class Toolbar can be used to render a set of actions.

Class ActionContext provides information about the current execution scope. The scope is a tile name and used by actions to check it’s own state, e.g. if action is selected, disabled or should be displayed at all. The scope gets calculated by a set of rules.

  • If bdajax.action found on request, use it as current scope. bdajax.action is always a tile name in cone.app context.
  • If tile name is layout, content tile name is used. The layout tile renders the entire page, thus the user is normally interested in the content tile name rather than the rendered tile name.
  • If tile name is content and model defines properties.default_content_tile, this one is used instead of content to ensure a user can detect the correct content tile currently rendered.

When inheriting from Action directly, class must provide a render function returning HTML markup.

from cone.app.browser.actions import Action

class ExampleAction(Action):

    @property
    def display(self):
        return self.permitted('view') and self.action_scope == 'content'

    def render(self):
        return '<a href="http://example.com">Example</a>'

When inheriting from TileAction, a tile by name is rendered.

from cone.app.browser.actions import TileAction
from cone.tile import tile
from cone.tile import Tile

@tile(name='example_action',
      path='cone.example:browser/templates/example_action.pt',
      permission='view')
class ExampleActionTile(Tile):
    pass

class ExampleAction(TileAction):
    tile = 'example_action'

When inheriting from TemplateAction, a template is rendered.

from cone.app.browser.actions import TemplateAction

class ExampleAction(TemplateAction):
    template = 'cone.example:browser/templates/example_action.pt'

When inheriting from DropdownAction, class must implement items which are used as dropdown menu items.

from cone.app import model
from cone.app.browser.actions import DropdownAction
from cone.app.browser.utils import make_url

class ExampleAction(DropdownAction):
    css = 'example_css_class'
    title = 'Example Dropdown'

    @property
    def items(self):
        item = model.Properties()
        item.icon = 'ion-ios7-gear'
        item.url = item.target = make_url(self.request, node=self.model)
        item.action = 'example_action:NONE:NONE'
        item.title = 'Example Action'
        return [item]

LinkAction represents a HTML link offering integration to bdajax, enabled and selected state and optionally rendering an icon.

from cone.app.browser.actions import LinkAction

class ExampleAction(LinkAction):
    bind = 'click'       # ``ajax:bind`` attribute
    id = None            # ``id`` attribute
    href = '#'           # ``href`` attribute
    css = None           # in addition for computed ``class`` attribute
    title = None         # ``title`` attribute
    action = None        # ``ajax:action`` attribute
    event = None         # ``ajax:event`` attribute
    confirm = None       # ``ajax:confirm`` attribute
    overlay = None       # ``ajax:overlay`` attribute
    path = None          # ``ajax:path`` attribute
    path_target = None   # ``ajax:path-target`` attribute
    path_action = None   # ``ajax:path-action`` attribute
    path_event = None    # ``ajax:path-event`` attribute
    path_overlay = None  # ``ajax:path-overlay`` attribute
    text = None          # link text
    enabled = True       # if ``False``, link gets 'disabled' CSS class
    selected = False     # if ``True``, link get 'selected' CSS class
    icon = None          # if set, render span tag with value as CSS class in link

Toolbar can be used to create a set of actions.

from cone.app.browser.actions import Toolbar
from cone.app.browser.actions import ActionView
from cone.app.browser.actions import ActionEdit

toolbar = Toolbar()
toolbar['view'] = ActionView()
toolbar['edit'] = ActionEdit()

# render toolbar with model and request
markup = toolbar(model, request)

cone.app ships with concrete Action implementations which are described in the following sections.

ActionUp

Renders content area tile on parent node to main content area.

Considered properties:

  • action_up: Flag whether to render “One level up” action.
  • action_up_tile: Considered if action_up is true. Defines the tilename used for rendering parent content area. Defaults to listing if undefined.
  • default_child: If set, use model.parent for target link creation.

ActionView

Renders content tile on node to main content area.

Considered properties:

  • action_view: Flag whether to render view action.
  • default_content_tile: If set, it is considered in target link creation.

ActionList

Renders listing tile on node to main content area.

Considered properties:

  • action_list: Flag whether to render list action.

ActionAdd

Renders add dropdown menu.

Considered nodeinfo:

  • addables: Addable children defined for node.

ActionEdit

Renders edit tile to main content area.

Considered nodeinfo:

  • action_edit: Flag whether to render edit action.

ActionDelete

Invokes delete tile on node after confirming action.

Considered nodeinfo:

  • action_delete: Flag whether to render delete action.
  • default_content_tile: If set, used to check if scope is view when calculating whether to display action.

ActionCut

Writes selected elements contained in cone.selectable.selected to cookie on client.

Action related node must implement cone.app.interfaces.ICopySupport.

ActionCopy

Writes selected elements contained in cone.selectable.selected to cookie on client.

Action related node must implement cone.app.interfaces.ICopySupport.

ActionPaste

Invokes paste tile on node.

Action related node must implement cone.app.interfaces.ICopySupport.

Considered properties:

  • action_paste_tile: Content tile name to render after paste. Defaults to listing if undefined.

ActionMoveUp

Invokes move_up tile on node.

Considered properties:

  • action_move: Flag on parent whether to render move up action.

ActionMoveDown

Invokes move_down tile on node.

Considered properties:

  • action_move: Flag on parent whether to render move down action.

ActionSharing

Renders sharing tile on node to main content area.

Action related node must implement cone.app.interfaces.IPrincipalACL.

ActionState

Renders workflow state dropdown menu.

Action related node must implement cone.app.interfaces.IWorkflowState.