第四章 Joomla!扩展开发--前端开发(一)
在第二章里,我们访问 http://localhost/joomla/index.php?option=com_reviews,页面与下图相似:
暂时不提供图片显示,请参考《Joomla! extension development》
我们将会在页面显示带有超链接的点评列表,所以我们要预先在后端加上一些点评的数据。首先,在 /component/com_reviews/reviews.php 文件中插入以下的代码:
jimport('joomla.application.helper');
require_once( JApplicationHelper::getPath( 'html' ) );
JTable::addIncludePath(JPATH_ADMINISTRATOR.DS.
'components'.DS.$option.DS.'tables');
switch($task)
{
default:
showPublishedReviews($option);
break;
}
function showPublishedReviews($option)
{
$db =& JFactory::getDBO();
$query = "SELECT * FROM #__reviews WHERE
published = '1' ORDER BY review_date DESC";
$db->setQuery( $query );
$rows = $db->loadObjectList();
if ($db->getErrorNum())
{
echo $db->stderr();
return false;
}
HTML_reviews::showReviews($rows, $option);
}
与后端的方法相似,require_once( JApplicationHelper::getPath( 'html' ) ); 导进文件reviews.html.php,传递 JPATH_ADMINISTRATOR.DS.'components'.DS.$option.DS.'tables' 到 Jtable::addIncludePath(); 导进数据表类。最后 switch() 语句设置了默认的 case 来显示所有发布的点评。这里的 SQL 语句确保只有发布的点评被选择并且以点评日期的倒序来排序。在刷新页面之前,我们需要在 /component/com_reviews/reviews.html.php 中加入 HTML_reviews 类:
<?php
class HTML_reviews
{
function showReviews($rows, $option)
{
?><table><?php
foreach($rows as $row)
{
$link = 'index.php?option=' .
$option . '&id=' . $row->id . '&task=view';
echo
'<tr>
<td>
<a href="' . $link . '">' . $row->name . '</a>
</td>
</tr>';
}
?></table><?php
}
}
?>
showReview() 函数接收一个数据对象的行和一个组件名为参数,使用 <table> 来显示数据,在 <tr> 作循环显示数据结果并在每一行加入链接,保存文件后刷新页面,你会看到相似的页面:
暂时不提供图片显示,请参考《Joomla! extension development》
显示一个点评
如果你没有写任何的代码来处理 “view” “task”,当你单击一条链接后,你看到的是相同的页面,在views.php 中加入以下代码:
function viewReview($option)
{
$id = JRequest::getVar('id', 0);
$row =& JTable::getInstance('review', 'Table');
$row->load($id);
if(!$row->published)
{
JError::raiseError( 404, JText::_( 'Invalid
ID provided' ) );
}
HTML_reviews::showReview($row, $option);
}
先,用 getVar() 获取请求的 id,它能检查变量的各种攻击。外部的数据处理要很小心,特别是处理公共访问的网站的数据,在我们的代码中统一使用 getVar() 将会提供一个合理的安全层。如果 id 的值丢失或者不合法,第二个参数 0 将会作为默认值提供给 id。
然后,我们从后端得到一个数据表类,加载相应 id 的记录后,我们检查选择的记录是否被发布,如果不是发布的,我们用 JError 的成员函数 raiseError() 来输出找不到信息的 404 页面:
暂时不提供图片显示,请参考《Joomla! extension development》
这个检查确保不让用户随便输入 id 来获取点评,而且如果记录不存在也会显示以上的页面。viewReview() 函数会做所有的事情来加载请求的点评,但是我们仍然需要加入代码来调用这个函数,加入下面的高亮代码到 switch() 中:
switch($task)
{
case 'view':
viewReview($option);
break;
default:
showPublishedReviews($option);
break;
我们也需要在我们的输出类创建一个显示函数,在 reviews.html.php 文件中加入 showReview() 函数到 HTML_reviews:
function showReview($row, $option)
{
?>
<p class="contentheading"><?php echo $row->name; ?></p>
<p class="createdate"><?php echo JHTML::Date
($row->review_date); ?></p>
<p><?php echo $row->quicktake; ?></p>
<p><strong>Address:</strong> <?php echo $row->address; ?></p>
<p><strong>Cuisine:</strong> <?php echo $row->cuisine; ?></p>
<p><strong>Average dinner price:</strong> $<?php echo
$row->avg_dinner_price; ?></p>
<p><strong>Credit cards:</strong> <?php echo
$row->credit_cards; ?></p>
<p><strong>Reservations:</strong> <?php echo
$row->reservations; ?></p>
<p><strong>Smoking:</strong> <?php
if($row->smoking == 0)
{
echo "No";
}
else
{
echo "Yes";
}
?></p>
<p><?php echo $row->review; ?></p>
<p><em>Notes:</em> <?php echo $row->notes; ?></p>
<?php $link = 'index.php?option=' . $option ; ?>
<a href="<?php echo $link; ?>">< return to the reviews</a>
<?php
}
showReview() 函数传进一个数据库行对象和组件的名字作为参数,这行记录的大部分字段都以HTML格式显示,也包含许多逻辑。Smoking 字段陪赋给合适的 Yes 或者 No 值。调用 JHTML::Date() 来格式化从数据库取出来的时间戳。最后,显示一个可以返回点评列表的链接,保存文件后,再次点击点评的链接,你会看到以下相似的页面:
暂时不提供图片显示,请参考《Joomla! extension development》
创建搜索引擎友好链接
现在浏览我们的点评的链接(http://localhost/joomla/index.
php?option=com_reviews&id=1&task=view&Itemid=1)出现了很长的 GET 字符串,用户肯定都会讨厌看到这么长的链接,更重要的是这样的链接对于搜索引擎收集我们的网站是没有帮助的,搜索引擎对这样的链接更友好:http://www.ourdomain.com/reviews/view/1,为了实现这样的链接,我们定义了一个路由来产生和解析 Search-Engine Friendly (SEF) 即搜索引擎友好的链接,去到后台的菜单“网站 | 配置”,将“搜索引擎友好URL”设置为 Yes,如果你使用的是 Apache 作为你的 Web 服务器并且启用了 mod_rewrite 模块,你也能够设置“使用 mod_rewrite”为 Yes,它会在你的URL中删除 index.php,你所做的设置应该像下图:
暂时不提供图片显示,请参考《Joomla! extension development》
如果你不能设置 mod_rewrite 模块,那么你的URL会像这样:http://www.yoursite.com/index.php/search/engine/friendly/link。
保存你刚才所做的设置,假设你是设置了 mod_rewrite 模块,然后重命名 .htaccess.txt 为 .htaccess,如果你看到提示说你的配置不能写,那么打开根目录下的 configuration.php 文件,设置 $sef 成员变量的值为1即可。
创建URL段
在 Joomla! 的组件和模块中创建内部链接的时候会调用 Jroute::_() 函数,这个函数将链接作为参数并且返回一个 SEF (搜索引擎友好)的链接。要创建 SEF 链接,JRoute::_() 首先将链接分析成数组,然后删除 option 元素并将它的值加到新的 URL 的第一段,这函数会在与 option 的值相同目录内寻找 router.php,如果找到,将文件包含进来并调用以组件名开头以 BuildRoute() 结束的函数,我们这个例子是调用 ReviewsBuildRoute()。要创建 ReviewsBuildRoute() ,打开/component/com_reviews 目录,创建 router.php 文件,然后加入以下的代码:
<?php
defined( '_JEXEC' ) or die( 'Restricted access' );
function ReviewsBuildRoute(&$query)
{
$segments = array();
if (isset($query['task']))
{
$segments[] = $query['task'];
unset($query['task']);
}
if(isset($query['id']))
{
$segments[] = $query['id'];
unset($query['id']);
}
return $segments;
}
?>
Jroute::_() 函数决定了正在处理的链接是餐厅的点评,ReviewBuildRoute() 函数会被调用并传递一个分析URL后返回的数组参数。为了创建SEF链接,我们需要返回URL段的有序数组。首先,赋值一个空数组给变量 $segments;下一步检查数组 $query 是否存在 task 元素,如果存在,我们把 task 的值加入到 $segments 中的第一个元素,然后将它从 $query 中删除;下一步我们对 id 做相同的操作;最后,我们返回 $segments 以便 JRoute::_() 能创建 URL。
要得到正确的 SEF URL ,这个函数的编写有两个很重要的方法要注意的,首先,变量 $query 要以引用传递(在变量前加上 &)。因为我们创建段时,我们会从 $query 中删除已经处理的元素,任何在 $query 中剩下来的元素都会被处理回到 URL 中,也就是会以原来的 GET 元素出现在 URL。如果我们没有以引用来传递,使用 unset() 只会影响局部的拷贝,URL中所有的 elements 都会出现在 SEF $segments 后面。既然 SEF URL 没有方法可以识别元素的值,那么唯一的方法就是靠我们预先定义好的顺序来做映射。当返回 $segments,Jroute::_() 从它返回每个元素,然后以斜线分隔加到 URL。如果在 $query 中有剩下来的元素会以 GET 方式加到 URL后面。
我们已经有 router.php 来生成 SEF URL,但是我们的组件输出函数还没有使用。打开/components/com_reviews/reviews.html.php 文件并注意 HTML_reviews的成员函数 showReviews() 中的高亮代码:
foreach($rows as $row)
{
$link = JRoute::_('index.php?option=' . $option . '&id=' .
$row->id . '&task=view');
echo '<tr><td><a href="' . $link . '">' .
$row->name . '</a></td></tr>';
}
同样也注意 HTML_reviews::showReview() 中的高亮代码:
<p><em>Notes:</em> <?php echo $row->notes; ?></p>
<?php $link = JRoute::_('index.php?option=' . $option); ?>
<a href="<?php echo $link; ?>">< return to the reviews</a>
现在,组件会根据我们在 ReviewsBuildRoute() 设定的模式来生成 SEF URL。