1. INTRODUCTION
All page templates are located in App/templates/. Create a file there, then display it from a route with render(), as shown in Routes.
Note!
Kristal Framework uses ordinary PHP and HTML for rendering. You don't need to learn a separate template language.
Important!
Save every page template with a .php extension, even if it only contains HTML.
2. HEADER & FOOTER
The shared header and footer are located in App/templates/base/. They are included automatically when your route calls render(). Variables passed to the page are also available in these files.
The header opens the HTML document and the footer closes it, so your page template only needs its own content.
Page Titles and Descriptions
The supplied header reads METADATA from config/config.php. Add an entry to that array using the name passed to render():
"home" => [
"title" => "Home | My Website",
"description" => "Welcome to my website.",
],
This entry belongs to render(“home”). METADATA[”*”] provides defaults for pages without their own entry. Individual entries should contain all the fields you want for that page; missing fields are not filled from the defaults, except for the title.
3. NAVIGATION
Create your navigation in App/templates/partials/navigation.php. To include it in a page or shared layout, use PHP’s include statement:
<?php include page("partials/navigation"); ?>
To highlight the active page, compare each link with the template name. Add this to your navigation file:
<?php $activePage = pathinfo($page, PATHINFO_FILENAME); ?>
<ul>
<li>
<a class="<?= $activePage === "home" ? "active" : ""; ?>"
href="<?= esc_url(route("home/")); ?>">Home</a>
</li>
<li>
<a class="<?= $activePage === "about" ? "active" : ""; ?>"
href="<?= esc_url(route("about/")); ?>">About</a>
</li>
</ul>
Register the home and about routes and create their templates before using these links. Style the active class in your stylesheet to make the selected page stand out.
4. ASSETS
Use image(), audio() and download() to get file URLs. For JavaScript and CSS, use js() and css(). The files belong in the matching folders under App/media/.
For an image in App/media/images/:
image("icon.png"); // Website URL.
imagePath("icon.png"); // Local file path for PHP.
For audio in App/media/audio/:
audio("song.wav"); // Website URL.
audioPath("song.wav"); // Local file path for PHP.
For a download in App/media/downloads/:
download("file.zip"); // Website URL.
downloadPath("file.zip"); // Local file path for PHP.
Use the URL helpers in your HTML after adding the files:
<img src="<?= esc_url(image("icon.png")); ?>" alt="Website icon">
<a href="<?= esc_url(download("file.zip")); ?>">Download the file</a>
<link rel="stylesheet" href="<?= esc_url(css("main.css")); ?>">
<script src="<?= esc_url(js("main.js")); ?>"></script>
For website links, use route(). It adds your base URL and selected language:
<a href="<?= esc_url(route("home/")); ?>">Home</a>
<a href="<?= esc_url(route("about/")); ?>">About</a>
Note!
Add the files before using these examples. Missing assets return an empty URL. Use esc_url() when placing URLs in HTML, and esc_html() for text.
WebP Images
To use a WebP version of an image:
<img src="<?= esc_url(webp("banner.jpg", 70)); ?>" alt="Website banner">
The helper creates the image during development and stores it in storage/webp/. Generate the images before enabling production mode, then upload the generated files too.
5. CONDITIONAL STATEMENTS
Use PHP’s if and else to display different content:
<?php if (Session::get("show_notice", false)): ?>
<p>New tutorials are available!</p>
<?php else: ?>
<p>Check back soon for more tutorials.</p>
<?php endif; ?>
Set show_notice to true with Session::add() to display the first message. You can use the same approach with variables passed from a route.
6. LOOPS
Use foreach to display the items in an array. Here’s a small list you can try in a page template:
<?php $topics = ["Routing", "Templates", "Forms"]; ?>
<ul>
<?php foreach ($topics as $topic): ?>
<li><?= esc_html($topic); ?></li>
<?php endforeach; ?>
</ul>
You can also read both the name and value of each entry:
<?php $details = ["Framework" => "Kristal", "Language" => "PHP"]; ?>
<?php foreach ($details as $key => $value): ?>
<p><?= esc_html($key); ?>: <?= esc_html($value); ?></p>
<?php endforeach; ?>
For larger pages, prepare the arrays in your route and pass them to render().
7. SESSION VARIABLES
Use Session::get() to read a saved session value. Its second argument is the value to use when nothing has been saved:
<p>Hello, <?= esc_html(Session::get("display_name", "Visitor")); ?>!</p>
To display something only when a value exists:
<?php if (Session::has("display_name")): ?>
<p>Your name has been saved for this visit.</p>
<?php endif; ?>
See Sessions to create, change and remove session values.
