summaryrefslogtreecommitdiff
path: root/demos/blog-tutorial
diff options
context:
space:
mode:
authorkabayan <>2007-08-28 17:55:45 +0000
committerkabayan <>2007-08-28 17:55:45 +0000
commit888fa27278a1791dc77385bfdb60a52df54e898b (patch)
tree97964c94b7810c58291a47f2a8b43558c7102810 /demos/blog-tutorial
parent60785e1670360529b968471c39232b5193772f15 (diff)
Indonesian Blog Tutorial Day 1 and Day 2
Diffstat (limited to 'demos/blog-tutorial')
-rw-r--r--demos/blog-tutorial/protected/layout/id/MainLayout.tpl2
-rw-r--r--demos/blog-tutorial/protected/pages/Day1/id/CreateContact.page204
-rw-r--r--demos/blog-tutorial/protected/pages/Day1/id/Setup.page164
-rw-r--r--demos/blog-tutorial/protected/pages/Day1/id/ShareLayout.page180
-rw-r--r--demos/blog-tutorial/protected/pages/Day1/id/directories.gifbin0 -> 3611 bytes
-rw-r--r--demos/blog-tutorial/protected/pages/Day1/id/directories2.gifbin0 -> 4147 bytes
-rw-r--r--demos/blog-tutorial/protected/pages/Day1/id/directories3.gifbin0 -> 3531 bytes
-rw-r--r--demos/blog-tutorial/protected/pages/Day1/id/output.gifbin0 -> 13379 bytes
-rw-r--r--demos/blog-tutorial/protected/pages/Day2/id/ConnectDB.page46
-rw-r--r--demos/blog-tutorial/protected/pages/Day2/id/CreateAR.page178
-rw-r--r--demos/blog-tutorial/protected/pages/Day2/id/CreateDB.page69
-rw-r--r--demos/blog-tutorial/protected/pages/Day2/id/ER.gifbin0 -> 4444 bytes
-rw-r--r--demos/blog-tutorial/protected/pages/Day2/id/directories.gifbin0 -> 4580 bytes
-rw-r--r--demos/blog-tutorial/protected/pages/Day2/id/directories2.gifbin0 -> 6795 bytes
14 files changed, 842 insertions, 1 deletions
diff --git a/demos/blog-tutorial/protected/layout/id/MainLayout.tpl b/demos/blog-tutorial/protected/layout/id/MainLayout.tpl
index 9f18cd46..7b3549f0 100644
--- a/demos/blog-tutorial/protected/layout/id/MainLayout.tpl
+++ b/demos/blog-tutorial/protected/layout/id/MainLayout.tpl
@@ -1,7 +1,7 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
-<com:THead Title="Tutorial Bloh PRADO">
+<com:THead Title="Tutorial Blog PRADO">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="content-language" content="en"/>
</com:THead>
diff --git a/demos/blog-tutorial/protected/pages/Day1/id/CreateContact.page b/demos/blog-tutorial/protected/pages/Day1/id/CreateContact.page
new file mode 100644
index 00000000..664363d0
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day1/id/CreateContact.page
@@ -0,0 +1,204 @@
+<com:TContent ID="Main">
+
+<h1>Membuat Halaman Kontak</h1>
+
+<p>
+Kita telah membuat halaman standar <tt>Home.page</tt> menggunakan <a href="http://www.pradosoft.com/demos/quickstart/?page=GettingStarted.CommandLine">piranti baris perintah PRADO</a>. Halaman relatif statis karena ia tidak berisi konten dinamis. Dalam bagian ini, kita akan membuat halaman interaktif bernama <tt>Contact</tt>.
+</p>
+
+<p>
+Kegunaan dari halaman <tt>Contact</tt> adalah untuk mengumpulkan umpan balik dari para pengguna sistem blog kita. Untuk melaksanakan tujuan ini, kita merencanakan untuk menyajikan para pengguna dengan sebuah formulir umpan balik yang harus diisi. Dalam formulir ini, kita akan mengharuskan para pengguna untuk menyediakan namanya, alamat email, dan konten umpan balik. Setelah formulir diisi dan dikirimkan, email yang berisi umpan balik akan dikirimkan ke administrator situs.
+</p>
+
+<p>
+Untuk membuat halaman <tt>Contact</tt>, kita memerluka dua file di bawah direktori <tt>pages</tt>: file template halaman <tt>Contact.page</tt> dan file kelas halaman <tt>Contact.php</tt>.
+</p>
+
+<img src="<%~ directories2.gif %>" class="output" />
+
+<com:InfoBox>
+<a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Pages">Halaman</a> harus berupa file <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.Templates1">template</a> (berekstensi <tt>.page</tt>) atau file kelas, atau keduanya:
+</p>
+
+<ul>
+<li>Hanya template-halaman yang biasanya berupa sebuah halaman sengan konten statis, seperti homepage yang sudah kita buat;</li>
+<li>Hanya file kelas halaman yang menghasilkan konten murni berdasarkan eksekusi metode kelas;</li>
+<li>Sebuah halaman dengan template dan kelasnya mengkombinasikan keunggulan keduanya: ia menggunakan template untuk memudahkan mengatur tata letak halaman dan menggunakan kelas untuk menyertakan logika yang menghasilkan konten dinamis.</li>
+</ul>
+</com:InfoBox>
+
+
+<h2>Membuat Template Halaman</h2>
+
+<p>
+Pertama kita membuat file template untuk halaman <tt>Contact</tt>.
+</p>
+
+<p>
+Kita menggunakan template untuk menghatur tata letak penyajian terhadap formulir umpan balik. Dalam template, kita menggunakan <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.TextBox">kotak teks</a> untuk mengumpulkan nama pengguna, email dan umpan balik. Dan kita menggunakan <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.Validation">validator</a> guna memastikan bahwa pengguna menyediakan semua informasi ini sebelum mengirimkan formulir umpan balik. Seluruh template adalah sebagai berikut,
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+<html>
+<head><title>My Blog - Contact</title></head>
+<body>
+<h1>Contact</h1>
+<p>Please fill out the following form to let me know your feedback on my blog. Thanks!</p>
+
+&lt;com:TForm>
+
+<span>Your Name:</span>
+&lt;com:TRequiredFieldValidator ControlToValidate="Name"
+ ErrorMessage="Please provide your name."
+ Display="Dynamic" />
+<br/>
+&lt;com:TTextBox ID="Name" />
+
+<br/>
+<span>Your Email:</span>
+&lt;com:TRequiredFieldValidator ControlToValidate="Email"
+ ErrorMessage="Please provide your email address."
+ Display="Dynamic" />
+&lt;com:TEmailAddressValidator ControlToValidate="Email"
+ ErrorMessage="You entered an invalid email address."
+ Display="Dynamic" />
+<br/>
+&lt;com:TTextBox ID="Email" />
+
+<br/>
+<span>Feedback:</span>
+&lt;com:TRequiredFieldValidator ControlToValidate="Feedback"
+ ErrorMessage="Please provide your feedback."
+ Display="Dynamic" />
+<br/>
+&lt;com:TTextBox ID="Feedback"
+ TextMode="MultiLine"
+ Rows="10"
+ Columns="40" />
+
+<br/>
+&lt;com:TButton Text="Submit" OnClick="submitButtonClicked" />
+
+&lt;/com:TForm>
+
+</body>
+</html>
+</com:TTextHighlighter>
+
+<p>
+Seperti kita lihat bahwa template terlihat sangat mirip dengan halaman HTML normal. Perbedaan utamanya adalah bahwa template berisi beberapa tag <tt>&lt;com:&gt;</tt>. Setap tag <tt>&lt;com:&gt;</tt> merujuk ke sebuah <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Controls">kontrol</a> yang propertinya diinisialisasi dengan pasangan nama-nilai dalam tag. Sebagai contoh, <tt>&lt;com:TButton&gt;</tt> merujuk ke kontrol <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.Button">TButton</a> guna menampilkan sebuah tombol di mana pengguna dapat di klik pengguna untuk mengirimkan formulir umpan balik. Untuk sintaks lengkap template, silahkan rujuk <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.Templates1">Tutorial Cepat</a>.
+</p>
+
+<com:InfoBox>
+PRADO menyediakan kontrol untuk setiap tipe input HTML. Sebagai contoh, <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.TextBox">TTextBox</a> menampilkan field input teks, <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.List">TDropDownList</a> menampilkan kotak kombo. Setiap kontrol adalah sebuah komponen yang dapat diakses dalam kode sebagai obyek dengan properti yang bisa dikonfigurasi.
+</com:InfoBox>
+
+<p>
+Selain kontrol <tt>TTextBox</tt>, template juga menggunakan banyak kontrol validator yang memastikan input pengguna memuaskan aturan validasi spesifik. Sebagai contoh, untuk memastikan alamat email sah yang dilengkapi, kita menggunakan dua validator untuk memvalidasi kotak teks "email", seperti ditampilkan dalam kode berikut:
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+<span>Your Email:</span>
+&lt;com:TRequiredFieldValidator
+ ControlToValidate="Email"
+ ErrorMessage="Please provide your email address."
+ Display="Dynamic" />
+&lt;com:TEmailAddressValidator
+ ControlToValidate="Email"
+ ErrorMessage="You entered an invalid email address."
+ Display="Dynamic" />
+<br/>
+&lt;com:TTextBox ID="Email" />
+<br/>
+</com:TTextHighlighter>
+
+<p>
+Di bawah ini kita meringkas kontrol yang dipakai dalam template halaman:
+</p>
+
+<ul>
+<li><a href="http://www.pradosoft.com/docs/classdoc/TForm">TForm</a> menampilkan sebuah formulir HTML. Setiap kontrol input harus dikurung di dalamnya. Dan yang terpenting, paling banyak satu <tt>TForm</tt> boleh muncul dalam sebuah halaman.</li>
+<li><a href="http://www.pradosoft.com/docs/classdoc/TTextBox">TTextBox</a> menampilkan kotak teks untuk mengumpulkan input teks pengguna.</li>
+<li><a href="http://www.pradosoft.com/docs/classdoc/TRequiredFieldValidator">TRequiredFieldValidator</a> memastikan bahwa kotak teks terkait tidak kosong saat umpan balik dikirimkan.</li>
+<li><a href="http://www.pradosoft.com/docs/classdoc/TEmailAddressValidator">TEmailAddressValidator</a> memastikan bahwa kotak teks berisi alamat email yang <i>benar</i> saat umpan balik dikirimkan.</li>
+</ul>
+
+<com:TipBox>
+Menulis template dengan editor teks biasa dapat membosankan dan tidak intuitif untuk para desainer. Untuk memudahkan situasi ini, PRADO telah menyertakan dalam rilis ekstensi Adobe Dreamweaver yang mendukung pelengkapan-otomatis tag PRADO (misalnya menyertakan nama kontrol, nama properti, nama event, dll) dalam Dreamweaver.
+</com:TipBox>
+
+
+<h2>Membuat Kelas Halaman</h2>
+
+<p>
+Sekarang kita membuat kelas halaman <tt>Contact.php</tt>. Alasan kita membutuhkan kelas halaman adalah karena kita perlu merespon umpan balik yang dikirimkan oleh pengguna.
+
+<p>
+Notice in the template we have the following line. The template essentially states that when a user clicks on the button, it should call the <tt>submitButtonClicked()</tt> method. Here <tt>OnClick</tt> is the name of the user click event, and the method must be defined in the page class.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+ &lt;com:TButton Text="Submit" OnClick="submitButtonClicked" />
+</com:TTextHighlighter>
+
+<p>
+Selanjutnya kita menuliskan kelas halaman seperti berikut:
+</p>
+
+<com:TTextHighlighter CssClass="source">
+<?php
+class Contact extends TPage
+{
+ /**
+ * Pengendali event untuk event OnClick pada tombol submit.
+ * @param TButton tombol yang memicu event
+ * @param TEventParameter parameter event (null di sini)
+ */
+ public function submitButtonClicked($sender, $param)
+ {
+ if ($this->IsValid) // memeriksa apakan validasi input berhasil
+ {
+ // mendapatkan nama pengguna, email, umpan balik dari kotak teks
+ $name = $this->Name->Text;
+ $email = $this->Email->Text;
+ $feedback = $this->Feedback->Text;
+
+ // mengirimkan email ke administrator dengan informasi di atas
+ $this->mailFeedback($name, $email, $feedback);
+ }
+ }
+
+ protected function mailFeedback($name, $email, $feedback)
+ {
+ // implementasi pengiriman email umpan balik
+ }
+}
+?>
+</com:TTextHighlighter>
+
+<p>
+Kode di atas sebagian besar cukup jelas. Kenyataannya, kami hanya menampilkan skema pemrograman pengendalian-event. Dalam pengendali event <tt>submitButtonClicked()</tt>, kita mengambil input pengguna. Sebagai contoh, <tt>$this->Name->Text</tt> mengembalikan nilai properti <tt>Text</tt> dari kontrol <tt>Name</tt> yang merupakan kotak teks yang mengumpulkan informasi nama pengguna.
+</p>
+
+<com:InfoBox>
+Nama kelas halaman harus sama seperti nama file. Ini juga persyaratan untuk penulisan komponen kelas PRADO.
+</com:InfoBox>
+
+
+<h2>Pengujian</h2>
+
+<p>
+<tt>Contact</tt> yang baru saja kita buat dapat kita uji dengan URL <tt>http://hostname/blog/index.php?page=Contact</tt>. Jika kita mengklik pada tombol submit tanpa memasukan informasi apapun, kita akan melihat pesan kesalahan muncil di sebelah kotak teks terkait. Jika kita memasukan semua informasi yang diperlukan, metode <tt>mailFeedback()</tt> akan dipanggil.
+</p>
+
+<img src="<%~ output.gif %>" class="output" />
+
+<p>
+Peningkatan berikutnya terhadap halaman ini adalah untuk menampilkan beberapa pesan konfirmasi pada halaman setelah pengguna mengirimkan umpan balik. Dan kemungkinan, browser akan dialihkan ke halaman lain jika pengiriman berhasil. Kita akan membiarkan tugas ini bagi para pembaca kita.
+</p>
+
+<com:InfoBox>
+Setiap validator mewakili aturan validasi. Satu kontrol input dapat dikaitkan dengan satu atau multipel validator. Validator melakukan validasi pada sisi klien dan sisi server. Pada sisi klien, yaitu browser, validasi dikerjakan dmenggunakan javascript; pada sisi server, validasi dikerjakan dengan menggunakan kode PHP. Validasi sisi-klien dapat dimatikan, sementara validasi sisi-server tidak bisa. Ini memastikan input pengguna selalu diperiksa oleh aturan validasi yang dietapkan.
+</com:InfoBox>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog-tutorial/protected/pages/Day1/id/Setup.page b/demos/blog-tutorial/protected/pages/Day1/id/Setup.page
new file mode 100644
index 00000000..16c8b498
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day1/id/Setup.page
@@ -0,0 +1,164 @@
+<com:TContent ID="Main">
+
+<h1>Persiapan Awal</h1>
+
+<p>
+Kita mulai dengan menyiapkan direktori dan file yang diperlukan oleh kebanyakan aplikasi PRADO. Kita menggunakan <a href="http://www.pradosoft.com/demos/quickstart/?page=GettingStarted.CommandLine">piranti baris perintah PRADO</a> untuk melaksanakan tujuan ini.
+</p>
+
+<p>
+Anggap <tt>blog</tt> adalah nama direktori untuk menampung seluruh sistem blog, dan URL untuk mengakses folder ini adalah <tt>http://hostname/blog/</tt> (ganti <tt>hostname</tt> dengan nama host sebenarnya).
+</p>
+
+<p>
+Di bawah direktori <tt>blog</tt>, kita menjalankan <a href="http://www.pradosoft.com/demos/quickstart/?page=GettingStarted.CommandLine">piranti baris perintah PRADO</a> dengan perintah berikut (ganti <tt>path/ke</tt> dengan path sebenarnya ke instalasi kerangka kerja PRADO):
+</p>
+<com:TTextHighlighter CssClass="source cli">
+php path/ke/prado-cli.php -c .
+</com:TTextHighlighter>
+
+<p>
+Menjalankan perintah di atas akan membuat direktori dan file berikut:
+</p>
+
+<img src="<%~ directories.gif %>" class="output" />
+
+<p>
+Sekarang kita mempunyai kerangka aplikasi PRADO yang dapat diakses melalui URL <tt>http://hostname/blog/index.php</tt> yang menampilkan halaman Web dengan tulisan "Welcome to PRADO".
+</p>
+
+<p>
+Sangat bermanfaat mempelajari lebih rinci mengenai direktori dan file yang baru saja kita buat.
+</p>
+
+
+<h2>File Awal</h2>
+
+<h3>Naskah Entri</h3>
+
+<p>
+Setiap aplikasi PRADO mempunyai naskah entri, sering dinamakan sebagai <tt>index.php</tt>. Dalam kebanyakan kasus, ia hanya naskah PHP yang secara langsung dapat diakses oleh pengguna Web. Ini mengurangi resiko terhadap ijin para pengguna Web untuk menjalankan naskah yang tidak diinginkan pada server.
+</p>
+
+<p>
+Kegunaan utama dari naskah entri adalah untuk mengawali aplikasi PRADO dan membiarkan ia menangani permintaan pengguna. Naskah entri biasanya berisi pernyataan PHP berikut,
+</p>
+
+<com:TTextHighlighter CssClass="source">
+<?php
+// sertakan prado.php yang berisi kelas PRADO dasar
+require_once('path/to/prado.php');
+// buat turunan aplikasi PRADO
+$application = new TApplication;
+// jalankan aplikasi dan tangani permintaan pengguna
+$application->run();
+?>
+</com:TTextHighlighter>
+
+<com:InfoBox>
+Nama naskah entri tidak harus <tt>index.php</tt>. Ia dapat berupa nama apa saja selama server Web dapat mengatakan bahwa naskah adalah naskah PHP 5. Sebagai contoh, pada beberapa lingkungan hosting berbagi, seseorang mungkin perlu untuk menamai naskah sebagai <tt>index.php5</tt> agar ia bisa ditangani dengan benar oleh server the Web.
+</com:InfoBox>
+
+<h3>Konfigurasi Aplikasi</h3>
+<p>
+File XML <i>opsional</i> <tt>application.xml</tt> berisi <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.AppConfig">konfigurasi aplikasi</a>. Kegunaan utamanya adalah untuk mengkustomisasi dalam cara yang bisa mengkonfigurasi turunan aplikasi yang dibuat dalam naskah entri. Sevagai contoh, kita dapat menghidupkan fitur <a href="http://www.pradosoft.com/demos/quickstart/?page=Advanced.Logging">pencatatan</a> untuk sistem blog kita dengan bantuan konfigurasi aplikasi.
+</p>
+
+<p>
+File <tt>application.xml</tt> yang sekarang kita miliki hampir kosong. Sebenarnya kita dapat menghapusnya dengan aman karena aplikasi pada saat ini hanya menggunakan seting standar PRADO. Seiring kita ke depan, kita akan merujuk kembali secara kontan dan menampilkan bagaimana untuk mengkonfigurasi aplikasi kita dalam <tt>application.xml</tt>.
+</p>
+
+
+<h3>Homepage</h3>
+
+<p>
+Homepage (juga disebut halaman standar) <tt>Home.page</tt> adalah satu-satunya <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Pages">halaman</a> yang dibuat oleh piranti baris perintah PRADO. Berisi konten dalam file ini yang muncul dalam browser saat mengunjungi URL <tt>http://hostname/blog/index.php</tt>.
+</p>
+
+<p>
+Content in the file <tt>Home.page</tt> uses the <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.Templates1">PRADO template format</a>, which is mostly like HTML enhanced with a few PRADO-specific tags. For example, in <tt>Home.page</tt> we see the following pure HTML content:
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+<html>
+<head>
+ <title>Welcome to PRADO</title>
+</head>
+<body>
+<h1>Welcome to PRADO!</h1>
+</body>
+</html>
+</com:TTextHighlighter>
+
+
+<h2>Direktori Awal</h2>
+
+<h3>Direktori <tt>protected</tt></h3>
+
+<p>
+Direktori <tt>protected</tt>, juga dikenal sebagai <i>path basis aplikasi</i>, adalah direktori akar yang menampung halaman, template, konfigurasi, data, dll. Nama <tt>protected</tt> menunjukan bahwa direktori ini harus disembunyikan dari para pengguna Web, karena file di bawah direktori ini berisi data sensitif.
+</p>
+
+<p>
+Server Web berbeda mempunyai berbeda terhadap "melindungi" direktori. Untuk sever httpd Apache, cara termudah adalah untuk menempatkan file bernama <tt>.htaccess</tt> di bawah direktori dengan isi <tt>deny from all</tt>.
+</p>
+
+
+<h3>Direktori <tt>protected/runtime</tt> dan <tt>assets</tt></h3>
+
+<p>
+Direktori <tt>protected/runtime</tt> dan <tt>assets</tt> adalah dua direktori yang harus disetel bisa ditulisi oleh proses server Web. Direktori <tt>runtime</tt> menyimpan data sensitif (misalnya konfigurasi aplikasi yang diuraikan) yang dibuat saat menjalankan aplikasi PRADO, karena direktori <tt>assets</tt> menyimpan sumber daya yang dipublikasikan (misalnya file gambar, file javascript).
+</p>
+
+<com:InfoBox>
+Aman untuk menghapus file dan direktori di bawah <tt>protected/runtime</tt> dan <tt>assets</tt>. Sebenarnya para pengembang direkomendasikan untuk melakukan pekerjaan pembersihan ini ketika mereka memutakhirkan instalasi PRADO.
+</com:InfoBox>
+
+
+<h3>Direktori <tt>pages</tt></h3>
+
+<p>
+Direktori <tt>pages</tt> adalah <i>akar direktori halaman</i> yang menampung seluruh <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Pages">halaman</a> dalam sebuah aplikasi PRADO. Ini mirip analogi terhadap direktori <tt>htdocs</tt> pada server Web httpd Apache.
+</p>
+
+<p>
+Kita sudah melihat bagaimana cara mengakses homepage. Untuk mengakses halaman yang ditempatkan di bawah <tt>pages</tt>, menggunakan URL <tt>http://hostname/blog/index.php?page=path.ke.NamaHalaman</tt>. Berdasarkan URL ini, PRADO akan melihar halaman bernama <tt>NamaHalaman</tt> di bawah direktori <tt>pages/path/ke</tt>. URL yang kita pakai untuk mengakses homepage sebelumnya sama dengan <tt>http://hostname/blog/index.php?page=Home</tt>.
+</p>
+
+
+<h2>Kustomisasi</h2>
+
+<p>
+Dimungkinkan untuk mengkustomisasi nama dan lokasi terhadap file dan direktori yang dijelaskan di atas.
+</p>
+
+<p>
+Sebagai contoh, untuk meningkatkan keamanan, seseorang mungkin ingin memindahkan seluruh direktori <tt>protected</tt> ke tempat lain yang bukan folder Web. Untuk melakukannya, gunakan pernyataan PHP berikut untuk membuat turunan aplikasi dalam naskah entri:
+</p>
+
+<com:TTextHighlighter CssClass="source">
+$application = new TApplication( 'path/ke/protected' );
+</com:TTextHighlighter>
+
+<p>
+Untuk membuat lokasi akar direktori halaman dan mengubah nama homepage, seseorang dapat menetapkannya dalam konfigurasi aplikasi <tt>application.xml</tt> sebagai berikut:
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="xml">
+<?xml version="1.0" encoding="utf-8"?>
+<application id="blog" mode="Debug">
+ <services>
+ <service id="page"
+ class="TPageService"
+ BasePath="path.to.pages"
+ DefaultPage="NewHome"
+ />
+ </services>
+</application>
+</com:TTextHighlighter>
+
+<p>
+Setelah anda mempelajari lebih jauh mengenai PRADO, anda akan melihat bahwa PRADO adalah kerangka kerja fleksibel yang membolehkan anda untuk mengkustomisasi hampir setiap aspeknya. Kami akan menjelaskan lebih lanjut teknik kustomisasi setelah kita melanjutkan tutorial kita.
+</p>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog-tutorial/protected/pages/Day1/id/ShareLayout.page b/demos/blog-tutorial/protected/pages/Day1/id/ShareLayout.page
new file mode 100644
index 00000000..d505beed
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day1/id/ShareLayout.page
@@ -0,0 +1,180 @@
+<com:TContent ID="Main">
+
+<h1>Berbagi Tata Letak Umum</h1>
+
+<p>
+Dalam bagian ini, kita akan menggunakan fitur <a href="http://www.pradosoft.com/demos/quickstart/?page=Advanced.MasterContent">master/content</a> PRADO untuk membagi tata letak umum diantara halaman. Tata letak merujuk ke area yang sama atay sebagian besar sama untuk setelan halaman. Sebagai contoh, dalam sistem blog kita, semua halaman akan berbagi header yang sama, footer dan bar-samping yang berisi link jalan pintas. Implementasi langsung adalah untuk mengulang tata letak umum dalam setiap halaman. Akan tetapi, pendekatan ini adalah cenderung salah dan sulit untuk dipelihara. Fitur <a href="http://www.pradosoft.com/demos/quickstart/?page=Advanced.MasterContent">master/content</a> membolehkan kita untuk menggunakan tata letak umum sebagai sebuah kontrol yang memusatkan logika dan penyajian tata letak umum untuk setiap halaman.
+</p>
+
+<com:InfoBox>
+Ini juga memungkinkan untuk membagi tata letak umum melalui <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.Templates1">penyertaan template</a>, yang mirip inklusi file PHP. Akibat dari penyertaan inklusi template ini adalah bahwa ia tidak berdiri sendiri dan tidak membawa kelas untuk mengisi logika untuk tata letak umum.
+</com:InfoBox>
+
+
+<h2>Membuat Kontrol Master</h2>
+
+<p>
+Sekarang kita membuat kontrol master <tt>MainLayout</tt> untuk mewakili tata letak umum berbagi dengan halaman blog kita. Kontrol <tt>MainLayout</tt> adalah kontrol template yang diperluas dari <tt>TTemplateControl</tt>. Ini mememerlukan file template <tt>MainLayout.tpl</tt> dan sebuah file kelas <tt>MainLayout.php</tt> yang ditempatkan di bawah direktori yang sama. Guna menjembatani pemeliharaan, kita membuat direktori baru <tt>protected/layouts</tt> untuk menampungnya.
+</p>
+
+<img src="<%~ directories3.gif %>" class="output" />
+
+<p>
+Untuk saat ini, <tt>MainLayout</tt> hanya berisi header dan footer sederhana, seperti ditampilkan berikut ini. Kedepan, kita akan menambahkan bar-samping. Para pembaca juga disarankan untuk meningkatkan tata letak dengan fitur yang lainnya.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+<html>
+&lt;com:THead />
+<body>
+&lt;com:TForm>
+<div id="page">
+
+<div id="header">
+<h1>My PRADO Blog</h1>
+</div>
+
+<div id="main">
+&lt;com:TContentPlaceHolder ID="Main" />
+</div>
+
+<div id="footer">
+&lt;%= PRADO::poweredByPrado() %>
+</div>
+
+</div>
+&lt;/com:TForm>
+</body>
+</html>
+</com:TTextHighlighter>
+
+<p>
+Contoh di atas memperlihatkan konten dalam file template <tt>MainLayout.tpl</tt>. Tiga tag baru ini dipakai:
+</p>
+<ul>
+<li><tt>&lt;com:TContentPlaceHolder&gt;</tt> mewakili kontrol <a href="http://www.pradosoft.com/docs/classdoc/TContentPlaceHolder">TContentPlaceHolder</a>. Ia menyimpan tempat dalam template di mana konten akan ditempatkan. Di sini, konten datang dari halaman yang menggunakan kontrol master ini.</li>
+<li><tt>&lt;com:THead&gt;</tt> mewakili kontrol <a href="http://www.pradosoft.com/docs/classdoc/THead">THead</a> yang menyajikan tag &lt;head&gt; dalam HTML. Ia membolehkan PRADO untuk memanipulasi tag &lt;head&gt; sebagai sebuah komponen (misalnya setelan judul halaman, menambahkan gaya CSS kustom.)</li>
+<li><tt>&lt;%= %&gt;</tt> adalah sebuah <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.Templates2#et">tag ekspresi</a>. Ia menampilkan hasil evaluasi daru ekspresi yang dikurung di tempat di mana ia muncul.</li>
+</ul>
+
+<p>
+File kelas <tt>MainLayout.php</tt> sangat sederhana:
+</p>
+
+<com:TTextHighlighter CssClass="source">
+<?php
+class MainLayout extends TTemplateControl
+{
+}
+?>
+</com:TTextHighlighter>
+
+<com:InfoBox>
+Nama ekstensi file untuk template halaman <tt>.page</tt>, sementara untuk template non-halaman yaitu <tt>.tpl</tt>. Ini untuk membedakan halaman dari kontrol lain. Keduanya menggunakan <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.Templates1">sintaks template</a> yang sama. Untuk halaman, file kelasnya adalah opsional (standarnya <tt>TPage</tt>), sementara untuk kontrol non-halaman, file kelasnya adalah mandatori. Mirip dengan Java, nama file kelas harus sama seperti nama kelas. Harap berhati-hati mengenai sensitifitas-huruf pada sistem Linux/Unix.
+</com:InfoBox>
+
+
+<h2>Menggunakan Kontrol Master</h2>
+<p>
+Untuk menggunakan kontrol master yang baru saja dibuat, kita akan memodifikasi <tt>Home.page</tt> dan <tt>Contact.page</tt>. Dalam keadaan tertentu, kita perlu untuk menghapus header dan footer darinya karena kontrol master akan bertanggung jawab untuk menampilkannya; dan kita perlu memberitahu dua halaman di mana mereka harus menggunakan <tt>MainLayout</tt> sebagai masternya.
+</p>
+
+<p>
+Kode berikut memperlihatkan konten dalam <tt>Contact.page</tt> setelah perubahan:
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+&lt;%@ MasterClass="Application.layouts.MainLayout" Title="My Blog - Contact" %>
+
+&lt;com:TContent ID="Main">
+
+<h1>Contact</h1>
+<p>Please fill out the following form to let me know your feedback on my blog. Thanks!</p>
+
+...kotak teks dan validator untuk nama pengguna...
+
+...kotak teks dan validator untuk emali pengguna...
+
+...kotak teks dan validator untuk konten umpan balik...
+
+&lt;com:TButton Text="Submit" OnClick="submitButtonClicked" />
+
+&lt;/com:TContent>
+</com:TTextHighlighter>
+
+<p>
+Konten yang dikurung di dalam tag <tt>&lt;com:TContent&gt;</tt> tag akan disisipkan ke dalam tempat yang disiapkan oleh <tt>&lt;com:TContentPlaceHolder&gt;</tt> pada template master.
+</p>
+
+<com:InfoBox>
+Dimungkinkan untuk memiliki multipel <tt>TContentPlaceHolder</tt> dalam sebuah template master dan multipel <tt>TContent</tt> dakan tenokate konten. Mereka saling dipasangkan dengan nilai <tt>ID</tt>-nya. Juga dimungkinkan untuk membuat template konten menjadi master template konten lainnya dengan menempatkan <tt>TContentPlaceHolder</tt> di pembentuk. Ini disebut <i>master berulang</i>.
+</com:InfoBox>
+
+<p>
+Selain <tt>&lt;com:TContent&gt;</tt>, kita juga melihat tag baru lain <tt>&lt;%@ %&gt;</tt> di atas, yang disebut <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.Templates1#tct">tag kontrol template</a>. Ia berisi pasangan nama-nilai yang dipakai untuk menginisialisasi properti terkait bagi pemilik template, yaitu, halaman <tt>Contact</tt>.
+</p>
+
+<p>
+Dengan menyetel properti <tt>MasterClass</tt> sebagai <tt>Application.layouts.MainLayout</tt>, kita menginstruksikan halaman <tt>Contact</tt> untuk menggunakan <tt>MainLayout</tt> sebagai masternya. Di sini, kita sedang menggunakan <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Components">format namespace</a> untuk merujuk ke kelas <tt>MainLayout</tt>.
+</p>
+
+<com:InfoBox>
+Format namespace sebagian besar dipakai dalam pemrograman PRADO. Dipakai bersama dengan <a href="http://www.pradosoft.com/demos/quickstart/index.php?page=Fundamentals.Components">alias path</a>. PRADO mendefinisikan dua alias path: <tt>System</tt> merujuk ke direktori <tt>framework</tt> pada instalasi PRADO, dan <tt>Application</tt> merujuk ke direktori <tt>protected</tt>. Namespace <tt>Application.layouts.MainLayout</tt> selanjutnya bisa diterjemahkan sebagai <tt>protected/layouts/MainLayout</tt> yang tepatnya adalah nama file (tanpa ekstensi <tt>.php</tt>) untuk kelas <tt>MainLayout</tt>.
+</com:InfoBox>
+
+
+<h2>Cara Alternatif Menetapkan Master</h2>
+
+<p>
+Ada beberapa cara tambahan untuk menetapkan kelas master untuk sebuah halaman.
+</p>
+
+<p>
+Kita dapat menetapkan master dalam kode seperti berikut untuk menghidupkan perubahan dinamis terhadap tata letak:
+</p>
+
+<com:TTextHighlighter CssClass="source">
+<?php
+class Contact extends TPage
+{
+ public function onPreInit($param)
+ {
+ parent::onPreInit($param);
+ $this->MasterClass='Path.To.NewLayout';
+ }
+
+ // ...
+}
+?>
+</com:TTextHighlighter>
+
+<p>
+Dalam contoh di atas, kita menetapkan <tt>MasterClass</tt> dalam metode <tt>onPreInit()</tt> yang diturunkan dari <tt>TPage</tt>. Metode dipanggil oleh PRADO langsung setelah turunan halaman dibuat. Selanjutnya kita dapat menentukan secara dinamis tata letak yang dipakai saat halaman diminta. Sebagai contoh, ketika halaman yang diminta oleh pengguna terdaftar kita memakai tata letak A, dan tata letak B dipakai jika pengguna tamu yang meminta halaman.
+</p>
+
+<p>
+Kita juga dapat menetapkan master dalam <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.AppConfig">konfigurasi aplikasi</a> atau <a href="http://www.pradosoft.com/demos/quickstart/?page=Configurations.PageConfig">konfigurasi halaman</a>. Kode berikut memperlihatkan konfigurasi aplikasi yang dimutakhirkan untuk sistem blog kita:
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="xml">
+<?xml version="1.0" encoding="utf-8"?>
+<application id="blog" mode="Debug">
+ <!-- konfigurasi untuk layanan yang tersedia -->
+ <services>
+ <service id="page" class="TPageService" DefaultPage="Home">
+ <!-- initial properties set for all pages -->
+ <pages MasterClass="Application.layouts.MainLayout" />
+ </service>
+ </services>
+</application>
+</com:TTextHighlighter>
+
+<p>
+Dengan melakukan demikian, kita menghindari kesulitan pada penetapan master dalam setiap template halaman. Jika kita memutuskan untuk menggunakan master yang berbeda untuk halaman, kita hanya perlu mengubah konfigurasi aplikasi. Untuk alasan ini, dalam sistem blog kita, kita akan menggunakan pendekatan untuk menetapkan master.
+</p>
+
+<com:InfoBox>
+Ada urutan yang menentukan master yang mana yang sebenarnya diterapkan ketika ia ditetapkan dalam tempat multipel. Dalam keadaan tertentu, <tt>onPreInit()</tt> diambil lebih dulu di atas template halaman di atas konfigurasi aplikasi/halaman. Oleh karena itu, jika kita menetapkan <tt>MainLayout</tt> dalam konfigurasi aplikasi/halaman dan kita menetapkan <tt>SpecialLayout</tt> dalam <tt>Contact.page</tt>, master yang efektif adalah yang terakhir.
+</com:InfoBox>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog-tutorial/protected/pages/Day1/id/directories.gif b/demos/blog-tutorial/protected/pages/Day1/id/directories.gif
new file mode 100644
index 00000000..884e15bc
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day1/id/directories.gif
Binary files differ
diff --git a/demos/blog-tutorial/protected/pages/Day1/id/directories2.gif b/demos/blog-tutorial/protected/pages/Day1/id/directories2.gif
new file mode 100644
index 00000000..edf264d0
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day1/id/directories2.gif
Binary files differ
diff --git a/demos/blog-tutorial/protected/pages/Day1/id/directories3.gif b/demos/blog-tutorial/protected/pages/Day1/id/directories3.gif
new file mode 100644
index 00000000..3451935f
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day1/id/directories3.gif
Binary files differ
diff --git a/demos/blog-tutorial/protected/pages/Day1/id/output.gif b/demos/blog-tutorial/protected/pages/Day1/id/output.gif
new file mode 100644
index 00000000..9ad2bfb8
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day1/id/output.gif
Binary files differ
diff --git a/demos/blog-tutorial/protected/pages/Day2/id/ConnectDB.page b/demos/blog-tutorial/protected/pages/Day2/id/ConnectDB.page
new file mode 100644
index 00000000..7d535293
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day2/id/ConnectDB.page
@@ -0,0 +1,46 @@
+<com:TContent ID="Main">
+
+<h1>Melakukan Koneksi DB</h1>
+
+<p>
+Untuk menggunakan database yang baru saja kita buat, pertama kita perlu melaksanakan koneksinya.
+</p>
+
+<p>
+Kita akan menggunakan <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.DAO">Data Access Objects (DAO)</a> untuk memisahkan mekanisme akses data kita. Jika nanti kita menggunakan DBMS yang berbeda (misalnya PostgreSQL, Oracle) untuk menyimpan data blog, kita hanya perlu mengubah nama sumber database atau data source nama (DSN) dam kita dapat menjaga kode PHP kita tetap utuh.
+</p>
+
+<com:NoteBox>
+Untuk menggunakan DAO, anda harus menginstalasi dan menghidupkan <a href="http://www.php.net/manual/en/ref.pdo.php">ekstensi PDO PHP</a> <i>dan</i> driver PDO spesifik-database (dalam kasus kita, itu adalah driver SQLite PDO). Ini bisa dilakukan secara mudah pada Windows dengan mengubah file <tt>php.ini</tt>, menambahkan baris berikut:
+<com:TTextHighlighter CssClass="source">
+extension=php_pdo.dll
+extension=php_pdo_sqlite.dll
+</com:TTextHighlighter>
+</com:NoteBox>
+
+<p>
+Selanjutnya untuk memisahkan tabel database sebenarnya, kita juga akan menggunakan fitur <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.ActiveRecord">Rekaman Aktif</a> (AR). Setiap rekaman data akan disajikan sebagai obyek Rekaman Aktif yang mampu melakukan query, menyimpan dan menghapus tanpa menulis pernyataan SQL.
+</p>
+
+<p>
+Kita memodifikasi file konfigurasi aplikasi kita <tt>protected/application.xml</tt> dengan menyisipkan baris berikut, yang memberitahu Rekaman Aktif bagaimana untuk menghubungkan ke database yang baru saja kita buat:
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="xml">
+<modules>
+ <module id="db" class="System.Data.TDataSourceConfig">
+ <database ConnectionString="sqlite:protected/data/blog.db" />
+ </module>
+ <module class="System.Data.ActiveRecord.TActiveRecordConfig" ConnectionID="db" />
+</modules>
+</com:TTextHighlighter>
+
+<p>
+Konfigurasi di atas memperlihatkan bahwa kita menambahkan dua <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Modules">modul</a> pada aplikasi kita. Modul <tt>TDataSourceConfig</tt> dikonfigurasi dengan string koneksi <tt>sqlite:protected/data/blog.db</tt> yang mengarah ke SQLite database kita. Koneksi ini dipakai oleh modul <tt>TActiveRecordConfig</tt> yang dibutuhkan leh Rekaman Aktif.
+</p>
+
+<com:InfoBox>
+Seseorang dapat menyiapkan dua atau lebih koneksi DB dalam konfigurasi aplikasi. Untuk lebih jelasnya, lihat <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.ActiveRecord">DOkumentasi Rekaman Aktif</a>. Dan tentunya, seseorang juga bisa secara eksplisit membuat koneksi DB dalam kode PHP menggunakan komponen <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.DAO">TDbConnection</a> dalam PDO.
+</com:InfoBox>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog-tutorial/protected/pages/Day2/id/CreateAR.page b/demos/blog-tutorial/protected/pages/Day2/id/CreateAR.page
new file mode 100644
index 00000000..533825c6
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day2/id/CreateAR.page
@@ -0,0 +1,178 @@
+<com:TContent ID="Main">
+
+<h1>Membuat Kelas Rekaman Aktif</h1>
+
+<p>
+Kita perlu membuat dua kelas <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.ActiveRecord">Rekaman Aktif</a>, <tt>UserRecord</tt> dan <tt>PostRecord</tt>, masing-masing untuk mewakili rekaman data dalam tabel <tt>users</tt> dan <tt>posts</tt>. Kelas Rekaman Aktif harus diperluas dari kelas basis <tt>ActiveRecord</tt>, dan harus mendefinisikan nama properti yang sama dengan nama field dari tabel terkait.
+</p>
+
+<p>
+Untuk mengatur lebih baik direktori, kita membuat direktori baru <tt>protected/database</tt> guna menampung file kelas. Kita juga memodifikasi konfigurasi aplikasi kita dengan menyisipkan baris berikut. Ini sama dengan menambahkan direktori <tt>protected/database</tt> ke PHP include_path, yang membolehkan kita untuk menggunakan kelas tanpa secara eksplisit menyertakannya.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="xml">
+<paths>
+ <using namespace="Application.database.*" />
+</paths>
+</com:TTextHighlighter>
+
+<p>
+Daripada menulis kelas secara manual, kita akan menggunakan <a href="http://www.pradosoft.com/demos/quickstart/?page=GettingStarted.CommandLine">piranti baris perintah PRADO</a> lagi untuk membuat kelas bagi kita.
+</p>
+
+<p>
+Di bawah direktori <tt>blog</tt>, jalankan perintah berikut untuk masuk ke dalam mode interaktif pada piranti baris perintah:
+</p>
+
+<com:TTextHighlighter CssClass="source cli">
+php path/ke/prado-cli.php shell .
+</com:TTextHighlighter>
+
+<p>
+Kita akan melihat
+</p>
+
+<com:TTextHighlighter CssClass="source cli">
+Command line tools for Prado 3.1.0.
+** Loaded PRADO appplication in directory "protected".
+PHP-Shell - Version 0.3.1
+(c) 2006, Jan Kneschke <jan@kneschke.de>
+
+>> use '?' to open the inline help
+
+>>
+</com:TTextHighlighter>
+
+<p>
+Pada prompt, masukkan dua perintah berikut untuk membuat kelas <tt>UserRecord</tt> dan <tt>PostRecord</tt>:
+</p>
+
+<com:TTextHighlighter CssClass="source cli">
+>> generate users Application.database.UserRecord
+
+>> generate posts Application.database.PostRecord
+</com:TTextHighlighter>
+
+<p>
+Di sini kita menggunakan <a href="http://www.pradosoft.com/demos/quickstart/?page=Fundamentals.Components">format namespace</a> lagi untuk menetapkan kelas yang dibuat. Path <tt>Application.database.UserRecord</tt> menunjukan bahwa kita ingin file kelas <tt>UserRecord</tt> menjadi <tt>protected/database/UserRecord.php</tt>.
+</p>
+
+<p>
+Kita akan melihat struktur direktori berikut dengan dua file baru di bawah <tt>protected/database</tt>:
+</p>
+
+<img src="<%~ directories2.gif %>" class="output" />
+
+<p>
+Jika kita memeriksa file kelas <tt>PostRecord</tt> , kita akan melihat konten berikut.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="php">
+class PostRecord extends TActiveRecord
+{
+ const TABLE='posts';
+ public $post_id;
+ public $author_id;
+ public $create_time;
+ public $title;
+ public $content;
+ public $status;
+
+ public static function finder($className=__CLASS__)
+ {
+ return parent::finder($className);
+ }
+}
+</com:TTextHighlighter>
+
+<p>
+Seperti kita lihat, untuk setiap field dalam tabel <tt>posts</tt>, kelas mempunyai anggota data terkait. Konstan <tt>TABLE</tt> menetapkan nama tabel untuk <tt>PostRecord</tt>. Metode statis <tt>finder()</tt> membolehkan kita melakukan query dan mengambil data tulisan dalam batasan obyek <tt>PostRecord</tt>.
+</p>
+
+<p>
+Kita dapat menggunakan piranti baris perintah untuk melakukan beberapa pengujian dengan kelas Rekaman Aktif yang baru saja kita buat. Masih dalam mode interaktif pada piranti baris perintah, kita memasukan pernyataan PHP dan seharusnya melihat kode berikut. Para pembaca yang tertarik dapat mencoba pernyataan PHP laninnya, seperti misalnya <tt>UserRecord::finder()->findAll()</tt>.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="php">
+>> PostRecord::finder()->findAll()
+array
+(
+ [0] => PostRecord#1
+ (
+ [post_id] => '1'
+ [author_id] => 'admin'
+ [create_time] => '1175708482'
+ [title] => 'first post'
+ [content] => 'this is my first post'
+ [status] => '0'
+ [TActiveRecord:_readOnly] => false
+ [TActiveRecord:_connection] => null
+ [TComponent:_e] => array()
+ )
+)
+</com:TTextHighlighter>
+
+<h1>Hubungan Antara Tulisan dan Pengguna</h1>
+<p>
+Mengingat bahwa ada hubungan kunci asing antara tabel <tt>users</tt> dan <tt>posts</tt>. Diagram hubungan-entitas ditampilkan di bawah ini demi kenyamanan.
+</p>
+
+<img src="<%~ ER.gif %>" class="output" />
+
+<p>
+Dari diagram hubungan-entitas di atas, kita merlihat bahwa tabel <tt>posts</tt> berisi field bernama <tt>author_id</tt>. Field <tt>author_id</tt> ini adalah kunci asing yang mereferensi tabel <tt>users</tt>. Dalam keadaan tertentu, nilai dalam field <tt>author_id</tt> seharusnya dari tabel <tt>users</tt> field <tt>username</tt>. Salah satu konsekuensi dari hubungan ini, dalam pola pikir obyek, adalah bahwa setiap "tulisan" milik "author" dan satu "author" dapat memiliki banyak "tulisan".
+</p>
+
+<p>
+Kita dapat membuat model hubungan antara tabel <tt>posts</tt> dan <tt>users</tt> dalam Rekaman Aktif dengan memodifikasi kelas <tt>PostRecord</tt> dan <tt>UserRecord</tt> seperti berikut.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="php">
+class PostRecord extends TActiveRecord
+{
+ //... properti dan metode seperti seblumnya
+
+ public $author; //menampung array UserRecord
+
+ protected static $RELATIONS=array
+ (
+ 'author' => array(self::BELONGS_TO, 'UserRecord'),
+ );
+}
+</com:TTextHighlighter>
+
+<p>
+Properti statis <tt>$RELATIONS</tt> pada <tt>PostRecord</tt> mendefinisikan bahwa properti <tt>$author</tt> dimiliki <tt>UserRecord</tt>. Dalam <tt>array(self::BELONGS_TO, 'UserRecord')</tt>, elemen pertama mendefinisikan tipe hubungan, dalam hal ini <tt>self::BELONGS_TO</tt>. Elemen kedua adalah nama pada rekaman terkait, dalam hal ini <tt>UserRecord</tt>. <tt>UserRecord</tt> didefinisikan sama di bawah ini, perbedaannya yaitu rekaman pengguna mempunyai banyak <tt>PostRecord</tt>.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="php">
+class UserRecord extends TActiveRecord
+{
+ //... properti dan metode seperti seblumnya
+
+ public $posts=array(); //menampung array PostRecord
+
+ protected static $RELATIONS=array
+ (
+ 'posts' => array(self::HAS_MANY, 'PostRecord'),
+ );
+}
+</com:TTextHighlighter>
+
+<p>
+Sebuah array <tt>UserRecord</tt> dengan dan tulisan terkaitnya dapat diambil seperti berikut.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="php">
+$users = UserRecord::finder()->withPosts()->findAll();
+</com:TTextHighlighter>
+
+<com:TipBox>
+Metode <tt>withXXX()</tt> (di mana XXX adalah nama properti hubungan, dalam hal ini, <tt>Posts</tt>) mengambil <tt>PostRecords</tt> terkait menggunakan query kedua (tidak dengan menggunakan join). Metode <tt>withXXX()</tt> menerima argumen yang sama sebagai finder lain dari TActiveRecord, misalhnya <tt>withPosts('status = ?', 0)</tt>.
+</com:TipBox>
+
+<p>
+Dokumentasi lengkap selanjutnya dapat ditemukan dalam dokumen quickstart <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.ActiveRecord">Rekaman Aktif</a>.
+</p>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog-tutorial/protected/pages/Day2/id/CreateDB.page b/demos/blog-tutorial/protected/pages/Day2/id/CreateDB.page
new file mode 100644
index 00000000..30868268
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day2/id/CreateDB.page
@@ -0,0 +1,69 @@
+<com:TContent ID="Main">
+
+<h1>Membuat Database</h1>
+
+<p>
+Banyak aplikasi Web menggunakan database untuk memelihara datanya. Sistem blog kita tidak terkecuali. Dalam bagian ini, kami akan menjelaskan bagaimana untuk menulis halaman kendali-database untuk sistem blog kita. Kita akan menggunakan teknik termasuk <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.DAO">database access object (DAO)</a> dan <a href="http://www.pradosoft.com/demos/quickstart/?page=Database.ActiveRecord">Rekaman Aktif</a>.
+</p>
+
+<p>
+Untuk keperluan tutorial, kita menyederhanakan kebutuhan sistem blog kita agar hanya perlu berhadapan dengan pengguna dan data tulisan. Selanjutnya kita membuat dua tabel database, <tt>users</tt> dan <tt>posts</tt>, seperti diperlihatkan dalam duagram hubungan entitas atau entity-relationship (ER) di bawah ini.
+</p>
+
+<img src="<%~ ER.gif %>" class="output" />
+
+<p>
+Kita menggunakan SQLite 3 database untuk menyimpan data kita. Pertama kita ubah diagram ER ke dalam pernyataan SQL berikut dan menyimpannya dalam file <tt>protected/schema.sql</tt>.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="sql">
+/* buat tabel pengguna */
+CREATE TABLE users (
+ username VARCHAR(128) NOT NULL PRIMARY KEY,
+ email VARCHAR(128) NOT NULL,
+ password VARCHAR(128) NOT NULL, /* dalam teks biasa */
+ role INTEGER NOT NULL, /* 0: pengguna normal, 1: administrator */
+ first_name VARCHAR(128),
+ last_name VARCHAR(128)
+);
+
+/* buat tabel tulisan */
+CREATE TABLE posts (
+ post_id INTEGER NOT NULL PRIMARY KEY,
+ author_id VARCHAR(128) NOT NULL
+ CONSTRAINT fk_author REFERENCES users(username),
+ create_time INTEGER NOT NULL, /* cap waktu UNIX */
+ title VARCHAR(256) NOT NULL, /* judul tulisan */
+ content TEXT, /* badan tulisan */
+ status INTEGER NOT NULL /* 0: diterbitkan; 1: draft; 2: ditunda; 2: ditolak */
+);
+
+/* sisipkan beberapa rekaman data awal untuk pengujian */
+INSERT INTO users VALUES ('admin', 'admin@example.com', 'demo', 1, 'Qiang', 'Xue');
+INSERT INTO users VALUES ('demo', 'demo@example.com', 'demo', 0, 'Wei', 'Zhuo');
+INSERT INTO posts VALUES (NULL, 'admin', 1175708482, 'first post', 'this is my first post', 0);
+</com:TTextHighlighter>
+
+<com:NoteBox>
+Batasan <tt>fk_author</tt> diabaikan oleh SQLite karena tidak mendukung <a href="http://www.sqlite.org/omitted.html">batasan kunci asing</a>. Meskipun demikian, kita masih memelihara batasan di sana untuk kemampuan pemindahan sistem blog kita ke DBMS yang berbeda. Juga, dalam contoh di atas kita mengeksploitasi bukti bahwa field <tt>posts.post_id</tt> adalah <a href="http://www.sqlite.org/autoinc.html">auto-incremental</a> jika kita menempatkan NULL untuk nilainya.
+</com:NoteBox>
+
+<p>
+Kemudian kita menggunakan <a href="http://www.sqlite.org/download.html">piranti baris perintah SQLite</a> untuk membuat SQLite database. Kita membuat sebuah direktori <tt>protected/data</tt> untuk menampung file database SQLite. Sekarang kita menjalankan perintah berikut di bawah direktori <tt>protected/data</tt>:
+</p>
+
+<com:TTextHighlighter CssClass="source cli">
+sqlite3 blog.db < ../schema.sql
+</com:TTextHighlighter>
+
+<p>
+Database sudah dibuat sebagai <tt>protected/data/blog.db</tt> dan kita akan melihat direktori dan file berikut:
+</p>
+
+<img src="<%~ directories.gif %>" class="output" />
+
+<com:NoteBox>
+SQLite memerlukan direktori <tt>protected/data</tt> dan file database <tt>protected/data/blog.db</tt> keduanya disetel agar bisa ditulisi oleh proses server Web.
+</com:NoteBox>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/blog-tutorial/protected/pages/Day2/id/ER.gif b/demos/blog-tutorial/protected/pages/Day2/id/ER.gif
new file mode 100644
index 00000000..7a5397b3
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day2/id/ER.gif
Binary files differ
diff --git a/demos/blog-tutorial/protected/pages/Day2/id/directories.gif b/demos/blog-tutorial/protected/pages/Day2/id/directories.gif
new file mode 100644
index 00000000..797ef932
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day2/id/directories.gif
Binary files differ
diff --git a/demos/blog-tutorial/protected/pages/Day2/id/directories2.gif b/demos/blog-tutorial/protected/pages/Day2/id/directories2.gif
new file mode 100644
index 00000000..b053b4c6
--- /dev/null
+++ b/demos/blog-tutorial/protected/pages/Day2/id/directories2.gif
Binary files differ