回顾在
我们第八天的学习中,我们很容易的为askeet添加了AJAX交互。现在程序已经相当有用了,但是还需要大量的小修改。在问题体中应允许丰富的文本,而
主键不应出现在URI中。在Symfony中修正这些问题并不难,今天将是我们练习我们所学东西的一个好机会,并且可以检测我们是否已经知道如何操作
MVC结构的所有层。
在question与answer上允许丰富的文本格式Markdownquestion与answer现在只允许接受普通文本。要允许基本的格式,粗体,斜体,超链接,图片,等,我们将会使用一个外部库,而不是重新发明轮子。
如
果我们阅读过文本格式的Symfony文档,那么你也许知道我们是Markdown的fans。Markdown是一个文本到HTML的转换工具,以及一
个文本格式化语法。例如,与Wiki或是论坛语法相比,Markdown的最大好处就是普通的markdown文本文件仍然具有可读性:
Test Markdown text
------------------
This is a **very simple** example of [Markdown][1].
The best thing about markdown is its _auto-escape_ feature for code chunks:
link to symfony>The `<` and `>` are properly escaped as `<` and `>`,
>and are not interpreted by any browser
[1]: "Markdown"
Markdown的渲染结果如下:
Test Markdown text
This is a very simple example of Markdown. The best thing about markdown is its auto-escape feature for code chunks:
link to symfony The < and > are properly escaped as < and >, and are not interpreted by any browser
Markdown库尽
管最初是使用Perl语言编写的,但是现在Markdown已经可以作为一个PHP库来下载了。而这正是我们要使用的。下载markdown.php文
件,并将其放置在askeet工程的lib目录下(askeet/lib)。就是这样:如果在我们的文件中首先进行请求,那么现在askeet程序的所有
类都可以访问这个库了:
require_once('markdown.php');
我们可以在每次要显示消息体时调用Markdown转换器,但是这会给我们的服务器造成沉重的负载。我们会在问题创建时将文本体转换为HTML,并且在Question表中存储内容的HTML版本。也许我们已经熟悉这样了,所以模块扩展并不惊奇。
扩展模块首先在schema.xml中的Question表部分添加一列:
column name="html_body" type="longvarchar" />
然后,生成模块并且更新数据库:
$ symfony propel-build-model
$ symfony propel-build-sql
$ symfony propel-insert-sql
覆盖setBody方法当调用Question类的->setBody()方法时,html_body列必须使用文本内容的Markdown版本进行更新。打开askeet/lib/model/Question.php模块文本,并且编写下面的函数:
public function setBody($v)
{
parent::setBody($v);
require_once('markdown.php');
// strip all HTML tags
$v = htmlentities($v, ENT_QUOTES, 'UTF-8');
$this->setHtmlBody(markdown($v));
}
在设置HTML内容之前使用htmlentities()函数可能保护askeet免受跨站点脚本(cross-site-scripting XSS)攻击,因为所有的