Belajar CodeIgniter - Views & Templating
Episode 5 of 27

Belajar CodeIgniter - Views & Templating

Membangun sistem templating yang rapi di CodeIgniter 4: me-render view dengan data dari controller, layout reusable dengan section dan partial, view cells untuk komponen dinamis, serta kebiasaan escape output.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 4 kita menguasai routing dan controllers, pada episode ini kita fokus ke sisi "V" dari MVC: Views dan templating. Di sinilah data dari controller diubah menjadi HTML yang kalian lihat di browser.

Mengapa templating penting? Karena aplikasi nyata tidak punya satu halaman — punya puluhan bahkan ratusan. Tanpa sistem layout yang reusable, kalian akan mengulang <head>, navbar, dan footer di setiap file. CodeIgniter 4 menyediakan view layouts, section, partial, dan view cells untuk menghindari pengulangan ini.

Me-render View dengan Data

Controller me-render view dengan method view() dan mengoper data sebagai array:

app/Controllers/Posts.php
<?php
 
namespace App\Controllers;
 
class Posts extends BaseController
{
    public function index(): string
    {
        $data = [
            'title' => 'Daftar Post',
            'posts' => [
                ['id' => 1, 'title' => 'Hello World', 'status' => 'published'],
                ['id' => 2, 'title' => 'Belajar MVC', 'status' => 'draft'],
            ],
        ];
 
        return view('posts/index', $data);
    }
}

Di dalam view, array data di-ekstrak menjadi variabel:

app/Views/posts/index.php
<h1><?= esc($title) ?></h1>
 
<?php foreach ($posts as $post): ?>
    <article>
        <h2><?= esc($post['title']) ?></h2>
        <span><?= esc($post['status']) ?></span>
    </article>
<?php endforeach; ?>

esc() adalah HTML escape yang mencegah XSS — kebiasaan yang wajib kalian tanamkan sejak episode ini. Tidak ada data dari pengguna yang boleh dirender tanpa esc() (detail di episode 8).

Tip

view() menerima path relatif ke app/Views/. Subfolder didukung: view('posts/index') membaca app/Views/posts/index.php. Struktur folder view yang rapi mengikuti struktur controller.

Layout dengan Section dan Extend

CodeIgniter 4 mendukung view layouts dengan $this->extend() dan $this->section(). Buat layout induk:

app/Views/layouts/default.php
<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?= esc($title ?? 'CodeIgniter') ?></title>
</head>
<body>
    <header>
        <nav>
            <a href="<?= site_url('/') ?>">Home</a>
            <a href="<?= site_url('posts') ?>">Posts</a>
        </nav>
    </header>
 
    <main>
        <?= $this->renderSection('content') ?>
    </main>
 
    <footer>
        <p>© <?= date('Y') ?> DevNull</p>
    </footer>
</body>
</html>

$this->renderSection('content') adalah placeholder yang diisi oleh view anak. Sekarang view halaman:

app/Views/posts/index.php
<?= $this->extend('layouts/default') ?>
 
<?= $this->section('content') ?>
    <h1><?= esc($title) ?></h1>
 
    <?php foreach ($posts as $post): ?>
        <article>
            <h2><?= esc($post['title']) ?></h2>
        </article>
    <?php endforeach; ?>
<?= $this->endSection() ?>

View anak hanya berisi bagian yang berbeda — semua kerangka (head, nav, footer) diambil dari layout. Ini menghilangkan duplikasi di seluruh aplikasi.

Section Tambahan

Layout bisa punya lebih dari satu section. Misalnya sidebar:

Layout dengan sidebar (cuplikan)
<aside>
    <?= $this->renderSection('sidebar') ?>
</aside>
View anak dengan dua section
<?= $this->section('sidebar') ?>
    <ul>
        <li>Kategori</li>
        <li>Arsip</li>
    </ul>
<?= $this->endSection() ?>

Partial dan View Cells

Partial (include)

Bagian kecil yang berulang — navbar, card, form field — bisa di-render sebagai partial:

Menyertakan partial
<?= $this->include('partials/_post_card', ['post' => $post]) ?>
app/Views/partials/_post_card.php
<article class="card">
    <h3><?= esc($post['title']) ?></h3>
    <a href="<?= site_url('posts/' . $post['id']) ?>">Baca selengkapnya</a>
</article>

View Cells

Untuk komponen yang butuh data sendiri (dari database, misalnya), gunakan view cells — semacam "komponen mandiri":

View cell di layout
<?= view_cell('App\Views\Cells\LatestPosts::show') ?>
app/Views/Cells/LatestPosts.php
<?php
 
namespace App\Views\Cells;
 
class LatestPosts
{
    public function show(): string
    {
        $posts = [
            ['id' => 1, 'title' => 'Post terbaru 1'],
            ['id' => 2, 'title' => 'Post terbaru 2'],
        ];
 
        return view('cells/latest_posts', ['posts' => $posts]);
    }
}

View cell bisa menerima parameter (view_cell('...::show', ['limit' => 5])) dan cocok untuk widget yang muncul di banyak halaman.

Warning

Jangan jalankan query database langsung di view. Semua pengambilan data idealnya di controller atau model — kecuali komponen mandiri seperti view cell yang memang dirancang untuk mengelola datanya sendiri.

Escaping Output dengan esc()

esc($data, $context) memproteksi output sesuai konteks:

Escape sesuai konteks
<?= esc($title) ?>                    // konteks HTML
<?= esc($attr, 'attr') ?>             // konteks atribut HTML
<?= esc($javascript, 'js') ?>         // konteks JavaScript

Gunakan selalu di view. Aturan sederhananya: apapun yang berasal dari user atau database, anggap tidak aman sampai di-escape.

Template Engine (Parser Class)

Jika kalian tidak ingin menulis PHP murni di view, CodeIgniter menyediakan Template Parser dengan sintaks {...}:

Menggunakan Parser
$parser = \Config\Services::parser();
$data = ['title' => 'Halo', 'posts' => $posts];
 
return $parser->setData($data)
              ->render('posts/index');
app/Views/posts/index.php (parser)
<h1>{title}</h1>
{posts}
    <p>{title}</p>
{/posts}

Parser cocok untuk view yang dikelola non-developer. Namun untuk control flow kompleks, PHP murni di view (dengan layout) jauh lebih fleksibel — inilah yang kita pakai sepanjang series.

Ringkasan Views & Templating

  • view() me-render file di app/Views/ dengan data dari controller.
  • Layout + section: $this->extend(), $this->section(), $this->renderSection().
  • Partial ($this->include()) untuk bagian berulang; view cell untuk widget mandiri.
  • esc() di semua output; Parser class untuk sintaks {...} jika dibutuhkan.

Penutup

Inti yang harus dibawa pulang:

  • Hindari duplikasi HTML dengan layout dan section.
  • Pisahkan komponen kecil ke partial, komponen dengan data sendiri ke view cell.
  • Escape semua output dengan esc() — kebiasaan yang mencegah XSS.
  • Pilih PHP murni untuk kontrol flow, Parser untuk view sederhana non-developer.

Di episode 6 selanjutnya kita akan masuk ke sisi "M" dari MVC: model dan database — konfigurasi koneksi database, Query Builder, class Model dengan CRUD dan validation bawaan, serta praktik CRUD posts. Siapkan MySQL kalian, karena mulai episode ini data benar-benar tersimpan!

Belajar CodeIgniter - Views & Templating | Belajar CodeIgniter