The help classes as a package: contents, build and handoff
Status: 19 October 2026, Exponential 6.0.15. Partner request: the help content classes as a package, with a build handoff. Plan: help-system.md; what the classes are: help maintained as content.
Who should read it: whoever builds the package for a release and hands it to the package server, and an administrator who wants the help classes on a site through Setup > Packages instead of the command line.
In short
- The package exp_help_classes (vendor
7x, typecontentclass) holds the eight help classes in the class group Help:help_manual,help_section,help_concept,help_task,help_reference,help_troubleshooting,help_screenshot,help_glossary_entry. - It is built from an installation that has the classes, with one command:
./console exp:help:content package -s <admin siteaccess>. The class files are the kernel's own class XML, so the package installs as every other class package does. ./console exp:help:content verify-package -s <admin siteaccess> --file=<.ezpkg>compares a built package with the classes of the release, without a database.- The package is not the whole help system. Sections, the object state group, the folder tree and the roles hold
ids of the installation;
./console exp:help:content install --applymakes them, and completes the classes a package installed. It is idempotent: after the package it prints only the parts the package does not carry. - Building is done here; publishing to the package server is the owner's step (below).
Contents
- What the package contains
- What it does not contain, and why
- Building it
- Checking it
- Version
- Handoff to the package server
- Installing it on a site
- Files
- Related pages
What the package contains
| Part | Content |
|---|---|
package.xml | name exp_help_classes, vendor 7x, type contentclass, install type install, license GPL, state stable, the release (below), one provide per class and one install item per class, in the order of expHelpContentSchema::classes() (the relation lists name their allowed classes by identifier, so the order does not matter) |
ezcontentclass/class-<identifier>.xml | each class as eZContentClassPackageHandler::classDOMTree() writes it: names and descriptions, identifier, remote_id (help-class-<identifier>), name pattern, container flag, the group Help, and every attribute with its datatype, flags and datatype parameters (string lengths, the selection options, the relation list's allowed classes) |
The selection options (audience, platform) are the ones of the installation the package is built from. Build on
an installation with the default options (exphelp.ini [ContentSettings] Audiences[], Platforms[] not
overridden), so the package carries Visitors, Members, Editors, Administrators and Web, Admin, Mobile. A site with
other options gets its own appended by exp:help:content install; options are only ever appended, never reordered.
What it does not contain, and why
| Not in the package | Made by | Why |
|---|---|---|
sections help_public, help_internal | exp:help:content tree | a section is a row with an id of the installation; the roles' limitations name it |
the object state group help_status (Draft, Review, Released) | exp:help:content tree | the same, and its first state is given to every object of the installation once |
the folder tree (help-root, help-pool ...) | exp:help:content tree | it goes below the node [ContentSettings] ParentNode names, which differs per site |
| the roles Help editor, Help release, the Anonymous policy | exp:help:content roles | they limit by section, state and subtree ids of the installation |
| topics, manuals, figures, the glossary | exp:help:content seed-glossary, seed-topics, or the editors | content, not structure; the seeds ship in share/help/ |
A content class package cannot express any of these without node, section or state ids that are wrong on the next installation. The command finds and creates them by identifier and remote_id on every site, idempotently.
Building it
On an installation of the release (a throwaway installation is best; never a production site with changed help settings):
./console exp:help:content classes --apply -s <admin siteaccess> # the classes, if not yet there
./console exp:help:content classes --apply -s <admin siteaccess> # "No change." (the acceptance test)
./console exp:help:content package -s <admin siteaccess> --dry-run # what would be written
./console exp:help:content package -s <admin siteaccess> [--output=<dir>] [--version=6.0.15]package:
- reads the eight classes by identifier; if one is missing it stops with "run exp:help:content classes first";
- writes the package directory
<dir>/exp_help_classes/(package.xml,ezcontentclass/), the maintainer and the change log entry from the user of--login(defaultadmin); - exports it as
<dir>/exp_help_classes-<version>.ezpkg(a gzip compressed tar file, asezpm.php exportwrites); - checks the archive with
verify-packageand printsPASS wrote ..., or the differences andFAIL(exit 1).
--output defaults to var/<site>/cache/exphelp/packages. An existing package directory and archive of the same
version in that directory are replaced. Nothing is written into var/storage/packages/: the package is not
imported into the installation it was built on.
Checking it
./console exp:help:content verify-package -s <admin siteaccess> --file=<dir>/exp_help_classes-6.0.15.ezpkg
./console exp:help:content verify-package -s <admin siteaccess> --file=<dir>/exp_help_classes # a directoryverify-package reads the archive in PHP (no unpacking to disk, no program is started) and compares it with
expHelpContentSchema::classes() of the release it runs on:
package.xml: the name, the typecontentclass, aprovideand an install item for each of the eight classes, no other class;- each class file: its identifier, the container flag, the class group Help, every attribute of the schema with its datatype and required flag, and no attribute the schema does not have.
It prints PASS ... matches the help classes of this release (exit 0) or one line per difference and FAIL (exit 1).
It needs no database, so it can run on the package server's checkout too.
The acceptance test of a release, on a new throwaway installation (never the live site):
- install the package (Setup > Packages > Upload, then Install, or
php ezpm.php import <file>andphp ezpm.php install exp_help_classes); ./console exp:help:content classes --apply -s <admin siteaccess>prints No change.: the package installed every class, attribute and option the command would have made;./console exp:help:content install --apply -s <admin siteaccess>then makes the sections, states, tree and roles, and a second run prints No change.;- remove the throwaway installation.
Last run on 19 October 2026 on a throwaway SQLite installation of 6.0.15 (sevenx_multisite): classes twice ("No
change." the second time), package (PASS wrote ... (8 classes)), verify-package PASS; then on the fresh
database ezpm.php import and install of exp_help_classes-6.0.15.ezpkg, after which classes printed
"No change.", install made the sections, states, tree and roles, and its second run printed "No change.".
Version
- The package's version is the Exponential release it was built from, split as the 7x packages are: version
6.0, release15for 6.0.15 (expHelpContentPackage::release()); the file isexp_help_classes-6.0.15.ezpkg. --version=builds another number (a correction of a release's package: build it from the corrected release and give it the next number; a published file is never replaced, see the release rules of the project).- A new package is needed when
expHelpContentSchema::classes()changes (a class or attribute added). The schema only grows: attributes are never changed or removed, so an older package still installs, andexp:help:content classesadds what it lacks.
Handoff to the package server
The builder hands over; the owner publishes. What the builder delivers:
| Item | Where |
|---|---|
the archive exp_help_classes-<version>.ezpkg | the output directory of package |
the output of verify-package (PASS) | in the handoff note |
| the output of the acceptance test (steps 2 and 3: "No change.") | in the handoff note |
| the commit of the release the package was built from | in the handoff note |
What the owner does (the package server's own procedure, outside this repository): copy the archive into the
package server's checkout for the release (exponential/6.0/6.0.15/), add it to that release's index.xml if it is
to be offered by the setup wizard, rebuild and commit the package server, then check that the download URL answers.
The setup wizard reads the index of its release from package.ini [RepositorySettings] RemotePackagesIndexURL.
Nothing is uploaded, pushed or published by the build itself.
Installing it on a site
An administrator who prefers packages to the command line:
- Setup > Packages > Upload, choose
exp_help_classes-<version>.ezpkg, then Install on its page. The classes appear in the class group Help. - Run
./console exp:help:content install --apply -s <admin siteaccess>once (sections, states, tree, roles). It finds the classes the package installed and changes nothing on them. - Optionally
seed-glossaryandseed-topicsfor the starting content, as on any installation.
Uninstalling the package removes the classes (it asks first when objects of a class exist, and removes them with
it); exp:help:content uninstall --with-content is the complete way back, with the tree, states and sections.
Files
kernel/classes/help/content/exphelpcontentpackage.php:expHelpContentPackage(definition,build(),verifyDirectory(),verifyArchive(),readArchive()).kernel/private/classes/commands/exphelpcontent.php: the actionspackageandverify-package.tests/tests/kernel/classes/help/expHelpContentPackageTest.php(no database).