Navigasi pada DNN - You can rewrite your URL !

Ya, judulnya provokatif banget. Tapi itulah kenyataannya. :)

Awalnya begini :

url

Kemudian dapat menjadi :

url2

Menarik ya ? :) Bagaimana caranya ? Ikuti penjelasan saya.

Latar belakang saya membuat artikel ini adalah karena beberapa waktu yang lalu kebetulan saya ditunjukkan CMS milik klien yang akan di rewrite ulang ke dalam DNN. Ada fitur menarik pada CMS milik klien tersebut yakni bahwa setiap konten yang dia isi (berita atau artikel) dapat dibuatkan alamat URL untuk mengaksesnya sekehendak hati (defaultnya sih nama Title artikelnya). Jadi misalkan dia membuat artikel dengan judul "Test Article", maka URL untuk mengaksesnya dapat menjadi begini :

http://www.clientdomain.com/media/artikel_berita_testarticle.php

dari sebelumya begini :

http://www.clientdomain.com/media/artikel_berita_berita.php?id=5

Dan dengan fitur URL Manager yang dia punya, maka URL itu dapat diganti menjadi apapun yang dia inginkan. Ini menarik karena sepertinya fitur ini tidak dimiliki oleh DNN module :) Hm, tidak juga sih, diluar sana ada kok 3rd party module yang polanya seperti itu. Tapi rasa-rasanya gatal jika tidak membuat sendiri karena toh sepertinya fitur ini sudah tersedia di dalam DNN tetapi masih hidden feature kayaknya. ;)

Jadi, idenya adalah bagaimana membuat 2 buah module yakni :

  1. URL Management Module, digunakan untuk mengatur penamaan URL pada modul Content Manager Module. Jadi, setiap kali client isi konten pada websitenya, URL-nya dapat dibuat sekehendak hati (defaultnya menggunakan Title jadi artikel)
  2. Content Manager Module, digunakan sebagai repository untuk konten yang akan ditambahkan ke dalam website

Dan karena dua module ini sudah selesai saya buat dalam 2 hari, maka tidak ada salahnya saya berbagi dengan Anda bagaimana cara saya melakukan modifikasi dan rewrite URL di level modul. Mungkin akan berguna bagi Anda yang kebetulan berurusan dengan pembuatan modul pada DNN.

Sebelumnya saya akan berikan penjelasan singkat mengenai navigasi pada DNN.

Navigasi pada DNN ditangani oleh method NavigateUrl dan EditUrl pada kelas Globals (tepatnya ada di dalam namespace DotNetNuke.Common). Meskipun cukup untuk melakukan proses navigasi antar module control (navigasi antar .ascx di dalam satu modul), Anda dapat juga menggunakan cara lain untuk melakukan navigasi.

Masih ingat dengan fitur DNN yang disebut dengan FriendlyUrl ? Nah, kita akan memanfaatkan fitur tersebut pada kode kita sehingga Anda dapat menggunakan itu sebagai bagian dari proses navigasi pada modul DNN Anda. Ada 2(dua) keuntungan yang saya lihat dari teknik ini yakni sbb :

  1. URL dapat Anda rewrite sekehendak hati Anda (tentunya dalam konteks yang masih masuk akal). Dan ini akan membuat informasi pada modul Anda bersifat SEO dan akan diindeks dengan baik dan dengan penamaan yang lebih manusiawi.
  2. Nilai baliknya yang berupa string, dapat dilekatkan pada Hyperlink dan memungkinkan untuk navigasi antar modul dari satu halaman ke halaman lain.

Baiklah kita mulai saja.

Saya menggunakan pendekatan non-WAP dengan menggunakan bahasa Visual C#, artinya code behind tidak saya compile menjadi DLL tersendiri karena memang ini hanyalah POC (proof of concept) saja yang saya buat. Meski demikian, Anda dipersilahkan menggunakan pendekatan cara membuat modul yang Anda sukai. Dan karena ini menggunakan pendekatan non-WAP maka Anda perlu menambahkan sedikit pada web.config.

Pertama, buatlah sebuah modul baru dari instance DNN Anda. Saya memberi contoh dengan ContentManager module (karena ini kebetulan modul yang sedang saya buat untuk client saya dengan pendekatan URL dinamis dan berisi URL Manager untuk konten modul tersebut). Caranya :

  • Buka Visual Studio 2008 Anda, lalu arahkan pada website DNN Anda
  • Dari jendela Solution Explorer, klik kanan pada folder DesktopModules lalu pilih New Folder. Beri nama folder baru tersebut dengan ContentManager (atau apapun yang Anda inginkan)
  • Dari jendela yang sama (Solution Explorer), klik kanan pada folder App_Code lalu tambahkan folder baru dengan nama ContentManager. Ingat, saya menggunakan bahasa yang berbeda dengan project DNN, maka saya harus melakukan 2 hal tambahan yakni menambahkan folder baru pada folder App_Code dan saya menambahkan entri pada web.config
  • Bukalah web.config, lalu tambahkan entri baru pada tag <codeSubDirectories> dengan entri <add directoryName="ContentManager" />

Buatlah sebuah file bernama injector.ascx. Saya menggunakan teknik injeksi .ascx ke dalam DNN secara dinamis. Informasi lebih lanjut dapat Anda lihat pada artikel saya disini.

  • Tambahkan sebuah Web User Control ke dalamnya dengan nama injector.ascx. Saya menggunakan bahasa C#. Tunggulah beberapa saat hingga tampil pada Visual Studio 2008 Anda.
  • Masuklah ke dalam code behind file tersebut, lalu hapus semua kode di dalamnya dan gantilah dengan kode berikut ini :

using System;
using DotNetNuke.Entities.Modules;

public partial class DesktopModules_ContentManager_Injector : DotNetNuke.Entities.Modules.PortalModuleBase
{
    private string mControlToLoad = string.Empty;

    protected void Page_Init(object sender, EventArgs e) {
        ReadQueryString();
        LoadControlType();
    }

    protected void Page_Load(object sender, EventArgs e){  }

    private void LoadControlType() {
        PortalModuleBase pmb = (PortalModuleBase)LoadControl(mControlToLoad);
        if (pmb != null) {
            pmb.ModuleConfiguration = this.ModuleConfiguration;
            pmb.ID = System.IO.Path.GetFileNameWithoutExtension(mControlToLoad);
            plhControl.Controls.Add(pmb);
        }
    }

    private void ReadQueryString() {
        string qs = string.Empty;
        if (Request.QueryString["ctrl"] != null) {
            qs = Request.QueryString["ctrl"].ToString();
            switch (qs) {
                case "home":
                    mControlToLoad = "ucHome.ascx";
                    break;
                case "view":
                    mControlToLoad = "ucView.ascx";
                    break;
                default:
                    mControlToLoad = "ucHome.ascx";
                    break;
            }
        }
        else {
            mControlToLoad = "ucHome.ascx";
        }
    }
}

Nah, jika Anda lihat pada method ReadQueryString() maka Anda akan melihat pada saya menyiapkan dua file yang masing-masing bernama ucHome.ascx dan ucView.ascx. Fungsi dari file ini adalah sbb :

  1. ucHome.ascx, sebagai file yang pertama kali akan diload oleh injector. Katakanlah sebagai mainpage dari module Anda yang berisi agregat dari artikel-artikel Anda. Agregat ini biasanya hanya judul artikel dan summary artikel. Pada halaman ini saya meletakkan dua buah kontrol yakni LinkButton1 dan Hyperlink1.
  2. ucView.ascx, sebagai file yang saya asumsikan konten dari detail artikel. Pada halaman ini saya meletakkan sebuah LinkButton untuk kembali ke halaman utama

Beginilah desain dari halaman ucHome.ascx dan ucView.ascx :

ucHome  ucView

Masuklah ke dalam code behind pada ucHome.ascx lalu gantilah semua kodenya dengan kode berikut ini (saya akan jelaskan kemudian):

using System;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Common;
using DotNetNuke.Entities.Portals;

public partial class DesktopModules_ContentManager_ucHome : PortalModuleBase
{
    protected void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack) {
            string usefriendly = DotNetNuke.Entities.Host.HostSettings.GetHostSetting("UseFriendlyUrls");
            if (usefriendly == "Y") {
                string strURL = Globals.ApplicationURL(PortalSettings.ActiveTab.TabID);
                PortalSettings settings = PortalController.GetCurrentPortalSettings();

                strURL = strURL + "&ctrl=view";
                string fullURL = Globals.FriendlyUrl(settings.ActiveTab, strURL, "SukaSukaKitaAjaNih.aspx", settings);

                lnk1.NavigateUrl = fullURL;
                lnk1.Text = "Test Article";
            }
        }
    }

    protected void lnkTest_Click(object sender, EventArgs e) {
        Response.Redirect(Globals.NavigateURL(PortalSettings.ActiveTab.TabID, "", "&ctrl=view"));
    }
}

Masuklah juga ke dalam code behind pada ucView.ascx lalu gantilah semua kodenya dengan kode berikut ini :

using System;
using DotNetNuke.Common;
using DotNetNuke.Entities.Modules;

public partial class DesktopModules_ContentManager_ucView : PortalModuleBase
{
    protected void Page_Load(object sender, EventArgs e)  {

    }
    protected void lnkReturn_Click(object sender, EventArgs e) {
        Response.Redirect(Globals.NavigateURL());
    }
}

Simpan semua perubahannya. Dan daftarkan module Anda ke dalam DotNetNuke. Caranya :

  • Login sebagai Host
  • Masuk ke menu Host --> Module Definitions
  • Dari jendela Edit Module Definitions, pilih Create Module Definitions. Lalu isikan masing-masingnya dengan informasi sebagai berikut :

Module Name : ContentManager
Folder Name : ContentManager
Friendly Name : ContentManager
Description : Content Manager module v1.0
Version : 01.00.00

  • Klik tombol Update.
  • Setelah itu isikan juga pada bagian New Definition dengan ContentManager. Klik Add Definition.
  • Tambahkan kontrol baru dengan cara klik link Add Control.
  • Dari jendela Edit Module Control, pilihlah DesktopModules/ContentManager/injector.ascx dari dropdown Source.
  • Klik tombol Update.

Module ContentManager Anda kini telah siap dan telah tersedia pada daftar modul di dalam Control Panel DNN. Tambahkan modul Anda ke dalam halaman Home seperti ini :

preview1

Kliklah pada "Test Articles" yang pertama. Lihatlah bahwa ucView.ascx akan di load dan ditampilkan. Perhatikan URL-nya sekarang :

url

Klik link Return untuk kembali ke halaman sebelumnya.

Sekarang klik pada "Test Articles" yang kedua. Lihat kembali bahwa ucView.ascx akan di load dan ditampilkan. Disinilah menariknya, lihatlah pada URL-nya sekarang :

url2

Cool yah !

Triknya ada pada kode berikut ini :

    protected void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack) {

            // Cek terlebih dahulu apakah fitur UseFriendlyUrls aktif dari menu
            // Host --> Host Settings. Nilai defaultnya selalu aktif.
            string usefriendly = DotNetNuke.Entities.Host.HostSettings.GetHostSetting("UseFriendlyUrls");

            // Jika Ya
            if (usefriendly == "Y") {
                // Dapatkan alamat aktif URL saat ini berdasarkan tab dimana module berada
                string strURL = Globals.ApplicationURL(PortalSettings.ActiveTab.TabID);

                // Ambil nilai PortalSettings aktif saat ini untuk kita rewrite
                PortalSettings settings = PortalController.GetCurrentPortalSettings();

                // Construct URL-nya dengan menambahkan parameter querystring yang
                // Anda butuhkan
                strURL = strURL + "&ctrl=view";

                // Ubah URL menggunakan FriendlyUrl untuk menggenerate yang baru
                // SukaSukaKitaAjaNih.aspx adalah penamaan yang dapat disesuaikan
                // dengan kebutuhan Anda
                string fullURL = Globals.FriendlyUrl(settings.ActiveTab, strURL, "SukaSukaKitaAjaNih.aspx", settings);

                // Lekatkan pada Hyperlink bernama lnk1
                lnk1.NavigateUrl = fullURL;
                lnk1.Text = "Test Article";
            }
        }

Nah, dengan cara ini sekarang module saya sudah dapat me-rewrite URL dengan kata apapun yang saya inginkan dan dengan demikian informasi dalam module sudah bersifat SEO-friendly.

Hope this help !

Share this post: | | | |
Filed under:

Comments

# reyza said:

nanti saya akan lihatkan betapa mudahnya bila dilakukan di Community Server. Ya iya lah $5000 makanya bisa dilakukan dengan mudah :)

Friday, May 23, 2008 11:52 AM
# agung said:

Whew, $5000 ! Itu artinya 46 jt euy. Wah, bisa buat beli apaan ya ? :)

Hayo donk CS tunjukkin. Eh Rez, di CS padanannya Page dan Module itu apa ya ?

Friday, May 23, 2008 12:20 PM
# reyza said:

$5000 = Rp. 46juta .. yuuuk mari.... :) Kalau ini sih seperti biasa 'saya ngga perduli semahal apapun harga CS' kenapa? nanti ceritanya menyusul :)

di CS memang kita diperbolehkan untuk mengubah 'nama URL' kok, tapi jarang kita gunakan. fasilitas itu ada di feature Article (cuma admin yang bisa bikin ini) milik CS dan juga Blog.

Saat kita melakukan 'Write a Blog Post' cek checkbox Advanced Options untuk mengeluarkan tab pilihan, pilih Options nanti ada kolom Name, nah disitu bisa ditulis 'nama URL'-nya ... jadi walau title dari Blog adalah "Hallo, Apa kabar Indonesia hari ini?', tetapi pada kolom Name kita tulis 'KabarIndonesiaHariIni' maka nanti url-nya adalah KabarIndonesiaHariIni.aspx. tapi dalam kasusnya adalah pada kolom Name ditulis kabar_indonesia_hari_ini yang keluar adalah indonesia_5F00_hari_5F00_ini.aspx :)

Di CS :

Page = Article ?

Module .. hmm.. apa ya?

Karena kurang ngerti maksud Page dan Module di DNN.

Friday, May 23, 2008 1:22 PM
# yulian said:

@agung

Mas agung, klo boleh tahu apakah data url yang direwrite itu di DNN disimpan secara persistent gak ya? klo iya disimpan dimana?database atau media lainnya?

Friday, May 23, 2008 1:27 PM
# agung said:

@rezya

$5000 = Rp. 46juta .. yuuuk mari.... :) Kalau ini sih seperti biasa 'saya ngga perduli semahal apapun harga CS' kenapa? nanti ceritanya menyusul :)

>>> iye iye, ane percaya. :p

Lha yang dibikin ama Zeddy pada agregate blogs INDC itu apaan kalo di CS namanya ? :) Yang menampilkan hits milis itu.

Friday, May 23, 2008 1:46 PM
# agung said:

@yulian

url tsb bisa disimpan di database secara persistent ataupun digenerate dynamic. Pada kebanyakan kasus yang saya lakukan untuk client, saya generate secara dynamic dari title artikel biasanya. Sebab secara fisik navigasi di DNN tidak disimpan dalam database karena berbasis kombinasi antara portalid, tabid, moduleid. Jadi, jika di dalam module ingin bersifat persisted, maka biasanya kombinasi portalid, tabid, dan moduleid yang disimpan di dalam database. URL-nya diconstruct dari kombinasi tersebut berdasarkan skenario.

Friday, May 23, 2008 1:50 PM
# reyza said:

oh itu? memang di CS ada module juga. CSModule namanya, kode yang dibuat Zeddy belum pernah liat sepertinya memang memanfaatkan CSModule. Kalau yang biasa saya bikin biasanya cuma memanfaatkan User Control biasa atau halaman biasa yang memanfaatkan Chameleon.

Cara deploy pun dengan cara biasa (copy paste file) tidak semantab DNN yang katanya bisa di upload (CMIIW)

$5000, maklum bukan tukang jualan lisensi, tapi cuma jualan solusi dan tukang service :)

Friday, May 23, 2008 1:55 PM
# yulian said:

@agung

apakah final settingnya disimpan di file web.config setelah disimpan didatabase? saya pengen tahu, soalnya kan mulai di asp.net 2.0 itu sudah ada fitur urlMapping yang diimplementasikan di file web.config dimana settingnya juga bisa dilakukan secara code behind via UrlMapping class yang ada di System.Web.Configuration namespace.

Friday, May 23, 2008 2:04 PM
# agung said:

@yulian

di DNN, kita bisa mengatur bagaimana perilaku URL melalui UrlFriendly settings dari menu Host --> Host Settings. Dan hasilnya akan disimpan pada file bernama SiteUrls.config yang letaknya ada pada root website DNN.

Dan karena DNN API menyediakan fitur FriendlyUrl tersendiri, maka developer DNN diberi kebebasan untuk menggunakannya dalam konteks skenario yang dia butuhkan. Apakah pada level Site, level Page, atau level Module. Disini menariknya. Meskipun kita tidak touch pengaturan UrlMapping itu dalam file SiteUrls.config ataupun via Host --> Host Settings, tapi kita masih bisa menggunakan DNN API pada level module untuk mengconstruct URL secara dynamic saat runtime.

Friday, May 23, 2008 2:24 PM

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above: