diff options
Diffstat (limited to 'demos/blog-tutorial/protected/pages/Day4/id')
-rw-r--r-- | demos/blog-tutorial/protected/pages/Day4/id/CreateEditPost.page | 133 | ||||
-rw-r--r-- | demos/blog-tutorial/protected/pages/Day4/id/CreateListPost.page | 185 | ||||
-rw-r--r-- | demos/blog-tutorial/protected/pages/Day4/id/CreateNewPost.page | 136 | ||||
-rw-r--r-- | demos/blog-tutorial/protected/pages/Day4/id/CreateReadPost.page | 135 | ||||
-rw-r--r-- | demos/blog-tutorial/protected/pages/Day4/id/Overview.page | 26 | ||||
-rw-r--r-- | demos/blog-tutorial/protected/pages/Day4/id/directories.gif | bin | 0 -> 11129 bytes | |||
-rw-r--r-- | demos/blog-tutorial/protected/pages/Day4/id/output.gif | bin | 0 -> 3406 bytes | |||
-rw-r--r-- | demos/blog-tutorial/protected/pages/Day4/id/output2.gif | bin | 0 -> 6326 bytes | |||
-rw-r--r-- | demos/blog-tutorial/protected/pages/Day4/id/output3.gif | bin | 0 -> 11874 bytes | |||
-rw-r--r-- | demos/blog-tutorial/protected/pages/Day4/id/output4.gif | bin | 0 -> 11916 bytes |
10 files changed, 615 insertions, 0 deletions
diff --git a/demos/blog-tutorial/protected/pages/Day4/id/CreateEditPost.page b/demos/blog-tutorial/protected/pages/Day4/id/CreateEditPost.page new file mode 100644 index 00000000..b7ded3b3 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day4/id/CreateEditPost.page @@ -0,0 +1,133 @@ +<com:TContent ID="Main">
+
+<h1>Membuat Halaman <tt>EditPost</tt></h1>
+
+<p>
+Halaman <tt>EditPost</tt> disediakan bagi para pembuat dan administrator untuk mengedit tulisan blog yang sudah ada. Seperti halaman <a href="?page=Day4.CreateNewPost">NewPost</a> , ia menampilkan sebuah formulir untuk mengumpulkan perubahan terhadap judul dan konten tulisan.
+</p>
+
+<p>
+Kita membuat dua file <tt>protected/pages/posts/EditPost.page</tt> dan <tt>protected/pages/posts/EditPost.php</tt> masing-masing untuk menyimpan template halaman dan kelas halaman.
+</p>
+
+<h2>Membuat Template Halaman</h2>
+<p>
+Template halaman <tt>EditPost</tt> sangat mirip dengan template <tt>NewPost</tt>. Hanya judul halaman dan tombol yang berbeda.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+<%@ Title="My Blog - Edit Post" %>
+
+<com:TContent ID="Main">
+
+<h1>Edit Post</h1>
+
+<span>Title:</span>
+<com:TRequiredFieldValidator
+ ControlToValidate="TitleEdit"
+ ErrorMessage="Please provide a title."
+ Display="Dynamic" />
+<br/>
+<com:TTextBox ID="TitleEdit" Columns="50" />
+
+<br/>
+<span>Content:</span>
+<com:TRequiredFieldValidator
+ ControlToValidate="ContentEdit"
+ ErrorMessage="Please provide content."
+ Display="Dynamic" />
+<br/>
+<com:THtmlArea ID="ContentEdit" />
+
+<br/>
+<com:TButton Text="Save" OnClick="saveButtonClicked" />
+
+</com:TContent>
+</com:TTextHighlighter>
+
+
+<h2>Membuat Kelas Halaman</h2>
+
+<p>
+Kelas halaman <tt>EditPage</tt> lebih kompleks dibanding <tt>NewPage</tt> karena ia perlu mengambil data tulisan yang ditetapkan terlebih dulu. Ia juga perlu melakukan pemeriksaan otorisasi tambahan. Ada kalanya ia perlu memastikan bahwa tulisan hanya bisa diedit oleh pembuat atau administrator. Pemeriksaan otorisasi sudah disediakan oleh PRADO.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="php">
+class EditPost extends TPage
+{
+ /**
+ * Menginisialisasi input dengan data tulisan yang sudah ada.
+ * Metode ini dipanggil oleh kerangka kerja saat halaman diinisialisasi.
+ * @param parameter event campuran
+ */
+ public function onInit($param)
+ {
+ parent::onInit($param);
+ // Menambil data pengguna yang sudah ada. Ini sama dengan:
+ // $postRecord=$this->getPost();
+ $postRecord=$this->Post;
+ // Pemeriksaan otorisasi: hanya pembuat atau administrator dapat mengedit tulisan
+ if($postRecord->author_id!==$this->User->Name && !$this->User->IsAdmin)
+ throw new THttpException(500,'You are not allowed to edit this post.');
+
+ if(!$this->IsPostBack) // jika halaman pertama kali diminta
+ {
+ // Mempopulasikan kontrol input dengan data tulisan yang sudah ada
+ $this->TitleEdit->Text=$postRecord->title;
+ $this->ContentEdit->Text=$postRecord->content;
+ }
+ }
+
+ /**
+ * Menyimpan tulisan jika semua input sudah benar.
+ * Metode ini merespon event OnClick pada tombol "Save".
+ * @param pengirim event campuran
+ * @param parameter event campuran
+ */
+ public function saveButtonClicked($sender,$param)
+ {
+ if($this->IsValid) // jika semua validasi sukses
+ {
+ // Mengambil data pengguna yang sudah ada. Ini sama dengan:
+ // $postRecord=$this->getPost();
+ $postRecord=$this->Post;
+
+ // Mengambil data input
+ $postRecord->title=$this->TitleEdit->SafeText;
+ $postRecord->content=$this->ContentEdit->SafeText;
+
+ // menyimpan ke database via mekanisme Rekaman Aktif
+ $postRecord->save();
+
+ // mengalihkan browser ke halaman ReadPost
+ $url=$this->Service->constructUrl('posts.ReadPost',array('id'=>$postRecord->post_id));
+ $this->Response->redirect($url);
+ }
+ }
+
+ /**
+ * Mengembalikan data tulisan yang akan diedit.
+ * @return PostRecord data tulisan yang akan diedit.
+ * @throws THttpException jika data tulisan tidak ada.
+ */
+ protected function getPost()
+ {
+ // ID tulisan yang diedit dikirimkan via parameter GET 'id'
+ $postID=(int)$this->Request['id'];
+ // gunakan Rekaman Aktif untuk mencari ID tulisan tertentu
+ $postRecord=PostRecord::finder()->findByPk($postID);
+ if($postRecord===null)
+ throw new THttpException(500,'Post is not found.');
+ return $postRecord;
+ }
+}
+</com:TTextHighlighter>
+
+<h2>Pengujian</h2>
+<p>
+Untuk menguji halaman <tt>EditPost</tt>, masuk lebih dulu dan kemudian kunjungi URL berikut: <tt>http://hostname/blog/index.php?page=EditPost&id=1</tt>. URL ini juga bisa dijangkau dengan mengklik link <tt>Edit</tt> pada halaman rician tulisan.
+</p>
+
+<img src="<%~ output4.gif %>" class="output" />
+
+</com:TContent>
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/id/CreateListPost.page b/demos/blog-tutorial/protected/pages/Day4/id/CreateListPost.page new file mode 100644 index 00000000..d682535e --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day4/id/CreateListPost.page @@ -0,0 +1,185 @@ +<com:TContent ID="Main">
+
+<h1>Membuat Halaman <tt>ListPost</tt></h1>
+
+<p>
+Halaman <tt>ListPost</tt> menampilkan tulisan blog terakhir dalam sebuah daftar. Jika di sana terlalu banyak tulisan, maka akan ditampilkan dalam beberapa lembar halaman.
+</p>
+
+<p>
+Sebelum kita berlanjut dengan implementasi, kita ingin mengarahkan homepage kita ke halaman <tt>ListPage</tt> mendatang, karena kita ingin para pengguna melihat tulisan terakhir saat mereka menyentuh website. Untuk melakukannya, kita mengubah konfigurasi aplikasi <tt>protected/application.xml</tt> sebagai berikut,
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="xml">
+......
+<services>
+ <service id="page" class="TPageService" DefaultPage="posts.ListPost">
+ <pages MasterClass="Application.layouts.MainLayout" />
+ </service>
+</services>
+</com:TTextHighlighter>
+
+<p>
+Sekarang kita membuat file template dan kelas untuk halaman <tt>ListPost</tt>: <tt>protected/pages/posts/ListPost.page</tt> dan <tt>protected/pages/posts/ListPost.php</tt>.
+</p>
+
+<h2>Membuat Template Halaman</h2>
+<p>
+Berdasarkan pada kebutuhan fungsionalitas halaman <tt>ListPost</tt>, kita akan menggunakan dua kontrol dalam template halaman:
+</p>
+<ul>
+<li><a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.Repeater">TRepeater</a>: kontrol ini dipakai terutama untuk menampilkan daftar atas item data. Penyajian dari setiap item data bisa ditetapkan melalui template inline atau kontrol template eksternal (pendekatan yang akan kita gunakan di sini).</li>
+<li><a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.Pager">TPager</a>: kontrol ini dipakai untuk memecah daftar item data. Ia berinteraksi dengan pengguna-akhir untuk menentukan halaman data mana yang ditampilkan dalam <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.List">kontrol daftar</a> (misalnya <tt>TListBox</tt>) pada <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.Data">kontrol data</a> (misalnya <tt>TRepeater</tt>).</li>
+</ul>
+
+<p>
+Di bawah ini adalah konten dalam template halaman:
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+<%@ Title="My Blog" %>
+
+<com:TContent ID="Main">
+
+<com:TRepeater ID="Repeater"
+ ItemRenderer="Application.pages.posts.PostRenderer"
+ AllowPaging="true"
+ AllowCustomPaging="true"
+ PageSize="5"
+ />
+
+<com:TPager ControlToPaginate="Repeater" OnPageIndexChanged="pageChanged" />
+
+</com:TContent>
+</com:TTextHighlighter>
+
+<p>
+Dalam pengulang, kita menetapkan bahwa konten yang diulang ditampilkan menggunakan penyaji item <tt>PostRenderer</tt> yang akan kita buat nantinya. Agar PRADO bisa menemukan kelas ini, kita memberikan namespace <tt>Application.pages.posts.PostRenderer</tt>, berarti file kelasnya adalah <tt>protected/pages/posts/PostRenderer.php</tt>.
+</p>
+
+<p>
+Kita juga menyetel beberapa properti lain pada pengulang untuk menghidupkan lembaran halaman. Dan kita menyetel properti <tt>ControlToPaginate</tt> pada lembaran agar ia mengetahui konten mana yang diulang harus dibuat lembaran.
+</p>
+
+
+<h2>Membuat Kelas Halaman</h2>
+
+<p>
+Dari template halaman di atas, kita melihat bahwa kita perlu menulis kelas halaman yang mengimplementasikan pengendali event: <tt>pageChanged()</tt> (ditempelkan ke event lembaran <tt>OnPageIndexChanged</tt>). Kita juga perlu mempopulasikan data tulisan ke dalam pengulang berdasarkan pada setelan lembaran saat ini. Berikut ini adalah kode sumber lengkap kelas halaman:
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="php">
+class ListPost extends TPage
+{
+ /**
+ * Menginisialisasi pengulang.
+ * Metode ini dipanggil oleh kerangka kerja saat menginisialisasi halaman
+ * @param mixed event parameter
+ */
+ public function onInit($param)
+ {
+ parent::onInit($param);
+ if(!$this->IsPostBack) // jika halaman diminta pertama kali
+ {
+ // ambil jumlah total tulisan yang tersedia
+ $this->Repeater->VirtualItemCount=PostRecord::finder()->count();
+ // populasikan data tulisan ke dalam pengulang
+ $this->populateData();
+ }
+ }
+
+ /**
+ * Pengendali event untuk event OnPageIndexChanged pada lembaran.
+ * Metode ini dipanggil saat pengguna mengklik tombol halaman
+ * dan kemudian mengubah halaman tulisan yang ditampilkan.
+ */
+ public function pageChanged($sender,$param)
+ {
+ // ubah indeks halaman sekarang ke yang baru
+ $this->Repeater->CurrentPageIndex=$param->NewPageIndex;
+ // re-populasi data ke dalam pengulang
+ $this->populateData();
+ }
+
+ /**
+ * Menentukan halaman tulisan mana yang ditampilkan dan
+ * mempopulasi pengulang dengan data yang sudah diambil.
+ */
+ protected function populateData()
+ {
+ $offset=$this->Repeater->CurrentPageIndex*$this->Repeater->PageSize;
+ $limit=$this->Repeater->PageSize;
+ if($offset+$limit>$this->Repeater->VirtualItemCount)
+ $limit=$this->Repeater->VirtualItemCount-$offset;
+ $this->Repeater->DataSource=$this->getPosts($offset,$limit);
+ $this->Repeater->dataBind();
+ }
+
+ /**
+ * Mengambil tulisan dari database dengan ofset dan limit.
+ */
+ protected function getPosts($offset, $limit)
+ {
+ // Bentuk kriteria query
+ $criteria=new TActiveRecordCriteria;
+ $criteria->OrdersBy['create_time']='desc';
+ $criteria->Limit=$limit;
+ $criteria->Offset=$offset;
+ // query untuk tulisan dengan kriteria di atas dan informasi pembuat
+ return PostRecord::finder()->withAuthor()->findAll($criteria);
+ }
+}
+</com:TTextHighlighter>
+
+<h2>Membuat <tt>PostRenderer</tt></h2>
+
+<p>
+Kita masih perlu untuk membuat kelas penyaji item <tt>PostRenderer</tt>. Ia mendefinisikan bagaimana setiap tulisan harus ditampilkan dalam pengulang. Kita membuatnya sebagai kontrol template yang membolehkan kita untuk menetapkan penyajian tulisan menggunakan sintaks template fleksibel kita. Template dan file kelas masing-masing disimpan sebagai <tt>PostRenderer.tpl</tt> dan <tt>PostRenderer.php</tt> di bawah direktori <tt>protected/pages/posts</tt>.
+</p>
+
+<h3>Membuat Template Penyaji</h3>
+<p>
+Template penyaji menetapkan penyajian berbagai field dalam sebuah tulisan, termasuk judul, nama pembuat, waktu penulisan dan kontennya. Kita me-link judul tulisan ke <tt>ReadPost</tt> yang menampilkan lebih rinci atas tulisan yang dipilih.
+</p>
+<p>
+Ekspresi <tt>$this->Data</tt> merujuk ke item data yang dikirimkan ke pengulang. Dalam kasus kita, ia adalah obyek <tt>PostRecord</tt>. Perhatikan bagaimana kita mengambil nama pembuat pada tulisan dengan <tt>$this->Data->author->username</tt>.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+<div class="post-box">
+<h3>
+<com:THyperLink Text="<%# $this->Data->title %>"
+ NavigateUrl="<%# $this->Service->constructUrl('posts.ReadPost',array('id'=>$this->Data->post_id)) %>" />
+</h3>
+
+<p>
+Author:
+<com:TLiteral Text="<%# $this->Data->author->username %>" /><br/>
+Time:
+<com:TLiteral Text="<%# date('m/d/Y h:m:sa', $this->Data->create_time) %>" />
+</p>
+
+<p>
+<com:TLiteral Text="<%# $this->Data->content %>" />
+</p>
+</div>
+</com:TTextHighlighter>
+
+<h3>Membuat Kelas Penyaji</h3>
+<p>
+Kelas penyaji sangat sederhana. Ia diperluas dari <tt>TRepeaterItemRenderer</tt> dan tidak berisi kode apapun.
+</p>
+<com:TTextHighlighter CssClass="source" Language="php">
+class PostRenderer extends TRepeaterItemRenderer
+{
+}
+</com:TTextHighlighter>
+
+<h2>Pengujian</h2>
+<p>
+Untuk menguji halaman <tt>ListPost</tt>, kunjungi URL <tt>http://hostname/blog/index.php</tt> (ingat kita telah menyetel <tt>ListPost</tt> sebagai homepage baru kita). Kita akan melihat hasil seperti berikut. Karena kita hanya mempunyai satu tulisan saat ini, lembaran tidak akan muncul. Nantinya ketika menyelesaikan <tt>NewPost</tt>, kita dapat menambah tulisan lebih banyak dan datang kembali untuk menguji lembaran halaman lagi.
+</p>
+
+<img src="<%~ output.gif %>" class="output" />
+
+</com:TContent>
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/id/CreateNewPost.page b/demos/blog-tutorial/protected/pages/Day4/id/CreateNewPost.page new file mode 100644 index 00000000..68dcde44 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day4/id/CreateNewPost.page @@ -0,0 +1,136 @@ +<com:TContent ID="Main">
+
+<h1>Membuat Halaman <tt>NewPost</tt></h1>
+
+<p>
+Halaman <tt>NewPost</tt> disediakan untuk mengotentikasi pengguna untuk pembuatan tulisan blog baru. Ia perlu untuk menampilkan formulir yang mengumpulkan informasi mengenai tulisan baru, termasuk judul tulisan dan konten badan tulisan.
+</p>
+
+<p>
+Karena <tt>NewPost</tt> hanya bisa diakses oleh pengguna terotentikasi, kita menambahkan file konfigurasi <tt>config.xml</tt> di bawah direktori <tt>protected/pages/posts</tt>. Konfigurasi menetapkan bahwa para pengguna tidak bisa mengakses <tt>NewPost</tt> dan <tt>EditPost</tt> yang akan diperkenalkan dalam bagian berikutnya.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="xml">
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <authorization>
+ <deny pages="NewPost,EditPost" users="?" />
+ </authorization>
+</configuration>
+</com:TTextHighlighter>
+
+<p>
+Karena jumlah halaman kita berkembang, kita ingin memodifikasi <tt>MainLayout</tt> agar dalam footer pada halaman blog kita ada link ke berbagai halaman, termasuk homepage, halaman <a href="?page=Day3.CreateNewUser">NewUser</a> (hanya terlihat oleh administrator), dan halaman <tt>NewPost</tt> mendatang (hanya terlihat oleh pengguna terotentikasi).
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+<div id="footer">
+<com:THyperLink Text="Home"
+ NavigateUrl="<%= $this->Service->DefaultPageUrl %>" />
+
+<com:THyperLink Text="New Post"
+ NavigateUrl="<%= $this->Service->constructUrl('posts.NewPost') %>"
+ Visible="<%= !$this->User->IsGuest %>" />
+
+<com:THyperLink Text="New User"
+ NavigateUrl="<%= $this->Service->constructUrl('users.NewUser') %>"
+ Visible="<%= $this->User->IsAdmin %>" />
+...other links...
+</div>
+</com:TTextHighlighter>
+
+<p>
+Sekarang kita membuat dua file <tt>protected/pages/posts/NewPost.page</tt> dan <tt>protected/pages/posts/NewPost.php</tt> masing-masing untuk menyimpan template halaman dan kelas halaman.
+</p>
+
+<h2>Membuat Template Halaman</h2>
+<p>
+Template halaman <tt>NewPost</tt> berisi <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.TextBox">TTextBox</a> untuk mengumpulkan judul tulisan dan <a href="http://www.pradosoft.com/demos/quickstart/?page=Controls.HtmlArea">THtmlArea</a> untuk mengumpulkan konten tulisan. Yang terakhir adalah editor HTML WYSIWYG. Guna memastikan bahwa input pengguna sudah benar, kita mengaitkan validator dengan kontrol input ini.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+<%@ Title="My Blog - New Post" %>
+
+<com:TContent ID="Main">
+
+<h1>Create New Post</h1>
+
+<span>Title:</span>
+<com:TRequiredFieldValidator
+ ControlToValidate="TitleEdit"
+ ErrorMessage="Please provide a title."
+ Display="Dynamic" />
+<br/>
+<com:TTextBox ID="TitleEdit" Columns="50" />
+
+<br/>
+<span>Content:</span>
+<com:TRequiredFieldValidator
+ ControlToValidate="ContentEdit"
+ ErrorMessage="Please provide content."
+ Display="Dynamic" />
+<br/>
+<com:THtmlArea ID="ContentEdit" />
+
+<br/>
+<com:TButton Text="Create" OnClick="createButtonClicked" />
+
+</com:TContent>
+</com:TTextHighlighter>
+
+
+<h2>Membuat Kelas Halaman</h2>
+
+<p>
+Dari template halaman di atas, kita melihat bahwa sebagian besar kita perlu menulis sebuah kelas halaman yang mengimplementasikan pengendali event: <tt>createButtonClicked()</tt> (ditempelkan ke tombo <tt>Create</tt> dalam event <tt>OnClick</tt>).
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="php">
+class NewPost extends TPage
+{
+ /**
+ * Membuat tulisan baru jika semua input benar.
+ * Metode ini merespon event OnClick pada tombol "create".
+ * @param mixed event sender
+ * @param mixed event parameter
+ */
+ public function createButtonClicked($sender,$param)
+ {
+ if($this->IsValid) // bila semua validasi sukses
+ {
+ // populasikan obyek PostRecord dengan input pengguna
+ $postRecord=new PostRecord;
+ // menggunakan SafeText datipada Text guna menghindari serangan Penaskahan Situs Silang
+ $postRecord->title=$this->TitleEdit->SafeText;
+ $postRecord->content=$this->ContentEdit->SafeText;
+ $postRecord->author_id=$this->User->Name;
+ $postRecord->create_time=time();
+ $postRecord->status=0;
+
+ // simpan ke database lewat mekanisme Rekaman Aktif
+ $postRecord->save();
+
+ // alihkan browser ke halaman tulisan yang baru dibuat
+ $url=$this->Service->constructUrl('posts.ReadPost',array('id'=>$postRecord->post_id));
+ $this->Response->redirect($url);
+ }
+ }
+}
+</com:TTextHighlighter>
+
+<h2>Pengujian</h2>
+<p>
+Untuk menguji halaman <tt>NewPost</tt>, masuk lebih dulu dan klik pada link tombol <tt>New Post</tt> dalam footer pada homepage. Browser kita akan menampilkan hasil berikut dengan URL <tt>http://hostname/blog/index.php?page=NewPost</tt>.
+</p>
+
+<com:InfoBox>
+Ketika anda mengunjungi halaman <tt>NewPost</tt> untuk pertama kali, anda bisa melihat bahwa ia memerlukan beberapa detik sebelum halaman ditampilkan. Ini dikarenakan PRADO perlu mengurai dan mempublikasikan kode javascript dan gambar untuk kontrol <tt>THtmlArea</tt> yang dipakai dalam halaman. Ini dikerjakan sekali dan untuk semuanya.
+</com:InfoBox>
+
+<com:TipBox>
+Untuk menguji fitur lembaran yang kita kembangkan untuk halaman <a href="?page=Day4.CreateListPost">ListPost</a>, kita dapat membuat lima atau lebih tulisan dan melihat apa yang terjadi pada homepage. Lembar dalam <tt>ListPost</tt> menampilkan lima tulisan setiap halamannya.
+</com:TipBox>
+
+<img src="<%~ output3.gif %>" class="output" />
+
+</com:TContent>
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/id/CreateReadPost.page b/demos/blog-tutorial/protected/pages/Day4/id/CreateReadPost.page new file mode 100644 index 00000000..83c059e7 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day4/id/CreateReadPost.page @@ -0,0 +1,135 @@ +<com:TContent ID="Main">
+
+<h1>Membuat Halaman <tt>ReadPost</tt></h1>
+
+<p>
+Halaman <tt>ReadPost</tt> menampilkan rincian konten tulisan blog. Untuk para pengguna yang diotorisasi, akan ditampilkan tombol link yang membolehkan mereka untuk mengedit atau menghapus tulisan.
+</p>
+
+<p>
+Kita membuat dua file <tt>protected/pages/posts/ReadPost.page</tt> dan <tt>protected/pages/posts/ReadPost.php</tt> masing-masing untuk menyimpan template halaman dan kelas halaman.
+</p>
+
+<h2>Membuat Template Halaman</h2>
+<p>
+Template halaman <tt>ReadPost</tt> sangat mirip dengan template <tt>PostRenderer</tt>, keduanya menyajikan konten tulisan. Perbedaannya adalah bahwa <tt>ReadPost</tt> perlu menampilkan dua tombol link ketika pengguna saat ini diotorisasi untuk mengedit atau menghapus tulisan.
+</p>
+
+<com:TTextHighlighter CssClass="source" Language="prado">
+<com:TContent ID="Main">
+
+<h2>
+<com:TLiteral Text="<%= $this->Post->title %>" />
+</h2>
+
+<com:TControl Visible="<%= $this->canEdit() %>">
+ <a href="<%= $this->Service->constructUrl('EditPost',array('id'=>$this->Post->post_id))%>">Edit</a> |
+ <com:TLinkButton Text="Delete"
+ OnClick="deletePost"
+ Attributes.onclick="javascript:if(!confirm('Are you sure?')) return false;" />
+</com:TControl>
+
+<p>
+Author:
+<com:TLiteral Text="<%= $this->Post->author->username %>" /><br/>
+Time:
+<com:TLiteral Text="<%= date('m/d/Y h:m:sa', $this->Post->create_time) %>" />
+</p>
+
+<p>
+<com:TLiteral Text="<%= $this->Post->content %>" />
+</p>
+
+</com:TContent>
+</com:TTextHighlighter>
+
+<p>
+Banyak ekspresi PHP dipakai dalam template di atas. Ekspresi <tt>$this->Post</tt> merujuk ke properti yang didefinisikan dalam kelas halaman <tt>ReadPost</tt>. Ia mewakili obyek <tt>PostRecord</tt> yang terkait dengan tulisan yang saat ini sedang dilihat.
+</p>
+
+<com:InfoBox>
+Meskipun sebagian besar kita menggunakan ekspresi dalam template, we do not overuse them. A major guideline in determining whether we should use an expression in a template is that <i>the expression should be a property or a simple presentational transformation of the property</i>. By following this guideline, we ensure content and presentation are well separated without losing sufficient flexibility.
+</com:InfoBox>
+
+<p>
+Kita juga mencatatan dalam template di atas bahwa dua link tombol dikurung di dalam <tt>TControl</tt> yang penampakannya ditentukan oleh ekspresi <tt>$this->canEdit()</tt>. Untuk link tombol <tt>Delete</tt>, kita menggunakan dialog konfirmasi javascript untuk memperoleh konfirmasi pengguna saat ia mengklik untuk menghapus tulisan.
+</p>
+
+<com:InfoBox>
+Seluruh kontrol PRADO mempunyai properti yang sangat berguna bernama <tt>Attributes</tt> yang dapat menerima pasangan nama-nilai bebas. Kebanyakan kontrol PRADO akan menyajikan pasangan nama-nilai dalam <tt>Attributes</tt> secara literal terkait tag HTML. Sebagai contoh, daam link tombol <tt>Delete</tt> di atas, kita mendefinisikan sebuah <tt>onclick</tt> yang disajikan sebagai atribut <tt>onclick</tt> yang menghasilkan tag <tt><a></tt>.
+</com:InfoBox>
+
+
+<h2>Membuat Kelas Halaman</h2>
+
+<p>
+Dari template halaman di atas, kita melihat bahwa kita perlu menulis kelas halaman yang mengimplementasikan pengendali event: <tt>deletePost()</tt> (ditempelkan ke tombol <tt>Delete</tt> dalam event <tt>OnClick</tt>). Kita juga perlu untuk mengambil data tulisan yang ditetapkan oleh ID tulisan melalui parameter GET <tt>id</tt>. </p>
+
+<com:InfoBox>
+Kita mengimplementasikan fitur penghapusan tulisan dalam halaman <tt>ReadPost</tt> karena ini sangat alami untuk melakukannya di sini. Ketika pengguna mengklik pada tombol <tt>Delete</tt>, dialog konfirmasi javascript akan muncul. Jika pengguna mengkonfirmasinya, penghapusan akan dibawa dalam respon terhadap event <tt>OnClick</tt> dari tombol <tt>Delete</tt>.
+</com:InfoBox>
+
+<com:TTextHighlighter CssClass="source" Language="php">
+class ReadPost extends TPage
+{
+ private $_post;
+ /**
+ * Mengambil data tulisan.
+ * Metode ini dipanggil oleh kerangka kerja saat inisialisasi halaman
+ * @param mixed event parameter
+ */
+ public function onInit($param)
+ {
+ parent::onInit($param);
+ // id tulisan dikirimkan via parameter GET 'id'
+ $postID=(int)$this->Request['id'];
+ // mengambil PostRecord dengan informasi pembuat terisi dalam
+ $this->_post=PostRecord::finder()->withAuthor()->findByPk($postID);
+ if($this->_post===null) // jika id tulisan tidak benar
+ throw new THttpException(500,'Unable to find the specified post.');
+ // setel judul halaman sebagai judul tulisan
+ $this->Title=$this->_post->title;
+ }
+
+ /**
+ * @return PostRecord yang saat ini sedang dilihat
+ */
+ public function getPost()
+ {
+ return $this->_post;
+ }
+
+ /**
+ * Menghapus tulisan yang saat ini sedang dilihat
+ * Metode ini dipanggil saat pengguna mengklik tombol "Delete"
+ */
+ public function deletePost($sender,$param)
+ {
+ // hanya pembuat atau administrator bisa menghapus tulisan
+ if(!$this->canEdit())
+ throw new THttpException('You are not allowed to perform this action.');
+ // hapus dari DB
+ $this->_post->delete();
+ // alihkan browser ke homepage
+ $this->Response->redirect($this->Service->DefaultPageUrl);
+ }
+
+ /**
+ * @return boolean apakah pengguna saat ini bisa mengedit/menghapus tulisan yg sedang dilihat
+ */
+ public function canEdit()
+ {
+ // hanya pembuat atau administrator bisa mengedi/menghapus tulisan
+ return $this->User->Name===$this->Post->author_id || $this->User->IsAdmin;
+ }
+}
+</com:TTextHighlighter>
+
+<h2>Pengujian</h2>
+<p>
+Untuk menguji halaman <tt>ReadPost</tt>, kunjungi URL <tt>http://hostname/blog/index.php</tt> dan klik pada judul tulisan. Browser kita akan menampilkan hasil berikut dengan URL <tt>http://hostname/blog/index.php?page=ReadPost&id=1</tt>. Catatan, jika kita tidak masuk, dua tombol link tidak akan terlihat.
+</p>
+
+<img src="<%~ output2.gif %>" class="output" />
+
+</com:TContent>
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/id/Overview.page b/demos/blog-tutorial/protected/pages/Day4/id/Overview.page new file mode 100644 index 00000000..3427e11f --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day4/id/Overview.page @@ -0,0 +1,26 @@ +<com:TContent ID="Main">
+
+<h1>Tinjauan Manajemen Tulisan</h1>
+
+<p>
+Pada bagian ini, kita membuat halaman yang terkait dengan manajemen tulisan. Dalam keadaan tertentu, kita mengimplementasikan operasi CRUD (Create-Retrieve-Update-Delete) dengan memperhatikan tulisan blog.
+</p>
+
+<p>
+Berdasarkan pada kebutuhan, kita perlu membuat halaman berikut yang diatur di bawah direktori baru <tt>protected/pages/posts</tt>.
+</p>
+
+<ul>
+ <li><tt>ListPost</tt> menampilkan tulisan dengan waktu pembuatan dalam urutan mengecil.</li>
+ <li><tt>ReadPost</tt> menampilkan rincian tulisan.</li>
+ <li><tt>NewPost</tt> membolehkan pengguna teregistrasi untuk membuat tulisan baru.</li>
+ <li><tt>EditPost</tt> membolehkan pembuat atau administrator untuk mengedit tulisan yang sudah ada.</li>
+</ul>
+
+<p>
+Setelah menyelesaikan bagian ini, kita akan mengharapkan untuk melihat direktori dan file berikut:
+</p>
+
+<img src="<%~ directories.gif %>" class="output" />
+
+</com:TContent>
\ No newline at end of file diff --git a/demos/blog-tutorial/protected/pages/Day4/id/directories.gif b/demos/blog-tutorial/protected/pages/Day4/id/directories.gif Binary files differnew file mode 100644 index 00000000..5ba55184 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day4/id/directories.gif diff --git a/demos/blog-tutorial/protected/pages/Day4/id/output.gif b/demos/blog-tutorial/protected/pages/Day4/id/output.gif Binary files differnew file mode 100644 index 00000000..8c1caea8 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day4/id/output.gif diff --git a/demos/blog-tutorial/protected/pages/Day4/id/output2.gif b/demos/blog-tutorial/protected/pages/Day4/id/output2.gif Binary files differnew file mode 100644 index 00000000..7078e6c6 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day4/id/output2.gif diff --git a/demos/blog-tutorial/protected/pages/Day4/id/output3.gif b/demos/blog-tutorial/protected/pages/Day4/id/output3.gif Binary files differnew file mode 100644 index 00000000..ff1834a4 --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day4/id/output3.gif diff --git a/demos/blog-tutorial/protected/pages/Day4/id/output4.gif b/demos/blog-tutorial/protected/pages/Day4/id/output4.gif Binary files differnew file mode 100644 index 00000000..b1208a0d --- /dev/null +++ b/demos/blog-tutorial/protected/pages/Day4/id/output4.gif |