Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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
}
<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

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:

...

    • noe

...

    • 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

...

  • 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

...

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}{code}

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
}
<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.

...

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
}
<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.

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

...

instead

...

of

...

a

...

Freemarker

...

template

...

here.

...

There

...

are

...

few

...

more

...

include

...

possibities,

...

at

...

all:

...

  • include-menu

...

  • include-form

...

  • include-tree

...

  • include-screen

...

  • include-portal-page

...

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:

...

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.

...

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}