The extension directory layout
Part 3, chapter 1. An extension is a folder under extension/ whose subfolders follow fixed names. The kernel finds
each kind of code by a name plus a setting that points at your extension. This chapter is the map; each row links the
chapter that explains it.
The full tree
extension/mysite_hello/
ezinfo.php metadata (class mysite_helloInfo)
extension.xml metadata and dependencies (read first)
composer.json for Composer and Packagist
README.md, LICENSE, doc/ documentation and license
settings/ *.ini.append.php (and your own *.ini)
siteaccess/<sa>/ per-siteaccess settings the extension owns
classes/ PHP classes (autoloaded)
autoloads/ eztemplateautoload.php: template operators
modules/<module>/ module.php, view scripts, function_definition.php
design/<design>/
templates/ templates
override/templates/ override templates
stylesheets/, javascript/, images/
datatypes/<datatype>/ <datatype>type.php
eventtypes/event/<event>/ <event>type.php
cronjobs/ cronjob scripts
bin/php/ command line scripts (ext:<extension>:<name>)
translations/<locale>/ translation.ts
share/ db_schema.dba, db_data.dba, filelist.md5
sql/<database>/ schema.sql per database engine
update/ upgrade scripts and SQL
packages/ packages the extension ships
tests/ PHPUnit testsNothing is required except a reason to exist: an extension with only settings/ is complete. ezinfo.php and
extension.xml are strongly recommended for every extension, because the administration and the upgrade checks read
them.
What the kernel does with each
| Path | Found because | Chapter |
|---|---|---|
ezinfo.php, extension.xml | read by expInfo for every extension on disk | ezinfo.php, extension.xml |
settings/ | added to the settings override directories of an active extension | Settings in an extension |
classes/ | scanned by php bin/php/ezpgenerateautoloads.php -e into var/autoload/ezp_extension.php | Autoloads and class naming |
autoloads/eztemplateautoload.php | site.ini [TemplateSettings] ExtensionAutoloadPath[]=<ext> | Template operators |
modules/<module>/module.php | module.ini [ModuleSettings] ExtensionRepositories[]=<ext> | Modules and views |
design/<design>/ | design.ini [ExtensionSettings] DesignExtensions[]=<ext> | A design inside an extension |
datatypes/<type>/<type>type.php | content.ini [DataTypeSettings] ExtensionDirectories[]=<ext> and AvailableDataTypes[]=<type> | Datatypes |
eventtypes/event/<type>/<type>type.php | workflow.ini [EventSettings] ExtensionDirectories[]=<ext> and AvailableEventTypes[]=event_<type> | Workflow event types |
cronjobs/<script>.php | cronjob.ini [CronjobSettings] ExtensionDirectories[]=<ext> and a part's Scripts[] | Cronjob parts |
bin/php/<name>.php | the console finds it as ext:<extension>:<name> | CLI scripts and console commands |
translations/<locale>/translation.ts | site.ini [RegionalSettings] TranslationExtensions[]=<ext> | Translations in an extension |
share/db_schema.dba, sql/ | the package installer, or your upgrade script | Database schema, .dba files and upgrades |
tests/ | your phpunit.xml.dist | Tests for extensions |
The rule behind the table: the folder name is a convention, and a setting in your extension's own
settings/ registers it. A datatypes/ folder in an extension that does not add itself to
ExtensionDirectories[] is never looked at.
The paths for datatypes and event types are exactly what the kernel builds: eZDataType::loadAndRegisterType()
includes <directory>/<type>/<type>type.php, and eZWorkflowType::loadAndRegisterType() splits an event type string
such as event_mysite_notify into the group event and the type mysite_notify and includes
<extension>/eventtypes/event/mysite_notify/mysite_notifytype.php.
How common is each folder?
On the reference installation (87 extensions on disk) the folders were used this often: settings/ 80,
classes/ 68, design/ 62, doc/ 60, translations/ 50, modules/ 45, autoloads/ 39, tests/ 35, bin/ 28,
sql/ 19, datatypes/ 17, share/ 17, cronjobs/ 15, update/ 8, eventtypes/ 6, packages/ 4. Count yours:
for d in settings classes design modules autoloads datatypes eventtypes cronjobs bin translations tests; do
printf "%-12s %s\n" "$d" "$(ls -d extension/*/$d 2>/dev/null | wc -l)"
doneNaming the extension
- Lower case letters, digits and underscores:
mysite_hello, notMySite-Hello. - Unique, and yours: a prefix of your organization or project (
mysite_,acme_) avoids collisions with every other extension. Extensions from 7x usesevenx(7x's official public PHP code prefix; "7x" cannot be one, since a name cannot start with a digit) orexp(used with intent for work assigned to the Exponential project and the Exponential Foundation): see Naming prefixes: sevenx and exp. Do not start new names withez, which belongs to the kernel's historical classes. - The folder name is used everywhere (settings, Composer's
extra, class names such asmysite_helloInfo), so choose it once.
Generated by the RAD tools
Every wizard at Setup > RAD writes this structure for the parts you choose and lists every file before writing it. Comparing a wizard's output with this map is a good way to learn it; see The RAD tools tour.
Related pages
- Previous: Part 3: The extension developer
- Next: ezinfo.php: who made it and which version
- Extension points
- What an extension is
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.