Membangun Aplikasi Mini HRD dengan Django (4): Memasang Web Template SB Admin 2

Ridwan Fajar 12 Juni 2016

Membangun Aplikasi Mini HRD dengan Django (4): Memasang Web Template SB Admin 2

Bagaimana dengan tiga tutorial Django sebelumnya? sepertinya berhasil mencoba semua dan dapat berjalan dengan sesuai. Sekarang kita akan menjadi make up artist terlebih dahulu, sebelum mengerjakan tutorial terakhir yang akan cukup menarik untuk menjadi teman ngabuburit. Selama tutorial pertama hingga tutorial ketiga, kita hanya menggunakan plain HTML tanpa CSS alias belum menggunakan web template yang memiliki tampilan menarik dan bagus. Tak akan lengkap rasanya bila aplikasi web yang dibangun tidak dipercantik dengan CSS buatan sendiri ataupun web template yang sudah jadi. Dengan menggunakan web template aplikasi web yang dibangun akan terlihat lebih ciamik dan enak digunakan.

Dalam tutorial ini Anda akan menggunakan SB Admin 2 yang dirilis Startbootstrap.com secara gratis. Web template tersebut memiliki beberapa template untuk halaman dan UI kit yang cukup lengkap. Selain itu layoutnya yang sederhana namun keren, dapat digunakan untuk proyek - proyek skala kecil seperti proyek akhir dalam skripsi atau proyek ngulik yang bisa Anda lakukan setiap Anda mempunyai ide ingin membangun aplikasi web dengan web framework tertentu. SB Admin 2 ini diperkuat oleh Twitter Bootstrap 3, jadi pastikan Anda yang sudah terbiasa dengan versi 2 dapat membaca dokumentasi Twitter Bootstrap 3 terlebih dahulu. Anda dapat mengunduh SB Admin 3 ini di http://startbootstrap.com.

Memang agak perlu perhatian khusus untuk memasang sebuah web template di web framework yang kita gunakan. Terlebih lagi kita harus memecah beberapa bagian yang sering muncul untuk di-include di halaman layout utama. Django sendiri memiliki sebuah fitur yang dinamakan Django Template Engine. Template engine tersebut sepintas mirip dengan Twig yang digunakan Symfony, atau template engine yang dimiliki oleh Angular.js. Salah satu kehandalan Django Template Engine adalah adanya fitur seperti berikut:

  • inheritance, Anda dapat membuat satu template global yang dapat menjadi wadah bagi sub-template yang dari halaman tertentu
  • include, Anda dapat membuat template kecil lainnya yang akan selalu disertakan di template global. Misalnya Anda membuat sebuah template navigasi yang akan disertakan di template global
  • logika if dan for, Anda tidak harus menggunakan sintaks Python di dalam sebuah template karena telah ditangani oleh if dan for yang dimiliki Django Template Engine
  • filter, ketika Anda mencetak suatu nilai di dalam template pasti Anda menginginkan bila teks tersebut dalam format kapital atau dalam format uang. Django Template Engine memiliki banyak filter yang dapat Anda gunakan untuk menampilkan data di template. Anda pun dapat membuat filter sendiri bila filter bawaan tidak dapat menangani permasalahan Anda.'
Dalam tutorial ini, Anda akan menggunakan file stater yang berisi struktur template dan asset yang sudah dirancang oleh tim Codepolitan, sehingga Anda cukup mengenal teknik dasarnya saja dan memasangnya pada proyek mini_hrd yang telah Anda selesaikan hingga tutorial ketiga. Silahkan unduh file starter untuk tutorial ini di tautan berikut: http://bit.ly/25UJuCl

Pengaturan template di Django

Hal yang pertama kita harus lakukan adalah membuat folder templates di bawah root folder alias di bawah folder mini_hrd bukan di bawah mini_hrd/mini_hrd:
$ cd mini_hrd
$ ls mini_hrd
assets  db.sqlite3  homepage  karyawan  kehadiran  manage.py  mini_hrd
$ mkdir templates
$ mkdir templates/layout
$ ls mini_hrd
assets  db.sqlite3  homepage  karyawan  kehadiran  manage.py  mini_hrd templates
Kemudian copy struktur template yang telah disediakan ke mini_hrd/templates/layout. Dan berikut adalah file yang harus ada di dalam folder template/layout:
$ ls templates/layout
base.html        base-login.html  head.html        js.html          nav.html         sidebar.html
Berikut adalah penjelasan untuk masing - masing file di dalam templates/layout:
  • base.html, adalah file template global yang akan menjadi wadah bagi file template di view lainnya
  • base-login.html, adalah file template yang menjadi wadah bagi file template khusus untuk view login
  • head.html, adalah file template berisi tag yang menyertakan CSS dan head yang akan disertakan di base.html
  • js.html, adalah file template berisi tag yang menyertakan Javascript yang akan disertakan di base.html
  • nav.html, adalah file template yang berisi tag yang mendefinisikan navigasi berupa dropdown yang akan disertakan di base.html
  • sidebar.html, adalah file template berisi tag yang mendenifisikan menu berupa sidebar di sebelah kiri yang akan disertakan di base.html
Anda akan mengenal lebih jauh tentang isi dari masing - masing file tersebut di bagian tutorial selanjutnya.

Karena file template membutuhkan CSS dan Javascript maka di dalam starter file yang kami sediakan pun terdapat folder assets yang sudah disesuaikan untuk tutorial ini. Silahkan buat terlebih dahulu folder assets di bawah root folder. Kemudian copy isi folder assets yang ada di file starter ke folder mini_hrd/assets:

$ ls assets
vendors
$ ls assets/vendors
sb-admin
$ ls assets/vendors/sb-admin
bower_components  dist

Di dalam folder vendors/sb-admin hanya terdapat dua folder yaitu bower_components dan dist. Folder bower_components berisi berbagai library Javascript yang akan digunakan untuk web template ini. Sedangkan folder dist adalah folder yang berisi file Javascript dan CSS utama yang digunakan untk membuat web template ini menjadi lebih keren. Sekarang kita akan melakukan penentuan folder template di settings.py. Silahkan cari bagian kode dibawah ini di mini_hrd/mini_hrd/settings.py kemudian tambahkan parameter templates di bagian DIRS:

...........................................

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

...........................................

Sekarang kita akan melakukan penentuan folder static di settings.py. Tambahkan kode STATICFILES_DIRS di bagian bawah file mini_hrd/mini_hrd/settings.py:

...........................................

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/

STATIC_URL = '/static/'

LOGIN_URL = '/login/'

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "assets"),
)

Pada kode diatas, kita mendefinisikan folder assets sebagai folder yang berisi file statik seperti Javascript, gambar, dan CSS. Tapi ketika diakses melalui URL, maka STATIC_URL akan digunakan sehingga bukan http://localhost:8000/assets tetapi http://localhost:8000/static yang akan kita gunakan untuk mengkases file statik yang akan kita gunakan untuk halaman web. Lalu kita coba lihat apakah file CSS dan Javascript sudah dapat diakses melalui browser atau belum. Silahkan nyalakan web server Django dengan perintah python manage.py runserver dan cobalah akses URL berikut di web browser:

  • http://localhost:8000/static/vendors/sb-admin/bower_components/bootstrap/dist/css/bootstrap.min.css
  • http://localhost:8000/static/vendors/sb-admin/dist/js/sb-admin-2.js
Silahkan lihat screenshot berikut sebagai perbandingan: Selection_005 Selection_006

Folder templates yang telah kita buat sebelumnya berisi file template global yang akan digunakan file template lainnya. File template yang terkait dengan modul - modul yang telah kita buat akan disimpan pada folder templates yang ada di setiap modul. Kita sudah melakukannya di tutorial kedua dan ketiga. Hanya saja belum dilakukan teknik inheritance template. Sekarang mari kita buat folder new di bawah folder templates di setiap folder modul:

$ mkdir homepage/templates/new
$ mkdir kehadiran/templates/new
$ mkdir karyawan/templates/new

Folder new tersebut akan berisi file template baru kita yang sudah ditambah dengan sistem template ala Django

Membuat layout untuk halaman web di Django

Di bagian ini kita akan mengenal lebih jauh tentang maksud kode - kode yang ada di dalam folder templates/layout. Mari kita awali dengan melihat isi file base-login.html yang akan digunakan sebagai wadah dari file template untuk login terlebih dahulu:
<!DOCTYPE html>
<html lang="en">

<head>

{% include "layout/head.html" %}

</head>

<body>

&lt;div id="container"&gt;

    {% block content %}
    {% endblock %}

&lt;/div&gt;
&lt;!-- /#wrapper --&gt;

{% include "layout/js.html" %}

{% block inline_js %}
{% endblock %}

</body>

</html>

Pada kode diatas, lazim terdapat tag html sebagai pembuka kemudian head, dan body. Tapi di dalam tag head terdapat sebuah sintaks template Django yang menyatakan akan meng-include file template layout/head.html. File template tersebut akan kita bahas nanti. Kemudian kita juga melihat sebuah sintaks block yang terdapat di dalam div dengan id container. Sintaks block akan menjadi wadah yang dinamis bagi file template yang meng-inherit template base-login.html. Kemudian dibawahnya ada juga proses meng-include layout/js.html dan penempatan block inline_js yang akan digunakan untuk membuat wadah bagi kode Javascript yang ingin disimpan pada template tertentu.

Sekarang mari kita lihat isi file templates/layout/base.html:

<!DOCTYPE html>
<html lang="en">

<head>

    {% include "layout/head.html" %}

</head>

<body>

    <div id="wrapper">

        <!-- Navigation -->
        <nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
            {% include "layout/nav.html" %}

            {% include "layout/sidebar.html" %}
        </nav>

        <div id="page-wrapper">
            {% block content %}
            {% endblock %}
        </div>
        <!-- /#page-wrapper -->

    </div>
    <!-- /#wrapper -->

    {% include "layout/js.html" %}

    {% block inline_js %}
    {% endblock %}
</body>

</html>

Pada kode diatas hampir mirip dengan base-login.html, namun diasan terdapat tag navigasi yang meng-include nav.html dan sidebar.html. Berbeda dengan base-login.html, base.html akan menampilkan navigasi dan sidebar ketika digunakan bersama file template yang meng-inheritance file template tersebut. Selanjutnya ada block content dan inline_js.

Sekarang mari kita lihat kode di file head.html:

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Mini HRD by Codepolitan</title>

    <!-- Bootstrap Core CSS -->
    <link href="/static/vendors/sb-admin/bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">

    <!-- MetisMenu CSS -->
    <link href="/static/vendors/sb-admin/bower_components/metisMenu/dist/metisMenu.min.css" rel="stylesheet">

    <!-- Custom CSS -->
    <link href="/static/vendors/sb-admin/dist/css/sb-admin-2.css" rel="stylesheet">

    <!-- Morris Charts CSS -->
    <link href="/static/vendors/sb-admin/bower_components/morrisjs/morris.css" rel="stylesheet">

    <!-- Custom Fonts -->
    <link href="/static/vendors/sb-admin/bower_components/fontawesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">

Pada kode diatas, kita mendefinisikan beberapa tag meta seperti charset, viewport, dan lainnya. Kemudian kita mendefinisikan juga tag title. Setelah itu kita pun menyertakan beberapa file CSS yang akan digunakan oleh SB Admin 2 diantaranya, sb-admin2.css, font-awesome.min.css, dan bootstrap.min.css. File template ini akan di-include di file base.html dan base-login.html.

Sekarang mari kita lihat kode di file nav.html:

            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="index.html">Mini HRD</a>
            </div>
            <!-- /.navbar-header -->

            <ul class="nav navbar-top-links navbar-right">                
                <!-- /.dropdown -->
                <li class="dropdown">
                    <a class="dropdown-toggle" data-toggle="dropdown" href="#">
                        <i class="fa fa-user fa-fw"></i>  <i class="fa fa-caret-down"></i>
                    </a>
                    <ul class="dropdown-menu dropdown-user">
                        <li><a href="/logout/"><i class="fa fa-sign-out fa-fw"></i> Logout</a>
                        </li>
                    </ul>
                    <!-- /.dropdown-user -->
                </li>
                <!-- /.dropdown -->
            </ul>
            <!-- /.navbar-top-links -->

Seperti yang Anda lihat pada kode diatas, kita mendefinisikan sebuah header dengan menggunakan class navbar-header. Kemudian membuat sebuah menu dropdown dengan menggunakan kombinasi class nav dan dropdown. Saat ini kita hanya mempunyai satu menu yaitu Logout. Lalu kita lihat juga isi kode di file sidebar.html:

<div class="navbar-default sidebar" role="navigation">
    <div class="sidebar-nav navbar-collapse">
        <ul class="nav" id="side-menu">
            <li>
                <a href="/"><i class="fa fa-dashboard fa-fw"></i> Profil</a>
            </li>
            <li>
                <a href="#"><i class="fa fa-bar-chart-o fa-fw"></i> Kehadiran<span class="fa arrow"></span></a>
                <ul class="nav nav-second-level">
                    <li>
                        <a href="/daftar_hadir">Daftar Hadir</a>
                    </li>
                    <li>
                        <a href="/daftar_izin">Daftar Pengajuan Izin Ketidakhadiran</a>
                    </li>
                    <li>
                        <a href="/pengajuan_izin">Buat Pengajuan Izin Ketidakhadiran</a>
                    </li>
                </ul>
            </li>
        </ul>
    </div>
    <!-- /.sidebar-collapse -->
</div>
<!-- /.navbar-static-side -->

Masih menggunakan class navbar, ditambah dengan menggunakan class sidebar-nav sekarang kita mempunyai menu sidebar ala SB Admin 2. Di dalam kode tersebut terdapat dua pendefinisian menu utama yaitu "Profil" dan "Kehadiran". Di bawah menu "Kehadiran" terdapat tiga menu lainnya untuk melihat daftar hadir, daftar pengajuan izin ketidakhadiran, dan membuat pengajuan izin ketidakhadiran.

Sedangkan isi kode di file js.html berisi penyertaan kode Javascript seperti jquery.min.js, bootstrap.min.js, sb-admin-2.js, dan lainnya:

    <!-- jQuery -->
    <script src="/static/vendors/sb-admin/bower_components/jquery/dist/jquery.min.js"></script>

    <!-- Bootstrap Core JavaScript -->
    <script src="/static/vendors/sb-admin/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>

    <!-- Metis Menu Plugin JavaScript -->
    <script src="/static/vendors/sb-admin/bower_components/metisMenu/dist/metisMenu.min.js"></script>

    <!-- Morris Charts JavaScript -->
    <script src="/static/vendors/sb-admin/bower_components/raphael/raphael-min.js"></script>
    <script src="/static/vendors/sb-admin/bower_components/morrisjs/morris.min.js"></script>

    <!-- Custom Theme JavaScript -->
    <script src="/static/vendors/sb-admin/dist/js/sb-admin-2.js"></script>

Setelah Anda melihat isi setiap struktur layout diatas, sekarang saatnya sekarang kita nge-rockkkkkkk.....

Memperbaiki halaman login

Seperti yang telah disampaikan di bagian tutorial sebelumnya, Anda harus membuat sebuah folder bernama new di dalam folder templates yang ada di setiap modul. Dengan membuat folder tersebut, Anda dapat membandingkan perbedaan template yang sudah memiliki struktur dan yang belum. Sekarang mari kita tambahkan sebuah file bernama login.html di homepage/templates/new. Kemudian salin kode berikut ke dalam file login.html yang baru:
{% extends "layout/base-login.html" %}
{% block content %}      
            <div class="row">
                <div class="col-md-4 col-md-offset-4">
                    <div class="login-panel panel panel-default">
                        <div class="panel-heading">
                            <h3 class="panel-title">Mini HRD - Silahkan Login</h3>
                        </div>
                        <div class="panel-body">
                            <form action="/login/" method="POST" role="form">
                                {% csrf_token %}
                                {% if messages %}
                                    <div class="alert alert-danger alert-dismissable">
                                        <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                                        <ul>
                                            {% for message in messages %}
                                              <li>{{ message }}</li>
                                            {% endfor %}
                                        </ul>
                                    </div>
                                {% endif %}
                                <fieldset>
                                    <div class="form-group">
                                        <input class="form-control" type="text" name="username" value="" placeholder="silahkan masukkan username..." />
                                    </div>
                                    <div class="form-group">
                                        <input class="form-control" type="password" name="password" value="" placeholder="silahkan masukkan password..." />
                                    </div>
                                    <input class="btn btn-lg btn-success btn-block" type="submit" value="Log In" />
                                </fieldset>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
            <!-- /.row -->
{% endblock %}
Pada kode diatas kita melakukan extends terhadap template layout/base-login.html yang mana kita menempatkan HTML yang ada di dalam block content untuk ditempelkan di template base-login.html. Pada kode diatas, kita gunakan template halaman login yang disediakan SB Admin2. Kemudian kita juga menambahkan sebuah alert yang akan memberitahu kita bila ada problem dengan proses login seperti salah password atau akun belum terdaftar. Berikut adalah screenshot dari halaman login yang baru: Selection_007 Selection_008 Selection_009

Memperbaiki halaman profil

Sekarang saatnya membuat halaman profil baru di karyawan/templates. Buatlah sebuah file dengan naman profil.html di folder tersebut. Kemudian salin kode berikut ke karyawan/templates/profil.html:
{% extends "layout/base.html" %}
{% block content %}      
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">Profil</h1>
                    <ol class="breadcrumb" style="margin-bottom: 5px;">
                      <li class="active">Beranda</li>
                    </ol>
                    <br />
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            <i class="fa fa-bar-chart-o fa-fw"></i> Hi, {{ request.session.username }}
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
                            <div class="row">
                                <div class="col-lg-12">
                                    <div class="table-responsive">
                                        <table class="table table-bordered table-hover table-striped">
                                            <tbody>
                                                <tr>
                                                    <td>Nama</td>
                                                    <td style="width:10px;">:</td>
                                                    <td>{{ karyawan.nama }}</td>
                                                </tr>
                                                <tr>
                                                    <td>Alamat</td>
                                                    <td style="width:10px;">:</td>
                                                    <td>{{ karyawan.alamat }}</td>
                                                </tr>
                                                <tr>
                                                    <td>Jenis Kelamin</td>
                                                    <td style="width:10px;">:</td>
                                                    <td>{{ karyawan.jenis_kelamin }}</td>
                                                </tr>
                                                <tr>
                                                    <td>Jenis Karyawan</td>
                                                    <td style="width:10px;">:</td>
                                                    <td>{{ karyawan.jenis_karyawan }}</td>
                                                </tr>
                                                <tr>
                                                    <td>No. Telepon</td>
                                                    <td style="width:10px;">:</td>
                                                    <td>{{ karyawan.no_telepon }}</td>
                                                </tr>
                                                <tr>
                                                    <td>E-mail</td>
                                                    <td style="width:10px;">:</td>
                                                    <td>{{ karyawan.email }}</td>
                                                </tr>
                                                <tr>
                                                    <td>No. Rekening</td>
                                                    <td style="width:10px;">:</td>
                                                    <td>{{ karyawan.no_rekening }}</td>
                                                </tr>
                                                <tr>
                                                    <td>Pemilik Rekening</td>
                                                    <td style="width:10px;">:</td>
                                                    <td>{{ karyawan.pemilik_rekening }}</td>
                                                </tr>
                                                <tr>
                                                    <td>Divisi</td>
                                                    <td style="width:10px;">:</td>
                                                    <td>{{ karyawan.divisi.nama }}</td>
                                                </tr>
                                                <tr>
                                                    <td>Jabatan</td>
                                                    <td style="width:10px;">:</td>
                                                    <td>{{ karyawan.jabatan.nama }}</td>
                                                </tr>
                                        &lt;/tbody&gt;
                                    &lt;/table&gt;
                                &lt;/div&gt;
                                &lt;!-- /.table-responsive --&gt;
                            &lt;/div&gt;
                            &lt;!-- /.col-lg-4 (nested) --&gt;
                        &lt;/div&gt;
                        &lt;!-- /.row --&gt;
                    &lt;/div&gt;
                    &lt;!-- /.panel-body --&gt;
                &lt;/div&gt;
                &lt;!-- /.panel --&gt;
            &lt;/div&gt;
            &lt;!-- /.col-lg-8 --&gt;
        &lt;/div&gt;
        &lt;!-- /.row --&gt;

{% endblock %}

Pada kode diatas, Seperti biasa, kita mulai meng-extends template induk, namun kali ini kita menggunakan layout/base.html. Kemudian kita membuat dua div dengan id row. Yang pertama kita gunakan untuk menempatkan page-header halaman dan sebuah breadcrumb. Kemudian di row yang kedua kita membuat sebuah table-responsive yang berisi 10 baris informasi dasar dari karyawan yang terdiri dari nama, jabatan, jenis kelamin, no rekening, divisi dan lainnya. Seperti inilah penampakan halaman profil yang baru:

Selection_011

Memperbaiki halaman pengajuan izin ketidakhadiran

Mari kita lanjutkan dengan memperbaiki form yang ada di halaman pengajuan izin ketidakhadiran. Buatlah file baru yang bernama tambah_izin.html di kehadiran/templates/new/. Kemudian buatlah kode berikut ke dalam file tersebut:
{% extends "layout/base.html" %}
{% block content %}      
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">Form Pengajuan Izin Ketidakhadiran</h1>
                    <ol class="breadcrumb" style="margin-bottom: 5px;">
                      <li><a href="/">Beranda</a></li>
                      <li class="active">Tambah Izin</li>
                    </ol>
                    <br />
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            <i class="fa fa-bar-chart-o fa-fw"></i> Silahkan buat pengajuan kenapa tidak dapat masuk kerja
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
                            {% if form.errors %}
                                <div class="alert alert-danger alert-dismissable">
                                    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                                    {{ form.errors }}
                                </div>
                            {% endif %}
                            <form action="/pengajuan_izin/" method="POST" role="form">
                                {% csrf_token %}
                                <div class="form-group  col-md-4">
                                    <label>{{ form.jenis_kehadiran.label }}</label>
                                    {{ form.jenis_kehadiran }}                           
                                </div>
                                <div class="form-group col-md-4">
                                    <label>{{ form.waktu_mulai.label }}</label>
                                    {{ form.waktu_mulai }}                           
                                </div>
                                <div class="form-group col-md-4">
                                    <label>{{ form.waktu_berhenti.label }}</label>
                                    {{ form.waktu_berhenti }}                           
                                </div>
                                <div class="form-group">
                                    <label>{{ form.alasan.label }}</label>
                                    {{ form.alasan }}                           
                                </div>
                                <!-- {{ form.as_p }} -->
                                <br /><br />
                                <input type="submit" class="btn btn-primary" value="Submit" />
                                <button type="reset" class="btn btn-danger"><i class="glyphicon glyphicon-back"></i> Reset</button>
                            </form>
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-8 -->
            </div>
            <!-- /.row -->
{% endblock %}
Seperti biasa kita meng-extend template layout/base.html, kemudian membuat dua row utama. Row pertama berisi page-header dan breadcrumb. Kemudian row kedua berisi pendefinisian panel Twitter Bootstrap yang didalamnya ada pendefinisian form ala Twitter Bootstrap. Pada form diatas, kita tambahkan sebuah alert yang bilaman terjadi error akan muncul di bagian atas form Kemudian kita membuat sbeuah form-group dengan kolom 4 agar dapat menjadi inline, lalu tidak lupa kita tambahkan tombol submit dan reset. Beginilah penampakan halaman pengajuan izin ketidakhadiran yang baru: Selection_012 Selection_013

Memperbaiki halaman daftar izin ketidakhadiran

Sekarang mari kita buat sebuah file baru yang bernama daftar_izin.html di kehadiran/templates/new/. Kemudian buat kode berikut di file tersebut:
{% extends "layout/base.html" %}
{% block content %}      
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">Daftar Izin</h1>
                    <ol class="breadcrumb" style="margin-bottom: 5px;">
                      <li><a href="/">Beranda</a></li>
                      <li class="active">Daftar Izin</li>
                    </ol>
                    <br />
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            <i class="fa fa-bar-chart-o fa-fw"></i> Daftar pengajuan izin Anda
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
                            <div class="row">
                                <div class="col-lg-12">
                                    <div class="table-responsive">
                                        <table class="table table-bordered table-hover table-striped">
                                            <thead>
                                                <tr>
                                                    <th>#</th>
                                                    <td>Jenis Izin</td>
                                                    <td>Waktu Mulai</td>
                                                    <td>Waktu Berhenti</td>
                                                    <td>Alasan</td>
                                                    <td>Disetujui</td>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                {% for izin in daftar_izin %}
                                                <tr>
                                                    <td>{{ forloop.counter }}</td>
                                                    <td>{{ izin.jenis_kehadiran }}</td>
                                                    <td>{{ izin.waktu_mulai }}</td>
                                                    <td>{{ izin.waktu_berhenti }}</td>
                                                    <td>{{ izin.alasan }}</td>
                                                    <td>
                                                        {% if izin.disetujui %}
                                                        <span class="label label-success">Sudah</span>
                                                        {% else %}
                                                        <span class="label label-danger">Belum</span>
                                                        {% endif %}
                                                    </td>
                                                </tr>
                                                {% endfor %}
                                            </tbody>
                                        </table>
                                    </div>
                                    <!-- /.table-responsive -->
                                </div>
                                <!-- /.col-lg-4 (nested) -->
                            </div>
                            <!-- /.row -->
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-8 -->
            </div>
            <!-- /.row -->
{% endblock %}
Seperti biasa kita meng-extend template layout/base.html, kemudian membuat dua row utama. Row pertama berisi page-header dan breadcrumb. Di dalam row yang kedua kita membuat sebuah table-responsive dengan field jenis izin, waktu mulai, waktu berhenti, alasan, dan disetujui atau tidak. Kemudian kita melakukan looping yang di dalamnya terdapat Lalu untuk field disetujui, kita menggunakan if untuk menampilkan label-success bila izin ketidakhadiran disetujui dan label-danger bila sebaliknya. Berikut penampakan halaman pengajuan izin ketidakhadiran yang baru: Selection_014

Memperbaiki halaman daftar hadir

Akhirnya kita menuju bagian yang terakhir. Silahkan buat sebuah file yang bernama daftar_hadir.html di folder kehadiran/templates/new/. Kemudian buat kode berikut di file tersebut:
{% extends "layout/base.html" %}
{% block content %}      
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">Daftar Izin</h1>
                    <ol class="breadcrumb" style="margin-bottom: 5px;">
                      <li><a href="/">Beranda</a></li>
                      <li class="active">Daftar Izin</li>
                    </ol>
                    <br />
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    <div class="panel panel-default">
                        <div class="panel-heading">
                            <i class="fa fa-bar-chart-o fa-fw"></i> Daftar pengajuan izin Anda
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
                            <div class="row">
                                <div class="col-lg-12">
                                    <form action="/daftar_hadir/" method="POST" role="form" class="form-inline">
                                        {% csrf_token %}
                                        <div class="form-group">
                                            <label>Tahun</label>
                                            <select name="tahun" class="form-control">
                                                <option value="2016">2016</option>
                                                <option value="2015">2015</option>
                                                <option value="2014">2014</option>
                                            </select>                          
                                        </div>
                                        <div class="form-group">
                                            <label>Bulan</label>
                                            <select name="bulan" class="form-control">
                                                <option value="01">Januari</option>
                                                <option value="02">Februari</option>
                                                <option value="03">Maret</option>
                                                <option value="04">April</option>
                                                <option value="05">Mei</option>
                                                <option value="06">Juni</option>
                                                <option value="07">Juli</option>
                                                <option value="08">Agustus</option>
                                                <option value="09">September</option>
                                                <option value="10">Oktober</option>
                                                <option value="11">November</option>
                                                <option value="12">Desember</option>
                                            </select>                          
                                        </div>
                                        <div class="form-group">
                                            <input type="submit" class="btn btn-primary" value="Submit" />
                                        </div>
                                    </form>
                                    <br/>
                                    <div class="table-responsive">
                                        <table class="table table-bordered table-hover table-striped">
                                            <thead>
                                                <tr>
                                                    <th>#</th>
                                                    <td>Tanggal</td>
                                                    <td>Status</td>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                {% if daftar_hadir %}
                                                    {% for hadir in daftar_hadir %}
                                                    <tr>
                                                        <td>{{ forloop.counter }}</td>
                                                        <td>{{ hadir.waktu }}</td>
                                                        <td>{{ hadir.jenis_kehadiran }}</td>
                                                    </tr>
                                                    {% endfor %}
                                                {% else %}
                                                <tr>
                                                    <td colspan="3" style="text-align:center;">Tidak ada data kehadiran saat ini...</td>
                                                </tr>
                                                {% endif %}
                                            </tbody>
                                        </table>
                                    </div>
                                    <!-- /.table-responsive -->
                                </div>
                                <!-- /.col-lg-4 (nested) -->
                            </div>
                            <!-- /.row -->
                        </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-8 -->
            </div>
            <!-- /.row -->
{% endblock %}
Pada kode diatas, seperti biasa kita meng-extend template layout/base.html. Kemudian kita membuat sebuah form yang mempunyai field tahun dan bulan untuk menentukan ingin melihat daftar hadir di bulan dan tahun berapa. Kemudian kita menampilkan daftar hadir dalam bentuk tabel. Berikut adalah contoh tampilan baru daftar hadir: Selection_017 Selection_016

Penutup

Dengan menggunakan web template yang sudah disediakan secara gratis atau dibuat oleh web designer maka halaman web akan menjadi lebih menarik dan enak digunakan. Anda pun dapat dengan efektif memecah suatu templatemenjadi beberapa bagian yang memudahkan pengelolaanya sehingga Anda tidak harus mengubah banyak file yang memiliki elemen yang sama. Bayangkan saja ketidakefektifannya apabila Anda harus mengedit sebuah navigasi bila ada di setiap halaman HTML yang Anda kembangkan. Banyak web framework termasuk Django yang sudah mendukung sistem template seperti ini, ada juga yang harus memasang third-party agar fungsionalitas ini dapat berjalan. Namun tentu saja Django memiliki fitur ini tanpa harus memasang plugin apapun. Sekali install Anda mendapatkan banyak fitur untuk digunakan.

(rfs/djangoproject)