Skip to content

Traditional WordPress Searching (Part 2)

Ringkasan

Video ini melanjutkan pembuatan pencarian tradisional WordPress. Kita akan membuat file search.php untuk menampilkan hasil pencarian dengan format yang sesuai per post type, menangani hasil kosong, dan membuat file searchform.php yang reusable.


1. Membuat File search.php

File search.php menggantikan index.php untuk menampilkan hasil pencarian WordPress.

Langkah:

  1. Copy semua isi dari index.php
  2. Buat file baru: search.php
  3. Paste dan modifikasi

Modifikasi Page Banner:

php
<?php
get_header();
pageBanner(array(
  'title' => 'Search Results',
  'subtitle' => 'You searched for &ldquo;' . esc_html(get_search_query(false)) . '&rdquo;'
));
?>

Fungsi Penting:

FungsiPenjelasan
get_search_query()Mengambil kata kunci pencarian dari URL (?s=kata)
get_search_query(false)Mengambil tanpa escape bawaan (karena kita escape sendiri)
esc_html()Meng-escape output sebagai HTML aman (mencegah XSS)
&ldquo; dan &rdquo;HTML entity untuk tanda kutip kiri dan kanan

2. Keamanan: Mencegah Cross-Site Scripting (XSS)

Masalah:

Jika seseorang memasukkan kode berbahaya di URL:

?s=<script>alert('hacked')</script>

Solusi:

php
// SALAH - bisa eksekusi JavaScript berbahaya
'subtitle' => 'You searched for ' . get_search_query(false)

// BENAR - di-escape sebagai teks biasa
'subtitle' => 'You searched for ' . esc_html(get_search_query(false))

Aturan Keamanan WordPress:

  • esc_html() — gunakan saat output ditampilkan dalam HTML (heading, paragraph)
  • get_search_query() (tanpa false) — sudah aman untuk digunakan di atribut HTML (value="")
  • esc_url() — gunakan saat output adalah URL

3. Dynamic Template Parts dengan get_template_part()

Alih-alih menulis if statements panjang untuk setiap post type, gunakan get_template_part() dengan get_post_type():

File: search.php (bagian while loop)

php
<div class="container container--narrow page-section">
<?php
if (have_posts()) {
  while(have_posts()) {
    the_post();
    get_template_part('template-parts/content', get_post_type());
  }
  echo paginate_links();
} else {
  echo '<h2 class="headline headline--small-plus">No results match that search.</h2>';
}
?>
</div>

Cara Kerja get_template_part():

php
get_template_part('template-parts/content', get_post_type());
  • Argumen 1: path dasar file → template-parts/content
  • Argumen 2: suffix → hasil dari get_post_type() (misalnya post, professor, program)
  • WordPress otomatis mencari file: template-parts/content-{post_type}.php

Contoh:

Post TypeFile yang Dicari
posttemplate-parts/content-post.php
professortemplate-parts/content-professor.php
programtemplate-parts/content-program.php
eventtemplate-parts/content-event.php
pagetemplate-parts/content-page.php
campustemplate-parts/content-campus.php

4. Membuat Template Part untuk Setiap Post Type

template-parts/content-post.php (Blog Post)

php
<div class="post-item">
  <h2 class="headline headline--medium headline--post-title">
    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
  </h2>
  <div class="metabox">
    <p>Posted by <?php the_author_posts_link(); ?> on <?php the_time('n.j.Y'); ?> in <?php echo get_the_category_list(', '); ?></p>
  </div>
  <div class="generic-content">
    <?php the_excerpt(); ?>
    <p><a class="btn btn--blue" href="<?php the_permalink(); ?>">Continue Reading &raquo;</a></p>
  </div>
</div>

template-parts/content-professor.php

php
<div class="post-item">
  <li class="professor-card__list-item">
    <a class="professor-card" href="<?php the_permalink(); ?>">
      <img class="professor-card__image" src="<?php the_post_thumbnail_url('professorLandscape'); ?>">
      <span class="professor-card__name"><?php the_title(); ?></span>
    </a>
  </li>
</div>

Catatan: Dibungkus dalam <div class="post-item"> untuk styling border dan spacing yang konsisten.

template-parts/content-program.php

php
<div class="post-item">
  <h2 class="headline headline--medium headline--post-title">
    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
  </h2>
  <div class="generic-content">
    <?php the_excerpt(); ?>
    <p><a class="btn btn--blue" href="<?php the_permalink(); ?>">View Program &raquo;</a></p>
  </div>
</div>

Sama seperti content-post tapi tanpa metabox dan tombolnya bertuliskan "View Program".

template-parts/content-page.php

php
<div class="post-item">
  <h2 class="headline headline--medium headline--post-title">
    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
  </h2>
  <div class="generic-content">
    <?php the_excerpt(); ?>
    <p><a class="btn btn--blue" href="<?php the_permalink(); ?>">Continue Reading &raquo;</a></p>
  </div>
</div>

Sama seperti content-post tapi tanpa metabox.

template-parts/content-campus.php

php
<div class="post-item">
  <h2 class="headline headline--medium headline--post-title">
    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
  </h2>
  <div class="generic-content">
    <?php the_excerpt(); ?>
    <p><a class="btn btn--blue" href="<?php the_permalink(); ?>">View Campus &raquo;</a></p>
  </div>
</div>

5. Menangani Hasil Pencarian Kosong

Gunakan have_posts() untuk cek apakah ada hasil:

php
<?php
if (have_posts()) {
  while(have_posts()) {
    the_post();
    get_template_part('template-parts/content', get_post_type());
  }
  echo paginate_links();
} else {
  echo '<h2 class="headline headline--small-plus">No results match that search.</h2>';
}
?>

6. File searchform.php — Reusable Search Form

Masalah:

Form pencarian yang sama dibutuhkan di:

  • page-search.php (halaman pencarian)
  • search.php (bagian bawah hasil pencarian)

Solusi: Buat file khusus searchform.php

WordPress punya fungsi get_search_form() yang otomatis mencari file bernama searchform.php (tanpa spasi, huruf kecil semua).

File: searchform.php (di root theme folder)

php
<form class="search-form" action="<?php echo esc_url(site_url('/')); ?>" method="get">
  <label class="headline headline--medium" for="s">Perform a New Search</label>
  <div class="search-form-row">
    <input type="search" name="s" id="s" class="s" placeholder="What are you looking for?">
    <input type="submit" class="search-submit" value="Search">
  </div>
</form>

Penggunaan:

Di page-search.php:

php
<div class="container container--narrow page-section">
  <?php get_search_form(); ?>
</div>

Di search.php (setelah blok hasil):

php
<?php
if (have_posts()) {
  // ... while loop ...
} else {
  echo '<h2 class="headline headline--small-plus">No results match that search.</h2>';
}
?>
<?php get_search_form(); ?>

Kode form hanya ada di satu tempat (searchform.php) — menghindari duplikasi kode!


7. Struktur File Lengkap

theme-folder/
├── search.php              ← Hasil pencarian (mengganti index.php)
├── searchform.php          ← Form pencarian reusable
├── page-search.php         ← Halaman dengan form pencarian
├── template-parts/
│   ├── content-post.php       ← Template blog post
│   ├── content-professor.php  ← Template professor (card)
│   ├── content-program.php    ← Template program
│   ├── content-event.php      ← Template event (sudah ada)
│   ├── content-page.php       ← Template page
│   └── content-campus.php     ← Template campus
└── header.php              ← Ikon search diubah jadi <a> tag

Catatan Penting

  • Pencarian tradisional ini tidak mencari berdasarkan relationships (seperti overlay search)
  • Di akhir course ada extra credit section yang membahas custom search logic untuk pencarian tradisional berbasis URL queries
  • Nama file searchform.php harus persis (tanpa spasi, huruf kecil) — ini konvensi WordPress