在本系列上一个文章中,我画了一些页面草图,用于展示网站原型。本文中将讲解如何用Drpual来实现。
在上面的文章中,我们已经创建了一个Food节点类型,用于存储各个菜单,供员工选择。也就是说,基本上实现了菜单的管理功能。那么接下来要实现在线订餐的功能了。
为了简化功能,我们先不实现购物车的功能,只需要实现用户在设置订餐数量后,即可提交一个订单。午餐管理员就可以查看用户订餐列表了。
可以看出,现在需要下列“东西”:
除此之外,还需要显示一些提示信息等。
在平时做项目时,我喜欢迭代式的开发,简单的讲就是先开发主要功能,再逐步完善。一方面这样可以使客户能够清楚的看到进展,另一方面也能确保系统更为“扎实”。除此之外,还可以使程序员自己有一定的满足感,避免整天忙碌于开发却看不到效果,产和厌倦感。
下面按照上面的列的“东西”,一个一个的找解决方案。
订餐表单
这个表单上需要下列元素:
-
一个选择框,列表值为:1, 2, 3, 4, 5。我们假定一个员工最多只能订5份套餐。
-
一个提交按钮
这应该是最简单的表单了,下面看看怎么实现。
毫无疑问,需要使用传说中的Form API。Form API简称FAPI是Drupal中一个非常强大的表单生成函数。它包括表单生成、表单处理及结果显示等各个阶段的功能。其中最重要的几个函数为:
有一个钩子函数和form有关,不过大家要弄清它的用途:hook_form。这个函数是用于通过模块自定义content type时使用的,可以捕获create/edit节点时提交的表单。但这里要用的是drupal_get_form(), 用于生成一个表单。
首先创建一个生成表单元素的函数function buy_food_form(),然后使用drupal_get_form('buy_food_form')就可以输出表单了。除了生成表单外,还要对用户提交的表单进行处理。Drupal中,表单处理分为两步:
-
验证提交的表单数据
-
对数据进行处理
这两个步骤都转变为两个钩子函数:hook_form_validate和hook_form_submit。我们只需要将hook换成生成表单函数的前缀即可,如food_order_form_validate和food_order_form_submit。
由于需要自己写函数了,因此不可避免的需要自定义模块了。我们将订餐模块命名为Food Order Module。需要创建下面两个文件:
-
food_order.info
-
food_order.module
下面分析一些表单提示函数和处理函数。
OK,表单准备好了,该研究一下将表单放哪里了。由设计图看出,我们需要将表单放置在每个菜单页面上,这样用户在浏览到感兴趣的菜单时,就可以直接订餐了。那么如何将表单放置在菜单页面中呢?有两种方法:
-
修改node-food.tpl.php
-
生成Block,放置在node/*页面中
我更倾向于第二种方法,虽然第一种方法更为直接。本例中我们还是使用第二种方法,因为这样更遵循`Drupal的MVC模式,而且自定义模块的好处是可以根据需要开关模块。
数据表
我们需要使用数据库来存储哪些同事订了什么餐。首先要做的工作是创建一个数据表。等等,由于我们使用的是强大的Drupal,是不是不需要创建数据表也可以实现这样的功能呢。答案是:YES,但是,本例为了让读者练习使用自定义的数据表,因此不采用Drupal模块的解决方案。其实在Drupal中有个很有名的电子商务类模块——Ubercart。其实订餐这个业务和买商品本质是一样的,因此Ubercart也可以实现这样的功能,只不过有点重量级了。感兴趣的朋友们可以试试Ubercart是否可以完成同样的需求。
Drupal之所以说它是CMF(Content Management Framework),是因为一方面,它具有很好的层次结构,比如“数据库抽像层”,同时提供了很多方便的API——一系列的数据库操作函数,用起来还是相当方便的。使用Drupal的DAL,可以使我们不去关心数据库服务器配置及连接等细节,而且由于Drupal除了mysql外还支持pgsql,因此我们的程序还可以移植到pgsql上而无须更改数据库操作代码。而且,有望在不远的将来,Drupal可以使用MSSQL和Oracle等大型数据库。数据库抽像层的好处也就更为明显了。
数据表中主要字段有:
-
菜单号(nid)
-
用户ID(uid)
-
订餐数量(qty)
-
应付金额(money)
-
订餐时间(created)
订餐查看页面
最后,需要一个页面,让管理员可以查看当天有哪些人订餐了。当然也可以查看历史订餐信息,不过这个没有什么太大意义。因此在这个页面上只查看当天的订餐信息就可以了。
我们通过一个表格显示所有订餐的信息。Drupal的API中有一个theme_table的函数,可以生成表格,而且还可以自动生成排序字段,不过使用起来稍微有些复杂。但还是推荐大家使用。
由于我们是自己创建的订餐表,因此需要用到db_query。
$sql = “SELECT * FROM {food_order}”;
$result = db_query($sql);
while ($row = db_fetch_array($result)) { }
另外,还可以使用pager_query轻松实现分页。
下面总结一下,本文给出了实现“在线订餐”的基本解决方案,主要是自己创建数据表,并使用FAPI生成表单,用db_query等插入数据及显示数据。下一小节将给出源代码,供大家参考。
drupal_get_form()