You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

Proposal: Widgets and Panels

Status

Proposal under development

Target Release

4.0

Original Authors

Allen Gilliland

Abstract

To keep pace with other major blogging systems and provide standard features for blog customization, Roller should support a system for providing blog widgets. This is a proposal for how a widgets system might work in Roller. Other major blog systems which already include widget functionality are MovableType/TypePad, WordPress, LiveJournal, and Blogger, and undoubtably there are others as well. It's a good idea to check out how these other systems use widgets as a comparative basis for this proposal.

Requirements

  • define what is meant by a widget and how it would be defined in Roller.
  • define how widgets would be configured and grouped for use in blog templates and themes.
  • discuss how widgets would be controlled via the Roller UI.
  • define a way for Roller administrators to view the list of configured widgets, import new widgets, remove old widgets, and enable/disable widgets.

Design (Overview)

What is a widget?

A widget is a reusable component of content that can be inserted into any blog template, typically on the blog sidebar.

What can a widget do, what can it not do?

  • A widget can display any content normally available to weblog templates.
  • A widget can make use of macros and models.
  • A widget can be defined once and reused unlimited times, like themes.
  • Like normal templates, a widget cannot modify any data.
  • A widget cannot rely on specific data from the request, such as custom parameters.
  • A widget cannot define any new core functionality not already defined by the system, such as new urls.
  • Widgets are not contextual components, meaning they work only on page XXX or under condition YYY. they should be generic enough to work under all rendering conditions.
  • A widget is only used for display on weblog html pages, not for xml feed or other views.

How are widgets defined and configured?

A widget would be defined in basically the same way that a theme is defined. Widgets will contain an xml descriptor which defines the widget properties and behavior, then the widget would contain any number of template files and resources needed to render the content. Some rules ...

  • All widgets must have an xml descriptor.
  • All widgets must define a control template which is the template used to render the widget content.
  • A widget will be bundled into some kind of archive file, such as a jar file, so that it can be imported into the application easily.
  • widgets would be configured via a new page in the administration section which would list what widgets are configured and allow for importing of new widgets, removal of existing widgets, and enabling/disabling of widgets. this would all be possible at runtime, so the application would not need to be restarted to change widget definitions.

Grouping widgets into panels.

Widgets are typically configured into groupings which can define some layout options typically to determine the ordering of the widgets. To organize these groupings we would create the concept of "panels" which may contain any number of widgets and define how the widgets are layed out. The typical example of a widget panel is a blog sidebar.

A weblog would be allowed to define any number of panels to use in its templates, and panels would be defined either in a theme definition, or defined and customized on the Roller UI. The reason to support the idea of having multiple panels is two fold ...

1. some themes/designs will want more than one sidebar and should be allowd to do so while still leveraging the widgets feature for each.
2. if you take the idea one step further then technically you could define an entire theme using just panels and widgets and therefore provide a way for the user to customize all kinds of elements of their design using widgets, not just a sidebar.

The exact semantics of how this would work on the UI will be discussed more in the section about "Controlling widgets via the UI" below.

How do widgets get into templates?

Widgets could be added into templates using a macro call such as ...

// display a single widget
#showWidget("fooWidget")

// display a configured panel
#showPanel("sidebar")

// the code for the #showPanel macro would be roughly this ...
#set($panel = $model.weblog.getPanel($panelName))
#foreach($widget in $panel.widgets)
  #showWidget($model.weblog, $widget)
#end

Controlling widgets via the UI

One of the most important aspects of the widget system is to make it easy for users to choose widgets and have them inserted into their templates. This would require a new UI page which gives the user a view of what panels they have defined, what widgets are configured for a panel, and all widgets that are available in the system. The user would then be able to choose a panel to work on, then add/remove widgets from a panel using the pool of all available widgets.

The details of how this would work can be done in many ways, but the approach would be comparable to what other blog systems currently offer, so to get a sense for the UI it's best to try out the other systems.

Also, before spending too much time drawing up a UI I'd like to get general approval from the community with regards to the functional aspects of the proposal. It would be wasted time to design a nice UI only to have it discarded because we decided to use a different approach to the problem. Once we are committed to this general approach then we would spend more time flushing out the UI design and discussing that specifically. The main point is that users would have a wysiwyg style UI for choosing widgets and organizing them in panels which would alleviate the need for direct template editing.

Design (Rendering)

what actually happens to render a widget and insert it into a template?

Option 1: Just #parse() the widget control template during normal page rendering

In this approach, widgets are rendered as part of the overall rendering process for a page, so widgets are just templates that get parsed and included. i.e. a call to #showWidget("foo") triggers a call to #parse("widget:foo") and relies on a WidgetResourceLoader to provide an input stream to the appropriate widget control template.

Pros:

  • simplest approach and least resource intensive.

Cons:

  • less opportunity for caching since the logic is inside of a macro call, tied to normal page rendering, and mostly handled by velocity.
  • we don't have much control over widget rendering. widgets would have to work with whatever is available in the normal model for page rendering, and wouldn't have an opportunity to be given special rendering attention. so in this situation widgets basically just become a glorified way to make macro calls.

Option 2: Widgets go through the full rendering system

With this scenario widgets go through the full rendering process and the output simply gets pasted into the template. so calling #showWidget("foo") calls a Model method like $model.widget("foo") that instigates the typical rendering process and inserts the returned output. The $model.widget("foo") call may trigger something like this ...

WidgetManager.renderWidget(widgetName, Weblog weblog)
    - caching lookup (optional)
    - lookup control Template for rendering specified widget
    - calls renderer manager to find renderer for widget template
    - render output
    - caching storage (optional)
    - return output

Pros:

  • Caching can be done easily by the WidgetManager so that widgets aren't re-rendered for every page.
  • We can control Models for widgets, optionally doing something fancy here like allowing special Model classes for certain widgets. we also wouldn't have to load the model with all the same data available for normal page rendering, which can be a lot of unnecessary data when pre-3.0 model loading is enabled.

Cons:

  • some level of performance hit during rendering since you add in the overhead of going back through the rendering system, possibly multiple times. this could likely be negated by providing some decent caching for widgets, so that once a widget is rendered it can be reused multiple times without needing to be re-rendered.

Issues

  • how to access widget resources? Roller takes the approach that all components used by a weblog should be accessed via that weblogs urls, but this creates some issues for resources that are meant to be shared across weblogs.
    • option 1, use the existing resource servlet the same way we do for theme resources.
    • option 2, pick a url location outside of the weblog url space (/roller-ui/) to use for accessing widget resources, such as /roller-ui/widgets/<widget>/
  • No labels