custom-controls-customer
A template repository for a customer's own UI5 artefacts in abap2UI5abap2UI5One ABAP class implementing z2ui5_if_app is the whole app: the browser loads a generic UI5 shell once, and every interaction after that is an HTTP roundtrip back into ABAP.community org, abap: an icon font, CSS, a reuse library or a custom control, served from a BSP of their own under the resourceRoot z2ui5_ccc.
Adding a UI5 reuse library to abap2UI5 used to mean patching the framework's own BSP by hand in four places: the resourceRoots in index.html, the library in manifest.json, the xmlns: in the view and the module in the controller. All four are generated from app/webapp in the abap2UI5 repository and force-overwritten in abap2UI5 frontendabap2UI5 frontendThe abap2UI5 frontend as installable ABAP artefacts: per system type one generated branch carrying the BSP or HTTP service with its handler, pulled into the system with abapGit.community org, abap on every framework update, so the patch survives until the next upgrade and then the icons are gone with no error message. This repository holds those artefacts instead: files go under app/webapp/, npm run app2bsp turns them into the BSP Z2UI5_CCC with its page directory and ICF nodes under src/01, and abapGitabapGitA Git client written in ABAP that runs inside the system, so objects are cloned, pulled and pushed without leaving it; with no package manager in ABAP, a cloned repository is how code is distributed.community org, abap installs the result. Four declaration blocks at the top of app/webapp/cc/Extension.js (resource roots, libraries, icon fonts and stylesheets) replace the four framework patches one for one, and from ABAP z2ui5_cl_ccc=>xmlns( ) and render( ) pull the extension into a view. abap2UI5 reserves the resourceRoot z2ui5_ccc in its manifest.json, so BSP, launchpad and ICF-service mode all resolve the BSP without configuration.
Facts
Where it sits
Who is behind it
In the atlas: maintains 21@abap2UI5-addonsmaintaineroblomov-devContributes to this
In the atlas: maintains 4, contributes to 44@oblomov-dev1 contributor
What it declares
Every artifact
- Type
- Sample
- Origin
- By a community org
As a sample
- Form
- A template or starter
Connections
Custom controls, wrappers and icon fonts packaged for reuse
UI5 apps written as one ABAP class, rendered by a generic shell
Git client written in ABAP that runs inside the system
abap2UI5 frontend as ABAP artefacts installed with abapGit
Download
README
quoted from abap2UI5-addons/custom-controls-customer under MIT, readcustom-controls-customer
A template repository for your own frontend artefacts in abap2UI5. A UI5
reuse library, an icon font, corporate CSS, a custom control — served to
abap2UI5 from a BSP that belongs to
you. Fork it (or copy it into your own git host), put your files under
app/webapp/, run npm run app2bsp, and install the result with abapGit.
Nothing in abap2UI5 or in its frontend BSP has to change, and no pull request
against the framework is needed.
Part of abap2UI5-addons - addons and apps for abap2UI5, installed with abapGit.
Why
Adding a UI5 reuse library to abap2UI5 used to mean patching the framework's own BSP by hand, in four places:
| File | Patch |
|---|---|
index.html | data-sap-ui-resourceroots → "com.myorg.reuselib": "/sap/bc/ui5_ui5/sap/zreuseicons/" |
manifest.json | sap.ui5.dependencies.libs → "com.myorg.reuselib": {} |
View1.view.xml | xmlns:custom="com.myorg.reuselib" |
View1.controller.js | sap.ui.define([… "com/myorg/reuselib/library"]) |
All four are generated from app/webapp in the abap2UI5 repository and
force-overwritten in abap2UI5/frontend
on every framework update — so the patch survives exactly until the next
upgrade, and then the icons are gone with no error message.
This repository is the supported place for those artefacts instead. It is the same mechanism abap2UI5-addons/custom-controls uses for the community controls, with a second reserved namespace so the two never collide.
Installation
Requirements
- Standard ABAP 7.50 or higher
- abap2UI5 - a version that reserves
the
z2ui5_cccresourceRoot, installed in the backend. On an older framework the check app renders an empty page and the browser console shows a failed request forz2ui5_ccc/cc/Extension.js. - abap2UI5/frontend — the frontend BSP, when running in BSP or launchpad mode
Steps - with abapGit, in this order:
- abap2UI5 (and abap2UI5/frontend for BSP or launchpad mode)
- fork this repository (or copy it into your own git host) and put your artefacts in - see Usage
- your fork (branch
main) - it brings the ABAP classes, the BSP applicationZ2UI5_CCCand the two ICF nodes it is served from
Start - ?app_start=z2ui5_cl_ccc_sample_00 — the check app. If the badge
renders, is styled and reacts to a click, the BSP is deployed and the
frontend resolves z2ui5_ccc.
Usage
1. Drop the files under app/webapp/
app/webapp/
├── index.html the BSP start page - a note, this BSP has no UI
├── Util.js small helpers (url, loadStyle, loadScript, logError)
├── cc/
│ ├── Extension.js THE FILE YOU EDIT - the four config blocks
│ └── Example.js a template custom control
└── css/
└── style.css your CSS
Two limits come from the BSP page format and are checked by app2bsp, which
fails loudly rather than letting SAP reject the import:
- at most one directory level —
cc/Example.jsis fine,cc/lib/x.jsis not - names from letters, digits,
_and.only — no hyphens
2. Declare what has to be registered
Everything that must happen once, before a view can use your artefacts, is
declared at the top of app/webapp/cc/Extension.js:
const RESOURCE_ROOTS = {
"com.myorg.reuselib": "/sap/bc/ui5_ui5/sap/zreuseicons/",
};
const LIBRARIES = ["com.myorg.reuselib"];
const ICON_FONTS = [{
fontFamily: "MyCustomFontFamily",
collectionName: "my-icons",
fontURI: Util.url("fonts"),
metadata: { Regal: "e910", Stapler: "e917" },
}];
const STYLESHEETS = [Util.url("css/style.css")];
Those four blocks are the replacement for the four framework patches in the table above, one for one.
3. Regenerate and commit
npm run app2bsp # app/webapp -> src/01 (BSP pages, page directory, ICF nodes)
npx abaplint abaplint.jsonc
CI runs both and fails on a diff, so a stale BSP page can never ship old JavaScript unnoticed.
4. Use it from ABAP
DATA(view) = z2ui5_cl_ui5_view_builder=>factory( ).
DATA(root) = view->ele( n = `View`
ns = `mvc`
)->a( n = `xmlns` v = `sap.m`
)->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ).
z2ui5_cl_ccc=>xmlns( root ). " declares xmlns:z2ui5_ccc - once per view
DATA(page) = root->ele( `Page` )->a( n = `title` v = `Warehouse` ).
z2ui5_cl_ccc=>render( page ). " loads and installs the extension
page->tag( `Button`
)->a( n = `icon` v = `sap-icon://my-icons/Regal` " your own icon font
)->a( n = `text` v = `Rack` ).
client->view_display( view->stringify( ) ).
render( ) is what pulls Extension.js into the page, so it belongs in every
view that relies on an icon font, a stylesheet or a registered library —
before the controls that use them. Calling it twice is harmless; the
installation runs once per page.
How it works
abap2UI5 reserves the resourceRoot z2ui5_ccc in its manifest.json:
"sap.ui5": { "resourceRoots": { "z2ui5_cci": "../z2ui5_cci/", "z2ui5_ccc": "../z2ui5_ccc/" } }
so the module z2ui5_ccc/cc/Example is served from
/sap/bc/ui5_ui5/sap/z2ui5_ccc/cc/Example.js — the BSP Z2UI5_CCC that this
repository builds. In the standalone HTTP service, where there is no sibling
BSP to resolve ../z2ui5_ccc/ against, z2ui5_cl_http_handler hands the
absolute path to the frontend instead. All three delivery modes (BSP,
launchpad, ICF service) therefore resolve it without configuration.
Registering the path costs nothing when this repository is not installed:
the browser requests nothing from z2ui5_ccc until a view actually names the
namespace.
your ABAP app ──► z2ui5_cl_ccc=>render( page )
│ emits <z2ui5_ccc:Extension/> into the view
▼
abap2UI5 frontend ──► loads z2ui5_ccc/cc/Extension.js from YOUR BSP
│ which registers, at page level:
├─ resource roots of other BSPs
├─ UI5 reuse libraries
├─ icon fonts (IconPool)
└─ stylesheets
Keeping an existing reuse-library BSP
You do not have to move an existing library into this BSP. Leave
ZREUSEICONS where it is and register it in RESOURCE_ROOTS plus
LIBRARIES — one entry each, in a file that no framework update overwrites.
The library keeps its own name (com.myorg.reuselib), and views address it
under their own prefix:
root->a( n = `xmlns:custom` v = `com.myorg.reuselib` ).
Moving it in here is still the tidier option when you can: one BSP, one transport, one thing to install.
Binary artefacts
BSP pages are text. A .woff2, .ttf or .png cannot be committed under
app/webapp — app2bsp would mangle it, so it rejects the name instead. Two
ways work:
-
base64 data URI in CSS — for a single icon font this is the simplest path, because a data URI is text and rides along in
css/style.css:@font-face { font-family: "MyCustomFontFamily"; src: url("data:font/woff2;base64,d09GMgABAAAAA...") format("woff2"); }Note that the UI5
IconPoolneeds the font file itself atfontURI, so forsap-icon://icons use the MIME route below; a data URI covers the CSS-class usage (<span class="my-icons">). -
MIME objects — upload the font into the BSP with
/UI5/UI5_REPOSITORY_LOAD(report/UI5/UI5_REPOSITORY_LOADinSE38) or keep it as aW3MIobject serialized by abapGit, then pointfontURIat the URL it is served from. This is the right choice for anything large or for a font the IconPool has to read.
Naming
ABAP objects here follow the scheme z2ui5_<type>_<token>_<object> the
abap2UI5 repositories share, with the token ccc — custom control
customers — reserved for this one, the way smp belongs to
abap2UI5/samples and cci to the
community add-on
abap2UI5-addons/custom-controls.
So every class starts with Z2UI5_CL_CCC (Z2UI5_CX_CCC for exceptions,
Z2UI5_IF_CCC for interfaces) and is at most 25 characters long —
object_naming in abaplint.jsonc enforces both, and the comment
there explains where the 25 comes from.
The frontend side carries the same token: the BSP is Z2UI5_CCC and the
resourceRoot it is served under is z2ui5_ccc — the ABAP name of the BSP,
lowercased. A resourceRoot resolves to the BSP's URL
(/sap/bc/ui5_ui5/sap/z2ui5_ccc/), so the two are necessarily the same
string, and keeping the ABAP token in it means there is one name to remember
for the whole repository instead of two. It is reserved in the abap2UI5
manifest.json, which is what makes this BSP findable without patching
anything downstream.
The community controls follow the same rule, so
abap2UI5-addons/custom-controls
ships the BSP Z2UI5_CCI under the root z2ui5_cci for its z2ui5_cl_cci*
classes. The two roots therefore differ in the last letter only: _cci is
the community one, _ccc this one. They are distinct strings and cannot
collide, but a typo in a view's xmlns: resolves against the wrong BSP and
shows up only as a failed module request in the browser console — so when a
control does not render, check that letter first.
Renaming
Z2UI5_CCC and the Z2UI5_CL_CCC* classes are the defaults. To use your own
namespace, change BSP and PREFIX in tools/app2bsp.mjs, the
resourceRoots key the frontend registers, the class names, and the
object_naming patterns in abaplint.jsonc — all together.
Be aware that z2ui5_ccc is the namespace abap2UI5 registers out of the box.
Renaming it means registering the new one yourself, which puts you back in the
business of patching framework files — so rename the ABAP objects if your
system demands it, but keep the resourceRoot.
What is in the box
| Artefact | Purpose |
|---|---|
app/webapp/cc/Extension.js | the bootstrap element — resource roots, libraries, icon fonts, stylesheets |
app/webapp/cc/Example.js | a template custom control (property, event, renderer) |
app/webapp/Util.js | url, loadStyle, loadScript, logError, isDestroyed |
src/z2ui5_cl_ccc.clas.abap | ABAP side — xmlns( ), render( ), example( ), leaf( ) |
src/00/z2ui5_cl_ccc_sample_00.clas.abap | installation check app |
tools/app2bsp.mjs | app/webapp → the abapGit BSP artefacts under src/01 |
Development
CI (.github/workflows/check.yml) runs on every push to main and every pull
request: abaplint against abaplint.jsonc, a check that the BSP under src/01
matches app/webapp (npm run app2bsp must leave no diff), and a syntax check
of every JavaScript file under app/webapp. Run the same before you push:
npm run app2bsp
npx abaplint abaplint.jsonc
Related
- abap2UI5-addons/custom-controls
— the same mechanism under the reserved namespace
z2ui5_cci, for controls shared with the community. If what you are building is generally useful, contribute it there instead.
Contributing
Issues and pull requests are welcome.
License
MIT - see LICENSE.
Details
Sources
Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.
Compatibility and provenance
Flavors
“- Standard ABAP 7.50 or higher” — abap2UI5-addons/custom-controls-customer — README
Contributors
History in the atlas
- First seen.
For your agent
- Ref
artifact:abap2ui5-addons-custom-controls-customer- JSON
- /artifacts/abap2ui5-addons-custom-controls-customer.json
- MCP
- Connecting an agent