Developers
Structure
A template is a directory. This chapter says what goes in it, what is required, and what the CMS does with each part.
Read it once before you start deleting things from the copy you made. Most of a template directory is convention you can rename or drop; a small part of it is looked for by name, and dropping that part fails silently rather than loudly.
Where it lives
Your templates go in app/templates/{name}. The templates that ship with the
CMS are in core/templates/{name} and are replaced on upgrade, so do not edit
them in place — copy one into app/templates instead, as the
overview describes. Nothing under app/ is part of
the distribution.
Hubzero\Template\Loader
resolves a style to a directory, checking app/ before core/. A template in
app/templates/kimera therefore shadows the shipped kimera entirely.
The tree
This is kimera, the fullest of the shipped site templates, and the tree
northgate inherits by copying it:
core/templates/kimera/
css/ Compiled stylesheets
browser/ Per-browser fixes: ie8.css, ie9.css
pages/ Per-page stylesheets: home.css, community.css, …
theme.php Parameter-driven colours, served as CSS
html/ Output overrides for other extensions
img/ Images the template's own CSS refers to
js/ Scripts: hub.js, html5.js
language/
en-GB/
en-GB.tpl_kimera.ini
less/ LESS sources for everything under css/
migrations/
Migration20170831000000TplKimera.php
component.php Layout for tmpl=component requests
composer.json Package metadata
error.php Layout for error pages
favicon.ico
index.php The main layout
offline.php Layout shown when the site is offline
templateDetails.xml
template_thumbnail.png
Nothing here is magic except the names. css/, js/, img/ and less/ are
conventions your own stylesheets and index.php refer to; you can call them
what you like. The rest the CMS looks for by name.
What is actually required
Only two things:
index.php. If it is missing,Hubzero\Document\Type\Htmlsilently falls back tocore/templates/systemand renders that instead. The symptom is a hub that looks unstyled rather than broken.- A row in
#__extensions, and a style in#__template_styles. The administrator's template list is a query against#__extensions, not a scan of the filesystem, so a directory nobody has registered is invisible — and, the other way round, a registered name whose directory is missing is still listed. Write a migration to register it.
templateDetails.xml is not required for the template to render. It is
required for the administrator to configure it: without it the template has no
parameters to edit and contributes no module positions. See
Packaging.
The parts
| Path | What reads it |
|---|---|
index.php |
The document, for every normal page. See Page layout. |
{tmpl}.php |
The document, when the request carries tmpl={name}. tmpl=component gives modal windows and popups their bare frame; com_help sets tmpl=help, com_cpanel sets tmpl=cpanel, com_login sets tmpl=login, and com_groups sets tmpl=group for super group pages. |
error.php |
The error document. |
offline.php |
Rendered when the site is switched offline and the visitor lacks core.login.offline. |
email.php |
Hubzero\Mail\Template, for HTML mail. |
templateDetails.xml |
com_templates for parameters and metadata, com_modules for the position list. |
language/{tag}/{tag}.tpl_{name}.ini |
Loaded automatically. See Languages. |
migrations/ |
muse migration. See Migrations. |
html/ |
Every extension's asset and layout lookup. See Output overrides. |
html/icons/{symbol}.svg |
Html::asset('icon', …), overriding core/assets/icons. |
template_thumbnail.png |
The template list in the administrator. 206 pixels wide; kimera's is 206×150. An optional template_preview.png beside it makes the thumbnail a link to the full-size image. |
favicon.ico |
Only if your index.php links to it. Nothing links it for you. |
composer.json |
Composer, when the template is installed as a package. |
What the shipped templates leave out
Not one of them has the full tree, which is a useful measure of what you can skip:
kimera |
lucent |
welcome |
kameleon |
system |
|
|---|---|---|---|---|---|
index.php |
yes | yes | yes | yes | yes |
component.php |
yes | yes | — | yes | yes |
error.php |
yes | yes | — | yes | yes |
templateDetails.xml |
yes | yes | yes | yes | — |
composer.json |
yes | — | yes | yes | yes |
migrations/ |
yes | yes | yes | yes | — |
html/ overrides |
32 files | — | — | 4 files | — |
template_thumbnail.png |
yes | — | — | yes | — |
system is the fallback and is never registered as a style, which is why it
has neither a manifest nor a migration. It also holds the shared email.php,
group.php, help.php, login.php and offline.php layouts that other
templates inherit when they do not define their own.
What to keep in northgate
Working from the kimera copy, this is the honest division:
| Keep | Because |
|---|---|
index.php, component.php, error.php |
Three of the four layouts a visitor can reach. Restyle all three or the hub looks unfinished inside every modal. |
less/ and the compiled css/ beside it |
Where the branding actually goes. |
language/, renamed |
Every string the layout prints. |
migrations/, renamed |
Nothing works until this runs. |
templateDetails.xml |
The parameters and the position list. |
| Drop | Because |
|---|---|
css/pages/*.css, css/print.css, css/download.css, css/upload.css |
No layout links them and nothing pushes them. They are dead in kimera too. See Cascading style sheets. |
css/browser/ie8.css, css/browser/ie9.css and their conditional comments |
Conditional comments stopped working at Internet Explorer 10. |
js/html5.js |
The HTML5 shiv, for the same browsers. |
Most of html/ |
32 per-component stylesheets tuned to kimera's colours. Keep the ones for components your hub actually shows — for northgate, that means the com_bookings overrides you write, not kimera's com_projects ones. |
Rewritten and checked against 2.4-main @ 91d03d0a23 on 2026-09-10.