OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (2024)

This tutorial is designed for beginners with little or no OFBiz experience. It covers the fundamentals of the OFBiz application development process. The goal is to make a developer conversant with best practices, coding conventions, basic control flow, and all other aspects which a developer needs for OFBiz customization.

This tutorial will help you in building your first "Demo Application" in OFBiz.

Important!

For any questions or concerns, please use OFBiz User Mailing List. Details about the mailing lists are available here.

Pre-Requisites

  • For 18.12, the ofbiz-framework trunk and ofbiz-plugins trunk the minimum requirement you need to be installed is Java 1.8 SDK or Sun JDK 1.8.
  • Apache OFBiz can be downloaded and run on both Unix-based and Windows-based systems.
  • Set JAVA_HOME environment variable (It is required to run Gradle build tool)
    Execute the following command on terminal: echo $JAVA_HOME(this will show a path(i.e home directory of your Java installation) which means the variable is set and if not please set)
  • System Specific requirements are availablehere.

Source Code!

OFBiz
Download Apache OFBiz®
OFBiz Source Repository and Access

Tutorial
The source code of the Practice Application demonstrated in this tutorial can be downloaded from [TODO].

Framework Introduction Videos
OFBiz YouTube Channel or Vimeo can be accessed for the same.

Overview (Introduction to OFBiz)

Apache OFBiz (OFBiz hereafter) is a suite of enterprise applications built on a common architecture using a Unified Data Model, common logic and process components. The loosely coupled nature of the applications makes these components easy to understand, extend and customize.

The tools and architecture of OFBiz make it easy to efficiently develop and maintain enterprise applications. This makes it possible for us as the creators and maintainers of the project to quickly release new functionality and maintain existing functionality without extensive effort. It also makes it easy to customize and extend existing functionality when you have a specific need.

The architecture alone makes it easier for you to customize the applications to your needs, but many of the best flexibility points in the system would be meaningless and even impossible if the system was not distributed as open-source software. OFBiz is licensed under the Apache License Version 2.0 (ASL2) which grants you the right to customize, extend, modify, repackage, resell, and many other potential uses of the system.

No restrictions are placed on these activities because we feel that they are necessary for the effective use of this type of software. Unlike other open-source licenses, such as the GPL, your changes do not have to be released as open-source. There are obvious benefits to contributing certain improvements, fixes, and additions back to the core project, but some changes will involve proprietary or confidential information that must not be released to the public. For this reason, OFBiz uses theASL2 which does not require this. The only required thing is to not remove the "copyright, patent, trademark, and attribution notices" you find in files. For more information on open source licenses see the Open Source Initiative (OSI) website atwww.opensource.org.

Another benefit of this open-source model is that we receive constant feedback from those who are using the software. We have received countless bug fixes, improvement suggestions, and best-practice business advice from users and potential users of OFBiz. Many of the greatest features in the project were inspired by some comments or suggestions sent to the mailing lists associated with the project. With dozens of organizations using the software and probably hundreds of deployed sites using one piece or another of the project we generally get 20-30 emails each day about the project.

To make sure our functionality is timely and useful we always start by researching public standards and common usage for any component we are working on. This helps us support and use common vocabularies and gives us an instant breadth of options and features that can only be achieved through standards processes and other group efforts. It also opens doors in the future for flexible communication with other systems that are built around the same standards, both inside your organization and in the partner or other organizations.

The applications and application components that come with the system provide you with a broad and flexible basis that can be used as-is with the best-practices-based designs or customized to your own special needs. The applications facilitate the management of everything from parties and products to accounting, customer service, and internal resource and asset management.

Reference:http://ofbiz.apache.org/apache-ofbiz-project-overview.html

Setting up and Running OFBiz

Download Apache OFBiz Framework

If you haven't already checkout Apache OFBiz Framework on your machine, let's do it.Anyone can checkout or browse the source code in the OFBiz public GIT repository.If you don't have Git, to install it you can goherefor instructions.

To clone the source code, simply use the following command (if you are using a GUI client, configure it appropriately):

  • Download ofbiz-framework codebase:$ git clone https://gitbox.apache.org/repos/asf/ofbiz-framework.git ofbiz-framework
  • Now point ofbiz-framework codebase to release18.12:$ git checkout origin/release18.12

Since therelease18.12 was split into ofbiz-framework and ofbiz-plugins, the specialpurpose and hot-deploy directories have disappeared.
New components must be put in a plugins directory which works as was the hot-deploy directory.

For OFBiz existing components, check them out using the Gradle tasksor the GIT command

1.Checkout viaGradle tasks

To get all components use pullAllPluginsSource(This command should be run from ofbiz-framework home). Beware this deletes a previously existing plugins directory.

For Linux/Mac: $ ./gradlew pullAllPluginsSourceFor Windows: > gradlew pullAllPluginsSource

2.Checkout viaGIT command(Following commands should be run from ofbiz-framework home)

  • Download ofbiz-plugins codebase:$ git clone https://gitbox.apache.org/repos/asf/ofbiz-plugins.git plugins
  • Now point ofbiz-plugins codebase to release18.12:$ git checkout origin/release18.12

For more details referApacheOFBiz Source Repositorypage.

Running Apache OFBiz

  • Using the command line, build and start OFBiz (with demo data), use command:
For Linux/Mac: $ ./gradlew cleanAll loadAll ofbizFor Windows: > gradlew cleanAll loadAll ofbiz

The above command will load demo data, (Sample Data to run apps) which comes with OFBiz, inDerbyDatabase. Derby comes configured with OFBiz ready to use.

For more options see README.MD.

  • Direct your browser tohttps://localhost:8443/webtoolsand login with username "admin" and password "ofbiz" and look around a bit.
    That's it, Apache OFBiz is now running on your system!!

Create Your First Application (Hello World...)

Introduction to Components

An OFBiz component is a folder, containing a special XML file, named “ofbiz-component.xml”, that describes the resources to be loaded and required by the component.
OFBiz itself is a set of components.

  • framework components:These are lower-level components that provide the technical layer and tools to the application components; the features provided by these components are typically the ones provided by any other development framework (data layer, business logic layer, transaction handling, data source pools, etc…)
  • application components:These are generic business components required for ERP applications that can be extended/customized (product, order, party, manufacturing, accounting, etc…); application components have access to the services and tools provided by the framework components and to the services published by other application components.
  • pluginscomponents:These components are similar to applications components but meant for special purpose applications like eCommerce, google base integration, eBay integration, etc

Create the plugin/component

It's very easy to set up a new custom component in OFBiz in the plugins directory. Using the command line you just need to run the following command.

$ ./gradlew createPlugin -PpluginId=ofbizDemo

OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (1)

Running your first application

Before running our first component, let's say 'Hello to the World'

  1. Simply open $OFBIZ_HOME/plugins/ofbizDemo/widget/OfbizDemoScreens.xml file from the ofbizDemo plugin (you just created)

    <?xmlversion="1.0"encoding="UTF-8"?><screens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ofbiz.apache.org/Widget-Screen" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Screen http://ofbiz.apache.org/dtds/widget-screen.xsd"> <screen name="main"> <section> <actions> <set field="headerItem" value="main"/><!-- this highlights the selected menu-item with name "main" --> </actions> <widgets> <decorator-screen name="OfbizDemoCommonDecorator" location="${parameters.mainDecoratorLocation}"> <decorator-section name="body"> <label text="Hello World!! :)"/> </decorator-section> </decorator-screen> </widgets> </section> </screen></screens>

    We have only added the<label text="Hello World!! :)" />

  2. Now you will need to restart OFBiz by reloading data($ ./gradlewloadAll ofbiz). It's required as you have created a new component with some security data for your component (Setup by default in your component data directory as OfbizDemoSecurityGroupDemoData.xml) and as you will restart it, the ofbizdemo component will also be loaded.
  3. As OFBiz restarted direct your browser to your application herehttps://localhost:8443/ofbizDemo
  4. You will be asked to log in. Login with user: admin password: ofbiz.
  5. As you log in you will see the ofbizdemo application up with the hello world message you have put on screen as shown below the given image.
    That's it, congratulations your first component is set up and running.

Creating First Database Entity (Table)

Defining entity

To create custom Entities/Tables in the database, you simply need to provide entity definition in the$OFBIZ_HOME/plugins/ofbizDemo/entitydef/entitymodel.xmlfile of your ofbizdemo application.This file structure is already set up when you used the Gradle task to set up your component. You simply need to go in and provide entity definition as shown below. Here we are going to add two new entities for the ofbizdemo application.

<?xml version="1.0" encoding="UTF-8"?> <entitymodel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/entitymodel.xsd"> <title>Entity of an Open For Business Project Component</title> <description>None</description> <version>1.0</version> <entity entity-name="OfbizDemoType" package-name="org.apache.ofbiz.ofbizdemo" title="OfbizDemo Type Entity"> <field name="ofbizDemoTypeId" type="id"><description>primary sequenced ID</description></field> <field name="description" type="description"></field> <prim-key field="ofbizDemoTypeId"/> </entity> <entity entity-name="OfbizDemo" package-name="org.apache.ofbiz.ofbizdemo" title="OfbizDemo Entity"> <field name="ofbizDemoId" type="id"><description>primary sequenced ID</description></field> <field name="ofbizDemoTypeId" type="id"></field> <field name="firstName" type="name"></field> <field name="lastName" type="name"></field> <field name="comments" type="comment"></field> <prim-key field="ofbizDemoId"/> <relation type="one" fk-name="ODEM_OD_TYPE_ID" rel-entity-name="OfbizDemoType"> <key-map field-name="ofbizDemoTypeId"/> </relation> </entity> </entitymodel>

Now have a look at the $OFBIZ_HOME/plugins/ofbizDemo/ofbiz-component.xml file. You already have resource entries made in it for loading these entities from their definitions to the database when the component loads. As shown below:

<entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel.xml"/>

To check simply re-start OFBiz (Ctrl+C followed by "./gradlew ofbiz") and direct your browser to Entity Data Maintenance Tool here:https://localhost:8443/webtools/control/entitymaintand search for entities OfbizDemoType and OfbizDemo. You will see it as shown in below given image.

OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (2)


Preparing data for an entity

As you have set up your custom entities, now is the time to prepare some sample data for it. You can do it in data XML files already set up under the data directory of your component as$OFBIZ_HOME/plugins/ofbizDemo/data/OfbizDemoTypeData.xmland$OFBIZ_HOME/plugins/ofbizDemo/data/OfbizDemoDemoData.xml. Set it up as shown below:

OfbizDemoTypeData.xml

<?xml version="1.0" encoding="UTF-8"?><entity-engine-xml> <OfbizDemoType ofbizDemoTypeId="INTERNAL" description="Internal Demo - Office"/> <OfbizDemoType ofbizDemoTypeId="EXTERNAL" description="External Demo - On Site"/></entity-engine-xml>

OfbizDemoDemoData.xml

<?xml version="1.0" encoding="UTF-8"?><entity-engine-xml> <OfbizDemo ofbizDemoId="SAMPLE_DEMO_1" ofbizDemoTypeId="INTERNAL" firstName="Sample First 1" lastName="Sample Last 1" comments="This is test comment for first record."/> <OfbizDemo ofbizDemoId="SAMPLE_DEMO_2" ofbizDemoTypeId="INTERNAL" firstName="Sample First 2" lastName="Sample last 2" comments="This is test comment for second record."/> <OfbizDemo ofbizDemoId="SAMPLE_DEMO_3" ofbizDemoTypeId="EXTERNAL" firstName="Sample First 3" lastName="Sample last 3" comments="This is test comment for third record."/> <OfbizDemo ofbizDemoId="SAMPLE_DEMO_4" ofbizDemoTypeId="EXTERNAL" firstName="Sample First 4" lastName="Sample last 4" comments="This is test comment for fourth record."/></entity-engine-xml>

Now again have a look at$OFBIZ_HOME/plugins/ofbizDemo/ofbiz-component.xmlfile. You already have resource entry made in it for loading data prepared in these files as:

Entry to be done in ofbiz-component.xml

<entity-resource type="data" reader-name="seed" loader="main" location="data/OfbizDemoTypeData.xml"/><entity-resource type="data" reader-name="demo" loader="main" location="data/OfbizDemoDemoData.xml"/>

Loading data in the entity

At this moment to load this sample data into entities/tables defined you can either run "./gradlew loadAll" on the console or can directly go here in webtools to load entity XMLhttps://localhost:8443/webtools/control/EntityImport.

Simply put your xml data in "Complete XML document (root tag: entity-engine-xml):" text area and hit "Import Text", as shown in below given image

OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (3)

As you will hit Import Text, it will load data and will show the result as shown below

OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (4)

After completing the data load process again visit Entity Data Maintenance(https://localhost:8443/webtools/control/entitymaint) and check your entities, you will find this data here that you just loaded.

That's it, you have successfully imported the data in the database tables, super easy, right!

Form and Services

In our previous section, we have seen how to create the entities (tables), now it's time to create a form that will allow you to make entries in that entity.

Create a Service

Before preparing the form, let's write aserviceto create records in the database for the OfbizDemo entity in the service definition XML file ($OFBIZ_HOME/plugins/ofbizDemo/servicedef/services.xml)

services.xml

<?xml version="1.0" encoding="UTF-8"?><services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/services.xsd"> <description>OfbizDemo Services</description> <vendor></vendor> <version>1.0</version> <service name="createOfbizDemo" default-entity-name="OfbizDemo" engine="entity-auto" invoke="create" auth="true"> <description>Create an Ofbiz Demo record</description> <auto-attributes include="pk" mode="OUT" optional="false"/> <auto-attributes include="nonpk" mode="IN" optional="false"/> <override name="comments" optional="true"/> </service> </services>

Now again have a look at the $OFBIZ_HOME/plugins/ofbizDemo/ofbiz-component.xml file. You already have resource entry made in it for loading services defined in this file as:

<!-- service resources: model(s), eca(s) and group definitions --><service-resource type="model" loader="main" location="servicedef/services.xml"/>

For this service definition to load you will need to restart OFBiz. To test this service you directly go to webtools --> Run Service option here:https://localhost:8443/webtools/control/runService

OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (5)

Running service via Web Tools: This is a smart utility provided by the framework to run your service.

On submission of the form above, you will present a form to enter IN parameters of the service.

Use of UILabels (Introduction)

Internationalization of Apache OFBiz is really easy, we define the UI Labels in various languages, and on the basis of the user's locale, the respective label is shown.

Here is the example of UI Labels (while creating component <component-name>UiLabels.xml is created by default, in our case it isOfbizDemoUiLabels.xml)

OfbizDemoUiLabels.xml

<?xml version="1.0" encoding="UTF-8"?><resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-properties.xsd"> <property key="OfbizDemoApplication"> <value xml:lang="en">OfbizDemo Application</value> <value xml:lang="zh">OfbizDemo应用程�?</value> <value xml:lang="zh-TW">OfbizDemo應用程�?</value> </property> <property key="OfbizDemoCompanyName"> <value xml:lang="en">OFBiz: OfbizDemo</value> <value xml:lang="zh-TW">OFBiz: OfbizDemo</value> </property> <property key="OfbizDemoCompanySubtitle"> <value xml:lang="en">Part of the Apache OFBiz Family of Open Source Software</value> <value xml:lang="it">Un modulo della famiglia di software open source Apache OFBiz</value> <value xml:lang="zh">开�?软件OFBiz的组�?部分</value> <value xml:lang="zh-TW">開�?軟體OFBiz的組�?部分</value> </property> <property key="OfbizDemoViewPermissionError"> <value xml:lang="en">You are not allowed to view this page.</value> <value xml:lang="zh">�?�?许你�?览这个页�?�。</value> <value xml:lang="zh-TW">�?�?許您檢視這個�?�?�.</value> </property></resource>

Create the add Form

Let's create our first form for this service and for that let's edit the existing file at location$OFBIZ_HOME/plugins/ofbizDemo/widget/OfbizDemoForms.xmland add Create Form for OfbizDemo as shown below:

OfbizDemoForms.xml

<?xml version="1.0" encoding="UTF-8"?><forms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ofbiz.apache.org/Widget-Form" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Form http://ofbiz.apache.org/dtds/widget-form.xsd"> <form name="AddOfbizDemo" type="single" target="createOfbizDemo"> <!-- We have this utility in OFBiz to render form based on service definition. Service attributes will automatically lookedup and will be shown on form --> <auto-fields-service service-name="createOfbizDemo"/> <field name="ofbizDemoTypeId" title="${uiLabelMap.CommonType}"> <drop-down allow-empty="false" current-description=""> <!---We have made this drop down options dynamic(Values from db) using this --> <entity-options description="${description}" key-field-name="ofbizDemoTypeId" entity-name="OfbizDemoType"> <entity-order-by field-name="description"/> </entity-options> </drop-down> </field> <field name="submitButton" title="${uiLabelMap.CommonAdd}"><submit button-type="button"/></field> </form></forms>

Here you can notice we have used auto-fields-service to auto-generate the form based on service definition IN/OUT attributes.

Go to Screens XML file(OfbizDemoScreens.xml) add this form location in decorator body to your screen that you used to show the Hello World... text. As shown below

Adding Form Location to the Main Screen

<?xml version="1.0" encoding="UTF-8"?><screens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ofbiz.apache.org/Widget-Screen" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Screen http://ofbiz.apache.org/dtds/widget-screen.xsd"> <screen name="main"> <section> <actions> <set field="headerItem" value="main"/> <!-- this highlights the selected menu-item with name "main" --> </actions> <widgets> <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}"> <decorator-section name="body"> <screenlet title="Add Ofbiz Demo"> <include-form name="AddOfbizDemo" location="component://ofbizDemo/widget/OfbizDemoForms.xml"/> </screenlet> </decorator-section> </decorator-screen> </widgets> </section> </screen></screens>

Controller Entry for Form

Before you go to the form and start creating OfbizDemo records from add form, you will need to make an entry in the$OFBIZ_HOME/plugins/ofbizDemo/webapp/ofbizDemo/WEB-INF/controller.xmlfile for the target service which will be called when a form is submitted. You can do it as shown below under Request Mappings in your ofbizdemo apps controller file:

<request-map uri="createOfbizDemo"> <security https="true" auth="true"/> <event type="service" invoke="createOfbizDemo"/> <response name="success" type="view" value="main"/></request-map>


Everything set, let's have a look into to our recently create formhttps://localhost:8443/ofbizDemo

OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (6)

The primary key(ofbizDemoId) is not needed to be sent in with the form, it will be auto sequenced by OFBiz in database records.


Create a Find Form

Let's create a find form for the entity OfbizDemo so that you search OfbizDemos being created.

1.) Add the forms (FindOfbizDemo and ListOfbizDemo) in OfbizDemoForms.xml

OfbizDemoForms.xml

<form name="FindOfbizDemo" type="single" target="FindOfbizDemo" default-entity-name="OfbizDemo"> <field name="noConditionFind"><hidden value="Y"/> <!-- if this isn't there then with all fields empty no query will be done --></field> <field name="ofbizDemoId" title="${uiLabelMap.OfbizDemoId}"><text-find/></field> <field name="firstName" title="${uiLabelMap.OfbizDemoFirstName}"><text-find/></field> <field name="lastName" title="${uiLabelMap.OfbizDemoLastName}"><text-find/></field> <field name="ofbizDemoTypeId" title="${uiLabelMap.OfbizDemoType}"> <drop-down allow-empty="true" current-description=""> <entity-options description="${description}" key-field-name="ofbizDemoTypeId" entity-name="OfbizDemoType"> <entity-order-by field-name="description"/> </entity-options> </drop-down> </field> <field name="searchButton" title="${uiLabelMap.CommonFind}" widget-style="smallSubmit"><submit button-type="button" image-location="/images/icons/magnifier.png"/></field></form> <form name="ListOfbizDemo" type="list" list-name="listIt" paginate-target="FindOfbizDemo" default-entity-name="OfbizDemo" separate-columns="true" odd-row-style="alternate-row" header-row-style="header-row-2" default-table-style="basic-table hover-bar"> <actions> <!-- Preparing search results for user query by using OFBiz stock service to perform find operations on a single entity or view entity --> <service service-name="performFind" result-map="result" result-map-list="listIt"> <field-map field-name="inputFields" from-field="ofbizDemoCtx"/> <field-map field-name="entityName" value="OfbizDemo"/> <field-map field-name="orderBy" from-field="parameters.sortField"/> <field-map field-name="viewIndex" from-field="viewIndex"/> <field-map field-name="viewSize" from-field="viewSize"/> </service> </actions> <field name="ofbizDemoId" title="${uiLabelMap.OfbizDemoId}"><display/></field> <field name="ofbizDemoTypeId" title="${uiLabelMap.OfbizDemoType}"><display-entity entity-name="OfbizDemoType"/></field> <field name="firstName" title="${uiLabelMap.OfbizDemoFirstName}" sort-field="true"><display/></field> <field name="lastName" title="${uiLabelMap.OfbizDemoLastName}" sort-field="true"><display/></field> <field name="comments" title="${uiLabelMap.OfbizDemoComment}"><display/></field></form>

Form or Screen's action tag is used for data preparation logic for your view.

We have used OOTB OFBiz generic service performFind to do the search operations which is easy and efficient to use when you have to perform a search on one entity or one view entity.

2.) In next step, we will include these forms in the screen, let's add these forms in theOfbizDemoScreens.xmlfile. For this include theFindOfbizDemoscreen defined below in theOfbizDemoScreens.xml

<!-- Find and list all ofbizdemos in a tabular format --><screen name="FindOfbizDemo"> <section> <actions> <set field="headerItem" value="findOfbizDemo"/> <set field="titleProperty" value="PageTitleFindOfbizDemo"/> <set field="ofbizDemoCtx" from-field="parameters"/> </actions> <widgets> <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}"> <decorator-section name="body"> <section> <condition> <if-has-permission permission="OFBIZDEMO" action="_VIEW"/> </condition> <widgets> <decorator-screen name="FindScreenDecorator" location="component://common/widget/CommonScreens.xml"> <decorator-section name="search-options"> <include-form name="FindOfbizDemo" location="component://ofbizDemo/widget/OfbizDemoForms.xml"/> </decorator-section> <decorator-section name="search-results"> <include-form name="ListOfbizDemo" location="component://ofbizDemo/widget/OfbizDemoForms.xml"/> </decorator-section> </decorator-screen> </widgets> <fail-widgets> <label style="h3">${uiLabelMap.OfbizDemoViewPermissionError}</label> </fail-widgets> </section> </decorator-section> </decorator-screen> </widgets> </section></screen>

3.) Add request mapping for accessing this new Find Ofbiz Demo page in controller.xml

<!-- Request Mapping --><request-map uri="FindOfbizDemo"><security https="true" auth="true"/><response name="success" type="view" value="FindOfbizDemo"/></request-map> <!-- View Mapping --><view-map name="FindOfbizDemo" type="screen" page="component://ofbizDemo/widget/OfbizDemoScreens.xml#FindOfbizDemo"/>

4.)Now, let's add a new menu for showing find option.
Creating a menu is really simple in OFBiz, all the menus are defined is *menus.xml.
When we create a component from a Gra, we get a file namedOfbizDemoMenus.xml

Make the following entry in the OfbizDemoMenus.xml file.

OfbizDemoMenus.xml

<?xml version="1.0" encoding="UTF-8"?><menus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ofbiz.apache.org/Widget-Menu" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Menu http://ofbiz.apache.org/dtds/widget-menu.xsd"> <menu name="MainAppBar" title="${uiLabelMap.OfbizDemoApplication}" extends="CommonAppBarMenu" extends-resource="component://common/widget/CommonMenus.xml"> <menu-item name="main" title="${uiLabelMap.CommonMain}"><link target="main"/></menu-item> <menu-item name="findOfbizDemo" title="${uiLabelMap.OfbizDemoFind}"><link target="FindOfbizDemo"/></menu-item> </menu></menus>

Use of UI Labels (Completion)

As we have seen above Internationalization of Apache OFBiz is really easy, we define the UI Labels in various languages, and on the basis of the user's locale, the respective label is shown.

Here we complete the example of UI Labels (while creating component <component-name>UiLabels.xml is created by default, in our case it isOfbizDemoUiLabels.xml)

OfbizDemoUiLabels.xml

<property key="OfbizDemoFind"> <value xml:lang="en">Find</value></property><property key="OfbizDemoFirstName"> <value xml:lang="en">First Name</value></property><property key="OfbizDemoId"> <value xml:lang="en">OFBiz Demo Id</value></property><property key="OfbizDemoLastName"> <value xml:lang="en">Last Name</value></property>

Now simply restart the server, under the ofbizdemo application (https://localhost:8443/ofbizDemo/control/main) you will see the Find menu option.

OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (7)

Services using other engines

Whenever you have to build a business logic you should prefer to write services to leverage features from its built-in Service Engine.

The service "createOfbizDemo" that you created earlier was using engine="entity-auto" and hence you didn't need to provide its implementation and OFBiz took care of create operation. When you need to work on complex operations in service involving multiple entities from database and custom logics to be built, you need to provide custom implementation to your service. In this section, we will focus on this.

Service in Java

You can implement a service in Java as directed here in the below-given steps:

1.) Define your service, here again, we will be operating on the same entity(OfbizDemo) of our custom Ofbiz Demo application.Open your service definition file $OFBIZ_HOME/plugins/ofbizDemo/servicedef/services.xmland add a new definition as:

services.xml

<service name="createOfbizDemoByJavaService" default-entity-name="OfbizDemo" engine="java" location="com.companyname.ofbizdemo.services.OfbizDemoServices" invoke="createOfbizDemo" auth="true"> <description>Create an Ofbiz Demo record using a service in Java</description> <auto-attributes include="pk" mode="OUT" optional="false"/> <auto-attributes include="nonpk" mode="IN" optional="false"/> <override name="comments" optional="true"/></service>

Notice we have this time used engine="java".

2.)Create package "com.companyname.ofbizdemo.services" in your ofbizDemo components src/main/java directory (create those if they don't exist in your src directory).

Example: src/main/java/com/companyname/ofbizdemo/services.Services for your application that have to be implemented in Java can be placed in this java directory.

3.) Define new Java Class in file OfbizDemoServices.java here in services directory and implement a method, which is going to be invoked by your service definition, as shown below:

OfbizDemoServices.java

package com.companyname.ofbizdemo.services;
import java.util.Map;

import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.service.DispatchContext;
import org.apache.ofbiz.service.ServiceUtil;

public class OfbizDemoServices {

public static final String module = OfbizDemoServices.class.getName();

public static Map<String, Object> createOfbizDemo(DispatchContext dctx, Map<String, ? extends Object> context) {
Map<String, Object> result = ServiceUtil.returnSuccess();
Delegator delegator = dctx.getDelegator();
try {
GenericValue ofbizDemo = delegator.makeValue("OfbizDemo");
// Auto generating next sequence of ofbizDemoId primary key
ofbizDemo.setNextSeqId();
// Setting up all non primary key field values from context map
ofbizDemo.setNonPKFields(context);
// Creating record in database for OfbizDemo entity for prepared value
ofbizDemo = delegator.create(ofbizDemo);
result.put("ofbizDemoId", ofbizDemo.getString("ofbizDemoId"));
Debug.log("==========This is my first Java Service implementation in Apache OFBiz. OfbizDemo record created successfully with ofbizDemoId: "+ofbizDemo.getString("ofbizDemoId"));
} catch (GenericEntityException e) {
Debug.logError(e, module);
return ServiceUtil.returnError("Error in creating record in OfbizDemo entity ........" +module);
}
return result;
}
}

4.) Stop the server and re-start using "./gradlew ofbiz", it will compile your class and will make it available when ofbiz restarts which updated jar file.

5.) Test service implemented using webtools --> Run Service option(https://localhost:8443/webtools/control/runService) or simplyupdate/add the service name/new service being called by your controller request to use this service instead and use add form in your app that you prepared earlier. By doing this your Add OfbizDemo form will call this java service.Find below to new servicecreateOfbizDemoByJavaServicewhich will be calledby your controller request.

<request-map uri="createOfbizDemoByJavaService">
<security https="true" auth="true"/>
<event type="service" invoke="createOfbizDemoByJavaService"/>
<response name="success" type="view" value="main"/>
</request-map>

To make sure this new service implementation is being executed, you can check this line in the console log that you have put in your code using Debug.log(....). For logging in OFBiz, you must always use Debug class methods in Java classes.

Console Log

[java] 2021-07-22 00:18:06,918(http-bio-0.0.0.0-8443-exec-2) [ OfbizDemoServices.java:27:INFO ] ==========This is my first Java Service implementation in Apache OFBiz. OfbizDemo record created successfully with ofbizDemoId: ......

Service in Groovy

To utilize features of on-the-fly compilation and fewer lines of code you can implement services for building business logic in OFBiz using Groovy DSL.

To implement a service using Groovy you can follow below given steps:

1.) Add new service definition to services/services.xml file as:

services.xml

<service name="createOfbizDemoByGroovyService" default-entity-name="OfbizDemo" engine="groovy"
location="component://ofbizDemo/groovyScripts/OfbizDemoServices.groovy" invoke="createOfbizDemo" auth="true">
<description>Create an Ofbiz Demo record using a service in Groovy</description>
<auto-attributes include="pk" mode="OUT" optional="false"/>
<auto-attributes include="nonpk" mode="IN" optional="false"/>
<override name="comments" optional="true"/>
</service>

2.) Add new groovy services file here component://ofbizDemo/script/com/companyname/ofbizdemo/OfbizDemoServices.groovy

3.) Add service implementation to the file OfbizDemoServices.groovy

OfbizDemoServices.groovy

import org.apache.ofbiz.entity.GenericEntityException;

def
createOfbizDemo() {
result = [:];
try {
ofbizDemo = delegator.makeValue("OfbizDemo");
// Auto generating next sequence of ofbizDemoId primary key
ofbizDemo.setNextSeqId();
// Setting up all non primary key field values from context map
ofbizDemo.setNonPKFields(context);
// Creating record in database for OfbizDemo entity for prepared value
ofbizDemo = delegator.create(ofbizDemo);
result.ofbizDemoId = ofbizDemo.ofbizDemoId;
logInfo("==========This is my first Groovy Service implementation in Apache OFBiz. OfbizDemo record "
+"created successfully with ofbizDemoId: "+ofbizDemo.getString("ofbizDemoId"));
} catch (GenericEntityException e) {
logError(e.getMessage());
return error("Error in creating record in OfbizDemo entity ........");
}
return result;
}

4.) Stop the server and re-start using"./gradlew ofbiz", this time we just need to load the new service definition, no explicit compilation is required as it's a service implementation in Groovy.

5.) Test service implemented using webtools --> Run Service option(https://localhost:8443/webtools/control/runService) or simply update/add the service name/new service being called by your controller request to use this service instead and use add form in your app that you prepared earlier for testing. By doing this your Add OfbizDemo form will call this groovy service. Find below the new servicecreateOfbizDemoByGroovyService which will be calledby your controller request.

controller.xml

<request-map uri="createOfbizDemoByGroovyService">
<security https="true" auth="true"/>
<event type="service" invoke="createOfbizDemoByGroovyService"/>
<response name="success" type="view" value="main"/>
</request-map>

To make sure this new service implementation is being executed, you can check this line in the console log that you have put in your code using Debug.log(....). For logging in OFBiz, you must always use Debug class methods in Java classes.

2021-07-22 00:29:08,212 |jsse-nio-8443-exec-7 |GroovyBaseScript |I| ==========This is my first Groovy Service implementation in Apache OFBiz. OfbizDemo record created successfully with ofbizDemoId: .....

To get more details about using Groovy DSL for service and events implementation in Apache OFBiz you can refer document created by Jacopo Cappellato in OFBiz Wikihere.

Events

Events demonstration

Events in Apache OFBiz are simply methods used to work with HttpServletRequest and HttpServletResponse objects. You don't need to provide definitions of these as you did with services. These are directly called from the controller. Events are also useful when you want to add custom server-side validations to input parameters. For performing database operations you still call prebuilt services from events.

To write an event in OFBiz follow these steps:

1.) Add a new events directory to package and a new Events class file as mentioned here:

OfbizDemoEvents.java

package com.companyname.ofbizdemo.events;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericValue;
import org.apache.ofbiz.service.GenericServiceException;
import org.apache.ofbiz.service.LocalDispatcher;

public class OfbizDemoEvents {

public static final String module = OfbizDemoEvents.class.getName();

public static String createOfbizDemoEvent(HttpServletRequest request, HttpServletResponse response) {
Delegator delegator = (Delegator) request.getAttribute("delegator");
LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
GenericValue userLogin = (GenericValue) request.getSession().getAttribute("userLogin");

String ofbizDemoTypeId = request.getParameter("ofbizDemoTypeId");
String firstName = request.getParameter("firstName");
String lastName = request.getParameter("lastName");

if (UtilValidate.isEmpty(firstName) || UtilValidate.isEmpty(lastName)) {
String errMsg = "First Name and Last Name are required fields on the form and can't be empty.";
request.setAttribute("_ERROR_MESSAGE_", errMsg);
return "error";
}
String comments = request.getParameter("comments");

try {
Debug.logInfo("=======Creating OfbizDemo record in event using service createOfbizDemoByGroovyService=========", module);
dispatcher.runSync("createOfbizDemoByGroovyService", UtilMisc.toMap("ofbizDemoTypeId", ofbizDemoTypeId,
"firstName", firstName, "lastName", lastName, "comments", comments, "userLogin", userLogin));
} catch (GenericServiceException e) {
String errMsg = "Unable to create new records in OfbizDemo entity: " + e.toString();
request.setAttribute("_ERROR_MESSAGE_", errMsg);
return "error";
}
request.setAttribute("_EVENT_MESSAGE_", "OFBiz Demo created succesfully.");
return "success";
}
}

2.) Add controller request of calling this event as:

controller.xml

<request-map uri="createOfbizDemoEvent">
<security https="true" auth="true"/>
<event type="java" path="com.companyname.ofbizdemo.events.OfbizDemoEvents" invoke="createOfbizDemoEvent"/>
<response name="success" type="view" value="main"/>
<response name="error" type="view" value="main"/>
</request-map>

3.) Stop and start the server by rebuilding it as we need to compile the Java event class that we have added in #1.

4.)Now to test the event you can simply change the AddOfbizDemo form target to read "createOfbizDemoEvent" and as it's submitted now it will call your event.

Difference between service and event

Here are some differences between services and events,

  • Events are used for validations and conversions using a map processor, while services are used for business logic like CRUD operations.
  • Service returns Map.
  • Event returns String.
  • Services are loaded with the server, any changes in definition (not implementation if in MiniLang) needs a reload.
  • We can call service inside the event. But we cannot call events inside the service.
  • An event is specific local piece functionality normally used in one place for one purpose and called from its location.
  • A service is a piece of functionality that can be located anywhere on the network, are most of the time used in several different places, and is called by its 'name'.
  • In case of events, you have access to HttpServletRequest and HttpServletResponse objects and you can read/write whatever you want. In the case of services, you have access only to service parameters.

References:https://cwiki.apache.org/confluence/display/OFBIZ/FAQ+-+Tips+-+Tricks+-+Cookbook+-+HowTo#FAQ-Tips-Tricks-Cookbook-HowTo-DifferenceBetweenEventAndServiceandhttp://ofbiz.135035.n4.nabble.com

CriteriaServicesEvents
Require DefinitionYesNo
Implementation possibilitiesEntity auto, Java, Simple (XML) & GroovySimple (XML), Java & Groovy
Return TypeMapString
Used to write business logicYesNo
Job Scheduling possibleYesNo

Customizing User Interface

Using FreeMarker Template and Groovy Script

Okay, so we are here in the last part of the OFBiz tutorial. In this part, we will focus on customizing the UI layer of Apache OFBiz for business management apps i.e. backend apps and esp. Most of the time you will find the OFBiz Widgets are enough. But sometimes the important thing is to develop applications as users exactly want them.

So to customize the UI part of your application first of all to make it easy we will be using Freemarker Templates instead of inbuilt Form Widgets. First of all, we will see how to use Freemarker and Groovy scripts with Apache OFBiz, and then we'll see how to put on custom styling on it by defining your own decorators. Initially, we will be using OFBiz default decorators.

Starting from here follow steps given:

1.)Add a new crud directory under the location$ OFBIZ_HOME/plugins/ofbizDemo/webapp/ofbizDemo/

2.)Add two Freemarker files at location $ OFBIZ_HOME/plugins/ofbizDemo/webapp/ofbizDemo/crud/AddOfbizDemo.ftl and ListOfbizDemo.ftl, as shown below:

AddOfbizDemo.ftl

<div class="screenlet-body">
<form id="createOfbizDemoEvent" method="post" action="<@ofbizUrl>createOfbizDemoEvent</@ofbizUrl>">
<input type="hidden" name="addOfbizDemoFromFtl" value="Y"/>
<fieldset>
<div>
<span class="label">${uiLabelMap.OfbizDemoType}</span>
<select name="ofbizDemoTypeId" class='required'>
<#list ofbizDemoTypes as demoType>
<option value='${demoType.ofbizDemoTypeId}'>${demoType.description}</option>
</#list>
</select>*
</div>
<div>
<span class="label">${uiLabelMap.OfbizDemoFirstName}</span>
<input type="text" name="firstName" id="firstName" class='required' maxlength="20" />*
</div>
<div>
<span class="label">${uiLabelMap.OfbizDemoLastName}</span>
<input type="text" name="lastName" id="lastName" class='required' maxlength="20" />*
</div>
<div>
<span class="label">${uiLabelMap.OfbizDemoComment}</span>
<input type="text" name="comments" id="comments" class='inputBox' size="60" maxlength="255" />
</div>
</fieldset>
<input type="submit" value="${uiLabelMap.CommonAdd}" />
</form>
</div>

ListOfbizDemo.ftl

<div class="screenlet-body">
<#if ofbizDemoList?has_content>
<table cellspacing=0 cellpadding=2 border=0 class="basic-table">
<thead><tr>
<th>${uiLabelMap.OfbizDemoId}</th>
<th>${uiLabelMap.OfbizDemoType}</th>
<th>${uiLabelMap.OfbizDemoFirstName}</th>
<th>${uiLabelMap.OfbizDemoLastName}</th>
<th>${uiLabelMap.OfbizDemoComment}</th>
</tr></thead>
<tbody>
<#list ofbizDemoList as ofbizDemo>
<tr>
<td>${ofbizDemo.ofbizDemoId}</td>
<td>${ofbizDemo.getRelatedOne("OfbizDemoType").get("description", locale)}</td>
<td>${ofbizDemo.firstName?default("NA")}</td>
<td>${ofbizDemo.lastName?default("NA")}</td>
<td>${ofbizDemo.comments!}</td>
</tr>
</#list>
</tbody>
</table>
</#if>
</div>

2.) Add new Groovy file for data fetching logic at location$ OFBIZ_HOME/plugins/ofbizDemo/webapp/ofbizDemo/WEB-INF/actions/crud/ListOfbizDemo.groovy and add code as shown to list out OfbizDemo records:

ofbizDemoTypes = delegator.findList("OfbizDemoType", null, null, null, null, false);
context.ofbizDemoTypes = ofbizDemoTypes;
ofbizDemoList = delegator.findList("OfbizDemo", null, null, null, null, false);
context.ofbizDemoList = ofbizDemoList;

3.) Add new screen file with Ofbiz default decorator to OfbizDemoScreens.xml with newly added freemarker and groovy files as:

OfbizDemoScreens.xml

<screen name="AddOfbizDemoFtl">
<section>
<actions>
<set field="titleProperty" value="PageTitleAddOfbizDemos"/>
<set field="headerItem" value="addOfbizDemoFtl"/>
<script location="component://ofbizDemo/webapp/ofbizDemo/WEB-INF/actions/crud/ListOfbizDemo.groovy"/>
</actions>
<widgets>
<decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
<decorator-section name="body">
<screenlet title="${uiLabelMap.OfbizDemoListOfbizDemos}">
<platform-specific>
<html><html-template location="component://ofbizDemo/webapp/ofbizDemo/crud/ListOfbizDemo.ftl"/></html>
</platform-specific>
</screenlet>
<screenlet title="${uiLabelMap.OfbizDemoAddOfbizDemoServiceByFtl}">
<platform-specific>
<html><html-template location="component://ofbizDemo/webapp/ofbizDemo/crud/AddOfbizDemo.ftl"/></html>
</platform-specific>
</screenlet>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>

4.) Add a new controller request and a new item for the OfbizDemo menu as:

controller.xml

<!--Request Mapping-->
<request-map uri="AddOfbizDemoFtl">
<security https="true" auth="true"/>
<response name="success" type="view" value="AddOfbizDemoFtl"/>
</request-map>

<!--View Mapping-->
<view-map name="AddOfbizDemoFtl" type="screen" page="component://ofbizDemo/widget/OfbizDemoScreens.xml#AddOfbizDemoFtl"/>

OfbizDemoMenus.xml

<menu-item name="addOfbizDemoFtl" title="${uiLabelMap.OfbizDemoAddFtl}"><link target="AddOfbizDemoFtl"/></menu-item>

5.) Add new UI Labels as used by your app.

6.) Run your ofbiz demo application and go to the new tab you just added. You should have viewed as:

OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (8)

Creating Custom Decorator

Having your UI in Freemarker gives you the freedom to experiment with it, doing CSS tweaks, and make your application the way a user wants. In this section, we will see how we can do that.

We will be doing it by defining a custom decorator for your application view. A decorator in OFBiz is nothing but a screen that you define and reuse afterward by including in your other screens of the application. You are already doing it with the default decorator (main-decorator –> ApplicationDecorator) which comes with OFBiz. Just observe your screens you have prepared so far, you will find that, you were using this main decorator, please refer below line in OfbizDemoScreens.xml.

OfbizDemoScreens.xml

<decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">

The mainDecoratorLocation is available in parameters map as it is defined in webapp's web.xml

web.xml

<context-param>
<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>
<param-name>mainDecoratorLocation</param-name>
<param-value>component://ofbizDemo/widget/CommonScreens.xml</param-value>
</context-param>

Now is the time to define your own decorator with custom styling.

In the sample given below, we are going to use Bootstrap to style our sample Freemarker screen we developed in the last part of this tutorial. Follow the below-given steps to build your own decorator.

1.) Download Bootstrap v3.3.7 directory, you can download it fromhereand unzip it.

2.) Create two new directories namely "css" and "js" at location$ OFBIZ_HOME/plugins/ofbizDemo/webapp/ofbizDemo/

3.) Copy bootstrap-3.3.7/dist/css/bootstrap.min.css to $ OFBIZ_HOME/plugins/ofbizDemo/webapp/ofbizDemo/css

4.) Copybootstrap-3.3.7/dist/js/bootstrap.min.js to$ OFBIZ_HOME/plugins/ofbizDemo/webapp/ofbizDemo/js.

5.) Open$ OFBIZ_HOME/plugins/ofbizDemo/webapp/ofbizDemo/WEB-INF/web.xml and make entries for css and js directories inallowedPaths at the end as shown below:

web.xml

<init-param>
<param-name>allowedPaths</param-name>
<param-value>/error:/control:/select:/index.html:/index.jsp:/default.html:/default.jsp:/images:/includes/maincss.css:/css:/js</param-value>
</init-param>

6.) Add a new directory named "includes" at location$ OFBIZ_HOME/plugins/ofbizDemo/webapp/ofbizDemo/ and create two new files in this new directory you just added named PreBody.ftl and PostBody.ftl. We will be using(including) these two files in our decorator screen to build a complete HTML page.

PreBody.ftl

<html>
<head>
<title>${layoutSettings.companyName}</title>
<meta name="viewport" content="width=device-width, user-scalable=no"/>
<#if webSiteFaviconContent?has_content>
<link rel="shortcut icon" href="">
</#if>
<#list layoutSettings.styleSheets as styleSheet>
<link rel="stylesheet" href="${StringUtil.wrapString(styleSheet)}" type="text/css"/>
</#list>
<#list layoutSettings.javaScripts as javaScript>
<script type="text/javascript" src="${StringUtil.wrapString(javaScript)}"></script>
</#list>
</head>
<body data-offset="125">
<h4 align="center"> ==================Page PreBody Starts From Decorator Screen========================= </h4>
<div class="container menus" id="container">
<div class="row">
<div class="col-sm-12">
<ul id="page-title" class="breadcrumb">
<li>
<a href="<@ofbizUrl>main</@ofbizUrl>">Main</a>
</li>
<li class="active"><span class="flipper-title">${StringUtil.wrapString(uiLabelMap[titleProperty])}</span></li>
<li class="pull-right">
<a href="<@ofbizUrl>logout</@ofbizUrl>" title="${uiLabelMap.CommonLogout}">logout</i></a>
</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-lg-12 header-col">
<div id="main-content">
<h4 align="center"> ==================Page PreBody Ends From Decorator Screen=========================</h4>
<h4 align="center"> ==================Page Body starts From Screen=========================</h4>

PostBody.ftl

<#-- Close the tags opened in the PreBody section -->
</div>
</div>
</div>
</div>
<h4 align="center"> ==================Page PostBody and Page body in general ends here from Decorator Screen=========================</h4>
</body>
</html>

7.)Open Common Screens file of your component$ OFBIZ_HOME/plugins/ofbizDemo/widget/CommonScreens.xml, this is the file we will define our custom decorator.

8.)Update screen named "OfbizDemoCommonDecorator"(which will serve as a custom decorator for your app) as shown below:

CommonScreens.xml

<screen name="OfbizDemoCommonDecorator">
<section>
<actions>
<property-map resource="OfbizDemoUiLabels" map-name="uiLabelMap" global="true"/>
<property-map resource="CommonUiLabels" map-name="uiLabelMap" global="true"/>

<setfield="layoutSettings.companyName"from-field="uiLabelMap.OfbizDemoCompanyName"global="true"/>

<!-- Including custom CSS Styles that you want to use in your application view. [] in field can be used to
set the order of loading CSS files to load if there are multiple -->
<set field="layoutSettings.styleSheets[]" value="/ofbizDemo/css/bootstrap.min.css"/>

<!-- Including custom JS that you want to use in your application view. [] in field can be used to
set the order of loading of JS files to load if there are multiple -->
<set field="layoutSettings.javaScripts[+0]" value="/ofbizDemo/js/bootstrap.min.js" global="true"/>
</actions>
<widgets>
<section>
<condition>
<if-has-permission permission="OFBIZDEMO" action="_VIEW"/>
</condition>
<widgets>
<platform-specific><html><html-template location="component://ofbizDemo/webapp/ofbizDemo/includes/PreBody.ftl"/></html></platform-specific>
<decorator-section-include name="pre-body"/>
<decorator-section-include name="body"/>
<platform-specific><html><html-template location="component://ofbizDemo/webapp/ofbizDemo/includes/PostBody.ftl"/></html></platform-specific>
</widgets>
<fail-widgets>
<label style="h3">${uiLabelMap.OfbizDemoViewPermissionError}</label>
</fail-widgets>
</section>
</widgets>
</section>
</screen>


In the code above you may have noticed thelayoutSettings.styleSheets[] andlayoutSettings.javaScripts[+0] notations. You can use the layoutSettings. notation for any files.

If you want to order styleSheets or JavaScripts with emptysquare brackets you simply add the file at the end of the layoutSettings.styleSheets orlayoutSettings.JavaScriptslist, with[+0] you add it at front of it.

9.) Use this decorator in your Freemarker screen that you created in the last part as:

OfbizDemoScreens.xml

<screen name="AddOfbizDemoFtl">
<section>
<actions>
<set field="titleProperty" value="OfbizDemoAddOfbizDemoFtl"/>
<set field="headerItem" value="addOfbizDemoFtl"/>
<script location="component://ofbizDemo/webapp/ofbizDemo/WEB-INF/actions/crud/ListOfbizDemo.groovy"/>
</actions>
<widgets>
<decorator-screen name="OfbizDemoCommonDecorator" location="${parameters.mainDecoratorLocation}">
<decorator-section name="body">
<label style="h4" text="${uiLabelMap.OfbizDemoListOfbizDemos}"/>
<platform-specific>
<html><html-template location="component://ofbizDemo/webapp/ofbizDemo/crud/ListOfbizDemo.ftl"/></html>
</platform-specific>
<label style="h4" text="${uiLabelMap.OfbizDemoAddOfbizDemoFtl}"/>
<platform-specific>
<html><html-template location="component://ofbizDemo/webapp/ofbizDemo/crud/AddOfbizDemo.ftl"/></html>
</platform-specific>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>

10.) Update your FTL files to follow HTML web standards and apply CSS on it as:

AddOfbizDemo.ftl

<form method="post" action="<@ofbizUrl>createOfbizDemoEventFtl</@ofbizUrl>" name="createOfbizDemoEvent" class="form-horizontal">
<div class="control-group">
<label class="control-label" for="ofbizDemoTypeId">${uiLabelMap.OfbizDemoType}</label>
<div class="controls">
<select id="ofbizDemoTypeId" name="ofbizDemoTypeId">
<#list ofbizDemoTypes as demoType>
<option value='${demoType.ofbizDemoTypeId}'>${demoType.description}</option>
</#list>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="firstName">${uiLabelMap.OfbizDemoFirstName}</label>
<div class="controls">
<input type="text" id="firstName" name="firstName" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="lastName">${uiLabelMap.OfbizDemoLastName}</label>
<div class="controls">
<input type="text" id="lastName" name="lastName" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="comments">${uiLabelMap.OfbizDemoComment}</label>
<div class="controls">
<input type="text" id="comments" name="comments">
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn">${uiLabelMap.CommonAdd}</button>
</div>
</div>
</form>

ListOfbizDemo.ftl

<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>${uiLabelMap.OfbizDemoId}</th>
<th>${uiLabelMap.OfbizDemoType}</th>
<th>${uiLabelMap.OfbizDemoFirstName}</th>
<th>${uiLabelMap.OfbizDemoLastName}</th>
<th>${uiLabelMap.OfbizDemoComment}</th>
</tr>
</thead>
<tbody>
<#list ofbizDemoList as ofbizDemo>
<tr>
<td>${ofbizDemo.ofbizDemoId}</td>
<td>${ofbizDemo.getRelatedOne("OfbizDemoType").get("description", locale)}</td>
<td>${ofbizDemo.firstName?default("NA")}</td>
<td>${ofbizDemo.lastName?default("NA")}</td>
<td>${ofbizDemo.comments!}</td>
</tr>
</#list>
</tbody>
</table>

10. Now restart OFBiz as you have made entries to allowedPaths in web.xml. As it reloads hithttps://localhost:8443/ofbizDemo/control/AddOfbizDemoFtlyou should see the page with custom styles that you have used instead of using the default OFBiz theme. It should look like:

OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (9)

Here you can now play with it as you want. Try changing the header or having a new one, adding a footer, putting in validations, etc. So this way you can customize the UI layer of OFBiz with Freemarker templates, CSS and JS.

You may want to add your own CSS or JS files, you can include those the same way we did for Bootstrap files.

What's next?

If you have followed all the steps and developed practice applications from this tutorial then this will help you in understanding other implementations in OFBiz. These things are the basic foundation of working in OFBiz. Now you know, how you can start development in OFBiz. Don't leave behind the extra links provided in this tutorial as they will help you a lot in understanding the things which are given there in detail.
Here is another good reading that can be of help is available at FAQ Tips Tricks Cookbook HowTo.
Now the next thing that comes in the way is the business processes which are really needed to be understood well for understanding the OOTB process flow in OFBiz and OOTB data model, so for this, books are available atOFBiz Related Books. Understanding well the OFBiz OOTB available data model and business processes will help in building better business solutions top of it.

Now you are ready to dive in. Welcome to OFBiz world.

OFBiz Tutorial - A Beginners Development Guide for 18.12 - OFBiz Project Open Wiki (2024)

FAQs

How to implement Apache OFBiz? ›

Building and Starting OFBiz
  1. Extract the downloaded zip file.
  2. Open a terminal and navigate into the newly created directory.
  3. If you are using Linux enter the following at the command line. ./gradlew loadAll ofbiz. If you are using Windows then enter the following at the command line. gradlew loadAll ofbiz.

What is Apache OFBiz used for? ›

Apache OFBiz is an open source enterprise resource planning (ERP) system. It provides a suite of enterprise applications that integrate and automate many of the business processes of an enterprise. OFBiz is an Apache Software Foundation top level project.

What database does OFBiz use? ›

Database Setup

By default OFBiz includes and is configured for an embedded Java database called Derby.

How do I create a component in OFBiz? ›

Setting up the sandbox
  1. go to the newly created folder: “cd ofbiz-framework”
  2. run the Gradle task to create a standard OFBiz component/plugin: “./gradlew createPlugin -PpluginId=hotwax”
  3. build OFBiz and load the demo data: “./gradlew loadDefault”
  4. run OFBiz: “./gradlew ofbiz –start”

How to configure Apache server in Oracle Linux? ›

See Oracle Linux: Managing Certificates and Public Key Infrastructure for more information.
  1. Install the HTTPS add-on for Apache. Copy sudo dnf install mod_ssl sudo systemctl restart httpd.
  2. Update the Apache configuration. ...
  3. Restart the Apache service to load the new configuration. ...
  4. (Optional) Configure the firewall.

Is Apache OFBiz free? ›

Apache OFBiz is available free of cost.

Who is the target audience for Apache OFBiz? ›

The majority of Apache OFBiz's customers for the erp category fall in the company size of 20 - 49 employees (28 companies), 0 - 9 employees (26 companies), 10,000+ employees (21 companies). You can view a distribution chart of Apache OFBiz customers by company size here.

What database does Apache use? ›

Apache is the web server that processes requests and serves web assets and content via HTTP. MySQL is the database that stores all your information in an easily queried format.

What is the default password for Apache Ofbiz? ›

You can log in with the user admin and password ofbiz. Note: the default configuration uses an embedded Java database (Apache Derby) and embedded application server components such as Apache Tomcat®, Apache Geronimo (transaction manager), etc.

What is the default password for Ofbiz? ›

The default administrative account is username: "admin", password: "ofbiz".

What gateways are supported by ofbiz? ›

OFBiz OOTB implementation supports multiple payment gateways like: Chase Paymentech Orbital, CyberSource / Authorize.net, and PayPal PayflowPro.

How do I manually create a component? ›

To create a new component manually:
  1. Navigate to your Angular project directory.
  2. Create a new file, <component-name>.component.ts .
  3. At the top of the file, add the following import statement. ...
  4. After the import statement, add a @Component decorator. ...
  5. Choose a CSS selector for the component.

How do I create a custom component? ›

Click the Access advanced features button and select Define custom component. The Custom Component Wizard dialog box opens. In the Type list, select the component type : connection, detail, seam, or part. In the Name box, enter a unique name for the component.

What is the introduction of OFBiz? ›

Overview (Introduction to OFBiz)

Open For Business (OFBiz) is a suite of enterprise applications built on a common architecture using common data, logic and process components. The loosely coupled nature of the applications makes these components easy to understand, extend and customize.

How to connect to Oracle database from Linux server? ›

Do one of the following:
  1. On Windows: Click Start, point to Programs (or All Programs), point to Oracle Database 11g Express Edition, and then select Run SQL Command Line.
  2. On Linux with Gnome: In the Applications menu, point to Oracle Database 11g Express Edition, and then select Run SQL Command Line.

How to setup Oracle client on Linux? ›

Database Client Installation Guide for Linux

Download the desired Oracle Instant Client zip files. Select the correct platform, architecture, and packages of your choice. For example, if your application is 64-bit, then ensure that you select 64-bit Instant Client and download the Basic Package zip file.

How to configure SSH in Oracle Linux? ›

Installing OpenSSH Server and Enabling sshd
  1. If necessary, install or update the openssh and openssh-server packages: Copy. sudo dnf install openssh openssh-server.
  2. Start the sshd service and configure it to start following a system reboot: Copy. sudo systemctl start sshd sudo systemctl enable sshd.

How to set up an API with PHP? ›

Contents
  1. Create the PHP Project Skeleton for Your REST API.
  2. Configure a Database for Your PHP REST API.
  3. Add a Gateway Class for the Person Table.
  4. Implement the PHP REST API.
  5. Secure Your PHP REST API with OAuth 2.0.
  6. Add Authentication to Your PHP REST API.
Mar 8, 2019

How to run a PHP project in localhost? ›

After starting both servers, you have to write a program in Notepad. After writing it, save that file as "program.php". Then copy that file program.php to C:/Program Files/XAMPP/htdocs. Open the browser and type http://localhost.

Does Google use Apache software? ›

Google makes extensive use of Apache projects, contribute our own, and most of our open source projects are released under an Apache 2 license.

How much does Apache OFBiz cost? ›

Yes Apache OFBiz is completely free.

Is Apache 2 license free? ›

The Apache Software Foundation and the Free Software Foundation agree that the Apache License 2.0 is a free software license, compatible with the GNU General Public License (GPL) version 3, meaning that code under GPLv3 and Apache License 2.0 can be combined, as long as the resulting software is licensed under the ...

Who pays Apache developers? ›

Our primary income is from our formal Sponsorship program, where organizations can provide a regular annual donation. As a 501(c)3 charity, we also have many individual donors, and some authors donate royalties from their books about Apache software to the ASF.

Which company uses Apache? ›

Some high-profile companies using Apache include Cisco, IBM, Salesforce, General Electric, Adobe, VMware, Xerox, LinkedIn, Facebook, Hewlett-Packard, AT&T, Siemens, eBay, and many more (source). In addition to its popularity, it's also one of the oldest web servers, with its first release all the way back in 1995.

Who maintains Apache projects? ›

A Project Management Committee (PMC), a self-selected team of active contributors, manages each project following The Apache Way and whatever additional guidelines for collaborative development are best suited to that project.

Does anyone still use Apache? ›

Yes, and right out of the box. Most web hosting companies will default to Apache as the main web server software. Some may offer additional options, but due to the ease of use, popularity, and resources available, most WordPress sites stick with Apache.

What is the difference between SQL and Apache? ›

MySQL belongs to "Databases" category of the tech stack, while Apache Spark can be primarily classified under "Big Data Tools". "Sql" is the top reason why over 778 developers like MySQL, while over 45 developers mention "Open-source" as the leading cause for choosing Apache Spark.

What is the default password list for mikrotik? ›

The default username is admin with no password (or, for some models with password, check it on the sticker). After you log in for the first time, please create a new user with a password in the "full" group, re-login and delete the default admin user.

What is the default password for www data in Apache? ›

The Apache2 install creates a user and group named "www-data" apparently with no password, blank. It uses this user account to run under.

How to check default password in Oracle? ›

Check user having Default password in Oracle Database

username = u. username ORDER BY 2,1; 3. You can also check user which is in open state and having default password.

What is the default admin password for FileCloud? ›

Getting Started After Deploying FileCloud

Admin Username is admin, Admin Password is password.

What is the default username and password for Apache airflow? ›

default credentials -- user: admin - password: admin.

What is Kali default login credentials? ›

Any default operating system credentials used during Live Boot, or pre-created image (like Virtual Machines & ARM) will be: User: kali. Password: kali.

What payment gateways are supported by Salesforce billing? ›

Salesforce Billing also offers gateway integrations with CyberSource, AuthorizeDotNet, and Payeezy.

How to create custom component in Android? ›

To enable this behaviour in your custom view, you must:
  1. Define custom attributes for your view in a <declare-styleable> resource element.
  2. Specify values for the attributes in your XML layout.
  3. Retrieve attribute values at runtime.
  4. Apply the retrieved attribute values to your view.

How do I pass data to an app component? ›

Passing Data into a Component
  1. There are two ways to pass data into a component, with 'property binding' and 'event binding'. ...
  2. The @Input() decorator defines a set of parameters that can be passed down from the component's parent. ...
  3. The point of making components is not only encapsulation, but also reusability.

How do I create a custom component in power app? ›

Create and use output property
  1. Open the list of components, and then select MenuComponent.
  2. In the right-hand pane, select the Properties tab, and then select New custom property.
  3. In the Display name, Property name, and Description boxes, type or paste Selected.
  4. Under Property type, select Output, and then select Create.
Jan 23, 2023

How do I create a UI component? ›

How to create UI components in the right way?
  1. Step 1 – Pick the right tools. ...
  2. Step 2 – Add static assets. ...
  3. Step 3 – Set global styles. ...
  4. Step 4 – Create a theme. ...
  5. Step 5 – Build the components.
Feb 28, 2022

How to create custom UI components? ›

Ans: Here are the steps to create custom Android UI components: Step 1: Create an XML layout. Step 2: Based on your layout, derive the component class from the parent component. Step 3: Add logic for components, and use attributes to enable users to modify the component's behavior. 2: Can you customize Android UI?

How do I create a custom element in HTML? ›

Steps involved in creating a Custom HTML Element:
  1. Create a new Class representing the New Element (ES6)
  2. Extend the class from “HTMLElement”
  3. Add “connectedCallback” function to the class to access DOM Element when the element is added to the document.
  4. Access the Custom DOM Element using “this” keyword.

How to run Node js app with Apache? ›

Configuring Apache for Node. js
  1. Confirm the Apache server is running.
  2. Create the Apache configuration file.
  3. Enable the proxy and proxy_http modules.
  4. Apply the configuration.
  5. Test the configuration.
Jan 14, 2022

How to install Apache OFBiz on Windows 7? ›

Step-by-step guide
  1. Install Java SDK. The current stable release (16.11) needs Java 1.8 as a minimum. ...
  2. Download the latest stable release. You can download the latest stable release via the following link (ADD link to Download)
  3. Building and Starting OFBiz. Extract the downloaded zip file. ...
  4. Stopping OFBiz.

How to create load balancer in Apache? ›

How to Configure Apache Load Balancer
  1. Install Apache on the Load Balancer Server.
  2. Enable Proxy Server Modules.
  3. Configure Apache Load Balancing.
  4. Configure Apache Load Balancer Manager.
Feb 15, 2021

How to configure Apache for security? ›

Apache Security – 10 Tips for a Secure Installation
  1. Disable the server-info Directive. ...
  2. Disable the server-status Directive. ...
  3. Disable the ServerSignature Directive. ...
  4. Set the ServerTokens Directive to Prod. ...
  5. Disable Directory Listing. ...
  6. Enable Only the Required Modules. ...
  7. Use An Appropriate User and Group. ...
  8. Restrict Unwanted Services.
Mar 16, 2020

How to connect to an API with Node js? ›

How to use an API with Node. js
  1. Sign Up For a Free Account on RapidAPI.
  2. Subscribe to an API.
  3. Set-Up Project.
  4. Add API Call.
  5. Make Asynchronous API Call.
Apr 20, 2021

What is the difference between Apache and node JS? ›

Well Apache is a web server such as listening for requests, and serving the content up that matches that request. On the other hand, Node. js is a runtime environment ( where javascript is executed outside of the browser).

How to deploy node js application on app engine? ›

How to deploy your Node. js app with Google
  1. Create a Project. ...
  2. Create Application in App Engine. ...
  3. Using the Cloud Shell or the Cloud SDK. ...
  4. Deploying your app. ...
  5. Set Environmental Variables. ...
  6. Run the Build. ...
  7. Set Start Script. ...
  8. Preview Your App.
Jul 5, 2020

What is the default user of ofbiz? ›

The default administrative account is username: "admin", password: "ofbiz". Have fun with it!

How to configure Apache HTTP server on Windows? ›

Contents:
  1. Step 1 - Download Apache for Windows.
  2. Step 2 - Unzip.
  3. Step 3 - Configure Apache.
  4. Step 4 - Start Apache.
  5. Step 5 - Check Apache.
  6. Step 6 - Install Apache as a Windows service.
  7. Step 7 - Monitor Apache (optional)
Jan 18, 2023

How to install Apache HTTP server on Windows server? ›

Step by step Apache install on Windows
  1. Download the installation media in the form of a ZIP file.
  2. Extract the contents of the Apache Web Server 2.4 zip to the file system.
  3. Locate the extracted Apache24 folder and copy this folder to the root of C:\
  4. Open the C:\Apache24\bin folder and run the httpd.exe command.
Jan 15, 2022

Can Apache be a load balancer? ›

Apache load balancer is open source and provides a server application traffic distribution solution. According to recent statistics, it has been utilized in over 100,000 websites.

How do I write my own load balancer? ›

To create a Classic Load Balancer
  1. On the navigation bar, choose a Region for your load balancer. Be sure to select the same Region that you selected for your EC2 instances.
  2. On the navigation pane, under LOAD BALANCING, choose Load Balancers.
  3. Choose Create Load Balancer.
  4. For Classic Load Balancer, choose Create.

Why nginx is better than Apache? ›

The main difference between NGINX and Apache web servers is that NGINX has event-driven architecture handling multiple requests within a single thread, while Apache is process-driven creating a thread per each request. Thus, allowing NGINX to have generally better performance.

What is the difference between Apache web server and Apache HTTP Server? ›

Web server is software that responds to the request for web resources. Apache HTTP Server is an open-source, cross-platform web server that was released under the license of Apache 2.0. It is developed and maintained by an open community of developers under the apache software foundation.

How to set TLS version in Apache? ›

To enable TLS 1.2 in Apache, you will need to change/add the SSLProtocol directive. To do any of this, mod_ssl should be enabled, if not, use the command sudo a2enmod ssl . You can also support TLSv1.

How to configure a port in Apache server? ›

To change the port number, follow the steps below:
  1. Edit the /opt/bitnami/apache/conf/httpd.conf file and modify the value specified in the Port directive. ...
  2. Edit the /opt/bitnami/apache/conf/bitnami/bitnami.conf file and modify the value specified in the VirtualHost directive.
Feb 9, 2023

Top Articles
Latest Posts
Article information

Author: Carlyn Walter

Last Updated:

Views: 6387

Rating: 5 / 5 (50 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Carlyn Walter

Birthday: 1996-01-03

Address: Suite 452 40815 Denyse Extensions, Sengermouth, OR 42374

Phone: +8501809515404

Job: Manufacturing Technician

Hobby: Table tennis, Archery, Vacation, Metal detecting, Yo-yoing, Crocheting, Creative writing

Introduction: My name is Carlyn Walter, I am a lively, glamorous, healthy, clean, powerful, calm, combative person who loves writing and wants to share my knowledge and understanding with you.