Variables

Access variables passed to render() via $this:

<h1><?= $this->title ?></h1>
<p><?= $this->description ?></p>

Variables are automatically wrapped in a Data object that provides auto-escaping and other utilities. When you access $this->title, Nate looks up the key title in the data array.

Note: Accessing a variable that doesn't exist in the data array will throw a DataNotFoundException. This helps catch typos and missing data early.

Auto-Escaping

By default, all output is automatically HTML-escaped using htmlspecialchars() with ENT_QUOTES | ENT_SUBSTITUTE and UTF-8 encoding:

<?php
// In your PHP code:
$template->render(['script' => '<script>alert("xss")</script>']);
?>

<!-- In your template: -->
<?= $this->script ?>
<!-- Output: &lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt; -->

Raw (Unescaped) Output

When you need to output unescaped HTML (e.g., trusted HTML content), use raw():

<?= $this->richContent->raw() ?>
<!-- Outputs the raw value without escaping -->

Tip: Always use escaped output (<?= $this->var ?>) by default. Only use raw() when you are certain the content is safe. This follows the principle of least privilege for security.

Control Structures

Since Nate templates are native PHP, you use standard PHP control structures with alternative syntax for cleaner templates:

Conditionals

<?php if ($this->showGreeting) : ?>
    <h1>Hello!</h1>
<?php endif ?>

<?php if ($this->role === 'admin') : ?>
    <a href="/admin">Admin Panel</a>
<?php elseif ($this->role === 'user') : ?>
    <a href="/dashboard">Dashboard</a>
<?php else : ?>
    <a href="/login">Login</a>
<?php endif ?>

Loops

<ul>
    <?php foreach ($this->items as $item) : ?>
        <li><?= $item ?></li>
    <?php endforeach ?>
</ul>

<?php foreach ($this->users as $key => $user) : ?>
    <div class="user">
        <strong><?= $key ?>:</strong>
        <?= $user->raw() ?>
    </div>
<?php endforeach ?>

Note: When iterating over arrays in a foreach, each value is automatically wrapped in a new Data object, preserving auto-escaping inside loops.

Using PHP Functions

Any PHP function can be called directly in templates — no filter system needed:

<?= strtoupper($this->name) ?>
<?= number_format($this->price, 2) ?>
<?= date('F j, Y', strtotime($this->createdAt)) ?>
<?= nl2br($this->description->raw()) ?>

Comments

Use standard PHP comments:

<?php // This is a single-line comment ?>
<?php /* This is a multi-line comment */ ?>