Category: Developer Community

Covering OroCommerce topics, B2B eCommerce trends, community updates and company announcements.

OroCommerce Documentation Now Available

by add comment

oroCommerce documentation

We’re excited to update our fabulous Community on the availability of the much requested technical documentation for OroCommerce 1.0.  To address every audience type using our unique B2B eCommerce platform, we’ve arranged the documentation into three stand-alone guides.

To access the guides, simply refer to the Documentation section available in the Community drop-down menu of our website. Depending on what information you’re looking for, read through our User, Developer, or Community Guides for any questions you may have. Remember you can always use the forum for any questions not covered in the guides. Read more

Using PHP instead of Twig for templates

by add comment

Using PHP instead of Twig for templates

Symfony, the underlying framework used in OroCommerce, OroCRM and OroPlatform, defaults to Twig for its template engine, but using PHP instead of Twig is still possible if necessary. Symfony provides equally good support of both templating engines.

If you preference is PHP templates, this article describes how to enable and use PHP templates with OroLayout bundle in the applications built on OroPlatform.

The Symfony framework documentation contains additional useful information about PHP templates and form rendering customization:

Configure OroLayoutBundle

Only one templating engine can be used at a time in an OroPlatform application. By default, OroLayoutBundle is configured to use Twig. If you decide to use PHP templates, you should disable Twig and make PHP templating the default templating engine in the application configuration file:

Modify layouts to use PHP templates

The default “base” OroPlatform theme uses Twig templates. You should choose a different approach in your default.yml file in your theme’s folder:

The example above creates a standard web page structure (head, metadata, and body) with two custom blocks in the body (content and greeting). And in this layout, we specified a different “block theme” (so that the templating engine will know where to find our PHP templates):

Creating templates

As you are not using Twig anymore, you should provide the PHP templates for the blocks used in the layout.

The PHP templates can be very simple, like in the following example of the greeting block template where we just want to display “Hello!”:


You can also create more complex templates that use variables and functions provided by the layout. This is an example of the content block template:

The layout and templates from our examples will produce the following HTML output:

A number of fully working PHP templates for various block types are already included in OroLayoutBundle – check the src/Oro/Bundle/LayoutBundle/Resources/views/Layout/php folder to see all the examples.

We prefer to use Twig in our products (e.g. see the default theme in OroCommerce) to better express presentation and to avoid including the program logic in the templates. However, using PHP instead of Twig may be better for you based on the needs of your customers and the approach you selected to build your OroPlatform-based application.

As always, please let us know if you find this article useful. We will appreciate your feedback in our forums.

Customizing CRUD in OroCommerce

by 1 comment

Customizing CRUD in OroCommerce

OroCommerce equips users and developers with powerful UIs that they can use to manage both simple and complex data entities, including all entity attributes (fields) and relations. As a developer, you can easily enable standard CRUD pages for a new entity, and with the same ease, you can add more fields to any of the entities that you have created before. Just add new entity properties, create a migration script and modify the templates if necessary.

But what if you need to add a few more fields to one of the OroCommerce built-in entities, or to an entity that has been created by somebody else’s extension? Where would you start?

Editing the OroCommerce source code or the code for third party extensions is never a good idea. In this article, we will show you how to customize the CRUD pages of the existing entities with the custom code in your own bundle.

CRUD stands for Create, Read, Update and Delete operations. They are commonly accompanied by some sort of listing or navigation that allows to retrieve, sort and filter multiple records at once. In the context of OroCommerce the data management UIs for the above operations are represented by the following pages:

  • List – represented by the data grids (for example, select Products → Products in the main navigation menu). We’ve already covered customization of the data grids in the Customizing Data Grids in OroCommerce blog post, so we won’t focus on it today.
  • Create – an entity creation screen (for example, go to Products → Products and click on the Create Product button above the product data grid). In most cases, the entity creation screen and entity editing screen look and work exactly the same, though there may be exceptions to this rule.
  • Read – an entity view page (for example, go to Products → Products and click on any product in the grid).
  • Update – an entity editing page (for example, go to Products → Products and select Edit in the action column, or click on the Edit button on the product view page).
  • Delete – there is no special screen for entity deletion other than the confirmation popup window (go to Products → Products select Delete in the action column, or click on the Delete button on the product view or edit page).

For the purpose of the today’s exercise, we will be adding a new text field to the product edit and view screens from our custom bundle.


Before we start writing code, you should create a new bundle in your application. If you are not familiar with bundle creation process yet, please check the OroCookbook article about how to create a new bundle in OroPlatform, OroCRM, or OroCommerce. If you have already created a bundle for your app customizations, you are good to go and may reuse it in other tutorials as well.

Custom Data Entity

As the first step we will create a new entity to store our custom data. It is still possible to create new product entity fields from your custom bundle, but we will show how you can add some data that is stored elsewhere (it may as well be calculated on the fly or submitted to an external web-service for storage).

Please check the How to Create Entities article in the OroCookbook to learn more.

Let’s also make our entity compliant with the ProductHolderInterface so it will be possible to reuse it in other places (e.g. reports). Other than the reference to the product, our entity will have only one text field to store our data. You can add multiple fields and use other data types according to your requirements.

This is how our custom entity will look like:

Installation And Migrations

It might be not necessary for this exercise, but if you plan to distribute your custom bundle, or if you want to deploy it later to another application or machine, you have to create the installation and migration scripts. The installation script should create the required database structures during application installation, and the migration scripts will be used to update your module in the application to a specific version.

More information about migrations is available in the OroMigrationBundle documentation.

We are going to have only one version of our custom bundle in this blog post, so the installation and migration code will look very similar.



Form Types

In order to customize the new product field, we need to implement a corresponding form type that will be used in the main form on the product create and edit pages:

The setDataClass method is used here to provide more flexibility while allowing for the re-use of this form type. Using it like this is optional.

Once you have your new form type, it should be registered in the service container to be recognizable by the Symfony’s form factory:

Form Type Extension

Any integrations between different form types within OroCommerce can use form type extension to tie in the form types together. In our case, we need to list the following form events:

  • FormEvents::POST_SET_DATA – it will be used to assign values to the form from our custom entity object;
  • FormEvents::POST_SUBMIT – it will be used to convert, validate and persist our custom values.

Our new form type extension should also be registered in the service container:

UI data targets and listener

Once the entity, the form type, and the form type extension are created, we can start customizing the User Interface.

Additional information about the UI customization is available here.

In our case, the custom data should be added to the product view page and the product edit/create pages, so we will use the following dataTargets:
product-view will be used to display our custom data on the product view page;
product-edit will be used to show our custom data on the product edit page;
product-create-step-two will be used to add our custom data to the product creation page.

The event listener may be implemented as follows:


And finally, we can define the templates – one for the form:

and one for the view:

As a result, the following blocks will be shown on the product edit, create, and view pages:

Product Edit Page

Product View Page

A fully working example, organized into a custom bundle is attached.

File Size: 13.47 KB

In order to add this bundle to your application:

  • please extract the content of the zip archive into a source code directory that is recognized by your composer autoload settings;
  • clear the application cache with the following command php app/console clear:cache
  • and run the migrations:
    app oro:migration:load --force --bundles=OroBlogPostExampleBundle

Please let us know if you find this article useful. We will appreciate your feedback in our forums.

Customizing Data Grids in OroCommerce

by add comment


Most business application users have to deal with significant amounts of data on a daily basis. Thus, efficiently navigating through large data sets becomes a must have requirement and OroCommerce is not an exception. The application users must be able to easily filter, sort, and search through thousands (or millions) of records, usually represented in the form of a data grid on a page.

Today, we will focus on customizing the existing data grids provided by the core product. If you are not familiar with OroPlatform data grids, you may find it helpful to check the Oro Cookbook articles on how to create a simple data grid, and how to pass request parameters to your data grid. The datagrid.yml configuration reference and the OroDataGridBundle documentation contain additional useful information.

Customizing Data Grids in OroCommerce

Data Sources

A data grid is usually used to visualize some data coming from a data source. OroDataGridBundle allows for use of various data sources for data grids, and includes the ORM data source adapter out of the box. It is possible to implement your own data source adapters as well.

The ORM data source types allow for database query specification, sorters and filters definitions to be specified in the data grid configuration. Data grid configuration can be supplied by a developer in YAML format. By convention, the datagrid.yml files placed in Resources/config folders of any application bundle are processed automatically. All supported data source configuration options that can be used in data source configuration section are described in the documentation.

Inner Workings of Data Grids

Data grids in Oro applications are highly customizable. It is possible to modify an existing grid in order to fetch more data than was originally defined in the grid configuration. In this article, we will retrieve and present to a user some additional data in the existing products-grid.

And before we start customizing it, let’s take a deeper look into two aspects of how the data grids actually work:

  • building and configuring a new DataGrid instance
  • fetching data

Building Grids

OroDataGridBundle base class diagram

Datagrid\Builder class is responsible for creating and configuring a data grid object and its data source. This is how the build method is processing the grid configuration internally:

Data grid build process

Imagine that you need to show a list of related price lists for every product record in the product grid. You want it to be displayed in a separate column with a multi-select filter. Also you want to add one more column to display owner of each of the product records.

One of the possible ways to customize this grid would be through events triggered by the system during the grid build process and when the data is fetched from the data source.

There are several events triggered before processing the data grid configuration files. In this case, a good choice is the onBuildBefore event. By listening to this event you can add new elements to the grid configuration or modify already existing configuration in your event listener.

More information about grid column definition configuration options is available in the documentation.

The Product entity has a many-to-one relation with the Business Unit entity, so in order to add the owner column to the grid and load the owner data from the data source, you should modify its query configuration by adding additional join and select parts.

Fetching Data

However, the retrieving data for the price lists column is a little bit more complicated, because the Product entity has many-to-many relation with price lists, and the join result will contain duplicate rows. In such situations or when some other dynamic data should be included into the query results, a possible solution would be data modification after the rows were fetched from the data source.

This is how the data retrieval works in general:

Data grid records retrieval

So in our customization, we will fetch the price list data in a separate query, and then we will attach this data to each of the product records in the grid.

Product Grid Customization

The resulting implementation of the ProductsGridListener may look similar to this example:

We will need to register this event listener in the service container:

After the application cache is refreshed (or immediately in the dev mode) two new columns will appear in the product grid.

Custom Filters

Our second customization task will be to add filters for the newly introduced column.

In most cases, the built-in filters would work just perfectly. But in the case of the price lists column, a custom filter is required. The purpose of this filter will be to modify the data retrieval query depending on the filter values entered by a user.

Our new filter should be registered in the service container with the oro_filter.extension.orm_filter.filter tag:

This filter can be added to the grid configuration similarly to how we added new columns – in an event listener. Thus the final implementation of the ProductsGridListener would look like this:

A fully working example, organized into a custom bundle is attached. In order to add this bundle to your application please extract the content of the zip archive into a source code directory that is recognized by your composer autoload settings.

File Size: 105.60 KB

Please let us know if you find this article useful. We hope it can help the developers in the OroCommerce community to further improve user experience and make dealing with data even more enjoyable and fun.

We will appreciate your feedback in our forums.