Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Overview

This document explains how OFBiz handles screen real estate. It will provide an overview of the OFBiz widget system. Understanding the custom widget system is a prerequisite if you want to change the look and feel of screens in OFBiz. Not only the internal facing screens but also the eCommerce application (the Online store) uses the home-grown OFBiz widget system to render screens. As you probably don't want to run an online store with the default layout that OFBiz comes with, you will need to understand how the OFBiz widget system is designed in order to customize the look and feel of your shop.

There are a couple more scenarios where understanding the OFBiz widget system might be helpful, for example if:

  • You intend to implement a different user interface technology for OFBiz, for example JSF, maybe in combination with AJAX.
  • You want to adapt parts of the OFBiz UI for smaller screens, for example mobile phones. 

...

OFBiz uses a custom widget system, partially based on the FreeMarker templating engine (

http://freemarker.sourceforge.net/

...

).

...

But

...

when

...

trying

...

to

...

understand

...

how

...

to

...

customize

...

both

...

the

...

look

...

and

...

feel

...

as

...

well

...

as

...

the

...

content

...

of

...

screens

...

in

...

OFBiz,

...

FreeMarker

...

essentially

...

comes

...

last.

...

You

...

will

...

need

...

to

...

get

...

your

...

mind

...

around

...

a

...

couple

...

more

...

things

...

before

...

templating

...

comes

...

to

...

play.

...

The

...

'what'

...

and

...

the

...

'how'

...

There

...

are

...

two

...

aspects

...

to

...

a

...

screen:

...

  • What

...

  • data

...

  • does

...

  • it

...

  • show.

...

  • How

...

  • does

...

  • it

...

  • present

...

  • that

...

  • data.

...

A

...

screen

...

is

...

usually

...

displayed

...

as

...

the

...

result

...

of

...

a

...

request.

...

In

...

a

...

webapp

...

this

...

is

...

going

...

to

...

be

...

an

...

HTTP

...

request,

...

for

...

example:

...

http://www.yourserver.com/partymgr/control/main

...

Most

...

OFBiz

...

URLs

...

follow

...

that

...

pattern.

...

The

...

first

...

part

...

after

...

the

...

server

...

name

...

selects

...

the

...

webapp

...

which

...

is

...

supposed

...

to

...

process

...

this

...

request.

...

In

...

this

...

case,

...

the

...

request

...

is

...

for

...

the

...

partymgr

...

webapp.

...

The

...

next

...

part,

...

control,

...

determines

...

that

...

this

...

request

...

should

...

be

...

processed

...

by

...

the

...

Controller

...

Servlet.

...

(See

...

the

...

mapping

...

in

...

web.xml

...

in

...

each

...

webapp.)

...

The

...

Controller

...

Servlet

...

uses

...

the

...

controller.xml

...

file

...

in

...

the

...

webapp's

...

WEB-INF

...

folder

...

to

...

decide

...

what

...

content

...

to

...

serve

...

in

...

response

...

to

...

this

...

request.

Panel
{panel}

Hint:

If

you

wanted

to

integrate

any

functionality

into

OFBiz

which

you

don't

want

to

base

on

the

Controller

Servlet,

you

can

use

any

URL

namespace

except

control

and

map

it

to

your

custom

servlet.

Rendering Screens

How the Controller Servlet handles a request

The Controller Servlet is configured using the controller.xml file in the WEB-INF folder. That file has three kinds of XML elements which are important now:

  1. handler
  2. request-map
  3. view-map

While this is the order in which they typically appear in the controller.xml file, let's start with the request-map.

Element: request-map 

  • Attributes: uri
  • Children: security, event, response

The uri attribute is used to match a request-map to the actual request. Keep in mind that the webapp name and control have already been matched by the servlet container to dispatch processing here. Therefore in our example, the remainder of the URL to match here is just "main".

The request map for the URI main looks like this:

Code Block

{panel}

h1. Rendering Screens


h2. How the Controller Servlet handles a request

The Controller Servlet is configured using the controller.xml file in the WEB-INF folder. That file has three kinds of XML elements which are important now:
# handler
# request-map
# view-map

While this is the order in which they typically appear in the controller.xml file, let's start with the request-map.

h3. Element: request-map 

* Attributes: uri
* Children: security, event, response

The uri attribute is used to match a request-map to the actual request. Keep in mind that the webapp name and control have already been matched by the servlet container to dispatch processing here. Therefore in our example, the remainder of the URL to match here is just "main".

The request map for the URI main looks like this:

{code}
<request-map uri="main">
    <security https="true" auth="true"/>
    <response name="success" type="view" value="main"/>
</request-map>
{code}

The _security_ element specifies that https is required (_

The security element specifies that https is required (https="true"

...

)

...

and

...

that

...

this

...

portion

...

of

...

the

...

application

...

requires

...

proper

...

user

...

authentication

...

and

...

authorization

...

(

...

auth="true"

...

).

...

Parts

...

of

...

the

...

application

...

which

...

do

...

not

...

require

...

either

...

one

...

are

...

the

...

online

...

store,

...

for

...

example.

...

The

...

security

...

element

...

might

...

intercept

...

the

...

processing

...

of

...

the

...

request.

...

If

...

auth="true"

...

and

...

there

...

is

...

no

...

valid

...

OFBiz

...

user

...

attached

...

to

...

the

...

current

...

servlet

...

session,

...

processing

...

will

...

branch

...

into

...

rendering

...

a

...

login

...

screen

...

to

...

obtain

...

a

...

valid

...

OFBiz

...

user,

...

then

...

return

...

and

...

check

...

if

...

the

...

currently

...

authenticated

...

user

...

has

...

sufficient

...

authorization

...

for

...

this

...

request.

...

(???

...

Is

...

this

...

really

...

handled

...

here),

...

after

...

that,

...

processing

...

will

...

continue.

...

If

...

the

...

user

...

logged

...

in

...

before

...

and

...

there

...

is

...

a

...

valid

...

OFBiz

...

user

...

available

...

in

...

the

...

session,

...

processing

...

will

...

just

...

continue.

...

Should

...

the

...

request

...

come

...

in

...

as

...

plain

...

HTTP

...

and

...

https="true"

...

is

...

set,

...

the

...

controller

...

servlet

...

will

...

redirect

...

the

...

client

...

browser

...

to

...

the

...

corresponding

...

HTTPS

...

URL.

...

In

...

our

...

example

...

(partymgr/control/main)

...

there

...

is

...

no

...

event

...

triggered

...

by

...

this

...

request,

...

so

...

no

...

processing

...

happens

...

in

...

this

...

case,

...

as

...

we

...

do

...

not

...

have

...

an

...

event

...

element.

...

In

...

case

...

there

...

is

...

no

...

processing,

...

an

...

outcome

...

of

...

success

...

is

...

the

...

default.

...

The

...

outcome

...

of

...

any

...

processing

...

(which

...

is

...

a

...

string)

...

determines

...

which

...

response

...

to

...

the

...

request

...

is

...

rendered

...

and

...

sent

...

back.

...

In

...

our

...

example,

...

there

...

is

...

only

...

one

...

response

...

to

...

choose

...

from,

...

which

...

is:

Code Block


{code}
<response name="success" type="view" value="main"/>
{code}

The

...

type

...

of

...

response

...

is

...

a

...

view

...

(type="view")

...

with

...

name

...

name

...

of

...

"main"

...

(value="main").

...

Don't

...

get

...

confused

...

by

...

the

...

view

...

name

...

being

...

identical

...

to

...

the

...

URI

...

part

...

that

...

the

...

request-map

...

matched.

...

This

...

is

...

just

...

by

...

chance

...

in

...

this

...

case.

...

The

...

view

...

could

...

be

...

named

...

anything,

...

as

...

long

...

as

...

there

...

will

...

be

...

a

...

view-map

...

element

...

with

...

that

...

name.

Panel
{panel} *

Note:

*

A

view

is

not

the

only

possible

response

to

a

request.

We

will

discuss

other

potential

responses

later

in

this

document.

Right

now,

we're

up

to

understanding

how

an

HTML

screen

is

rendered

in

a

webapp

in

response

to

an

HTTP(S)

request.

{panel} h3.

Element:

...

view-map

...

  •  Attributes: name,

...

  • type,

...

  • page

...

Let's

...

look

...

at

...

the

...

view-map

...

entry

...

for

...

the

...

view

...

with

...

the

...

name

...

main:

Code Block


{code}
<view-map name="main" type="screen" page="component://party/widget/partymgr/PartyScreens.xml#findparty"/>
{code}

The

...

type

...

of

...

the

...

view

...

is

...

screen

...

(type="screen")

...

and

...

the

...

screen

...

definition

...

is

...

read

...

from

...

the

...

URI

...

"component://party/widget/partymgr/PartyScreens.xml#findparty".

...

The

...

component:

...

protocol

...

is

...

a

...

OFBiz

...

internal

...

mechanism

...

which

...

retrieves

...

just

...

the

...

screen

...

definition

...

for

...

the

...

findparty

...

screen

...

from

...

the

...

file

...

PartyScreens.xml.

...

That

...

file

...

may

...

contain

...

more

...

than

...

one

...

screen

...

definition.

...

So

...

this

...

mechanism

...

primarily

...

serves

...

the

...

purpose

...

of

...

not

...

having

...

to

...

have

...

too

...

many

...

small

...

XML

...

files,

...

which

...

would

...

be

...

the

...

case

...

if

...

a

...

single

...

XML

...

file

...

could

...

contain

...

only

...

one

...

screen

...

definition.

...

You

...

can

...

think

...

of

...

such

...

an

...

XML

...

file

...

as

...

a

...

library

...

of

...

screen

...

definitions.

...

We

...

will

...

examine

...

that

...

file

...

and

...

its

...

format

...

later.

...

Element:

...

handler

...

  • Attributes:

...

  • name,

...

  • type,

...

  • class

...

The

...

information

...

from

...

the

...

view-map

...

element

...

is

...

resolved

...

against

...

the

...

handlers

...

defined

...

by

...

the

...

elements

...

of

...

type

...

handler,

...

usually

...

in

...

the

...

first

...

section

...

of

...

the

...

controller.xml

...

document.

...

As

...

we

...

are

...

rendering

...

a

...

view,

...

we're

...

only

...

interested

...

in

...

handlers

...

of

...

type

...

"view",

...

so

...

we

...

do

...

a

...

lookup

...

for

...

a

...

handler

...

with

...

type="view"

...

and

...

name="screen":

Code Block


{code}
<handler name="screen" type="view" class="org.ofbiz.widget.screen.ScreenWidgetViewHandler"/>
{code}

The result of the lookup is a Java class - *

The result of the lookup is a Java class - org.ofbiz.widget.screen.ScreenWidgetViewHandler

...

in

...

this

...

case

...

-

...

which

...

extends

...

the

...

AbstractViewHandler

...

class,

...

which

...

implements

...

the

...

ViewHandler

...

interface.

The control servlet will now pass on the processing to the specified view handler by calling the render method using the a, b and c as parameters. It's entirely up to the implementation of the view handler to generate the response and write it to the servlet response channel.

Panel

Hint: If you wanted to implement a view handler which is not based on the OFBiz widgets toolkit but using whatever other view technology, as long as it's a servlet based technology, you would have to implement your own ViewHandler class and make it known to the controller servlet by adding a handler element to the controller.xml file. Then you could create one or more view-map elements with the type="yournewhandler" and have any response in a request-map dispatch processing to that view.

Anatomy of a screen definition

In our example, the page parameter passed to the render method is a URI: component://party/widget/partymgr/PartyScreens.xml#findparty.

...

This

...

URI

...

is

...

split

...

by

...

the

...

ScreeenWidgetViewHandler

...

into

...

two

...

pieces.

...

Anything

...

left

...

of

...

the

...

hash

...

('#')

...

sign

...

is

...

used

...

to

...

locate

...

an

...

XML

...

file,

...

in

...

this

...

case

...

the

...

file

...

PartyScreens.xml,

...

which

...

should

...

be

...

found

...

in

...

the

...

party/widget/partymgr

...

directory.

...

As

...

mentioned

...

before,

...

a

...

single

...

XML

...

file

...

may

...

contain

...

several

...

screen

...

definitions.

...

Therefore

...

the

...

right-hand

...

portion

...

of

...

the

...

URI

...

is

...

used

...

as

...

a

...

key

...

to

...

find

...

the

...

screen

...

definition

...

with

...

the

...

id

...

findparty

...

within

...

that

...

file.

...

The

...

PartyScreens.xml

...

file

...

looks

...

like

...

this:

...

Element:

...

screen

...

Children:

...

section 

Each screen can consist of a number of sections. In our example, we have only one section.

Element: section

Children: actions, widgets

Element: actions

Here you define the possible actions you need to do. For that you can use different type of actions

  • Labels actions
    • property-map: to define labels (in a map) from a xml labels file
    • property-to-field:

...

    • to

...

    • define

...

    • a

...

    • field

...

    • value

...

    • from

...

    • a

...

    • properties

...

    • file

...

  • Entity

...

  • actions,

...

  • this

...

  • is

...

  • simple

...

  • action

...

  • directly

...

  • on

...

  • entities,

...

  • they

...

  • are

...

    • entity-and

...

    • entity-condition

...

    • entity-one

...

    • get-related-one

...

    • get-related

...

  • Set

...

  • actions,

...

  • mostly

...

  • 2

...

  • "sub-types"

...

    • set

...

    • :

...

    • simple

...

    • assignation

...

    • use

...

    • of

...

    • Groovy

...

    • snippet

...

    • for

...

    • a

...

    • bit

...

    • more

...

    • involved

...

    • assignation

...

    • (filtered,

...

    • modified,

...

    • etc.).

...

    • Advantage:

...

    • no need

...

    • to

...

    • create/open

...

    • a

...

    • new

...

    • file,

...

    • immediately

...

    • visible/readable.

...

      • syntax

...

      • :

...

      • <set

...

      • field="fieldName"

...

      • value="${groovy:

...

      • 1+1}"/>

...

      • (you

...

      • may

...

      • need

...

      • to

...

      • set

...

      • a

...

      • type

...

      • using

...

      • the

...

      • type

...

      • attribute

...

      • of

...

      • the

...

      • set

...

      • element)

...

  • Script
    • script:

...

    • to

...

    • call

...

    • a

...

    • Groovy

...

    • script

...

    • from

...

    • a

...

    • file,

...

    • not

...

    • short

...

    • enough

...

    • to

...

    • be

...

    • snippet.  Inside your Groovy script you prepare and set your data in a context variable.
  • Service
    • service: to call a service

Element: widgets

In our example, the whole section of the screen contains just one widget, which is a decorator-screen.

A decorator literally takes the net content of the screen and decorates it with everything else which you will see on the screen later. For example, the net content of the findparty screen is just the search form, consisting of some field labels, fields, and a submit button. When the page is rendered in the browser, it needs to have headers, footers, the menu bar, etc. All these elements are added by the decorator.

The location attribute of the decorator-screen element points to the definition of the decorator. In most cases, you will find the decorator as part of the framework, not inside a vertical application, unless there is a need to have an application specific decorator. Variables such as ${parameters.mainDecoratorLocation} can be used to point to the decorator definition, which does not always make it easy to find the corresponding definition.

A typical place to look for the definition of the mainDecoratorLocation parameter would be the WEB-INF/web.xml

...

file

...

of

...

the

...

respective

...

webapp,

...

where

...

this

...

parameter

...

can

...

be

...

defined

...

as

...

a

...

context

...

parameter

...

of

...

the

...

web

...

application.

...

In

...

our

...

example

...

(the

...

partymgr

...

app)

...

you

...

will

...

find

...

the

...

following

...

data

...

there:

Code Block


{code}
<context-param>
  <param-name>mainDecoratorLocation</param-name>
    <param-value>component://party/widget/partymgr/CommonScreens.xml</param-value>
    <description>The location of the main-decorator screen to use for this webapp; referred to as a context variable in screen def XML files.</description>
</context-param>
{code}

We

...

can

...

get

...

away

...

with

...

some

...

guesswork

...

about

...

the

...

implementation

...

details

...

of

...

the

...

decorator

...

here,

...

though,

...

to

...

make

...

sure

...

we

...

maintain

...

the

...

bird's

...

eye

...

perspective.

...

You

...

can

...

examine

...

the

...

detailed

...

definition

...

of

...

the

...

decorator

...

later.

...

It's

...

just

...

another

...

widget.

...

Imagine

...

the

...

decorator-screen

...

widget

...

as

...

a

...

kind

...

of

...

screen

...

template

...

with

...

one

...

or

...

more

...

areas

...

to

...

be

...

filled

...

with

...

actual

...

content.

...

In

...

our

...

example,

...

we

...

can

...

see

...

that

...

the

...

screen

...

definition

...

has

...

content

...

for

...

just

...

one

...

decorator-section

...

with

...

the

...

name

...

body.

...

You

...

can

...

think

...

of

...

at

...

analogue

...

to

...

the

...

body

...

section

...

of

...

an

...

HTML

...

page,

...

i.e.

...

this

...

is

...

the

...

main

...

content

...

of

...

the

...

screen.

...

Again,

...

we

...

can

...

find

...

three

...

child

...

elements

...

here:

...

  • conditions
  • widgets
  • fail-widgets

...

Think

...

of

...

this

...

as

...

a

...

simple

...

switch:

...

If

...

the

...

conditions

...

are

...

met,

...

the

...

widgets

...

will

...

be

...

rendered,

...

otherwise

...

the

...

fail-widgets

...

will

...

be

...

rendered.

...

In

...

our

...

example,

...

the

...

condition

...

is

...

used

...

to

...

evaluate

...

if

...

the

...

user

...

belonging

...

to

...

the

...

respective

...

session

...

is

...

allowed

...

to

...

view

...

this

...

screen

...

or

...

not.

...

In

...

case

...

the

...

user's

...

session

...

does

...

not

...

have

...

appropriate

...

rights,

...

a

...

simple

...

error

...

message

...

is

...

displayed,

...

using

...

the

...

label

...

widget.

...

In

...

case

...

the

...

user

...

has

...

the

...

right

...

to

...

view

...

the

...

findparty

...

form,

...

the

...

actual

...

form

...

content

...

is

...

rendered,

...

controlled

...

by

...

the

...

following

...

XML

...

fragment:

Code Block


{code}
<widgets>
  <platform-specific>
    <html>
      <html-template location="component://party/webapp/partymgr/party/findparty.ftl"/>
    </html>
  </platform-specific>
</widgets>
{code}

The plaform

The platform-specific

...

widget

...

again

...

is

...

a

...

kind

...

of

...

switch-case-statement.

...

The

...

OFBiz

...

widget

...

toolkit

...

isn't

...

limited

...

to

...

rendering

...

HTML

...

user

...

interfaces.

...

It

...

can

...

could

...

theoretically

...

render

...

the

...

user

...

interface

...

in

...

any

...

different

...

technology

...

you

...

can

...

imaging,

...

like

...

Swing,

...

XUML,

...

Flash,

...

speech,

...

...

...

In

...

case

...

the

...

UI

...

is

...

being

...

rendered

...

in

...

HTML

...

(which

...

is

...

the

...

case

...

most

...

of

...

the

...

time

...

in

...

OFBiz)

...

all

...

widgets

...

which

...

are

...

children

...

of

...

the

...

html

...

element

...

will

...

be

...

rendered.

...

In

...

this

...

simple

...

example,

...

there

...

is

...

just

...

one

...

widget

...

as

...

a

...

child

...

element

...

of

...

html,

...

which

...

is

...

html-template.

...

That

...

widget

...

uses

...

Freemarker

...

to

...

fill

...

in

...

actual

...

content

...

into

...

a

...

FreeMaker

...

HTML

...

template.

...

The

...

template

...

is

...

pointed

...

to

...

by

...

the

...

component

...

attribute

...

of

...

the

...

html-element

...

widget.

...

The

...

component

...

protocol

...

means

...

that

...

the

...

location

...

of

...

the

...

template

...

is

...

relative

...

to

...

the

...

application.

...

Strictly speaking,

...

this

...

is

...

where

...

we

...

leave

...

the

...

OFBiz

...

widget

...

toolkit

...

and

...

you

...

would

...

have

...

to

...

turn

...

to

...

a

...

FreeMaker

...

tutorial

...

to

...

understand

...

the

...

template

...

being

...

used

...

there.

...

Please

...

refer

...

to the FreeMarker Manual.

You may also use the form widget (using <include-form...)

...

instead

...

of

...

a

...

Freemarker template here.  A form widget is a definition in xml of a list or single form.  The form widget is discussed here.

There are few more include possibilities, at all:

What to display: Data Binding in Forms

Depending on the tool you will use for final rendering, you will use one of the techniques below to bind data to your fields:

Form actions

If you include one or more form widgets, the better way to prepare your data is to use the action sub element to specify actions specific to the form. This helps if you want to reuse your form elsewhere, or have the actions legible when defining your form. There, you will also find a row-action element to prepare forms of the list type (or multi type, which is variation of the list type).  You may also call a service using the service element.  There are plenty of examples of form actions available OOTB, which can be found with the following one line script:

Code Block
languagebash
find -name "*Forms.xml" -printf '\n\n%p\n\n' -exec sed -n -e '/<actions>/,/<\/actions>/p' {} \;

Groovy script form action

If you use Freemarker the better way to prepare your form data is to call one or more Groovy scripts. You call them in the action part of the screen. Inside you prepare and set your data in a context variable. There are several examples of Groovy form actions available OOTB, which can be found with the following one line script:

Code Block
languagebash
find -name "*Forms.xml" -printf '\n\n%p\n\n' -exec xmllint --xpath "//form//actions//script" {} \;
Panel
titletutorial

To continue on screen and form widget, see OFBiz Tutorial - A Beginners Development Guide

template here. There are few more include possibities, at all: * include-menu * include-form * include-tree * include-screen * include-portal-page h1. What to display: Data Binding Depending of the tool you will use for final rendering , you will one of the technic below to bind data to your fields: h2. Form actions If you include one or more form widgets, the better way to prepare your data is to use the action part of the screen for the actions specific to the screen. If you want to reuse your form elsewhere, or have the actions legible when defining your form, you may prefer to use the action part of the form (we will not detail it here). There, you will also find a row-action element to prepare forms of the list type (or multi type, which is variation of the list type). You may also call a service using the service element. Anyway, there are plenty of examples of form action available OOTB. h2. Groovy script If you use Freemarker the better way to prepare your data is to call one or more Grrovy scripts. You call them in the action part of the screen. Inside you prepare and set your data in a *context* variable. There are plenty of examples available OOTB. {note:title=tutorial} To continue on screen and form widget, see [OFBiz Tutorial - A Beginners Development Guide|OFBIZ:OFBiz+Tutorial+-+A+Beginners+Development+Guide] {note}