URL Handling

Pengenalan URL Handling

URL Handling adalah proses mengelola dan memanipulasi URL dalam aplikasi. NexaController menyediakan berbagai method untuk mengakses, memanipulasi, dan menganalisis URL, memudahkan pengembang dalam mengelola navigasi dan routing dalam aplikasi.

Mendapatkan Informasi URL

NexaController menyediakan beberapa method untuk mendapatkan informasi URL:


// Mendapatkan URI request
$requestUri = $this->getRequestUri();  // /products/category/electronics?page=2&sort=price

// Mendapatkan path request
$path = $this->getPath();              // /products/category/electronics

// Mendapatkan path request yang sudah dibersihkan
$cleanPath = $this->getCleanPath();    // products/category/electronics

// Mendapatkan URL saat ini
$currentUrl = $this->getCurrentUrl();  // https://example.com/products/category/electronics?page=2&sort=price

// Mendapatkan URL canonical
$canonicalUrl = $this->getCanonicalUrl();  // https://example.com/products/category/electronics

// Mendapatkan URL canonical dengan query string
$canonicalUrlWithQuery = $this->getCanonicalUrl(true);  // https://example.com/products/category/electronics?page=2&sort=price
        

Membuat URL

Untuk membuat URL relatif, gunakan method url():


// Membuat URL relatif
$homeUrl = $this->url();               // /
$productsUrl = $this->url('products'); // /products
$productUrl = $this->url('products/1'); // /products/1

// Contoh penggunaan dalam controller
public function productList(): void
{
    $products = $this->useModels('Product', 'getAll');
    
    // Membuat URL untuk setiap produk
    foreach ($products as &$product) {
        $product['url'] = $this->url('products/' . $product['id']);
    }
    
    $this->assignVars([
        'products' => $products,
        'create_url' => $this->url('products/create')
    ]);
    
    $this->render('products/list');
}
        

Query String

NexaController menyediakan method untuk mengakses parameter query string:


// Mendapatkan parameter query string
$page = $this->getQuery('page', 1);    // 2
$sort = $this->getQuery('sort');       // price

// Mendapatkan semua parameter query string
$allParams = $this->getQueryParams();  // ['page' => 2, 'sort' => 'price']

// Contoh penggunaan dalam controller
public function productList(): void
1; // Clone query params dan ubah parameter page $nextPageParams = $queryParams; $nextPageParams['page'] = $nextPage; $prevPageParams = $queryParams; $prevPageParams['page'] = $prevPage; // Buat URL dengan query string $nextPageUrl = $this->url('products') . '?' . http_build_query($nextPageParams); $prevPageUrl = $this->url('products') . '?' . http_build_query($prevPageParams); $this->assignVars([ 'products' => $products, 'page' => $page, 'limit' => $limit, 'sort' => $sort, 'order' => $order, 'next_page_url' => $nextPageUrl, 'prev_page_url' => $prevPageUrl ]); $this->render('products/list');
        

Path Segments

NexaController menyediakan beberapa method untuk mengakses segmen path:


// Mendapatkan semua segmen path
$segments = $this->getPathSegments();  // ['products', 'category', 'electronics']

// Mendapatkan segmen path relatif
$relativeSegments = $this->getRelativePathSegments();

// Mendapatkan segmen path tertentu
$segment0 = $this->getPathSegment(0);  // products
$segment1 = $this->getPathSegment(1);  // category
$segment2 = $this->getPathSegment(2);  // electronics

// Mendapatkan segmen path relatif tertentu
$relativeSegment0 = $this->getRelativePathSegment(0);

// Contoh penggunaan dalam controller
public function categoryProducts(): void
{
    // Mendapatkan kategori dari path
    $category = $this->getPathSegment(2, 'all');
    
    // Mendapatkan produk berdasarkan kategori
    $products = $this->useModels('Product', 'getByCategory', [$category]);
    
    $this->assignVars([
        'category' => $category,
        'products' => $products
    ]);
    
    $this->render('products/category');
}
        

Slug Handling

NexaController menyediakan berbagai method untuk mengelola slug:


// Mendapatkan array slug
$slugArray = $this->getSlugArray();

// Mendapatkan array part
$partArray = $this->getPartArray();

// Mendapatkan array segmen
$segmentArrays = $this->getSegmentArrays();

// Mendapatkan slug tertentu
$slug0 = $this->getSlug(0);  // products
$slug1 = $this->getSlug(1);  // category
$slug2 = $this->getSlug(2);  // electronics

// Mendapatkan part tertentu
$part0 = $this->getPart(0);
$part1 = $this->getPart(1);

// Memeriksa slug
$hasSlug = $this->hasSlug(1, 'category');  // true
$containsSlug = $this->containsSlug('electronics');  // true

// Mendapatkan slug pertama dan terakhir
$firstSlug = $this->getFirstSlug();  // products
$lastSlug = $this->getLastSlug();    // electronics

// Mendapatkan jumlah slug
$slugCount = $this->getSlugCount();  // 3

// Mendapatkan semua nilai slug dan part
$slugValues = $this->getSlugValues();  // ['products', 'category', 'electronics']
$partValues = $this->getPartValues();

// Contoh penggunaan dalam controller
public function productDetail(): void
{
    // Mendapatkan kategori dan slug produk dari URL
    $category = $this->getSlug(1, 'all');
    $productSlug = $this->getSlug(2);
    
    // Mendapatkan produk berdasarkan slug
    $product = $this->useModels('Product', 'getBySlug', [$productSlug]);
    
    if (!$product) {
        // Produk tidak ditemukan
        $this->render('errors/404');
        return;
    }
    
    $this->assignVars([
        'category' => $category,
        'product' => $product
    ]);
    
    $this->render('products/detail');
}
        

URL Pattern Matching

NexaController menyediakan method untuk mencocokkan pattern URL:


// Memeriksa apakah URL cocok dengan pattern
$matches = $this->matchesSlugPattern('products/:category/:id');  // true for /products/electronics/123

// Mengekstrak parameter dari URL berdasarkan pattern
$params = $this->extractSlugParams('products/:category/:id');  // ['category' => 'electronics', 'id' => '123']

// Menetapkan data slug ke template
$this->assignSlugData();  // Menetapkan semua slug ke template dengan prefix 'slug_'
$this->assignSlugData('url_');  // Menetapkan semua slug ke template dengan prefix 'url_'

// Contoh penggunaan dalam controller
public function dynamicRoute(): void
{
    // Memeriksa apakah URL cocok dengan pattern
    if ($this->matchesSlugPattern('products/:category/:id')) {
        // Mengekstrak parameter dari URL
        $params = $this->extractSlugParams('products/:category/:id');
        
        // Mendapatkan produk berdasarkan parameter
        $product = $this->useModels('Product', 'getById', [$params['id']]);
        
        if (!$product) {
            // Produk tidak ditemukan
            $this->render('errors/404');
            return;
        }
        
        // Memeriksa apakah kategori cocok
        if ($product['category'] !== $params['category']) {
            // Kategori tidak cocok, redirect ke URL yang benar
            $this->redirect($this->url('products/' . $product['category'] . '/' . $product['id']));
            return;
        }
        
        $this->assignVars([
            'product' => $product,
            'category' => $params['category']
        ]);
        
        $this->render('products/detail');
        return;
    }
    
    // URL tidak cocok dengan pattern
    $this->render('errors/404');
}
        

Breadcrumbs

NexaController menyediakan method untuk membuat breadcrumbs berdasarkan URL:


// Mendapatkan breadcrumbs
$breadcrumbs = $this->getBreadcrumbs();  // [['url' => '/', 'label' => 'Home'], ['url' => '/products', 'label' => 'Products'], ...]

// Mendapatkan breadcrumbs dengan separator kustom
$breadcrumbs = $this->getBreadcrumbs(' > ');

// Mendapatkan breadcrumbs tanpa home
$breadcrumbs = $this->getBreadcrumbs(' > ', false);

// Contoh penggunaan dalam controller
public function productDetail(): void
{
    // Mendapatkan breadcrumbs
    $breadcrumbs = $this->getBreadcrumbs();
    
    // Mendapatkan produk
    $productId = $this->getSlug(2);
    $product = $this->useModels('Product', 'getById', [$productId]);
    
    $this->assignVars([
        'breadcrumbs' => $breadcrumbs,
        'product' => $product
    ]);
    
    $this->render('products/detail');
}
        

Di template, breadcrumbs dapat dirender seperti ini:


<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        {{#each breadcrumbs}}
            {{#if @last}}
                <li class="breadcrumb-item active" aria-current="page">{{label}}</li>
            {}
                <li class="breadcrumb-item"><a href="{{url}}">{{label}}</a></li>
            {{/if}}
        {{/each}}
    </ol>
</nav>
        

Page Title Generation

NexaController menyediakan method untuk menghasilkan judul halaman berdasarkan URL:


// Menghasilkan judul halaman
$pageTitle = $this->generatePageTitle();  // "Electronics | Products | My Site"

// Menghasilkan judul halaman dengan separator kustom
$pageTitle = $this->generatePageTitle(' - ');  // "Electronics - Products - My Site"

// Menghasilkan judul halaman dengan suffix
$pageTitle = $this->generatePageTitle(' | ', 'My Site');  // "Electronics | Products | My Site"

// Menghasilkan judul halaman tanpa reverse
$pageTitle = $this->generatePageTitle(' | ', 'My Site', false);  // "My Site | Products | Electronics"

// Contoh penggunaan dalam controller
public function productDetail(): void
{
    // Menghasilkan judul halaman
    $pageTitle = $this->generatePageTitle();
    
    // Mendapatkan produk
    $productId = $this->getSlug(2);
    $product = $this->useModels('Product', 'getById', [$productId]);
    
    // Mengatur judul halaman dengan nama produk
    $this->setTitle($product['name'] . ' | ' . $pageTitle);
    
    $this->assignVars([
        'product' => $product
    ]);
    
    $this->render('products/detail');
}
        

URL Checking

NexaController menyediakan method untuk memeriksa URL:


// Memeriksa apakah path saat ini cocok dengan path tertentu
$isCurrentPath = $this->isCurrentPath('/products');  // true if current path is /products

// Memeriksa apakah path saat ini dimulai dengan prefix tertentu
$pathStartsWith = $this->pathStartsWith('/products');  // true if current path starts with /products

// Contoh penggunaan dalam controller
public function navigation(): void
{
    // Memeriksa path saat ini untuk menandai menu aktif
    $activeMenu = 'home';
    
    if ($this->isCurrentPath('/products')) {
        $activeMenu = 'products';
    } elseif ($this->isCurrentPath('/about')) {
        $activeMenu = 'about';
    } elseif ($this->pathStartsWith('/blog')) {
        $activeMenu = 'blog';
    }
    
    $this->assignVar('active_menu', $activeMenu);
    
    $this->render('navigation');
}
        

Di template, menu aktif dapat dirender seperti ini:


<nav class="navbar">
    <ul class="nav">
        <li class="nav-item {{#if (eq active_menu 'home')}}active{{/if}}">
            <a class="nav-link" href="{{url}}">Home</a>
        </li>
        <li class="nav-item {{#if (eq active_menu 'products')}}active{{/if}}">
            <a class="nav-link" href="{{url 'products'}}">Products</a>
        </li>
        <li class="nav-item {{#if (eq active_menu 'about')}}active{{/if}}">
            <a class="nav-link" href="{{url 'about'}}">About</a>
        </li>
        <li class="nav-item {{#if (eq active_menu 'blog')}}active{{/if}}">
            <a class="nav-link" href="{{url 'blog'}}">Blog</a>
        </li>
    </ul>
</nav>
        

Base64 URL

NexaController menyediakan method untuk bekerja dengan Base64 dalam URL:


// Memeriksa apakah string adalah Base64 valid
$isValid = $this->isValidBase64($string);

// Decode Base64 dengan aman
$data = $this->safeBase64Decode($encodedData, $default);

// Decode Base64 sederhana
$data = $this->simpleBase64Decode($encodedData, $default);

// Memeriksa apakah slug adalah Base64 valid
$isValid = $this->isSlugValidBase64(1);

// Mendapatkan slug yang di-decode
$decodedSlug = $this->getDecodedSlug(1, $default);

// Contoh penggunaan dalam controller
public function viewEncoded(): void
{
    // Mendapatkan encoded ID dari slug
    $encodedId = $this->getSlug(1, '');
    
    if (!$this->isValidBase64($encodedId)) {
        // ID tidak valid
        $this->render('errors/400');
        return;
    }
    
    // Decode ID
    $id = $this->safeBase64Decode($encodedId, null);
    
    if ($id === null) {
        // Decode gagal
        $this->render('errors/400');
        return;
    }
    
    // Mendapatkan data berdasarkan ID
    $data = $this->useModels('Data', 'getById', [$id]);
    
    $this->assignVar('data', $data);
    
    $this->render('data/view');
}
        

Best Practices

Berikut adalah beberapa praktik terbaik dalam mengelola URL:

  • Gunakan method url() untuk membuat URL relatif
  • Gunakan method getSlug() dan getPathSegment() untuk mengakses bagian URL
  • Gunakan method matchesSlugPattern() dan extractSlugParams() untuk routing dinamis
  • Gunakan method getBreadcrumbs() untuk membuat navigasi breadcrumb
  • Gunakan method generatePageTitle() untuk membuat judul halaman yang konsisten
  • Gunakan method isCurrentPath() dan pathStartsWith() untuk menandai menu aktif
  • Selalu validasi dan sanitize parameter URL sebelum digunakan
  • Gunakan URL yang SEO-friendly dengan slug yang deskriptif
  • Gunakan Base64 encoding untuk ID sensitif dalam URL