Development

Documentation/id_ID/book/1.0/04-The-Basics-of-Page-Creation

You must first sign up to be able to contribute.

Bab 4 - Dasar-Dasar Pembuatan Halaman

Penuh rasa ingin tahu, tutorial pertama yang diikuti oleh programmer ketika belajar bahasa baru atau sebuah framework adalah sesuatu untuk menampilkan "Hello, world!" pada layar. Sebenarnya aneh berpikir jika komputer sebagai benda yang dapat menyapa seluruh dunia, semenjak setiap usaha pada lapangan inteligensia buatan selalu menghasilkan kemampuan percakapan yang buruk. Tetapi symfony tidak sebodoh itu dibandingkan program lain, dan buktinya adalah, anda dapat membuat halaman yang menyapa "Hello, <Your Name Here>" di dalamnya.

Bab ini akan mengajarkan anda bagaimana untuk membuat sebuah modul, yang merupakan struktur elemen yang mengelompokkan halaman-halaman. Anda juga akan belajar untuk membuat halaman, yang dipisah antara action dan template, karena adanya pola MVC. Link dan form adalah interaksi web dasar; anda akan melihat bagaiman untuk menysispkannya pada template dan menanganinya pada action.

Membuat Kerangka Modul

Sebagaimana diterangkan pada Bab 2, symfony mengelompokkan halaman-halaman ke dalam modul-modul. Sebelum membuat sebuah halaman, anda perlu membuat sebuah modul, yang awalnya berupa kulit kosong dengan struktur file yang dapat dikenali oleh symfony.

Baris perintah symfony mengotomatisasi pembuatan modul-modul. Anda hanya perlu memanggil tugas init-module dengan nama aplikasi dan nama modul sebagai argumen. Pada bab sebelumnya, anda sudah membuat sebuah applikasi myapp. Untuk menambahkan modul mymodule ke aplikasi ini, ketik perintah-perintah berikut:

> cd ~/myproject
> symfony init-module myapp mymodule

>> dir+      ~/myproject/apps/myapp/modules/mymodule
>> dir+      ~/myproject/apps/myapp/modules/mymodule/actions
>> file+     ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php
>> dir+      ~/myproject/apps/myapp/modules/mymodule/config
>> dir+      ~/myproject/apps/myapp/modules/mymodule/lib
>> dir+      ~/myproject/apps/myapp/modules/mymodule/templates
>> file+     ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php
>> dir+      ~/myproject/apps/myapp/modules/mymodule/validate
>> file+     ~/myproject/test/functional/myapp/mymoduleActionsTest.php
>> tokens    ~/myproject/test/functional/myapp/mymoduleActionsTest.php
>> tokens    ~/myproject/apps/myapp/modules/mymodule/actions/actions.class.php
>> tokens    ~/myproject/apps/myapp/modules/mymodule/templates/indexSuccess.php

Diluar direktori actions/, config/, lib/, templates/, dan validate/, perintah ini membuat hanya tiga file saja. Satu pada folder test/ yang berhubungan dengan pengujian unit, dan anda tidak perlu terganggu dengannya hingga Bab 15. File actions.class.php (ditunjukkan pada Listing 4-1) mem-forward ke halaman ucapan selamat modul default. File templates/indexSuccess.php yang masih kosong.

Listing 4-1 - Action Default yang Diciptakan, pada actions/actions.class.php

[php]
<?php

class mymoduleActions extends sfActions
{
  public function executeIndex()
  {
    $this->forward('default', 'module');
  }
}

CATATAN Jika anda melihat ke file actions.class.php aktual, anda akan menemukan lebih banyak baris daripada sebelumnya, termasuk banyak sekali komentar. Hal ini dikarenakan symfony merekomendasikan menggunakan komentar PHP untuk dokumentasi proyek anda dan menyiapkan setiap file kelas agar kompatibel dengan tool phpDocumentor (http://www.phpdoc.org/).

Untuk setiap modul yang baru, symfony membuat sebuah action default index. Yang disusun dari sebuah action yang dinamakan executeIndex dan sebuah file template yang dinamakan indexSuccess.php. Arti dari awalan execute dan akhiran Success akan dijelaskan pada Bab 6 dan 7, secara berurutan. Sementara ini, anda pertimbangkan penamaan ini sebagai sebuah konvensi. Anda dapat melihat halaman yang dihasilkan (ditampilkan lagi pada Figur 4-1) dengan mengarahkan ke URL berikut:

http://localhost/myapp_dev.php/mymodule/index

Action default index tidak akan digunakan pada bab ini, jadi anda dapat menghapus metode executeIndex() dari file actions.class.php, dan menghapus fileindexSuccess.php dari direktori templates/.

CATATAN Symfony menawarkan cara lain untuk menginisialiasi sebuah modul selain menggunakan baris perintah. Salah satunya adalah dengan membuat direktori-direktori dan file-file itu sendiri. Dalam banyak kasus, action-action dan template-template sebuah modul kebanyakan ditujukan untuk memanipulasi data pada tabel yang ditentukan. Sebagaimana kode yang dibutuhkan untuk membuat (create), mengambil (retrieve), update, dan menghapus (delete) rekord dari tabel sering kali sama, symfony menyediakan sebuah mekanisme yang dinamakan scaffolding untuk menciptakan kode ini untuk anda. Lihat Bab 14 untuk informasi lanjut mengenai teknik ini.

Figur 4-1 - Halaman index default yang diciptakan

The default generated index page

Menambah Halaman

Dalam symfony, logika di belakang halaman-halaman disimpan pada action, dan presentasi ada pada template-template. Halaman-halaman tanpa logika (masih) membutuhkan sebuah action yang kosong.

Menambah Action

Halaman "Hello, world!" akan dapat diakses memlaui action myAction. Untuk membuatnya, tambahkan saja metode executeMyAction ke kelas mymoduleActions, seperti ditunjukkan pada Listing 4-2.

Listing 4-2 - Menambahkan Action Layaknya Menambah Metode Execute ke Kelas Action

[php]
<?php

class mymoduleActions extends sfActions
{
  public function executeMyAction()
  {
  }
}

Nama dari metode action selalu `executeXxx()`, dimana bagian kedua dari nama tersebut adalah nama action dengan huruf depan kapital.

Sekarang, jika anda me-request URL berikut:

http://localhost/myapp_dev.php/mymodule/myAction

symfony akan mengatakan bahwa tidak ada file template myActionSuccess.php. Hal tersebut wajar; dalam symfony, sebuah halaman selalu terdiri dari sebuah action dan sebuah template.

PERHATIAN URL-URL (bukan nama domain) bersifat case-sensitive, dan juga symfony (meskipun nama metode bersifat case-insensitive dalam PHP). Ini berarti jika anda menambahkan metode executemyaction(), atau executeMyaction(), dan anda memanggil myAction melalui browser, symfony akan mengembalikan kesalahan 404.

-

SIDEBAR URL-URL adalah bagian dari respon

Symfony menyediakan sistem routing yang memperbolehkan anda menggunakan pemisahan penuh antara nama action sebenarnya dan bentuk URL yang digunakan untuk memanggilnya. Ini memperbolehkan format kustom pada URL sebaimana jika URL tersebut sebagai bagian dari respon. Anda tidak lagi dibatasi oleh struktur file atau parameter-parameter request; URL untuk sebuah action dapat terlihat sebagai frase yang anda inginkan. Sebagai contoh, pemanggilan action index dari suatu modul yang dinamakan artikel biasanya terlihat seperti ini:

http://localhost/myapp_dev.php/article/index?id=123

URL ini mengambil artikel yang diberikan dari database. Pada contoh ini, artikel diambil (dengan id=123) tentang bagian di Eropa yang secara khusus mendiskusikan masalah keuangan di Perancis. Tetapi URL dapat ditulis dengan cara sangat berbeda dengan contoh sebelumnya dengan cukup merubah file konfigurasi routing.yml:

http://localhost/articles/europe/france/finance.html

Bukan hanya URL yang dihasilkan search engine-friendly, tetapi juga sangat berarti bagi pengguna, yang selanjutnya dapat menggunakan address bar sebagai baris perintah pseudo untuk membuat query-query kustom, seperti berikut:

http://localhost/articles/tagged/finance+france+euro

Symfony mengetahui bagaimana cara memroses dan menciptkan URL-URL pintar untuk pengguna. Sistem routing otomatis menempelkan parameter-parameter request dari URL pintar dan menyediakannya untuk action. Dia juga memformat hyperlink-hyperlink yang disertakan dalam respon sehingga hyperlink tersebut terlihat "pintar". Anda akan banyak belajar mengenai fitur ini pada Bab 9.

Secara keseluruhan, ini berarti bahwa bagimana anda menamai suatu action dari aplikasi-aplikasi anda seharusnya tidak mempengaruhi bagimana bentuk URL yang digunakan untuk memanggilnya harus terlihat, melainkan dari fungsi-fungsi action-action aplikasi tersebut. Nama sebuah action menjelaskan apa sebenarnya yang dapat dikerjakannya, dan sering berupa kata kerja dalam bentuk infinitif (semisal show, list, edit, dll). Nama-nama action dapat dibuat sama sekali tak nampak kepada pengguna, jadi jangan ragu untuk menggunakan nama-nama action eksplisit (semisal listByName atau showWithComments). Anda akan menhemat komentar-komentar kode untuk menjelaskan fungsi action anda, plus kode anda akan lebih mudah dipahami.

Menambah Template

Action mengharapkan sebuah template untuk me-render dirinya. Sebuah template adalah file yang diletakkan pada direktori templates/ dari sebuah modul, dinamakan dengan action dan terminasi action. Terminasi action default adalah "success," jadi file template yang harus dibuat untuk action myAction dinamakan myActionSuccess.php.

Template-template disarankan hanya berisi kode presentasi saja, jadi usahakan sedikit mungkin menggunakan kode PHP. Sebagai fakta, halaman yang menampilkan "Hello, world!" dapat menggunakan template sederhana seperti ditunjukkan pada Listing 4-3.

Listing 4-3 - Template mymodule/templates/myActionSuccess.php

[php]
<p>Hello, world!</p>

Jika anda perlu untuk mengeksekusi beberapa kode PHP dalam template, anda seharusnya menghindari penggunakan sintaks PHP biasa, seperti ditunjukkan pada Listing 4-4. Melainkan, tulis template-template menggunakan sintaks PHP alternatif, seperti ditunjukkan pada Listing 4-5, untuk menjaga kode mudah dimengerti oleh programer-programer non PHP. Bukan hanya kode akhir akan teridentasi dengan benar, tetapi juga membuat kode PHP kompleks tetap dalam action, karena hanya statemen-statemen kontrol (if, foreach, while, dll) yang memiliki sintaks alternatif.

Listing 4-4 - Sintaks PHP Biasa, Bagus untuk Action, Tetapi Buruk untuk Template

[php]
<p>Hello, world!</p>
<?php

if ($test)
{
  echo "<p>".time()."</p>";
}

?>

Listing 4-5 - Sintaks PHP Alternatif, Bagus untuk Template

[php]
<p>Hello, world!</p>
<?php if ($test): ?>
<p><?php echo time(); ?></p>
<?php endif; ?>

TIP Sebuah aturan yang baik untuk memeriksa jika sintaks template cukup mudah dibaca adalah file tersebut seharusnya tidak berisi kode HTML yang di-echo-kan oleh PHP atau menggunakan kurung kurawal. Dari kebanyakan waktu, ketika membuka <?php, anda juga akan menutupnya dengan ?> pada baris yang sama.

Melewatkan Informasi dari Action ke Template

Tugas sebuah action adalah melakukan semua kalkulasi yang rumit, pengambilan data, dan pengujian-pengujian, dan untuk menentukan variabel-variabel bagi template untuk di-echo-kan atau diujikan. Symfony menyediakan atribut-atribut dalam kelas action (diakses melalui $this->variableName dalam action) yang langsung dapat diakses dalam template dari namespace global (via $variableName). Listing 4-6 dan 4-7 menunjukkan bagaimana untuk melewatkan informasi dari action ke template.

Listing 4-6 - Setting Atribut Action dalam Action untuk Membuatnya Tersedia bagi Template

[php]
<?php

class mymoduleActions extends sfActions
{
  public function executeMyAction()
  {
    $today = getdate();
    $this->hour = $today['hours'];
  }
}

Listing 4-7 - Template Memiliki Akses Langsung ke Attribut-Attribut Action

[php]
<p>Hello, world!</p>
<?php if ($hour >= 18): ?>
<p>Or should I say good evening? It is already <?php echo $hour ?>.</p>
<?php endif; ?>

CATATAN Template sudah punya akses ke beberapa potong data tanpa perlu setup variabel dalam action. Setiap template dapat memanggil metode-metode dari obyek-obyek $sf_context, $sf_request, $sf_params, dan $sf_user. Mereka berisi data yang berkaitan dengan konteks sekarang, request, parameter-parameter request, dan sesi. Anda akan belajar bagaimana menggunakannya secara efisien.

Mendapatkan Informasi dari Pengguna dengan Form

Form adalah cara terbaik untuk mendapatkan informasi dari pengguna. Menulis form dan elemen-elemen dalam HTML kadang-kadang dapat menyusahkan, khususnya jika anda menginginkan hasil yang XHTML-compliant. Anda dapat menyertakan elemen-elemen form dalam template-template symfony seperti biasa, sepeti ditunjukkan pada Listing 4-8, tetapi symfony menyediakan helper-helper yang membuat tugas ini menjadi mudah.

Listing 4-8 - Template Dapat Beisi Kode HTML Umum

[php]
<p>Hello, world!</p>
<?php if ($hour >= 18): ?>
<p>Or should I say good evening? It is already <?php echo $hour ?>.</p>
<?php endif; ?>
<form method="post" action="/myapp_dev.php/mymodule/anotherAction">
  <label for="name">What is your name?</label>
  <input type="text" name="name" id="name" value="" />
  <input type="submit" value="Ok" />
</form>

Sebuah helper adalah fungsi PHP yang didefinisikan oleh symfony yang dimaksudkan untuk digunakan dalam template-template. Helper menghasilkan beberapa kode HTML dan lebih cepat digunakan dibandingkan dengan menulis kode HTML aktual sendiri. Menggunakan helper-helper symfony, anda mendapatkan hasil yang sama dengan Listing 4-8 dengan kode yang ditunjukkan pada Listing 4-9.

Listing 4-9 - Lebih Cepat dan Mudah Menggunakan Helper daripada Menggunakan Tag HTML

[php]
<p>Hello, world!</p>
<?php if ($hour >= 18): ?>
<p>Or should I say good evening? It is already <?php echo $hour ?>.</p>
<?php endif; ?>
<?php echo form_tag('mymodule/anotherAction') ?>
  <?php echo label_for('name', 'What is your name?') ?>
  <?php echo input_tag('name') ?>
  <?php echo submit_tag('Ok') ?>
</form>

SIDEBAR Helper disediakan untuk membantu anda

Misal, seperti contoh pada Listing 4-9, anda berpikir bahwa versi helper tidak sebegitu cepat dibandingkan dengan menulis sendiri kode HTML, pertimbangkan berikut ini:

[php]
<?php
$card_list = array(
  'VISA' => 'Visa',
  'MAST' => 'MasterCard',
  'AMEX' => 'American Express',
  'DISC' => 'Discover');
echo select_tag('cc_type', options_for_select($card_list, 'AMEX'));
?>

Yang menghasilkan HTML berikut:

[php]
<select name="cc_type" id="cc_type">
  <option value="VISA">Visa</option>
  <option value="MAST">MasterCard</option>
  <option value="AMEX" selected="selected">American Express</option>
  <option value="DISC">Discover</option>
</select>

Keuntungan menggunakan helper dalam template adalah kecepatan coding, kejelasan kode, dan ringkas. Harga yang harus dibayar hanyalah waktu yang dibutuhkan untuk belajar, yang akan selesai ketika anda menyelesaikan buku ini, dan waktu untuk menulis <?php echo ?>, yang mungkin anda sudah memiliki jalan pintas pada penyunting teks favorit anda. Jadi anda bisa saja tidak menggunakan helper symfony dalam template-template dan menulis kode HTML sebagaimana biasa anda lakukan, tetapi hal ini banyak merugikan dan juga kurang menyenangkan.

Perlu dicatat penggunaan tag pembuka pendek (<?=, yang ekuivalen dengan <?php echo) tidak direkomendasikan dalam aplikasi-aplikasi web profesional, karena server web produksi anda mungkin bisa mengenali lebih dari satu bahasa scripting sehingga terjadi kebingungan. Di samping itu, tag pembuka pendek tidak bekerja dengan konfigurasi PHP default dan perlu pengaktifan tweaking server. Akhirnya, ketika anda harus bekerja dengan XML dan validasi, itu akan gagal segera karena <? memiliki arti khusus dalam XML.

Manipulasi form membutuhkan satu bab tersendiri, semenjak symfony menyediakan berbagai macam peralatan-peralatan, kebanyakan helper, untuk membuatnya lebih mudah. Anda akan belajar lebih banyak mengenai helper-helper tersebut pada Bab 10.

Link ke Action Lain

Anda sudah mengetahui bahwa ada pemisahan total antara nama action dan URL yang digunakan untuk memanggilnya. Jadi jika anda membuat link ke anotherAction dalam template seperti pada Listing 4-10, itu hanya akan bekerja dengan routing default. Jika kemudian anda memutuskan untuk merubah tampilan URL, maka anda perlu melihat lagi semua template-template dan merubah hyperlink.

Listing 4-10 - Hyperlink, dengan Cara Klasik

[php]
<a href="/myapp_dev.php/mymodule/anotherAction?name=anonymous">
  I never say my name
</a>

Untuk menghindari usaha ini, anda seharusnya selalu menggunakan helper link_to() untuk membuat hyperlink ke action-action aplikasi. Listing 4-11 mendemonstrasikan penggunaan helper hyperlink.

Listing 4-11 - Helper link_to()

[php]
<p>Hello, world!</p>
<?php if ($hour >= 18): ?>
<p>Or should I say good evening? It is already <?php echo $hour ?>.</p>
<?php endif; ?>
<?php echo form_tag('mymodule/anotherAction') ?>
  <?php echo label_for('name', 'What is your name?') ?>
  <?php echo input_tag('name') ?>
  <?php echo submit_tag('Ok') ?>
  <?php echo link_to('I never say my name','mymodule/anotherAction?name=anonymous') ?>
</form>

HTML yang dihasilkan sama dengan sebelumnya, kecuali ketika anda mengubah aturan-aturan routing, semua template-template akan bertindak dengan benar dan mem-format URL secara sesuai.

Helper link_to(), seperti kebanyakan helper lainnya, menerima argumen lain sebagai pilihan khusus dan attribut-atribut tag tambahan. Listing 4-12 menunjukkan contoh sebuah argumen pilihan dan HTML yang dihasilkan. Arguman pilihan bisa berupa array asosiatif atau string sederhana ditunjukkan dengan pasangan key=value yang dipisahkan oelh spasi.

Listing 4-12 - Kebanyakan Helper Menerima Argumen Pilihan

[php]
// Argumen pilihan dengan array asosiatif
<?php echo link_to('I never say my name', 'mymodule/anotherAction?name=anonymous',
  array(
    'class'    => 'special_link',
    'confirm'  => 'Are you sure?',
    'absolute' => true
)) ?>

// Argumen pilihan dengan string
<?php echo link_to('I never say my name', 'mymodule/anotherAction?name=anonymous',
  'class=special_link confirm=Are you sure? absolute=true') ?>

// Kedua pemanggilan tersebut menghasilkan output sama
 => <a class="special_link" onclick="return confirm('Are you sure?');"
    href="http://localhost/myapp_dev.php/mymodule/anotherAction/name/anonymous">
    I never say my name</a>

Kapan pun anda menggunakan helper symfony yang menghasilkan tag HTML, anda dapat menyisipkan atribut-atribut tag tambahan (semisal atribut class pada contoh pada Listing 4-12) dalam argumen pilihan. Anda bahkan dapat menulis atribut-atribut ini dengan cara HTML 4.0 "quick-and-dirty" (tanpa tanda kutip ganda), dan symfony akan menghasilkan format XHTML yang manis. Itulah alasan lain mengapa helper-helper lebih cepat daripada menulis HTML.

CATATAN Karena membutuhkan pengolahan dan transformasi tambahan, sintaks string sedikit lebih lambat dibandingkan dengan sintaks array.

Seperti helper-helper form, helper-helper link jumlahnya banyak dan memiliki banyak pilihan. Bab 9 akan menggambarkannya secara detail.

Mendapatkan Informasi dari Request

Baik pengguna mengirimkan informasi via form (biasanya dengan request POST) atau via URL (request GET), anda dapat mengambil data terkait dari action dengan metode getRequestParameter() dari obyek sfActions. Listing 4-13 menunjukkan bagaimana, pada anotherAction, anda mengambil nilai dari parameter name.

Listing 4-13 - Mengambil Data dari Parameter Request dalam Action

[php]
<?php

class mymoduleActions extends sfActions
{
  ...

  public function executeAnotherAction()
  {
    $this->name = $this->getRequestParameter('name');
  }
}

Jika manipulasi data cukup sederhana, anda bahkan tidak membutuhkan action untuk mengambil parameter request. Template memiliki akses ke obyek yabg dinamakan $sf_params, yang menawarkan metode get() untuk mengambil parameter-parameter request, sama seperti getRequestParameter() dalam action.

Jika executeAnotherAction() kosong, Listing 4-14 menunjukkan bagaimana template anotherActionSuccess.php mengambil parameter name yang sama.

Listing 4-14 - Mengambil Data dari Parameter Request Langsung pada Template

[php]
<p>Hello, <?php echo $sf_params->get('name') ?>!</p>

CATATAN Mengapa tidak memakai variabel $_POST, $_GET, atau $_REQUEST? Karena kemudian URL-URL anda akan di-format dengan berbeda (seperti pada http://localhost/articles/europe/france/finance.html, tanpa ? maupun =), variabel-variabel PHP umum tidak akan bekerja lagi, dan hanya sistem routing saja yang dapat mengambil parameter-parameter request. Dan anda mungkin menginginkan untuk menambahkan filering input untuk mencegah injeksi kode perusak, yang hanya mungkin jika anda menyimpan semua parameter-parameter request dalam satu parameter holder yang bersih.

Obyek $sf_params lebih powerful daripada hanya memberikan sebuah getter yang sama dengan array. Sebagai contoh, jika anda hanya ingin menguji keberadaan sebuah parameter request, anda cukup menggunakan metode $sf_params->has() daripada menguji nilai aktual dengan get(), seperti pada Listing 4-15.

Listing 4-15 - Menguji Keberadaan Parameter Request pada Template

[php]
<?php if ($sf_params->has('name')): ?>
  <p>Hello, <?php echo $sf_params->get('name') ?>!</p>
<?php else: ?>
  <p>Hello, John Doe!</p>
<?php endif; ?>

Anda mungkin sudah menebak ini bisa ditulis dalam satu baris saja. Seperti dengan kebanyakan metode-metode getter dalam symfony, baik metode getRequestParameter() pada action dan metode $sf_params->get() pada template keduanya (yang, sebagai fakta, memanggil metode yang sama pada obyek yang sama) menerima argumen kedua: nilai default yang digunakan jika parameter request tidak ada.

[php]
<p>Hello, <?php echo $sf_params->get('name', 'John Doe') ?>!</p>

Kesimpulan

Dalam symfony, halaman-halaman dikomposisikan dari sebuah action (sebuah metode dalam file actions/actions.class.php yang diawali execute) dan sebuah template (file pada direktori templates/, umumnya diakhiri dengan Success.php). Mereka dikelompokkan dalam modul-modul, sesuai fungsi mereka dalam aplikasi. Pembuatan template-template difasilitasi dengan helper-helper, yang merupakan fungsi-fungsi yang disediakan oleh symfony yang menghasilkan kode HTML. Dan anda perlu men-cam-kan bahwa URL adalah sebagai bagian dari respon, yang dapat diformat sesuai keperluan, jadi anda seharusnya tidak dibingungkan dengan penggunaan referensi langsung ke URL dalam penamaan action atau pengambilan parameter request.

Sekali anda mengetahui prinsip-prinsip dasar ini, anda sudah siap menulis sebuah aplikasi utuh dengan symfony. Tetapi itu akan membutuhkan jalan yang panjang, semenjak setiap tugas yang harus anda capai sepanjang pengembangan aplikasi difasilitasi dengan satu atau jalan lain oleh beberapa fitur symfony . . . dan itulah mengapa buku ini tidak berhenti sampai di sini.