Senin, Desember 01, 2014

Presentasi "Interoperabilitas SLiMS" dan "RDA dengan SLiMS" di SLiMS Commeet 2014 Semarang

Bagi rekan-rekan yang tertarik dan ingin membaca presentasi saya mengenai Interoperabilitas dengan SLiMS dan RDA dengan SLiMS di SLiMS Commeet 2014 Semarang beberapa waktu yang lalu, bisa mengunduhnya pada tautan berikut ini:

Senin, Agustus 04, 2014

Memindahkan Direktori Database MySQL di Ubuntu GNU/Linux

Baru baru ini saya meng-install sistem operasi desktop Ubuntu versi 14.04.1 LTS ke laptop dan salah satu aplikasi "wajib" adalah database server MySQL, karena hampir semua aplikasi web yang saya bangun menggunakan MySQL sebagai backend-nya. Salah satu kebiasaan saya ketika meng-install MySQL adalah memindahkan direktori tempat MySQL menyimpan semua databasenya ke lokasi non-standar, yang by default berlokasi di /var/lib/mysql, saya pindahkan ke lokasi /home/direktori/mysql misalnya. Hal ini saya lakukan agar memudahkan pemindahan dan backup data apabila Ubuntu-nya akan saya upgrade ke versi major.

Ternyata memindahkan direktori database MySQL di distro GNU/Linux populer seperti Ubuntu dan CentOS tidak semudah zaman dahulu, seperti zaman Ubuntu versi 8.04 dulu (lama banged yak :p) misalnya. Kalau dulu cukup ubah konfigurasi di file konfigurasi /etc/my.cnf, ubah permission direktori, restart daemon semua langsung jalan. Dengan semakin tinggi-nya keamanan di lapisan aplikasi ada beberapa hal yang harus kita lakukan untuk memindahkan direktori database MySQL di distro Ubuntu 14.04. Berikut akan saya paparkan caranya.

Ubah konfigurasi di my.cnf

Tahap pertama adalah dengan mengubah/memodifikasi file konfigurasi utama MySQL, my.cnf, yang pada Ubuntu terletak pada direktori /etc/mysql. Pada konfigurasi default kita akan melihat konfigurasi seperti ini:

...
[mysqld]
#
# * Basic Settings
#
...
datadir  = /var/lib/mysql/
...
Ubah file my.cnf dengan text editor favorit anda, dan ubah pada bagian parameter datadir dan pada bagian InnoDB menjadi sebagai berikut:
...
[mysqld]
#
# * Basic Settings
#
...
datadir  = /home/dicarve/mysql # sesuaikan dengan direktori baru database MySQL yang kita inginkan
...
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
innodb_data_home_dir = /home/dicarve/mysql/
innodb_log_group_home_dir = /home/dicarve/mysql/
innodb_data_file_path = ibdata1:10M:autoextend
...
Simpan perubahan file tersebut.

Selanjutnya buka program Terminal dan ubah ownership direktori baru database MySQL kita (dalam hal ini /home/dicarve/mysql), agar bisa diakses oleh daemon server MySQL, sekaligus kita copy-kan isi direktori /var/lib/mysql ke direktori baru kita dengan perintah:

dicarve@localhost:~$ sudo cp -R /var/lib/mysql/* /home/dicarve/mysql/
dicarve@localhost:~$ sudo chown -R mysql /home/dicarve/mysql

Ubah setting AppArmor

Distro GNU/Linux populer biasanya menggunakan AppArmor, sebuah modul sistem keamanan kernel Linux yang salah satu fungsinya adalah membatasi aplikasi-aplikasi tertentu di lingkungan GNU/Linux, agar hanya bisa mengakses berkas atau direktori tertentu. Untuk lebih jelasnya mengenai AppArmor bisa kita baca di Wiki AppArmor. Agar daemon server MySQL bisa mengakses direktori database baru yang sudah kita ubah di file my.cnf, kita harus mengubah konfigurasi AppArmor MySQL dengan memodifikasi file /etc/apparmor.d/local/usr.sbin.mysqld. Tambahkan baris berikut pada berkas tersebut:

# Site-specific additions and overrides for usr.sbin.mysqld.
# For more details, please see /etc/apparmor.d/local/README.
/home/dicarve/mysql/* rw
Simpan perubahan berkas tersebut kemudian jalan perintah berikut pada Terminal:
dicarve@localhost:~$ sudo /etc/init.d/apparmor reload

Restart server MySQL

Selanjutnya adalah me-restart server MySQL kita dengan perintah:

dicarve@localhost:~$ sudo /etc/init.d/mysql restart
Apabila semua berjalan lancar, maka kita telah berhasil memindahkan direktori database MySQL kita ke lokasi yang baru yang kita inginkan. Ada kemungkinan cara ini juga berhasil untuk database server MariaDB, tetapi saya belum mencobanya. Semoga bermanfaat dan selamat mencoba :).

Selasa, Mei 13, 2014

Memanfaatkan Facades pada Framework Laravel

"Facades provide a "static" interface to classes that are available in the application's IoC container."

Terjemahan bebas dari saya adalah Facades menyediakan antar muka static pada semua kelas yang ada dalam Laravel, biasanya Model. Untuk lebih mengerti mengenai apa itu Inversion of Control (IoC) container dan Facade silahkan anda membaca artikel karya Edd Mann yang berjudul How Static Facades and IoC are used in Laravel. Salah satu fitur menarik dari framework Laravel adalah Facades, Facade ada dimana-mana pada Laravel, bahkan tanpa sadar kita juga sudah sering menggunakannya, misalnya statement View::make('form'), Redirect::to('front'), Input::get('nama'), dsb. Misalnya kita memiliki sebuah kelas model dalam aplikasi Laravel kita seperti ini:

namespace AhliInformasi;
class Pustakawan {
  /**
   * Ambil semua data Pustakawan
   */
  public function semuaPustakawan($offset=0, $limit=100) {
    return DB::table('pustakawan')->select(DB::Raw('id,
        nama_pustakawan,
        tingkatan.nama as tingkatan_pustakawan,
        status.nama as status_pustakawan,
        email_pustakawan, 
   foto_pustakawan'))
      ->join('tingkatan', 'pustakawan.tingkatan', '=', 'tingkatan.id')
      ->join('status', 'pustakawan.status', '=', 'status.id')
      ->orderBy('login_terakhir', 'desc')->skip($offset)->take($limit);
  }

  /**
   * Ambil detail data Pustakawan
   */
  public function seorangPustakawan($id_nya) {
    return DB::table('pustakawan')->where('id', '=', $id_nya)->first();
  }
}

Model tersebut kita simpan dengan nama AhliInformasi/Pustakawan.php (karena kita menggunakan namespace disini) dalam direktori model. Nah biasanya ketika kita memanggil model ini di controller kita melakukannya dengan seperti ini:

class PustakawanController extends BaseController {
  /**
   * Ambil semua data Pustakawan
   */
  public function lihatSemuaPustakawan($offset=0, $limit=100) {
    $pustakawan = new \AhliInformasi\Pustakawan;
    $view_data['data_pustakawan'] = $pustakawan->semuaPustakawan($offset, $limit);
    return View::make('ahliinformasi.index', $view_data);
  }
}

Dengan memanfaatkan Facades kita bisa lebih mempersingkat pemanggilan model kita sekaligus lebih ekspresif dan juga lebih mudah di-tes. Untuk menjadikan model kita menjadi Facade maka kita akan menambahkan sedikit kode, yang pertama adalah "mengikat" atau bahasa kerennya binding model kita sebagai IoC Container. Cara paling elegan adalah dengan menambahkan Service Provider:

namespace AhliInformasi;
use Illuminate\Support\ServiceProvider;
class PustakawanServiceProvider extends ServiceProvider {
    public function register()
    {
        $this->app->bind('pustakawan', function()
        {
            return new \AhliInformasi\Pustakawan;
        });
    }
}

Simpan file dengan nama PustakawanServiceProvider.php pada direktori model/AhliInformasi. Kemudian tambahkan juga implementasi kelas Facade kita dengan kode berikut ini:

namespace AhliInformasi;
use Illuminate\Support\Facades\Facade;
class PustakawanFacade extends Facade {
  protected static function getFacadeAccessor() { return 'pustakawan'; }
}

Kemudian simpan dengan nama PustakawanFacade.php pada direktori model/AhliInformasi. Langkah selanjutnya adalah me-register Service Provider dan Facade kita pada file konfigurasi config/app.php, dengan menambahkan:

'providers' => array(

  'Illuminate\Foundation\Providers\ArtisanServiceProvider',
  'Illuminate\Auth\AuthServiceProvider',
  'Illuminate\Cache\CacheServiceProvider',
  'Illuminate\Session\CommandsServiceProvider',
  ...
  'AhliInformasi\PustakawanServiceProvider' // tambahkan ini

),
...
'aliases' => array(

    'App'             => 'Illuminate\Support\Facades\App',
    'Artisan'         => 'Illuminate\Support\Facades\Artisan',
    'Auth'            => 'Illuminate\Support\Facades\Auth',
    'Blade'           => 'Illuminate\Support\Facades\Blade',
    'Cache'           => 'Illuminate\Support\Facades\Cache',
    'ClassLoader'     => 'Illuminate\Support\ClassLoader',
    ...
    'Pustakawan'      => 'AhliInformasi\PustakawanFacade' // tambahkan ini
),

Terakhir jangan lupa untuk men-generate ulang file autoload.php agar kelas-kelas kita yang baru kita buat dikenali langsung oleh aplikasi (tanpa harus include/require manual), dengan menjalankan perintah berikut dengan menggunakan terminal pada direktori root aplikasi Laravel:

composer dump-autoload

Jujur sebenarnya saya juga bingung kenapa harus melakukan proses dump-autoload, karena seharusnya semua kelas yang ada di dalam direktori model secara otomatis di-load oleh Laravel pada saat proses bootstrap, tetapi ketika saya tidak melakukan proses ini muncul error kelas Service Provider tidak ditemukan. Selanjutnya dan seterusnya untuk memanggil model Pustakawan kita bisa langsung memanggilnya melalui Facade kita dengan seperti ini:

class PustakawanController extends BaseController {
  /**
   * Ambil semua data Pustakawan
   */
  public function lihatSemuaPustakawan($offset=0, $limit=100) {
    $view_data['data_pustakawan'] = Pustakawan::semuaPustakawan($offset, $limit);
    return View::make('ahliinformasi.index', $view_data);
  }
}

Nah itu penjelasan mengenai Facades pada Laravel, semoga bermanfaat!

Minggu, April 13, 2014

An (Relatively) Easy Way for Installing Social Feed Manager on Mac OSX

On Monday, March 24, 2014 at Code4Lib 2014 Conference in Raleigh, North Carolina, i was fortunate to get the opportunity to learn Social Feed Manager (SFM), directly from the developers, Daniel Chudnov, Daniel Kerchner and also Laura Wruber from George Washington University (thank you for all of you for patienly guide me to get SFM working). SFM is a django application for managing multiple feeds of social media data. It's been a long time i'm searching for this kind of software to grab social media feed from Twitter. I know that Twitter already provide an API to fetch tweets, but i'm too lazy to learn the API :D, so SFM is great solution for me.

This article will try to explain step by step on how to install SFM on Mac OSX. Why Mac OSX? because i use Mac OSX on Macbook Air everyday for my work. Currently at the time this article was written, i'm using Mac OSX version 10.7.5 (Lion) with latest update from Apple. Below are the specs of my Macbook Air:

Ok, lets get it started, before installing SFM on Mac OSX you NEED to have/install these requirements:

  1. A working (and fast if you have) Internet connection
  2. A Twitter account!
  3. Latest Xcode. After finished installing Xcode, open the Xcode.app and accept the Xcode license agreement.
  4. Latest PostgreSQL database server for Mac OSX. I prefer Postgres.app, "The easiest way to get started with PostgreSQL on the Mac" <- that's what they said about it, and i think it is true :)
  5. and after installing Xcode and PostgreSQL, you need to install Homebrew, a package manager similiar to apt on Ubuntu for Mac OSX.

After successfully installing above three softwares, now you must open Terminal application (press Command+Space button and type "Terminal" if you're too lazy to find it :D) and do the "geek typing" works :D. If you

First installing python package manager, "pip" by typing:

$ sudo easy_install pip

Second, you need to install python "virtualenv" package by typing:

$ sudo pip install virtualenv
with virtualenv you can localize all required python library dependacies only on project directory (in this case is SFM).

Now, we start to install the SFM itself by cloning the source code directly from the SFM GitHub repository by typing:

$ cd
$ git clone git://github.com/gwu-libraries/social-feed-manager.git
$ cd social-feed-manager
In this example, we install the SFM on our home directory. You will see that there is social-feed-manager directory on our home directory now.

Currently, we are inside the social-feed-manager directory. We will create a virtual environment directory inside this folder, and we name it ENV by invoking below commands:

$ virtualenv --no-site-packages ENV
$ source ENV/bin/activate
You will see there is something a bit different with our command shell, it is appended with "(ENV)" which means that we are already inside our python sandbox/virtual environment.

So far so good? Hopefully! :D. Don't worry we will see our SFM working in a few hour to go hahaha, just kidding, in a "few steps" to go. Next step is preparing our PostgreSQL database for SFM to store its data, so we will launch our Postgres.app application and click "Open psql" button to open "psql" terminal. On psql console type below commands:

CREATE USER sfmuser with createdb PASSWORD 'sfmuser_secret';
CREATE DATABASE sfmdb WITH OWNER sfmuser;
Remember we create a new database user/role named "sfmuser" with password "sfmuser_secret" and database named "sfmdb". We will use these values on SFM configuration file later.

Now go back to the first Terminal application where we installing SFM. We will install all python library dependancies needed by SFM such as Django, Django Social Auth, Oauth, and etc. using below command:

$ pip install -r requirements.txt
Just wait until all process finished, and if everything is running smooth you'll see like this:

Continue! now type the following commands:

$ cd sfm
$ cp sfm/local_settings.py.template sfm/local_settings.py
$ nano sfm/local_settings.py
Now you'll see that you're opening the local_settings.py file using nano text editor (yes, you can use another text editors to edit the file if you're allergic to nano), and you must edit some value inside it according to your twitter app configuration. To create your Twitter app, login to https://apps.twitter.com using your Twitter account and create new application in https://apps.twitter.com/app/new. Fill the new application form like mine below:

After creating your new Twitter application will get an API Key like this.

On local_settings.py you need to change these lines according to your database settings

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'sfmdb',
        'USER': 'sfmuser',
        'PASSWORD': 'sfmuser_secret',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}
You MUST also change below lines according to your Twitter app API settings
TWITTER_DEFAULT_USERNAME = 'YOUR TWITTER USERNAME'
TWITTER_CONSUMER_KEY = 'YOUR TWITTER API KEY'
TWITTER_CONSUMER_SECRET = 'YOUR TWITTER API SECRET'
Save the changes by pressing Control+X and then press Y (if you're using nano).

Now you must edit the wsgi.py file by typing these commands:

$ cp sfm/wsgi.py.template sfm/wsgi.py
$ nano sfm/wsgi.py
Remove "#" in front of lines like below and change the ENV line so it will be look like this :
import site
ENV = '/Users/arienugraha/social-feed-manager/ENV'
site.addsitedir(ENV + '/lib/python2.7/site-packages')
Don't forget to save the changes by pressing Control+X and then press Y (if you're using nano).

Next step we will create setup a database to be used by djago by typing this command

$ ./manage.py syncdb
You'll be asked to create superuser for SFM administration page (DON'T USE YOUR TWITTER USERNAME!). In this article i create superuser with username "admin" and password "admin". If everything went smooth you'll something like this:

Next run this:

$ ./manage.py migrate

Hoorrayyyy!!! we almost finished! Next we need to run the Django built in web server (yes, you don't have to use Apache or another web server for development and testing) so we can access SFM administration UI. Run below command

$ ./manage.py runserver
Open your web browser and go to http://localhost:8000/admin to access SFM administration UI. By default Django web server will run on port 8000. If you want Django to run on another port, say it port 9090, just run the command like this :
$ ./manage.py runserver 9090
and go to http://localhost:9090/admin on your web browser! You'll see something like this on your web browser if everything is OK :

Login with username we already create on previous "syncdb" step, in this example the username is "admin" and the password is "admin", and you'll see webpage like this:

Fiuuhhhh!!! now we have our SFM installed and we are ready to grab Twitter feeds we want. The question is HOW DO I GRAB THE FEEDS THAT I WANT? Relax bro, relax :D. Suppose we want to grab tweets from Twitter user named @slims_official, what we must do is adding her/his Twitter screen name on http://localhost:8000/admin/ui/twitteruser/add/ and fill it on Name form field like this:

then click "Save" button at the bottom of the screen. Now on Terminal, run this command to grab about 3200 latest tweets from this user:
$ ./manage.py user_timeline
and you'll see something like this on your Terminal screen:
You see that SFM grab 200 tweets each time from the latest to the older tweets.

That's it hopefully you will find this article useful. Next i will try to write an article on how to use/utilize feeds from SFM with PHP. (Please don't ask me about Python and Django, i can only write standard "Hello World" using Python :D)

Kamis, November 21, 2013

Rilis SLIMS 7 Cendana!

Kamis, Tanggal 21 November 2013, bertempat di Auditorium gedung 1 Fakultas Ilmu Pengetahuan Budaya Universitas Indonesia, SLIMS versi terbaru, yaitu SLIMS 7 Cendana secara resmi dirilis. SLIMS 7 Cendana membawa beberapa fitur baru seperti antara lain:

  1. Responsive User Interface
  2. User Interface baru untuk halaman Admin/Librarian
  3. RSS
  4. Komentar untuk koleksi
  5. Keyword suggestions atau auto correct
  6. Keyword highlighting
  7. Sharing koleksi di OPAC ke berbagai Social app seperti Facebook dan Twitter
  8. Implementasi PDF viewer baru tanpa Flash
  9. Librarian page!
  10. User interface baru untuk kemudahan pengubahan konfigurasi label, barcode dan kartu anggota
  11. Model pengindeksan bibliografi baru dengan MongoDB
  12. Tooltip untuk panduan pengisian data bibliografi
  13. dan beberapa fitur dan perbaikan bugs lain...

Responsive UI
Librarian page
Social sharing

SLIMS 7 Cendana sudah bisa di-unduh melalui laman resmi SLIMS SLIMS. Enjoy!

Kamis, April 18, 2013

PUSTAKAWAN: membuat pathfinder online menjadi lebih mudah

Pustakawan adalah projek open source baru saya untuk memudahkan pustakawan dan profesional informasi lain dalam membangun pathfinder online. Bagi anda yang belum mengetahui apa itu pathfinder, izinkan saya menjelaskan sedikit mengenai apa yang disebut pathfinder. Sederhananya pathfinder adalah panduan yang disusun oleh pustakawan, yang berisikan daftar-daftar sumber informasi dalam berbagai bentuk, seperti buku, website, jurnal, jurnal online, dll. mengenai topik tertentu, untuk membantu pemustaka mendapat sumber YANG TEPAT mengenai topik tertentu

Halaman depan "Pustakawan" menampilkan daftar subjek terkait sumber informasi yang digunakan

Halaman daftar sumber informasi pada subjek tertentu

Fitur-fitur yang akan direncanakan ke depan adalah:

  • Metadata sumber informasi menggunakan standar metadata Dublin Core
  • Manajemen taksonomi subjek hirarkis dengan konsep semantik seperti Tesaurus
  • Fitur langganan bagi pemustaka/peneliti yang ingin mendapatkan update mengenai subjek yang mereka inginkan
  • Integrasi dengan sumber sumber perpustakaan elektronik seperti metadata MODS yang disediakan oleh Senayan Library Management System
  • Layanan feed/sindikasi sumber informasi menggunakan RSS
  • Pencarian data sumber informasi
  • Fitur "Ask Librarian" yang memungkinkan pemustaka berkomunikasi real-time dengan pustakawan

Untuk saat ini software "Pustakawan" masih dalam tahap pengembangan dini, yang artinya masih sangat awal dan belum dapat digunakan untuk skala testing apalagi percobaan. Mohon doa dan restu agar bisa segera dirampungkan versi awal dari software ini. Sekali lagi dengan software ini saya ingin menekankan bahwa software hanyalah "alat", "ISI"-nya adalah tugas intelektual seorang pustakawan :)

Sabtu, Oktober 27, 2012

Genius's Guides to: membuat module Drupal 6 bagian 2

Nah setelah pada posting sebelumnya kita mengenal dasar-dasar coding pada file .module-nya Drupal, kali ini kita akan membahas mengenai file bernama .install yang berisikan definisi dari struktur tabel database untuk kita gunakan pada module. Drupal memungkinkan kita menambahkan atau menghapus tabel-tabel module kita pada struktur database Drupal melalui hook_schema, hook_install dan hook_uninstall.

Pada contoh ini misalnya kita akan membuat sebuah tabel yang nantinya akan kita gunakan sebagai tempat untuk menampung record atau data dari module kita. Jumlah tabel yang kita bisa tambahkan bisa lebih dari satu. Berikut isi dari file .install untuk module Latihan kita:

/**
 * Module Latihan
 * Copyright Arie Nugraha (dicarve@gmail.com) 2012
 * Licensed under GPL v3
 *
 */

/**
 * Fungsi ini dijalankan oleh Drupal ketika kita pertama menginstall module Latihan
 */
function latihan_install() {
  // Create tables.
  drupal_install_schema('latihan');
}

/**
 * Fungsi ini dijalankan oleh Drupal melakukan un-install pada Latihan
 */
function latihan_uninstall() {
  // Remove tables.
  drupal_uninstall_schema('latihan');
}

/**
 * Pada fungsi ini kita mendefinisikan struktur tabel2 database yang akan
 * kita gunakan untuk menyimpan data2 module Latihan
 */
function latihan_schema() {
  $schema['latihan'] = array(
    'description' => 'Tabel untuk menyimpan data module Latihan.',
    'fields' => array(
      'lat_id'     => array(
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'description' => "ID/Key utama tabel latihan"
        ),
      'lat_judul'     => array(
        'type' => 'varchar',
        'length' => '250',
        'not null' => TRUE,
        'default' => '',
        'description' => "Judul konten latihan"
        ),
      'lat_content' => array(
        'type' => 'text',
        'not null' => TRUE,
        'default' => '',
        'description' => 'Konten dari tabel latihan.'
        )
      ),
    'primary key' => array('lat_id'),
    'indexes' => array(
      'judul' => array('lat_judul')
      )
    );

  return $schema;
}

Kita bisa lihat pada implementasi hook_schema yaitu pada fungsi latihan_schema, kita mendefinisikan tabel dengan nama "latihan" dengan dua tiga field yaitu "lat_id", "lat_judul" dan "lat_content", dengan primary key-nya adalah "lat_id" dan juga sebuah indeks dengan nama "judul" pada field "lat_judul". Drupal akan menerjamahkan definisi ini menjadi syntax SQL yang akan di-eksekusi pada saat module "Latihan" pertama kali di-aktifkan.

Pertanyaan berikutnya adalah bagaimana kita memasukkan data ke dalam tabel module "Latihan"? Jawaban sederhananya adalah kita harus membuat form untuk memasukkan data tersebut. Terus bagaimana kita buat form di Drupal? Seperti saya pernah sebutkan sebelumnya Drupal sudah menyediakan API yang sangat lengkap, termasuk di dalamnya adalah Form API yang memudahkan kita dalam membuat form serta memproses form, termasuk dalam hal validasi.

Tanpa banyak basa-basi, mari kita tambahkan kode berikut ini pada file latihan.module kita:

/**
 * Fungsi ini mendefinisikan struktur form yang akan kita gunakan untuk
 * input data
 * @return Array array struktur form
 */
function latihan_inputdata_formdata() {
  // definisikan elemen form
  $form['judul'] = array(
    '#type' => 'textfield',
    '#title' => t('Judul konten Latihan'),
    '#default_value' => '',
    '#size' => 60,
    '#maxlength' => 250,
    '#description' => t('Judul konten latihan yang akan kita masukkan ke dalam database')
  );

  $form['konten'] = array(
    '#type' => 'textarea',
    '#title' => t('Isi konten Latihan'),
    '#default_value' => '',
    '#cols' => 60,
    '#rows' => 5,
    '#disabled' => false,
    '#description' => t('Data konten latihan yang akan kita masukkan ke dalam database')
  );

  $form['data_tersembunyi'] = array('#type' => 'hidden', '#value' => 'Contoh data form tersembunyi');
  $form['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#submit' => array('latihan_inputdata_formdata_submit'));
  return $form;
}


/**
 * Fungsi ini dipanggil ketika form input data latihan di-submit
 * Pada fungsi ini kita memanfaatkan Database API Drupal, yaitu fungsi
 * db_query() untuk melakukan query SQL ke database
 * Data form yang dikirimkan browser bisa kita akses lewat variabel $form_state['values'],
 * misalnya untuk mengakses data form "judul" kita mengaksesnya lewat
 * $form_state['values']['judul']
 */
function latihan_inputdata_formdata_submit($form, &$form_state) {
  db_query("INSERT INTO {latihan} (lat_judul, lat_content) VALUES ('%s', '%s')",
    $form_state['values']['judul'],
    $form_state['values']['konten']);
  // redirect ke web ke halaman/path "latihan"
  $form_state['redirect'] = 'latihan';
  drupal_set_message(t('"Latihan" form data has been saved'));
}


/**
 * Fungsi dibawah ini berfungsi me-render/menampilkan form yang sudah kita definisikan
 * pada fungsi latihan_inputdata_form
 */
function latihan_inputdata() {
  return drupal_get_form('latihan_inputdata_formdata');
}

Agar form input data-nya gampang diakses tentunya kita harus menempatkan link yang bisa diklik oler user, maka dari itu jangan lupa tambahkan kode berikut pada fungsi latihan_menu:

$items['latihan/inputdata'] = array(
  'title' => 'Input data module Latihan',
  'page callback' => 'latihan_inputdata',
  'access arguments' => array('membuat konten latihan'),
  'type' => MENU_NORMAL_ITEM
);

Apabila semua berjalan lancar, maka kita akan bisa melihat tampilan sebagai berikut pada Drupal kita:

Begitulah kira-kira cara dasar pemrosesan form pada Drupal. Pertanyaan berikutnya adalah bagaimana kemudian kita menampilkan data yang sudah kita masukkan ke database? Bagaiman cara kita membuat data yang sudah kita entry bisa di-edit/diubah? Entar dulu yak ane istirahat dulu, nanti ane tulis di bagian 3 :). Semoga bermanfaat