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 |
---|
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:
- 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.
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 |
---|
] 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} 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. {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 |
---|
} <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 |
---|
} <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 |
---|
} <handler name="screen" type="view" class="org.ofbiz.widget.screen.ScreenWidgetViewHandler"/> {code} |
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
...
inteface.
...
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 |
---|
{panel}
* Hint: *So 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. {panel} h2. Anatomy of a screen definition In our example, the page parameter passed to the render method is a URI: |
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
(cover the service element later)
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 is 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 and fields and a submit button. But 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
Code Block |
---|
${parameters.mainDecoratorLocation} |
can be used to point to the decorator defintion, 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 |
---|
} <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
...
bid's
...
eye
...
perspective.
...
You
...
can
...
examine
...
the
...
detailed
...
definition
...
of
...
the
...
decorator
...
later.
...
It's
...
just
...
another
...
widget.
...
Imaginge
...
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 |
---|
} <widgets> <platform-specific> <html> <html-template location="component://party/webapp/partymgr/party/findparty.ftl"/> </html> </platform-specific> </widgets> {code} |
The
...
plaform-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.
...
Stricly
...
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.
In case you don't
...
want
...
to
...
use
...
FreeMarker
...
templates,
...
you
...
could
...
use
...
a
...
different
...
widget
...
here
...
which
...
makes
...
use
...
of
...
your
...
favorite
...
engine
...
which
...
will
...
generate
...
the
...
HTML
...
you
...
want.
...
(Are
...
there
...
any
...
alternatives
...
to
...
html-template
...
readily
...
available
...
in
...
OFBiz?)
...
For
...
some
...
additional
...
information
...
on
...
the
...
use
...
of
...
the
...
decorator
...
widget,
...
see
...
also
...
the
...
section
...
entitled
...
"Decorating
...
Your
...
Page"
...
of
...
the
...
respective
...
...
...
...
...
What to display: Data Binding
To be written...