Topics
Quick Start
Get started writing JavaScript for OroCommerce and OroPlatform applications.
JavaScript Modularity
ES6 modules, AMD, CommonJS, and loading scripts from remote resources.
Page Component
Micro-controllers that manage specific parts of a page. The primary extension point for adding front-end functionality.
Registry
Application-level registry for sharing state between components.
Component Shortcuts
Concise syntax for declaring Page Components in HTML.
JavaScript Unit Tests
Writing and running unit tests for JavaScript modules.
NPM Dependencies with Composer
Manage JavaScript dependencies declared in Composer packages.
Framework Integration
Integrate third-party JavaScript frameworks into Oro applications.
Technology Stack
Libraries used by OroPlatform on the client side:- jQuery + jQuery UI
- Bootstrap
- Backbone + Underscore
- Chaplin
jquery rather than oroui/lib/jquery.
Application Entry Point
The application is initialized by theoroui/js/app module, which is the entry point of the Webpack build. It exports an instance of the application (an extension of Chaplin.Application) and depends on:
oroui/js/app/application— Application classoroui/js/app/routes— Collection of routers- Configuration passed from
oroui/js/app - Optional app modules
Routes
The routes module contains a single route that matches any URL and routes toPageController::index:
Application configuration
Application options are passed via@OroAsset/Asset.html.twig macros in the @OroUI/js_modules_config.html.twig template:
Naming Conventions
File structures and naming follow Backbone best practices adapted for Oro:- Modules supporting Chaplin architecture live in the
appfolder. - The
appdirectory contains five sub-folders:components,controllers,models,modules,views. - Each filename ends with a type suffix:
-view.js,-model.js,-component.js. - All filenames and folder names use lowercase with
-as word separators. - Utility code or jQuery-UI widgets live outside the
appfolder.
Application Lifecycle
Chaplin extends Backbone by introducing controllers and a structured lifecycle. A controller and all of its models and views exist only between navigation actions. When the route changes:- The active controller is disposed, along with all nested views and related models.
- A new controller is created for the current route with fresh views and models.
application, router, dispatcher, layout, and composer persist throughout the entire navigation session.
Page Controller
All routes lead to a singlePageController::index action:
PageController loads page content via PageModel and emits the following system events in order:
| Event | Description |
|---|---|
page:beforeChange | Fired before the page starts changing |
page:request | Fired when the page request begins |
page:update | Fired when new page HTML is ready |
page:afterChange | Fired after all components have initialized |
Page Layout View
PageLayoutView is the top-level application view, initialized on the body element and kept in memory across route changes. In addition to handling link clicks and form submissions, it implements the ComponentContainer interface and initializes top-level Page Components defined in the page HTML.
JS Templates (Underscore.js)
For client-rendered templates, Oro uses Underscore.js templates. JS templates belong to specific JS components defined as JS modules and can be overridden the same way as any other JS module.JavaScript Modularity
Oro uses ES6 modules as the recommended approach. Webpack also supports AMD and CommonJS for legacy code.- ES6 (recommended)
- AMD (legacy)
Loading scripts from remote resources
Use thescriptjs library to download dependencies not managed by Webpack:
Page Component
Page Components are the primary mechanism for adding functionality to specific parts of a page. They act as micro-controllers tied to a DOM element.Define a Page Component in HTML
data- attributes:
| Attribute | Description |
|---|---|
data-page-component-module | Module name of the component |
data-page-component-options | JSON-encoded options object |
data-page-component-name | Optional name for accessing the component by name |
data-page-component-init-on | Defer initialization until a DOM event (click, focusin, mouseover) |
Extend BaseComponent
Deferred initialization on DOM events
Postpone initialization until a DOM event to improve performance for hidden UI elements:App Modules
App Modules are atomic parts of the application that run before the application instance is created. They:- Register handlers in the Chaplin mediator
- Subscribe to mediator events
- Perform preliminary setup actions
jsmodules.yml:
Example
oroui/js/app/modules/messenger-module registers messenger handlers in the mediator: