Oro Layout Component
This package is auto-updated.
Last update: 2021-04-19 20:26:40 UTC
Oro Layout component defines the object-oriented presentation of a page structure and provides tools to build, manage, and render the page.
IMPORTANT: This component is not finished yet.
Oro Layout Component provides tools for:
- defining the elements of the layout (blocks) that can be used to build different types of layouts, including HTML, XML, etc.
- managing the layout structure and themes.
Before you begin working with layout, make sure you are familiar with the following key
Oro Layout Component concepts:
A layout is a set of widgets that are arranged in a hierarchical structure, where a widget is a logical block that contains certain content.
Neither the layout nor a widget know how they should be converted (or in other words, rendered) into the output string (e.g. HTML). To make this conversion, we use renderers, for example a renderer based on TWIG templates.
The root idea and implementation of Oro layouts are mostly similar to the Symfony's Forms component. However, the difference is that layouts support only one-way data flow. It means that content of layout widgets can be rendered based on data, but layouts cannot be used to process user-submitted data.
There are two core layout widgets, the block and the container:
The block represents a widget which cannot contain any other widgets. Examples of blocks can be a label, a chart, a grid, etc.
The container is a structural widget which can contain other widgets. Examples of containers can be a header, a side bar, a page body, etc.
The Oro Layout component includes three main layers:
- The Foundation layer provides the main architectural components used to build a layout.
- The Extensions layer extends the layout with more useful features, such as loading widgets from the DI container and working with layout inheritance.
- The View layer provides components responsible for translating a layout into rendering HTML, XML, or any other format.
The Oro Layout component provides several pluggable extensions out of the box:
- The Core extension provides all widget definitions (called block types) implemented by the component.
- The DI extension adds support for the Symfony's Dependency Injection component.
- The Themes extensions allows to build layouts based on other layouts and provide flexible configuration of layouts.
The layout usually goes through the stages outlined in the following table.
|Create the layout context||The layout context should be created manually by calling the constructor of the LayoutContext class. If necessary, additional variables can be added to the context at this stage.|
|Configure the layout context||At this stage, the
|Resolve the layout context||After this stage, adding new variables to the layout context is not possible, but it is still possible to change the value of existing variables.|
||The root block should be added manually to start the execution of the layout update chain. See the description of the next stage for more details.|
|Execute layout updates||The layout updates are linked to the layout blocks, so they are executed after a block is added to the layout. If a block is not specified for an layout update, it is linked to the root block.|
|Build blocks||A block hierarchy is build starting from a parent block. The
|Build block views||A block view hierarchy is build starting from a parent block. The
|Finish building of block views||First, a parent view finishes building. The
|Render the layout||the layout rendering is the same as in Symfony Forms. See How to Customize Form Rendering for more details.|
The following example illustrates how a simple layout can be build.
$context = new LayoutContext(); $context->getResolver() ->setRequired(['some_variable']); $context->set('some_variable', 'some_value'); $layoutFactory = Layouts::createLayoutFactory(); $layout = $layoutFactory->createLayoutBuilder() ->add('root', null, 'root') ->add('header', 'root', 'header') ->add('logo', 'header', 'logo', ['title' => 'Hello World!']) ->getLayout($context); echo $layout->render();
Also you can render only layout subtree instead of full tree.
For this you should set
rootId argument in
$layout = $layoutFactory->createLayoutBuilder() ... ->getLayout($context, 'some_block_id'); echo $layout->render();
To improve your understanding of how the layout works, study the Layouts class, the
getLayout method of the LayoutBuilder class and the BlockFactory class. pay close attention to the
postExecuteAction method of theDeferredLayoutManipulator class and the LayoutRegistry class.
The following is the list of the most important classes of the Oro Layout component:
- LayoutManager is the main entry point to the Oro Layout component.
- Layouts is the static helper that can be used if a dependency injection container is not used in your application.
- Layout represents a layout which is ready to be rendered.
- LayoutBuilder provides a set of methods to build the layout.
- LayoutRegistry holds all layout extensions.
- RawLayout represents a storage for all layout data, including a list of items, hierarchy of items, aliases, etc. This is an internal class and usually you do not need to use it outside of the component.
- RawLayoutBuilder provides a way to build the layout data storage. This is an internal class and usually you do not need to use it outside of the component.
- DeferredLayoutManipulator allows to construct a layout without worrying about the order of method calls.
- BlockTypeInterface provides an interface for all block types.
- AbstractType can be used as the base class for all block block types.
- AbstractContainerType can be used as the base class for all container block types.
- BlockFactory implements the logic for building layout blocks and their views.
- DataProviderDecorator allows to calls methods with pre-defined prefix.
- ThemeExtension loads layout updates.
- ImportVisitor loads imports.