| .. | ||
| docs_footer.php | ||
| docs_header.php | ||
| docs_main_close.php | ||
| docs_main_open.php | ||
| docs_sidebar.php | ||
| installation_content.php | ||
| installation.php | ||
| README.md | ||
CI4 Dev Docs
Docs pages live in app/Views/docs/.
Shared layout partials live in app/Views/docs/partials/.
File list
| File | Purpose |
|---|---|
docs_header.php |
<head>, CSS tokens, top bar, opens <div class="docs-layout"> |
docs_sidebar.php |
Left nav sidebar — edit the $nav array to add/remove pages |
docs_main_open.php |
Opens <main>, renders breadcrumb, h1, meta row |
docs_main_close.php |
Closes </main>, prev/next nav, right TOC, closes layout div |
docs_footer.php |
Global footer bar, hljs init, closes </body></html> |
installation.php |
Sample content-only page — copy this as the template for every new page |
How to use
With DocsController, each docs page should contain content only.
Do not render docs_header, docs_sidebar, docs_main_open, docs_main_close,
or docs_footer inside individual page views, because the controller already
wraps the page with the full layout.
Each docs page should look like this:
<?php
/**
* Content only.
* The controller injects the layout and page metadata.
*/
?>
<p>...</p>
<h2 id="section-one">Section One</h2>
<p>...</p>
Adding a new page to the sidebar
Open app/Controllers/Docs/DocsController.php and update:
- The
$navarray to add a sidebar link. - The
$pagesarray to map the slug to its view and metadata.
Example:
['id' => 'my-new-page', 'label' => 'My New Page', 'url' => 'docs/my-new-page'],
'my-new-page' => [
'view' => 'docs/my-new-page',
'title' => 'My New Page',
'breadcrumb' => 'Getting Started',
'last_updated' => 'May 2026',
'author' => 'Core Team',
'read_time' => '3 min read',
'toc' => [
['label' => 'Section One', 'href' => '#section-one'],
],
'prev' => null,
'next' => null,
],
Then create app/Views/docs/my-new-page.php by copying installation.php
and updating only the page content.
Available content components
All CSS is in docs_header.php. These classes are ready to use in any page:
| Class / Element | What it renders |
|---|---|
<h2 id="..."> <h3 id="..."> |
Section headings (id required for TOC scroll) |
.callout.info |
Blue info box |
.callout.warning |
Amber warning box |
.callout.danger |
Red danger box |
.callout.success |
Green success box |
<ol class="steps"> |
Numbered step list with connector lines |
<table> |
Styled data / param / API tables |
.badge.get/post/put/delete |
HTTP method badges |
.badge.req / .badge.opt |
Required / Optional param badges |
.param-name |
Monospace blue param name in tables |
.code-header + <pre> |
Dark code block with filename header |
Route setup (CI4)
Add a catch-all route in app/Config/Routes.php:
$routes->get('docs', 'Docs\DocsController::index');
$routes->get('docs/(:segment)', 'Docs\DocsController::page/$1');
Then in DocsController, let the controller render the content view and wrap it:
public function page(string $slug): string
{
$config = $this->getPageConfig($slug);
$content = $this->renderContentView($config['view'], $config);
return $this->renderDocPage($config, $content);
}