# 文章評論
博客已經部署,我們寫了一些非常好的博客帖子,并通過Adminer發布。 人們正在閱讀博客,他們非常熱衷于我們的想法。 我們每天都收到很多贊美的電子郵件。 但是,當我們只有在電子郵件中,所以沒有其他人可以閱讀它的所有贊美? 如果人們可以直接在博客上評論,以便其他人可以閱讀我們是多么真棒,這不會更好嗎?
# 創建新表
我們用工具創建一個新表格InnoDB類,名稱為comments

~~~
CREATE TABLE `comments` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`post_id` int(11) NOT NULL,
`name` varchar(250) NOT NULL,
`email` varchar(250) NOT NULL,
`content` text NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
) ENGINE=InnoDB CHARSET=utf8;
~~~
如果創建時出錯,查看是否第一個posts表是不是InnoDB類型。
# 表單
首先,我們需要創建一個表單,這將允許用戶對我們的頁面發表評論。 Nette Framework對表單提供了極好的支持。 它們可以在控制器中配置并在模板中呈現。
Nette Framework有一個組件的概念。 組件是可重用的類或代碼片段,可以附加到另一個組件。 即使控制器是一個組件。 每個組件都是使用組件中心創建的。 所以讓我們在PostPresenter中加入以下代碼。
~~~
protected function createComponentCommentForm()
{
$form = new Form; // means Nette\Application\UI\Form
$form->addText('name', 'Your name:')
->setRequired();
$form->addEmail('email', 'Email:');
$form->addTextArea('content', 'Comment:')
->setRequired();
$form->addSubmit('send', 'Publish comment');
return $form;
}
~~~
讓我們解釋一下。 第一行創建一個Form組件的新實例。
以下方法將HTML輸入附加到表單定義中。 - > addText將呈現為<input type = text name = name>,帶有<label>您的姓名:</ label>。 正如你可能已經猜到了, - > addTextArea附加一個<textarea>和 - > addSubmit添加一個<input type = submit>。 有更多的方法,但這是所有你必須知道,現在。 您可以在文檔中了解更多。
一旦在控制器中定義了表單組件,我們可以在模板中顯示它。因此,請將{control}放在帖子詳細信息模板的末尾,在app / presenters / templates / Post / show.latte中。 因為組件的名稱是commentForm(它是從方法createComponentCommentForm的名稱派生的),
~~~
...
<h2>Post new comment</h2>
{control commentForm}
...
~~~
意思是你在show.latte里面加入以上代碼就象以下一樣

再刷新文章詳細頁面,就了現了表單!

# 批論保存到數據庫
現在可以嘗試提交一些數據? 您可能已經注意到,表單沒有執行任何操作。 它只是在那里,看起來很酷,什么也不做。 我們必須給它附加一個回調方法,這將保存提交的數據。
將以下行放在組件工廠中返回行之前的createComponentCommentForm中:
~~~
$form->onSuccess[] = [$this, 'commentFormSucceeded'];
~~~

這意味著“表單成功提交后,調用當前控制器的方法commentFormSucceeded”。 但是這個方法還不存在,所以讓我們來創建它。
~~~
public function commentFormSucceeded($form, $values)
{
$postId = $this->getParameter('postId');
$this->database->table('comments')->insert([
'post_id' => $postId,
'name' => $values->name,
'email' => $values->email,
'content' => $values->content,
]);
$this->flashMessage('Thank you for your comment', 'success');
$this->redirect('this');
}
~~~
以上代碼一定要放在createComponentCommentForm()下面

新方法有一個參數,它是被提交的表單的實例,由createComponentCommentForm()創建。 我們收到在$values中提交的值。 然后我們將數據插入數據庫。
當我們提交時 $this->flashMessage('Thank you for your comment', 'success');
會產生信息提示,但是他都是在上部出現,如果我們想把這個信息提交按模板
出現,那我們應如下操作,先在
app/presenters/templates/@layout.latte
中加入以下代碼
~~~
<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{$flash->message}</div>
~~~

我們再試一次就明白了。
# 顯示評論
Nette \ Database有一個很酷的功能,名為Selection API。 你還記得我們創建的表是InnoDB嗎? 管理員創建了所謂的外鍵,這將為我們節省大量的工作。
Nette \ Database使用外鍵來解析表之間的關系,并且知道關系,它可以自動為您創建查詢。
你還記得,我們已經將$ post變量傳遞給PostPresenter :: renderShow()中的模板,現在我們要遍歷所有的post_id等于$ post-> id的評論。 你可以通過調用$ post-> related('comments')。 就是這么簡單。 看看結果代碼。
~~~
public function renderShow($postId)
{
...
$this->template->post = $post;
$this->template->comments = $post->related('comments')->order('created_at');
}
~~~

然后在show.latte模板中加入以下代碼
!
注意特殊的n:tag-if屬性。 你已經知道n:屬性如何工作。 嗯,如果你用tag-添加屬性,它將只包裹標簽,而不是它們的內容。 如果他們提供了電子郵件,這允許您將評論者的名字變成鏈接。 這兩行結果相同:

- Nette簡介
- 快速開始
- 入門
- 主頁
- 顯示文章詳細頁
- 文章評論
- 創建和編輯帖子
- 權限驗證
- 程序員指南
- MVC應用程序和控制器
- URL路由
- Tracy - PHP調試器
- 調試器擴展
- 增強PHP語言
- HTTP請求和響應
- 數據庫
- 數據庫:ActiveRow
- 數據庫和表
- Sessions
- 用戶授權和權限
- 配置
- 依賴注入
- 獲取依賴關系
- DI容器擴展
- 組件
- 字符串處理
- 數組處理
- HTML元素
- 使用URL
- 表單
- 驗證器
- 模板
- AJAX & Snippets
- 發送電子郵件
- 圖像操作
- 緩存
- 本土化
- Nette Tester - 單元測試
- 與Travis CI的持續集成
- 分頁
- 自動加載
- 文件搜索:Finder
- 原子操作