The folder structure of a theme extension
This page is for designers who want to know where each file of a theme goes. How the folders below design/<name>/
are organized in detail is explained in Design directory layout.
The complete tree
extension/mytheme/
├── ezinfo.php metadata for the About page (required)
├── extension.xml packaged metadata, read first (required)
├── composer.json when the theme is a Composer package
├── LICENSE the license text (required for publishing)
├── README.md what it is and how to switch it on
├── INSTALL.md, CHANGELOG.md install steps and history (recommended)
├── design/
│ └── mytheme/ the design (its name is the SiteDesign value)
│ ├── templates/ pagelayout.tpl and the templates
│ ├── override/templates/ templates chosen by override rules
│ ├── stylesheets/
│ ├── javascript/
│ ├── images/
│ └── fonts/
├── settings/
│ ├── design.ini.append.php DesignExtensions[]=mytheme (required)
│ ├── site.ini.append.php optional
│ ├── override.ini.append.php override rules (optional)
│ ├── mytheme.ini a settings file of your own (optional)
│ └── siteaccess/<siteaccess>/ settings for one siteaccess (optional)
├── autoloads/ template operators (optional)
├── classes/ PHP classes (optional)
├── modules/ modules with views (optional)
├── translations/<locale>/translation.ts
├── share/ demo images, files, database seed data
└── packages/ .ezpkg files shipped with the themeWhat reads each part
| Part | Read by | Page |
|---|---|---|
ezinfo.php, extension.xml | Setup > About, Setup > Extensions, the upgrade checks | ezinfo.php, extension.xml |
design/<name>/ | The template system, once DesignExtensions[] names the extension | Registering the design |
settings/*.ini.append.php | The settings system, for every active extension | Settings files in an extension |
settings/siteaccess/<sa>/ | The settings system, only while that siteaccess runs | Siteaccess settings inside a theme |
autoloads/, classes/ | The autoload array, after php bin/php/ezpgenerateautoloads.php -e | Template operators in a theme |
translations/ | The translation system when TranslationExtensions[] names the extension | Translations in a theme |
share/ | Installers and your own scripts | The share folder |
packages/ | Whoever imports them with ezpm or Setup > Packages | Bundling content class packages |
Three published themes compared
| Folder | sevenx_themes_simple | cjw_themes_jumper | sevenx_themes_media |
|---|---|---|---|
design/ | simple | starter, standard | media |
settings/siteaccess/ | yes | cjw_starter | yes |
classes/, modules/ | - | yes | yes |
translations/ | yes | ger-DE | yes |
packages/ | 20 content class packages | - | - |
share/ | - | content-images, content-files | database schema and data |
CHANGELOG.md | - | yes | - |
Read the trees yourself: ls extension/cjw_themes_jumper on an installation that has it, or browse the repository on
GitHub.
Step by step: create the skeleton by hand
mkdir -p extension/mytheme/design/mytheme/{templates,stylesheets,javascript,images} extension/mytheme/settings- Write
settings/design.ini.append.php(Registering the design). - Write
ezinfo.phpandextension.xml. - Add
LICENSEandREADME.md. - Check:
php -l extension/mytheme/ezinfo.phpandxmllint --noout extension/mytheme/extension.xml.
Or let the design extension wizard write all of it.
Related pages
- Tutorial: create a theme extension
- What a theme 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.