系列:开发Joomla! 3.0扩展 - 第四集:更多功能
几个月来,我们关于Joomla! 3.x开发的系列文章一直在稳步推进。到目前为止,你应该已经对扩展开发的基础有了相当好的理解,我希望你已经开始编写自己的代码。在这篇文章中,你将通过在开发中使用Bootstrap来深入了解代码。不要忘记通过重新阅读系列中的前几篇文章来复习你的现有知识。
步骤0:准备一杯咖啡
我们已经一起探讨了组件的实施。我相信,到目前为止,你已经掌握了前几篇文章中的每个步骤的第一步。在开始编写代码或构建开发步骤的下一步之前,继续我们一开始就采用的常规做法是很重要的。拿起你最喜欢的杯子,倒入你选择的蜜糖。如果你刚开始这个步骤,我建议你阅读每一篇先前的文章。从开头开始,一直读到这几行。
来吧,我在这里等你。
好的?那就回来吧。
在这篇文章中,我们将研究一些用于Lendr的其它功能。你会发现我已经补充了许多先前为空文件中的代码。与其花时间去研究每一个文件,我更愿意专注于我们添加了新功能或某些概念的某些部分。你应该能够轻松理解我们在前几篇文章中研究的代码。因此,我们继续这个系列,编写Lendr组件所需的不同模态窗口。
步骤1:创建模态窗口
在这篇文章中,我们的方法将不那么紧张,因为我们将在一些附加功能和某些细节上工作。你会发现我们添加了不同的模态窗口。我们都是以相同的方式创建它们的(使用Bootstrap技术)。为了更详细地解释,我将解释两个选项,并描述选择的选项。
首先,您可以通过AJAX加载一个视图和布局,并使用Joomla!的经典方法。虽然这种方法也提供了模态窗口的显示功能,但当点击按钮或链接时,它会加载一个完整的视图文件。这是Joomla!中传统上用于显示模态窗口的方法(可以将其视为类似iframe的东西)。
第二种方法是在页面初始加载后,在页面上方加载模态窗口的详细信息。然而,默认情况下,模态窗口(本质上是一个包含视图的
关于Lendr的模态窗口,我选择了第二种方法,原因有两个。
在要加载的页面上添加一个模态
选择这种模态窗口显示方法的第二个原因是,要添加到窗口中的数据字段非常少。所需数据很少,因此将变量“即时”分配给模态显示比通过AJAX调用整个页面要简单得多。再次强调,这是一个非常主观的偏好,但主要是由速度决定的。
让我们看看在页面上包含模态窗口所需的代码行。
首先,我们将查看“container”视图的html.php文件。它也可以被视为我们打算加载的模态窗口的“父”视图。
html.php
_lend.php
book.php
我将在Lendr中使用此代码多次来加载模态窗口。您会注意到有两种不同的调用类型来加载这些窗口。第一种是直接加载模态窗口(当模态窗口中不需要额外数据时),第二种使用JavaScript调用加载窗口(我将使用第二种方法,在显示模态窗口之前添加一个变量)。
第2步:编写贷款和归还贷款的功能
现在我们的模态窗口可以加载并显示额外信息,我们将通过使用这些窗口来添加Lendr的功能。首先,我们将查看处理贷款和归还贷款的Joomla!核心基本流程。如果您对这项功能感到担忧,我必须向您保证,我们不会在这里创建一个过于复杂的跟踪和监控系统(这可以作为一个后续的详细研究项目,根据您的需求)。在Lendr中,我们只是允许您借阅一本书,并在归还时标记为已归还。
有两个文件与贷款和归还贷款流程相关。让我们详细查看它们。
控制器
首先,我们查看控制器lend.php文件,它是贷款和归还的主要控制器。
joomla_root/components/com_lendr/controllers/lend.php
?php defined( '_JEXEC' ) or die( 'Restricted access' ); class LendrControllersLend extends JControllerBase { public function execute() { $return = array("success"=>false); $model = new LendrModelsBook(); if ( $row = $model->lend() ) { $return['success'] = true; $return['msg'] = JText::_('COM_LENDR_BOOK_LEND_SUCCESS'); }else{ $return['msg'] = JText::_('COM_LENDR_BOOK_LEND_FAILURE'); } echo json_encode($return); } }
模型
在控制器中,我们再次只执行一个任务(execute),该任务将数据和要求直接传递给book模型,该模型将处理借阅函数的调用。以下是book模型中的借阅函数
joomla_root/components/com_lendr/models/book.php
public function lend($data = null) { $data = isset($data) ? $data : JRequest::get('post'); if (isset($data['lend']) && $data['lend']==1) { $date = date("Y-m-d H:i:s"); $data['lent'] = 1; $data['lent_date'] = $date; $data['lent_uid'] = $data['borrower_id']; $waitlistData = array('waitlist_id'=> $data['waitlist_id'], 'fulfilled' => 1, 'fulfilled_time' => $date, 'table' => 'Waitlist'); $waitlistModel = new LendrModelsWaitlist(); $waitlistModel->store($waitlistData); } else { $data['lent'] = 0; $data['lent_date'] = NULL; $data['lent_uid'] = NULL; } $row = parent::store($data); return $row; }
在这个函数中,您会发现我们同时处理借阅和归还借阅。此外,当借阅成功时,我们将对应的等待列表中的元素验证为已完成。
JavaScript
以下是与借阅和归还借阅功能相关的JavaScript函数。正如我之前提到的,我将首先创建一个用于加载模态窗口的函数(这样我就可以向其中注入变量)。第二个函数用于借阅书籍。我使用jQuery AJAX调用将表单数据传递给借阅控制器(见上文)。如果控制器/模型执行成功,则模态窗口将关闭。
joomla_root/components/com_lendr/assets/js/lendr.js
function loadLendModal(book_id, borrower_id, borrower, waitlist_id) { jQuery("#lendBookModal").modal('show'); jQuery('#borrower_name').html(borrower); jQuery("#book_id").val(book_id); jQuery("#borrower_id").val(borrower_id); jQuery("#waitlist_id").val(waitlist_id); } function lendBook() { var lendForm = {}; jQuery("#lendForm :input").each(function(idx,ele){ lendForm[jQuery(ele).attr('name')] = jQuery(ele).val(); }); jQuery.ajax({ url:'index.php?option=com_lendr&controller=lend&format=raw&tmpl=component', type:'POST', data:lendForm, dataType:'JSON', success:function(data) { if ( data.success ) { jQuery("#lendBookModal").modal('hide'); } } }); }
您可以在许多地方注意到缺少错误消息。我们将一次性编写所有这些消息,这将是下一篇文章的主题。
第3步:添加愿望单、等待列表和评论
我们将处理与书籍相关的三个元素。愿望单和等待列表的功能相对简单。两个功能都只是加载一个模态窗口,以便将书籍添加到用户的愿望单或等待列表中。同样,此代码与上述模态窗口和列表代码相似。关于评论功能的代码需要更多自定义工作,我们将专注于这一点。
最初,我的意图是使用评论控制器来处理新的评论,但经过深思熟虑后,我决定从技术角度来看,新的评论应该遵循其他系统部分的相同“添加”控制器。这要求部分重写“添加”控制器,以便正确地将数据传递到适当的模型。
评论是从模态窗口创建的。窗口显示一个包含标题和评论摘要的表单。隐藏的字段允许跟踪书籍和提交评论的用户。以下是新评论的表单
joomla_root/components/com_lendr/views/review/tmpl/_add.php
<div id="newReviewModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="newReviewModal" aria-hidden="true"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h3 id="myModalLabel"<>?php echo JText::_('COM_LENDR_ADD_REVIEW'); ?></h3> </div> <div class="modal-body"> <div class="row-fluid"> <form id="reviewForm"> <input class="span12" type="text" name="title" placeholder="<?php echo JText::_('COM_LENDR_TITLE'); ?>" /> <textarea class="span12" placeholder="<?php echo JText::_('COM_LENDR_SUMMARY'); ?>" name="review" rows="10"</textarea> <input type="hidden" name="user_id" value=">?php echo $this->user->id; ?>" /> <input type="hidden" name="view" value="review" /> <input type="hidden" name="book_id" value="<?php echo $this->book->book_id; ?>" /> <input type="hidden" name="model" value="review" /> <input type="hidden" name="item" value="review" /> <input type="hidden" name="table" value="review" /> </form> </div> </div> <div class="modal-footer"> <button class="btn" data-dismiss="modal" aria-hidden="true"><?php echo JText::_('COM_LENDR_CLOSE'); ?<>/button> <button class="btn btn-primary" onclick="addReview()"><?php echo JText::_('COM_LENDR_ADD'); ?></button> </div> </div>
以下是与评论过程相关的JavaScript
joomla_root/components/com_lendr/assets/js/lendr.js
//add a review function addReview() { var reviewInfo = {}; jQuery("#reviewForm :input").each(function(idx,ele){ reviewInfo[jQuery(ele).attr('name')] = jQuery(ele).val(); }); jQuery.ajax({ url:'index.php?option=com_lendr&controller=add&format=raw&tmpl=component', type:'POST', data:reviewInfo, dataType:'JSON', success:function(data) { if ( data.success ){ console.log(data.html); jQuery("#review-list").append(data.html); jQuery("#newReviewModal").modal('hide'); }else{ } } }); }
在这个函数中,我们执行两个操作。首先,我们使用一个巧妙的JQuery循环来获取表单的所有数据,并通过控制器进行传递。提交表单后,我们等待响应。如果响应存在,则将响应添加到评论列表中,并隐藏模态窗口。这意味着我们通过Ajax调用传递了全部HTML。以下是我们的更新后的控制器如何处理这种情况。
joomla_root/components/com_lendr/controllers/add.php
<?php defined( '_JEXEC' ) or die( 'Restricted access' ); class LendrControllersAdd extends JControllerBase { public function execute() { $app = JFactory::getApplication(); $return = array("success"=>false); $modelName = $app->input->get('model', 'Book'); $view = $app->input->get('view', 'Book'); $layout = $app->input->get('layout', '_entry'); $item = $app->input->get('item', 'book'); $modelName = 'LendrModels'.ucwords($modelName); $model = new $modelName(); if ( $row = $model->store() ) { $return['success'] = true; $return['msg'] = JText::_('COM_LENDR_SAVE_SUCCESS'); $return['html'] = LendrHelpersView::getHtml($view, $layout, $item, $row); }else{ $return['msg'] = JText::_('COM_LENDR_SAVE_FAILURE'); } echo json_encode($return); } }
返回给JavaScript的HTML是从Helper文件中加载的。您会注意到我们直接通过getHtml函数将视图、布局、元素和数据传递。在此阶段,因此需要重新编写helper文件中的此getHtml函数。
joomla_root/components/com_lendr/helpers/view.php
function getHtml($view, $layout, $item, $data) { $objectView = LendrHelpersView::load($view, $layout, 'phtml'); $objectView->$item = $data; ob_start(); echo $objectView->render(); $html = ob_get_contents(); ob_clean(); return $html; }
此视图有两个目标。首先,它加载位于文件View helper更高位置的视图部分,然后加载完成后,将该视图传递给一个变量。然后,该变量被返回以传递给JavaScript,JavaScript将添加到页面上。
您可以直接在我们的GitHub存储库中找到所有相关文件:GitHub。
步骤 4:搜索书籍
搜索功能非常值得研究。再次,您有两个选择。
您可以将一个完整且独立的搜索系统集成到您的组件中,或者利用Joomla!预存的系统,包括其组件(Finder)、模块及其搜索插件。
尽管使用原生搜索系统不一定总是合适的,但我们将选择此选项以将其集成到Lendr组件中。这样做可以减少代码量并简化Lendr的结构。此外,我们还将能够研究创建插件所需的代码,该插件的目标是向原生搜索功能添加新的内容类型。
我为添加到原生搜索功能而编写的插件非常简单,肯定不包含系统插件类型的所有功能。以下是与我们编写的搜索插件(我将其命名为Smart Search - Books)相关的XML文件。
books.xml
books.php
这些函数被Finder用于索引正确的表、加载数据并将其正确地转发到搜索结果中。鉴于本教程的目标水平,我将不详细说明每个附加功能、使用的函数以及通常用于定义特定语言的辅助文件(helpers)的次要路径。如果您想了解更多关于系统搜索插件的信息,请在评论区留言或联系我以获取更多信息。
步骤 5:结论
在本篇文章中,我们讨论了不同的功能、设计结构和一些可以应用于其他组件的附加想法。
我们探讨了如何最佳地使用Bootstrap进行模态窗口,更详细地研究了JavaScript函数及其使用,然后通过集成一个次要插件扩展了我们的应用范围。我有意不在此处包括所有编写的文件和修改的所有函数,以便我们专注于本文的主要目标:组件开发过程中的推理和一般概念。因此,我已将特定功能的处理放在一边,这些内容在前面的文章中已经讨论过。
如果您对现有代码有任何问题,请随时提问。
在下一篇文章中,我们将开始完成代码。我们将涵盖有关管理界面、当Ajax调用完成后在页面上使用实时更新的主题,并将开始清理我们的代码,删除无用文件,并研究简化或减少我们代码的不同可能性。
访问完整的教程网站:http://lendr.sparkbuilt.com/
《Joomla社区杂志》上的一些文章代表作者对特定主题的个人意见或经验,可能并不代表Joomla项目的官方立场。
通过接受,您将访问https://magazine.joomla.net.cn/外部第三方提供的服务
评论