Sunday, February 15, 2015

Symfony 2 Hari 6: Routing di Symfony 2

Artikel ini dirunut berdasarkan Jobeet Tutorial, yang dibuat oleh Fabien Potencier, untuk Symfony 1.4.

Urlnya

Jika kamu mengklik pada salah satu lowongan maka kamu akan melihat url seperti ini: /job/1/show jika kamu pernah membangun aplikasi web sebelumnya mungkin kamu menggunakan url seperti ini: /job.php?id=1. Jadi bagaimana url di Symfony 2 bekerja? Bagaimana $id-nya terkirim? Ok berikut ini adalah penjelasan dari Symfony 2 routing.

Coba kamu lihat src/Ibw/JobeetBundle/Resources/views/Job/index.html.twig di sana kamu akan menemukan kode seperti berikut:

src/Ibw/JobeetBundle/Resources/views/Job/index.html.twig

{{ path('ibw_job_show', { 'id': entity.id }) }}

Penggunaan fungsi path merupakan contoh penggunaan template helper untuk menggenerate url dengan $id = entity.id, sedangkan ibw_job_show adalah nama routing yang digunakan. Yang didefinisikan sebagai berikut:

Routing configuration

Di Symfony 2 konfigurasi routing terletak di app/config/routing.yml yang akan mengimport detail routing yang ada di dalam bundle, dalam hal ini adalah file src/Ibw/JobeetBundle/Resources/config/routing.yml yang akan diimport.

app/config/routing.yml


ibw_jobeet:
    resource: "@IbwJobeetBundle/Resources/config/routing.yml"
    prefix:   /
 


Sekarang kalau kamu lihat JobeetBundle routing maka kamu akan melihat ia juga mengimport file routing lainnya:

src/Ibw/JobeetBundle/Resources/config/routing.yml

IbwJobeetBundle_job:
    resource: "@IbwJobeetBundle/Resources/config/routing/job.yml"
    prefix: /job

ibw_jobeet_homepage:
    pattern:  /hello/{name}
    defaults: { _controller: IbwJobeetBundle:Default:index }
 



src/Ibw/JobeetBundle/Resources/config/routing/job.yml

ibw_job:
    pattern:  /
    defaults: { _controller: "IbwJobeetBundle:Job:index" }

ibw_job_show:
    pattern:  /{id}/show
    defaults: { _controller: "IbwJobeetBundle:Job:show" }

ibw_job_new:
    pattern:  /new
    defaults: { _controller: "IbwJobeetBundle:Job:new" }

ibw_job_create:
    pattern:  /create
    defaults: { _controller: "IbwJobeetBundle:Job:create" }
    requirements: { _method: post }

ibw_job_edit:
    pattern:  /{id}/edit
    defaults: { _controller: "IbwJobeetBundle:Job:edit" }

ibw_job_update:
    pattern:  /{id}/update
    defaults: { _controller: "IbwJobeetBundle:Job:update" }
    requirements: { _method: post|put }

ibw_job_delete:
    pattern:  /{id}/delete
    defaults: { _controller: "IbwJobeetBundle:Job:delete" }
    requirements: { _method: post|delete } 


Mari kita perhatikan routing ibw_job_show, di sana didefinisikan jika pola ibw_job_show seperti /*/show di mana tanda * merupakan pendifinisan dari $id. Untuk url /1/show value dari $id adalah 1. Dan _controller  mendefinisikan method dari controller mana yang akan dipakai oleh url ini, di sini yang akan digunakan adalah method showAction di JobController yang ada di JobeetBundle. Parameter dalam routing sangat penting di sini karena parameter (id) tersebut akan digunakan dalam method showAction tersebut.

Konfigurasi routing di dalam level development

Di dalam level development akan menggunakan file app/config/routing_dev.yml yang digunakan oleh toolbar web debug, untuk melihatnya perhatikan di footer aplikasimu.

Customisasi routing

Untuk menseting rout utama localhost/sanbox/web/app_dev.php/ agar langsung mengarah ke halaman utama Jobeet edit file src/Ibw/JobeetBundle/Resources/config/routing.yml seperti berikut ini:

src/Ibw/JobeetBundle/Resources/config/routing.yml

ibw_jobeet_homepage:
    pattern:  /
    defaults: { _controller: IbwJobeetBundle:Job:index }
Sekarang kalau kamu bersihkan cachenya maka saat kamu mengakses localhost/sandbox/ akan langsung muncul halaman utama Jobeet.

Ubah link di Jobeet logo agar sesuai dengan routing yang baru saja dibuat.

src/Ibw/JobeetBundle/Resources/views/layout.html.twig
<!-- ... -->    
    <h1><a href="{{ path('ibw_jobeet_homepage') }}">
        <img alt="Jobeet Job Board" src="{{ asset('bundles/ibwjobeet/images/logo.jpg') }}" />
    </a></h1>
<!-- ... -->
Agar lebih friendly mari kita ubah Jobeet show urlnya menjadi seperti ini:
/job/sensio-labs/paris-france/1/web-developer
Dengan begitu tanpa harus melihat halaman lowongannya, kamu dapat mengetahui bahwa ada lowongan web developer di Kota Paris, Perancis. Url tersebut memiliki pola sebagai berikut:
/job/{company}/{location}/{id}/{position}
Edit ibw_job_show routenya:
src/Ibw/JobeetBundle/Resources/config/routing/job.yml
# ...
ibw_job_show:
    pattern:  /{company}/{location}/{id}/{position}
    defaults: { _controller: "IbwJobeetBundle:Job:show" }
Kemudian ubah parameter yang dikirim oleh template agar dapat terbaca oleh routingnya.
src/Ibw/JobeetBundle/Resources/views/Job/index.html.twig
<!-- ... -->
<a href="{{ path('ibw_job_show', { 'id': entity.id, 'company': entity.company, 'location': entity.location, 'position': entity.position }) }}">
    {{ entity.position }}
</a>
<!-- ... -->
Namun jika kamu melihat urlnya sekarang, url tersebut terlihat masih ada spasi dan karakter lainnya yang tidak diperlukan untuk itu kita harus membuat satu method di model untuk menggenerate url yang lebih baik. Edit Job model menjadi seperti berikut ini:
src/Ibw/JobeetBundle/Entity/Job.php

// ...
use Ibw\JobeetBundle\Utils\Jobeet as Jobeet;
class Job
{
    // ...
    public function getCompanySlug()
    {
        return Jobeet::slugify($this->getCompany());
    }
    public function getPositionSlug()
    {
        return Jobeet::slugify($this->getPosition());
    }
    public function getLocationSlug()
    {
        return Jobeet::slugify($this->getLocation());
    }
}


Buat juga file Jobeet untuk mendefinisikan Slugify method:
  
src/Ibw/JobeetBundle/Utils/Jobeet.php

namespace Ibw\JobeetBundle\Utils;
class Jobeet
{
    static public function slugify($text)
    {
        // replace all non letters or digits by -
        $text = preg_replace('/\W+/', '-', $text);
        // trim and lowercase
        $text = strtolower(trim($text, '-'));
        return $text;
    }
}


Kita telah mendefinisikan tiga “virtual” accessors: getCompanySlug(), getPositionSlug(), dan getLocationSlug(). Accessor tersebut akan mengirimkan return value berupa data kolom yang sudah di regenerate oleh method slugify(). Sekarang kamu dapat mengganti nama kolom asli dengan virtual accessor tersebut.

src/Ibw/JobeetBundle/views/Job/index.html.twig

<!-- ... -->
<a href="{{ path('ibw_job_show', { 'id': entity.id, 'company': entity.companyslug, 'location': entity.locationslug, 'position': entity.positionslug}) }}">
   {{ entity.position }}
</a>
<!-- ... -->

Route requirement

Routing di Symfony 2 dibangun dengan fitur validasi masing-masing variabel dapat divalidasi sesuai dengan kebutuhan variable tersebut, dengan menambahkannya di definisi url-nya.

src/Ibw/JobeetBundle/Resources/config/routing/job.yml

# ...
ibw_job_show:
    pattern:  /{company}/{location}/{id}/{position}
    defaults: { _controller: "IbwJobeetBundle:Job:show" }
    requirements:
        id:  \d+
# ...
Validasi diatas meminta variable id harus berupa integer. Jika id bukan integer maka routingnya tidak akan cocok.

Route debugging

Ketika menambah dan memodifikasi routing maka akan sangat membantu jika kita bisa melihat routing apa saja yang ada di dalam aplikasi kita. Jalankan perintah berikut untuk melihat daftar routing yang dalam aplikasimu.

php app/console router:debug
Kita juga dapat menampilkan sesuatu yang lebih spesifik lagi misalnya dengan menambahkan nama bundlenya untuk menampilkan routing yang ada dalam suatu bundle.
php app/console router:debug ibw_job_show

Ok, that's all for to day guys!

No comments:

Post a Comment