Skip to content

8. Menus, i18n, validate, publish

The menu

spk-assembly/metadata/menu/office-equipment-menu.json (real file) — one group node Office Equipment with three children pointing at the three pages' route.pattern values, modules: ["office-equipment"].

Because this is a standalone plugin (it ships its own application, chapter 1), there is no master menu scaffold to keep in sync — one menu file is enough.

The translations

spk-assembly/metadata/i18n/en.json (real file) — a flat map of every i18n key the three pages, the menu, the app and the module reference (~70 keys):

json
{
  "office-equipment.application.title": "Office Equipment",
  "office-equipment.module.title": "Equipment",
  "office-equipment.equipment-register.title": "Equipment Register",
  "office-equipment.equipment-register.newBtn": "New",
  "office-equipment.equipment-register.column.asset_tag": "Asset Tag",
  "office-equipment.equipment-checkout.status.OVERDUE": "Overdue",
  "office-equipment.equipment-checkout.status.DUE_SOON": "Due Soon"
}

A missing key is caught by erp plugin test as I18N-001.

Validate everything

bash
erp plugin validate example-plugin/spk-assembly
erp plugin test     example-plugin/spk-assembly
validated 3 page(s) — clean

Plugin Tests
────────────────────────────────────────
✓ page:equipment-catalog.json
✓ page:equipment-checkout.json
✓ page:equipment-register.json
✓ plugin.json:valid-json
4 passed, 0 failed, 0 semantic warning(s), 3 skipped

And the docs example runner, which also schema-validates every artifact:

bash
node developer-docs/examples/test-examples.mjs
# ... All examples valid.

Build

bash
erp plugin build example-plugin/spk-assembly -o example-plugin/office-equipment-1.0.0.spk
validated 3 page(s) — clean
packaged 33 files -> example-plugin/office-equipment-1.0.0.spk (231986 bytes)
sha256: ...

Publish

bash
erp plugin publish example-plugin/office-equipment-1.0.0.spk --tenant 2
installed:
{"pluginId":"office-equipment","version":"1.0.0","state":"installed","pf4jState":"STARTED", ...}

Confirm it's all live

bash
# pages
$ erp api get "/api/v1/authoring/pages?module=office-equipment"
[ {"name":"equipment-catalog", "route":{"pattern":"/office-equipment/equipment-catalog"}, ...},
  {"name":"equipment-checkout", ...}, {"name":"equipment-register", ...} ]

# seeded reference data
$ erp api get "/api/v1/entities/oeq_category/records/query?size=10"
{"rows":[{"category_code":"LAPTOP", ...}, ... ],"total":4}

# the reminder job
$ erp api get "/api/v1/jobs/engine-entity.status-date-sweep"
{"status":"ENABLED", ...}

# the approval rule
$ erp api get "/api/v1/entity-rules?entityType=oeq_checkout"
[{"name":"oeq_checkout_submit_workflow","active":true, ...}]

Open /app/office-equipment/equipment/office-equipment/equipment-register in your ERP. The module is complete: three working pages, seeded categories, an approval workflow, and a nightly reminder sweep — and you wrote one line of Java.

Iterating from here

To change anything: edit the file, bump plugin.json version, rebuild, re-publish. Don't uninstall to iterate — see Publish and upgrade for why.

Where to go next