Borges QuickRef


$Id: quickref,v 1.1 2004/04/11 06:00:55 drbrain Exp $

Borges Documentation

This documentation was gathered while using Borges for the Aristoteles project. This is a start; I don't claim that anything here is correct or complete.

Class Design

The basic blocks of a borges application are :

The controllers will be the main agents in the application, defining several tasks for acting out their will. Components are often also called views and will be a basic block of display, a widget. Task and Component are both subclasses of Controller, so they all share a common interface.

Html rendering is done by using the render_on method of classes and by passing a HtmlBuilder instance inside. The HtmlBuilder class allows for building html code:

r.paragraph {
  "Some text " + r.bold("is") + "here"
}

Classes

Index

Fundamentally, the Borges framework builds on the Borges::Controller, Borges::Component and the Borges::Task.

For constructing a task from a block, use Borges::PluggableTask.

Rendering is done by Borges::HtmlRenderer, which is derived from the class Borges::HtmlBuilder.

State is held in Borges::Session.

A mechanism for making state depend on the page displayed is available trought Borges::StateHolder. The implementation of that mechanism is completely available trough Borges::Session, but uses a Borges::StateRegistry behind the scenes.

Filters can be used to modify behaviour of Borges. There are prebuilt filters for authentication (Borges::BasicAuthentication), for controlling sequence of actions (Borges::Once) and for transactions (Borges::Transaction), all of which derive from Borges::Filter.

User HTTP requests are represented by Borges::Request.

There are a few user interface components that you can reuse in your project. These include:

BatchedList
Automatically handles pagination of a list of objects. User must display the objects himself:
NavigationBar
Automatically generate a navigation menu: Borges::NavigationBar.
TaskFrame
A frame for embedding a task like a component somewhere on the page: Borges::TaskFrame.

Internally, the system uses Borges::ApplicationList and Borges::ApplicationEditor to provide you with what you normally find below /borges/config (default is 'seaside'/'admin').

Borges::Application

Introduction

This class represents your registered Borges application in the web server. When using

register_application('test')

an Application object is created and registered with the Borges::Dispatcher.

An Application has a base_path and a name. These are used to dispatch user HTTP requests to the correct application. Borges internally stores a tree of registered applications, chosing the right one (hopefully) for every request. This is the biggest building block of a Borges application, obviously.

Each application defines its on Borges::Session class that is used for holding its state.

Application is a Borges::Registry.

Borges::ApplicationEditor

Introduction

Displays the preferences for a given application and allows editing of these preferences. See also Borges::ApplicationList.

ApplicationEditor is a Borges::ApplicationList.

Borges::ApplicationList

Introduction

Displays a list of all currently registered applications. This provides links to Borges::ApplicationEditor to allow edit of applications.

Normally you can access this component as part of your default installation below /borges/config; default user is (still) 'seaside' and password is 'admin'.

ApplicationList is a Borges::Component.

Borges::BasicAuthentication

Introduction

Basic authentication makes it possible to protect a whole path of your application using HTTP basic authentication (see RFC 2617).

BasicAuthentication is a Borges::Filter.

Methods

BasicAuthentication.new {|user, password| ... }
Create a basic authentication filter. The block should decide

Borges::BatchedList

Introduction

Display a list of objects on different pages, each page containing a number of objects. Pages can be switched using a forward and a back button or can be jumped to directly using their number.

Typical usage is:

# silly example displaying the numbers from 1 to hundred, see also 
# SushiNet for better example. 
@batcher = BatchedList.new (1..100).to_a  

# when rendering 
r.list_do( @batcher.batch ) do |el|
  r.text(el)
end
# now displaying page switching links
r.render(@batcher)

Methods

BatchedList#batch
Return the current page's items.
BatchedList#batch_size
Accessor for the size of one page.
BatchedList#current_page
Accessor for the current page that is displayed.
BatchedList#end_index
Index of last item on current page.
BatchedList#items
Accessor for the list of items in the Batch.
BatchedList#max_pages
Return the total number of pages, 1-based.
BatchedList.new(items)
Create a batched list containing items.
BatchedList#next_page
Move to next page unless this is already the last page.
BatchedList#on_first_page?
true if current page is the first page.
BatchedList#on_last_page?
true if current page is the last page.
BatchedList#previous_page
Move to the previous page unless this page is the first one.
BatchedList#start_index
Index of first item on current page.

Borges::Controller

Methods

Controller#call(aController)
Pass control to the controller aController. If no
Controller#answer(value = self)
Return from component aComponent.
Controller#confirm(str)
Open a dialog asking the user to confirm str.
Controller#inform(str)
Notify the user of str.
Controller#session
Accessor for the current session.
Controller#will_answer?
Once called, will this controller ever answer ? This is to optimize
Controller#will_call?
Will this controller call others ? Default value is true.

Calling other controllers includes methods of Borges::Controller itself like inform and confirm. To be able to use these methods you need to return true here.

Class Methods

Controller.application_with_path(path, klass=nil)
Construct this Controller as standalone application
Controller.register_application(app_name, session_class=default_session_class)
Register this class as Application to the Web Server.
Controller.register_authenticated_application(app_name, user, password)
Register this class as access restricted application.

Borges::Component

A borges component is like a widget; it represents part of a page or an entire page. Components can pass control to other components, and return control flow to calling components.

All of the render_..._on methods are there for you to override them and fill them with meaning.

Component is a Borges::Controller.

Component#footer
Construct this components footer. This returns an empty footer by
Component#header
Construct this components header. This returns an empty header by
Component#render_all_on(r)
Render header, content and footer to renderer r.
Component#render_content_on(r)
Renders content of this Component to renderer r.
Component#render_footer_on(r)
Renders this components footer to renderer r.
Component#render_head_elements_on(r)
Render this components head elements to renderer r
Component#render_header_on(r)
Render this components header on renderer r.
Component#render_with(context)
Render the whole component (render_all_on) to the renderer
Component#default_renderer_class
Return the class used by default for rendering this Component.
Component#script
Render a piece of client side script; in html, this can be
Component#style
Render a piece of CSS.

Borges::Filter

Introduction

A Borges Filter allows you to filter requests before they are handled by normal control flow.

To use this class, derive from it and override the method handle_request_in.

Methods

Filter#handle_request_in(req, session)
Do filter action, returning modified response or req,

Users of Borges::Filter must override this method.

Borges::HtmlBuilder

Introduction

Most of the methods of HtmlBuilder can either be called with a block or with an object directly. Function prototype in this case looks like this:

User may choose what seems more natural to him.

The reader should be familiar with a basic set of HTML-tags defined by w3c.

Methods

HtmlBuilder#bold(obj=nil) { ... }
Marks of a run of text as bold.
HtmlBuilder#code(obj) { ... }
Marks a run of text as code.
HtmlBuilder#css_class(class_name)
Makes the current html element an element of css class class_name.
HtmlBuilder#div(obj=nil) { ... }
Creates a div section.
HtmlBuilder#div_named(name, obj=nil) { ... }
Create a div section with id name.
HtmlBuilder#div_with_class(class_name, obj=nil) { ... }
Create a div section with class name class_name.
HtmlBuilder#element_id(id)
Set current html elements id to id.
HtmlBuilder#encode_char(char)
Encode a char using its ascii value; like '
'.
HtmlBuilder#encode_text(obj)
Turn an object into a string and encode it with HTML entities, ie:
HtmlBuilder#head_tag(name)
Create a tag name, returning it.
HtmlBuilder#head_tag_with(name, child)
Create a tag and fill it with child.
HtmlBuilder#heading(str)
Create str as level one heading.
HtmlBuilder#heading_level(obj, level)
Create a heading of level level.
HtmlBuilder#input(type, name=nil, value=nil)
Create a form input field with type, name
HtmlBuilder#italic(obj=nil) { ... }
Set a run of text as italic.
HtmlBuilder#list(items)
Build an unordered list of items from an Enumerable. #text
HtmlBuilder#list_do(items) {|item| ... }
Build an unordered list of items from an Enumerable. The
HtmlBuilder#open_tag(name)
Create a html tag name, making it the current tag under
HtmlBuilder#paragraph(obj=nil) { ... }
Enclose text in paragraph markers.
HtmlBuilder#preformatted(obj=nil) { ... }
Output text as pre-formatted.
HtmlBuilder#render(obj)
Render any Ruby object by sending it the message
HtmlBuilder#set_attribute(attr, val)
Set current tag's attribute attr to value val.
HtmlBuilder#table_headings(*headings)
Create a table heading row. HtmlBuilder#table_heading
HtmlBuilder#table_row { ... }
Create a table row containing the block.
HtmlBuilder#table_row_span(span) { ... }
Create a row that spans several columns.
HtmlBuilder#table_row_width(obj=nil) { ... }
Create a table row containing a single data cell; block gives
HtmlBuilder#table_row_labeled(label, obj=nil) { ... }
Create a row that contains two cells: One containing the
HtmlBuilder#table_spacer_row
Create a table row that contains only a non breaking space.
HtmlBuilder#tag(str)
Create the tag str and close it.
HtmlBuilder#tag_do(name, obj)
Render obj inside the tag name.
HtmlBuilder#text(obj)
Turn an object into a string. It is _not_ recommened to use
HtmlBuilder#title(str)
Create a title html element filled with text str.
HtmlBuilder#url_anchor(url, obj=nil) { ... }
Create a link to another url.
HtmlBuilder#image(url)
Insert an image.
HtmlBuilder#image_altText(urlString, altText)
Insert an image with alternative text. HTML4 image must have
HtmlBuilder#image_width_height(urlString, width, height)
Insert image with given width and height.
HtmlBuilder#image_width_height_altText(url, width, height, altText)
Insert image while specifying width, height and alternative
HtmlBuilder#span { ... }
Insert a span element.

Borges::HtmlRenderer

Introduction

HtmlRenderer is a Borges::HtmlBuilder.

Methods

HtmlRenderer#action_url
Form action url.
HtmlRenderer#anchor_on(symb, obj)
Renderes a hyperlink. The text of the hyperlink is produced
HtmlRenderer#callbacks
Returns all registered callbacks.
HtmlRenderer#context
Return Borges rendering context
HtmlRenderer#default_action { ... }
Define a default action for the page.
HtmlRenderer#file_upload { ... }
Define an action for file upload.
HtmlRenderer#form { ... }
Open a form tag and render elements of action inside the form.
HtmlRenderer#option(label, selected) { ... }
Create an option button that calls the block when clicked.
HtmlRenderer#radio_button(group, value) { ... }
Create a radio button that belongs to group with value
HtmlRenderer#select(list, selected, labels_block=nil) {|item| ... }
Create a selection list of items from list.
HtmlRenderer#style(css)
Link to the cascading style sheet for this document. The
HtmlRenderer#url_for { ... }
Create and register a callback.
HtmlRenderer#url_for_document(obj, mime_type=nil)
Create and register a callback for the document.
HtmlRenderer#value_input(type, value) {|val| ... }
Type preserving input field. The type parameter

Borges::NavigationBar

Introduction

This class helps you to display a navigation menu. Typical usage might be as follows:

class SomeComponent < Borges::Component

  def initialize
    @navigation = Borges::NavigationBar.new(self)
  end	

  def actions
    [:foo, :bar]
  end

  def foo
    inform('foo')
  end

  def bar
    inform('bar')
  end

  def render_content_on(r)
    r.render(@navigation)
    r.hr
    r.text "your content here"
  end
end

This displays a page containing the menu titles 'Foo' and 'Bar', followed by 'your content here'. If clicked, the navigation bar will call back your component: In this example the link behind 'Foo' will call your method foo and 'Bar' will call bar.

Borges::Once

Introduction

The Once filter can be used to ensure that a certain sequence of dialog with the user is maintained. For example, if we want to say first foo and then bar, we will

session.once {
  inform('foo')
  inform('bar')
}

The user will be able to click on the back button once he reaches 'bar', but he cannot have the application display bar again: A refresh or a click on the button will take him to whatever comes after 'bar', thereby maintaining sequence of 'foo' and 'bar'.

As you can see from the above example, a more direct way of accessing Borges::Once is by using Session#once.

Once is a Borges::Filter.

Borges::PluggableTask

Introduction

PluggableTask is a Borges::Task.

PluggableTask allows to create an anonymous task from a block.

Methods

PluggableTask.new { ... }
Create the task from a block.

Borges::Registry

Introduction

Registry for request handlers. Methods for registering, collecting and unregistering handlers.

Registry is a Borges::RequestHandler.

Methods

Registry#base_path
Return the base path for this application.

Borges::Request

Introduction

Borges represents user HTTP requests with this class.

This class uses the concepts

for describing the url the user sees.

/borges/test/@ixINGFNKLHrQvkAo/JQcnHomJ
| path       | handler key    | action key

Methods

Request#action_key
The second part of an action url; this part is specific for
Request#handler_key
The first part of the action url; this part specifies user
Request#cookies
Return cookies.
Request#fields
Return a hash of query POST/GET fields.
Request#headers
Hash of HTTP headers in request.
Request.new(url, headers, fields, cookies)
Construct a Request from a url, the request
Request#path
Return path portion of request url.
Request#url
Return original url in request.
Request#username
Return username that was used for browser basic authorisation.
Request#password
Return password that was used for browser basic authorisation.

Borges::Session

Introduction

Base class for state persistence. This class provides features that can be used to have application wide state that is accessible for all classes.

One of the features of the Session class is that state can be registered and saved for every application point; this state information can be retrieved for every point automatically. This can be used to have state that is restored when the user backtracks in the application.

Methods

Session#action_url_for_continuation(cont)
Register the continuation cont with the system and
Session#add_filter(filter)
Add filter to filter chain. See also Session#filter.
Session#add_to_path(str)
Create a path using the applications base path, augmenting it
Session#application
Return Borges::Application instance for this session.
Session.application(app)
Create a new session and initialize it with the application
Session.basic_auth_do(auth_block) { ... }
Don't execute block unless user can be authenticated using

The example below illustrates passing control to the Test component to a given user. This realm is from then on protected by a basic authentication and only a valid session will execute anything below the Test component.

Session#filter(filter) { ... }
Apply the filter filter and call the block.
Session#initialize_with(application)
Initialize this session by using application as
Session#isolate { ... }
Execute block as part of a transaction. A transaction can
Session#once { ... }
Use Borges::Once to make sure the block passed in gets
Session#page_expired
Tell the user that the current page has expired and cannot be
Session#path
Return this session's path. This is the base path to your
Session#register_for_backtracking(obj)
Register obj for backtracking. The pointed to object
Session#wrap_continuation(cont)
Wrap the continuation cont: Save snapshot of session

Borges::StateHolder

Introduction

Any class that subclasses the StateHolder class will automatically register with the session object for having its state restored on a per page basis (Session#register_for_backtracking).

This can be used to directly create a class that encapsulates information that should correspond to the view state and not to the application state.

Alternatively, the StateHolder class can be used directly to store a single piece of information called contents.

Methods

StateHolder#contents
Access the contents of this state holder.
StateHolder.new(contents)
Initialize a new state holder to hold contents.

Borges::StateRegistry

Introduction

The StateRegistry is used to track, save, and restore the states of objects registered into it.

Session uses this to restore registered objects to the state they were at when the user first viewed the page they are attached to.

For example, in Borges/Component/Counter.rb, the Counter object is registered with the session when it is initialized. Every time a new page is rendered, a snapshot of the Counter's state is created, so that if the user goes back in their history, any requested actions on the Counter will operate with the Counter's state from the first rendering of that page.

Here's a timeline to help explain things better:

load /borges/counter

load /borges/counter/session/a

load /borges/counter/session/b

load /borges/counter/session/b

The snapshots allow an object's state to be backtracked easily. The snapshots created by the registry will drop unreferenced objects when the Session drops an old page from its cache of recent pages.

If the Session's history cache contains 10 pages, and the user performs five operations in the Counter, then moves on to another task and spends 10 operations there, the Counter will no longer be accessible in their Session history, and no longer restorable.

Borges::Task

Introduction

Task is a Borges::Controller. Typically a single controller will use several tasks for achieving his goals, having them return control.

Methods

Task#go
Override this method to define main action of the Task.

Borges::TaskFrame

Introduction

Base class for tasks that need to behave like a component. This makes it possible to embed a sequence of commands (a task) inside a page somewhere. The page will continue to execute on its own UI thread, the task will run in the screen space allocated.

class MyTask < Borges::TaskFrame
  def go
    inform("this is a framed task")
    inform("ending now. ")
    answer('foobar')
  end
end

TaskFrame is a Borges::Component.

Methods

TaskFrame#go
Override this method to provide the frame with a behaviour.

Borges::Transaction

Introduction

A transaction is a group of consecutive page views, which can be made to expire all at once by closing the transaction. A transaction gives you no control over order of page views inside the transaction, but once the transaction is closed, none of the pages within can be refreshed.

Transaction is a Borges::Filter.

Methods

Transaction#close
Closes the transaction, invalidating all the pages that are

*1NOTE: The URL is really the path portion of a URI, not including the host.