•  
  •  
  •  
  •  
1 1 1 1 1 1 1 1 1 1 Рейтинг 5.00 (1 Голос)
Как ведется разработка расширений под Joomla! 3.0 – расширение функционала (Статья 4) - 5.0 out of 5 based on 1 vote

Эта статья направлена на рассмотрение некоторых других возможностей, которыми обладает компонент Lendr. Вами, естественно, обращено внимание на то, что нами добавлен весьма большой объем кода в файлы, которые ранее оставались не заполненными. Но мы не будем затрачивать время для их рассмотрения, а лучше сконцентрироваться на тех моментах, в которых мы затрагивали добавление нового функционала или концепций.

Вам не должно быть трудно разобраться в строках кода, основанного на более ранних статьях. Нами будет продолжен наш цикл по созданию различных модальных окон, которые необходимы для элемента Lendr.

Шаг 1: Создание модального окна

Не следует забывать, что нами уже были созданы определенные модальные окна. Для создания всех их мы прибегали к использованию одного и того же способа (с помощь Bootstrap). Вначале мы познакомим вас с двумя способами по созданию таких окон, а далее займемся подробным описанием способа, которым мы решили воспользоваться.

Первым способом является загрузка представления и шаблона с помощью AJAX. Для этого мы будем пользоваться стандартным методом Joomla, которым обеспечивается загрузка внутреннего файла представления в модальное окно при нажатии кнопки. Традиционно этот подход стал стандартом в Joomla, который обеспечивает загрузку модальных окон (необходимо думать о них как о iframes).

Второй метод заключается в загрузке всех модальных окон на страницу во время загрузки страницы, но при этом они будут скрыты до тех пор, пока не произойдет активации с помощью клика по ссылке или кнопке.

Мы отдаем предпочтение второму методу из-за следующих причин. Непосредственная загрузка модального окна при загрузке страницы обеспечивает для нас отображение его моментально с помощью клика по ссылке или кнопке. У вас может возникнуть мысль, что с подобным способом замедляется загрузка страницы. Но в действительности это является весьма незначительной потерей в скорости. Естественно, каждый человек обладает своими предпочтениями, но мы склоняемся к выбору высокой скорости загрузки модального окна. Вторая причина выбора этого способа заключается в том, что мы нуждаемся в передаче совсем небольших объемов данных в поля нашего окна. Это значит, что нетрудно сделать это быстро, вместо того, чтобы делать запрос для целого представления с помощью AJAX. Опять же это является личным предпочтением.

Давайте перейдем к рассмотрению кода, которым мы будем пользоваться при включении модального окна в нашу страницу. Вначале займемся разбором файла html.php, который в целом выступает в роли родительского представления для нашего модального окна.

views/book/html.php

<?php defined( '_JEXEC' ) or die( 'Restricted access' ); 
 
class LendrViewsBookHtml extends JViewHtml
{
  function render()
  {
    $app = JFactory::getApplication();
   
    //retrieve task list from model
    $model = new LendrModelsBook();
    $this->book = $model->getItem();
    
    $this->_addReviewView = LendrHelpersView::load('Review','_add','phtml');
    $this->_addReviewView->book = $this->book;
    $this->_addReviewView->user = JFactory::getUser();
    $this->_lendBookView = LendrHelpersView::load('Book', '_lend', 'phtml');
    $this->_lendBookView->borrower = $this->book->waitlist_user;
    $this->_lendBookView->book = $this->book;
    $this->_returnBookView = LendrHelpersView::load('Book', '_return', 'phtml');
    $this->_returnBookView->borrower = $this->book->waitlist_user;
    $this->_returnBookView->book = $this->book;
    $this->_reviewsView = LendrHelpersView::load('Review','list','phtml');
    $this->_reviewsView->reviews = $this->book->reviews;
    $this->_modalMessage = LendrHelpersView::load('Profile','_message','phtml');
    //display
    return parent::render();
  } 
}

В данном случае нами используется Lendr Helper, который нами создан и использовался раньше. Следует обратить внимание к тому, что нами используется подчеркивание (_) чтобы выделить частичные шаблоны и указать phtml как формат.

Файл частичного шаблона.

views/book/tmpl/_lend.php

<div id="lendBookModal" tabindex="-1" role="dialog" aria-labelledby="lendBookModalLabel" aria-hidden="true">
    <div>
        <button type="button" data-dismiss="modal" aria-hidden="true">×</button>
        <h3 id="myModalLabel"><?php echo JText::_('COM_LENDR_LEND_BOOK'); ?></h3>
    </div>
    <div>
        <div>
            <form id="lendForm">
                <div>
                    <?php echo JText::_('COM_LENDR_LEND_BOOK_TO'); ?> <span id="borrower_name"></span>
                </div>
                <div id="book-modal-info"></div>
                <input type="hidden" name="book_id" id="bookid" value="<?php echo $this->book->book_id; ?>" />
                <input type="hidden" name="user_id" value="<?php echo JFactory::getUser()->id; ?>" />
                <input type="hidden" name="table" value="Book" />
                <input type="hidden" name="waitlist_id" value="<?php echo $this->book->waitlist_id; ?>" />
                <input type="hidden" name="borrower_id" id="borrower_id" value="<?php echo $this->book->borrower_id; ?>" />
                <input type="hidden" name="lend" value="1" />
            </form>
        </div>
    </div>
    <div>
        <button data-dismiss="modal" aria-hidden="true"><?php echo JText::_('COM_LENDR_CLOSE'); ?></button>
        <button on-click="lendBook();"><?php echo JText::_('COM_LENDR_LEND'); ?></button>
    </div>
</div>

views/book/tmpl/book.php

<h2><?php echo $this->book->title; ?></h2>
<div>
  <div>
    <img src="http://covers.openlibrary.org/b/isbn/<?php echo $this->book->isbn; ?>-L.jpg">
  </div>
  <div>
      <h3><?php echo $this->book->title; ?></h3>
      <p><?php echo $this->book->summary; ?></p>
      <p>
        <?php if($this->book->user_id == JFactory::getUser()->id) { ?>
                <?php if ($this->book->lent) { ?>
                    <a href="#returnBookModal"><?php echo JText::_('COM_LENDR_RETURN'); ?></a>                   
                <?php } elseif($this->book->waitlist_id > 0) { ?>
                 <a href="#lendBookModal" data-toggle="modal" role="button" id="lendButton"><?php echo JText::_('COM_LENDR_LEND_BOOK'); ?></a>
                <?php } ?>
          <?php } else {       
              if(($this->book->waitlist_id > 0) && $this->book->user_id == JFactory::getUser()->id) { ?>
              <a href="javascript:void(0);" on-click="cancelRequest(<?php echo $this->book->book_id; ?>);"><?php echo JText::_('COM_LENDR_CANCEL_REQUEST'); ?></a>
              <?php } else { ?>
              <div>
                <a href="javascript:void(0);" on-click="borrowBookModal(<?php echo $this->book->book_id; ?>);"><?php echo JText::_('COM_LENDR_BORROW'); ?></a>
                <button data-toggle="dropdown">
                  <span></span>
                </button>
                <ul>
                  <li><a href="javascript:void(0);" on-click="addToWishlist('<?php echo $this->book->book_id; ?>');"><?php echo JText::_('COM_LENDR_ADD_WISHLIST'); ?></a></li>
                  <li><a href="#newReviewModal" data-toggle="modal"><?php echo JText::_('COM_LENDR_WRITE_REVIEW'); ?></a></li>
                </ul>
              </div>
              
              <?php } 
          } ?>
        </p>
  </div>
</div>
<br />
<div>
<div>
  <ul>
    <li><a href="#detailsTab" data-toggle="tab"><?php echo JText::_('COM_LENDR_BOOK_DETAILS'); ?></a></li>
    <li><a href="#reviewsTab" data-toggle="tab"><?php echo JText::_('COM_LENDR_REVIEWS'); ?></a></li>
  </ul>
  <div>
    <div id="detailsTab">
      <h2><?php echo JText::_('COM_LENDR_BOOK_DETAILS'); ?></h2>
      <p>
        <strong><?php echo JText::_('COM_LENDR_AUTHOR'); ?></strong><br />
        <?php echo $this->book->author; ?>
      </p>
      <p>
        <strong><?php echo JText::_('COM_LENDR_PAGES'); ?></strong><br />
        <?php echo $this->book->pages; ?>
      </p>
      <p>
        <strong><?php echo JText::_('COM_LENDR_PUBLISH_DATE'); ?></strong><br />
        <?php echo $this->book->publish_date; ?>
      </p>
      <p>
        <strong><?php echo JText::_('COM_LENDR_ISBN'); ?></strong><br />
        <?php echo $this->book->isbn; ?>
      </p>
    </div>
    <div id="reviewsTab">
      <a href="#newReviewModal" role="button" data-toggle="modal"><i></i> <?php echo JText::_('COM_LENDR_ADD_REVIEW'); ?></a>
      <h2><?php echo JText::_('COM_LENDR_REVIEWS'); ?></h2>
      <?php echo $this->_reviewsView->render(); ?>
    </div>
  </div>
</div>
</div><?php echo $this->_addReviewView->render(); ?>
<?php echo $this->_lendBookView->render(); ?>
<?php echo $this->_returnBookView->render(); ?>
<?php echo $this->_modalMessage->render(); ?>

В этом отобразится внутреннее представление на странице, но так как нами использован Bootstrap CSS, div будет являться скрытым до своей активации.

Мы будем продолжать пользоваться этим кодом, чтобы загружать модальные окна в Lendr. Присмотритесь к тому, что нами используются различные вызовы для загрузки. Первый выражен прямой загрузкой окна (применяется в том случае, когда окно не нуждается в дополнительной информации). Второй отличается использованием javascript (применяется тогда, когда в окно следует передать различные данные до его отображения).

Шаг 2: Функционал одалживания и возврата

В момент, когда нашими модальными окнами загружается и отображается информация, мы можем приступать к работе над функциональностью, связанной с данными окнами. Вначале следует заняться рассмотрением базового процесса одалживания и возврата. В Lendr мы лишь можем одалживать книги и помещать их как возвращенные во время возврата. Для этого процесса используются сразу несколько файлов. Следует познакомиться с ними поближе.

Контроллер

Для начала разберемся с файлом контроллера lend.php, который выступает в роли главного контроллера, как при одалживании, так и при возврате.

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, которая занимается обработкой вызова функции lend.

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, которые обеспечивает передачу данных формы для контроллера lend (мы описали его выше). При успешном выполнении контроллера/модели происходит закрытие модального окна.

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: Добавление списков избранных, списков ожидания и обзоров

Нами продолжается работа над тремя областями, которые относятся к книгам. Функционал списка ожидания и списка избранного отличаются своей простотой. Они отвечают лишь за загрузку модального окна, а также добавление определенной книги либо в один, либо в другой список пользователей. И опять этому коду присуща схожесть с кодом модальных окон, который был рассмотрен ранее. Более подробное изучение кода обеспечивается GitHub репозиторием. Мы же уделим время обзорам.

Вначале, для обзора мы хотели воспользоваться контроллером review, но потом было решено, что технически новому обзору стоит следовать контроллеру добавления «add» как и другим частям компонента. Для этого потребуется небольшое переписывание контроллера, чтобы обеспечить правильную передачу данных с помощью соответствующей модели.

Для создания обзор используется модальное окно. Окном загружается форма, которая включает в себя название и текст обзора. Скрытые поля обеспечивают отслеживание книгу и пользователя, которым оставляется обзор. Вот код этой формы:

views/review/tmpl/_add.php

<div id="newReviewModal" tabindex="-1" role="dialog" aria-labelledby="newReviewModal" aria-hidden="true">
  <div>
    <button type="button" data-dismiss="modal" aria-hidden="true">×</button>
    <h3 id="myModalLabel"><?php echo JText::_('COM_LENDR_ADD_REVIEW'); ?></h3>
  </div>
  <div>
    <div>
        <form id="reviewForm">
            <input type="text" name="title" placeholder="<?php echo JText::_('COM_LENDR_TITLE'); ?>" />
      <textarea 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>
    <button data-dismiss="modal" aria-hidden="true"><?php echo JText::_('COM_LENDR_CLOSE'); ?></button>
    <button on-click="addReview()"><?php echo JText::_('COM_LENDR_ADD'); ?></button>
  </div>
</div>

Каким образом разрабатываются расширения для Joomla! 3.0 – больше функционала (Статья 4)

Далее следует javascript код, который относится к процессу обзора:

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{            }
        }
    });
}

Возвращаемый HTML загружаем из хелпера файла. Следует посмотреть, что осуществляется функцией getHtml этого хелпера:

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;
}

Вначале методом загружается частичное представление с последующей передачей ему данных. После этого, используется буферизация, нами назначается полученный результат переменной и возвращаем её.

Шаг 4: Процесс поиска книг

Поиск является наиболее интересным процессом. Для его осуществления могут быть использованы разные пути. Нами может проводиться внедрение своей собственной системы поиска или мы можем воспользоваться возможностями, которые предоставляются встроенным в Joomla компонентом "Умный поиск". Конечно, не во всех случаях следует применять Finder, нам все-таки будет использоваться именно эта возможность. Также, она уменьшит объем кода и внесет упрощение структуры нашего компонента. Также, это обеспечит демонстрацию кода, необходимого при создании Finder плагина для нового типа контента.

Плагин, которым мы будем пользоваться для Finder отличается простотой и, конечно, не способен продемонстрировать все возможности.

plugins/finder/books/books.xml

<?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="finder" method="upgrade">
    <name>Smart Search - Books</name>
    <author>Joomla! Project</author>
    <creationDate>March 2013</creationDate>
    <copyright>(C) 2005 - 2013 Open Source Matters. All rights reserved.</copyright>
    <license>GNU General Public License version 2 or later; see    LICENSE.txt</license>
    <authorEmail>admin @ joomla.org</authorEmail>
    <authorUrl>www.joomla.org</authorUrl>
    <version>3.0.0</version>
    <description></description>
    <files>
        <file plugin="books">books.php</file>
        <filename>index.html</filename>
    </files>
</extension>

Так выглядит код плагина.

plugins/finder/books/books.php

<?php
/**
 * @package     Joomla.Plugin
 * @subpackage  Finder.Books
 *
 * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE
 */
 
defined('JPATH_BASE') or die;
 
require_once JPATH_ADMINISTRATOR . '/components/com_finder/helpers/indexer/adapter.php';
 
/**
 * Finder adapter for Lendr Books.
 *
 * @package     Joomla.Plugin
 * @subpackage  Finder.Books
 * @since       3.0
 */
class PlgFinderBooks extends FinderIndexerAdapter
{
    /**
     * The plugin identifier.
     *
     * @var    string
     * @since  2.5
     */
    protected $context = 'Books';
 
    /**
     * The extension name.
     *
     * @var    string
     * @since  2.5
     */
    protected $extension = 'com_lendr';
 
    /**
     * The sublayout to use when rendering the results.
     *
     * @var    string
     * @since  2.5
     */
    protected $layout = 'book';
 
    /**
     * The type of content that the adapter indexes.
     *
     * @var    string
     * @since  2.5
     */
    protected $type_title = 'Book';
 
    /**
     * The table name.
     *
     * @var    string
     * @since  2.5
     */
    protected $table = '#__lendr_books';
 
    /**
     * The field the published state is stored in.
     *
     * @var    string
     * @since  2.5
     */
    protected $state_field = 'published';
 
    /**
     * Load the language file on instantiation.
     *
     * @var    boolean
     * @since  3.1
     */
    protected $autoloadLanguage = true;
 
    /**
     * Method to remove the link information for items that have been deleted.
     *
     * @param   string  $context  The context of the action being performed.
     * @param   JTable  $table    A JTable object containing the record to be deleted
     *
     * @return  boolean  True on success.
     *
     * @since   2.5
     * @throws  Exception on database error.
     */
    public function onFinderDelete($context, $table)
    {
        if ($context == 'com_lendr.book')
        {
            $id = $table->id;
        }
        elseif ($context == 'com_finder.index')
        {
            $id = $table->link_id;
        }
        else
        {
            return true;
        }
        // Remove the items.
        return $this->remove($id);
    }
 
    /**
     * Method to determine if the access level of an item changed.
     *
     * @param   string   $context  The context of the content passed to the plugin.
     * @param   JTable   $row      A JTable object
     * @param   boolean  $isNew    If the content has just been created
     *
     * @return  boolean  True on success.
     *
     * @since   2.5
     * @throws  Exception on database error.
     */
    public function onFinderAfterSave($context, $row, $isNew)
    {
        // We only want to handle books here
        if ($context == 'com_lendr.book')
        {
            // Check if the access levels are different
            if (!$isNew && $this->old_access != $row->access)
            {
                // Process the change.
                $this->itemAccessChange($row);
            }
 
            // Reindex the item
            $this->reindex($row->id);
        }
        return true;
    }
 
    /**
     * Method to reindex the link information for an item that has been saved.
     * This event is fired before the data is actually saved so we are going
     * to queue the item to be indexed later.
     *
     * @param   string   $context  The context of the content passed to the plugin.
     * @param   JTable   $row     A JTable object
     * @param   boolean  $isNew    If the content is just about to be created
     *
     * @return  boolean  True on success.
     *
     * @since   2.5
     * @throws  Exception on database error.
     */
    public function onFinderBeforeSave($context, $row, $isNew)
    {
        // We only want to handle books here
        if ($context == 'com_lendr.book')
        {
            // Query the database for the old access level if the item isn't new
            if (!$isNew)
            {
                $this->checkItemAccess($row);
            }
        }
 
        return true;
    }
 
    /**
     * Method to update the link information for items that have been changed
     * from outside the edit screen. This is fired when the item is published,
     * unpublished, archived, or unarchived from the list view.
     *
     * @param   string   $context  The context for the content passed to the plugin.
     * @param   array    $pks      A list of primary key ids of the content that has changed state.
     * @param   integer  $value    The value of the state that the content has been changed to.
     *
     * @return  void
     *
     * @since   2.5
     */
    public function onFinderChangeState($context, $pks, $value)
    {
        // We only want to handle articles here
        if ($context == 'com_lendr.book')
        {
            $this->itemStateChange($pks, $value);
        }
        // Handle when the plugin is disabled
        if ($context == 'com_plugins.plugin' && $value === 0)
        {
            $this->pluginDisable($pks);
        }
    }
 
    /**
     * Method to index an item. The item must be a FinderIndexerResult object.
     *
     * @param   FinderIndexerResult  $item    The item to index as an FinderIndexerResult object.
     * @param   string               $format  The item format
     *
     * @return  void
     *
     * @since   2.5
     * @throws  Exception on database error.
     */
    protected function index(FinderIndexerResult $item, $format = 'html')
    {
        // Check if the extension is enabled
        if (JComponentHelper::isEnabled($this->extension) == false)
        {
            return;
        }
 
        $item->setLanguage();
 
        $extension = ucfirst(substr($item->extension, 4));
 
        $item->url = $this->getURL($item->id, $item->extension, $this->layout);
        $item->route = 'index.php?option='.$this->extension.'&view=book&layout='.$this->layout.'&id='.$item->book_id;
 
        // Add the type taxonomy data.
        $item->addTaxonomy('Type', 'Book');
 
        // Add the language taxonomy data.
        $item->addTaxonomy('Language', $item->language);
 
        // Index the item.
        $this->indexer->index($item);
    }
 
    /**
     * Method to get the SQL query used to retrieve the list of books.
     *
     * @param   mixed  $sql  A JDatabaseQuery object or null.
     *
     * @return  JDatabaseQuery  A database object.
     *
     * @since   2.5
     */
    protected function getListQuery($sql = null)
    {
        $db = JFactory::getDbo();
        // Check if we can use the supplied SQL query.
        $sql = $sql instanceof JDatabaseQuery ? $sql : $db->getQuery(true);
        $sql->select('b.book_id as id, b.title, b.author, b.summary, b.pages, b.publish_date');
        $sql->from('#__lendr_books AS b');
        $sql->where($db->quoteName('b.book_id') . ' > 1');
 
        return $sql;
    }
 
    /**
     * Method to get a SQL query to load the published state
     *
     * @return  JDatabaseQuery  A database object.
     *
     * @since   2.5
     */
    protected function getStateQuery()
    {
        $sql = $this->db->getQuery(true);
        $sql->select($this->db->quoteName('b.book_id'));
        $sql->select($this->db->quoteName('b.published') . ' AS book_state');
        $sql->from($this->db->quoteName('#__lendr_books') . ' AS b');
 
        return $sql;
    }
}

Finder пользуется этими функциями, чтобы индексировать таблицы, а также для загрузки данных и при установке ссылок в результатах поиска.

Шаг 5: Подведение итогов

Статья позволила охватить некоторые функции, их структурные особенности. Мы познакомили вас с некоторыми дополнительными идеями, которыми можно воспользоваться при создании любого другого компонента. Нами показан принцип использования Bootstrap для модальных окон.  Нам удалось еще больше углубиться в javascript, познакомиться с его функциональностью и использованием, а также рассмотреть создание плагина. Нами не включался каждый полученный файл или измененная функция с той целью, чтобы сфокусироваться в этой статье на процессе размышления и концепций, окружающих создание компонента.

Следующая статья позволит нам заняться подгоном кода, что позволит перейти к окончанию процесса разработки. Нами будет рассмотрен администраторский интерфейс, применение обновлений на странице при завершении AJAX вызова. Уделим время чистке кода, удалению ненужных файлов и попыткам нахождения путей по упрощению и уменьшению объема кода.

Все статьи цикла:

  1. Каким образом разрабатываются расширения для Joomla! 3.0 – подготовка (Статья 1)
  2. Каким образом разрабатываются расширения для Joomla! 3.0 – начинаем разработку (Статья 2)
  3. Каким образом разрабатываются расширения для Joomla! 3.0 – создаем ядро (Статья 3)
  4. Текущая статья
  5. Каким образом разрабатываются расширения для Joomla! 3.0 – интерфейс администратора и доработка кода (Статья 5)
Портфолио
Память о Вас и Ваших близких на многие поколения
Подробнее
Прокат металла
Подробнее
Интернет-магазин кожи и меха
Подробнее
100% оригинальная парфюмерия в Москве
Подробнее
Вьетнамский ресторан премиум класса
Подробнее
Внедрение информационных систем
Подробнее
Организация международных конференций
Подробнее
Производство молочной продукции
Подробнее
Спортивный сайт
Подробнее
Интернет-магазин мебели и аксессуаров
Подробнее
Интернет-магазин электротранспорта
Подробнее
Сайт института актуальной экономики
Подробнее
Наши клиенты
Парк развлечений Boom Zoom
Алгор
Норбит
Molga Consulting
Metrotile
Нетология
Monqi
Премиум Пак
Aasha Herbals
Аджва
Салон красоты Сударушка
Пава
ТЦ &quot;Панфиловский&quot;
Фитнес Лаборатория
Система Главбух
Vanguard
GoAsia
ТЦ «Солнечный ветер»
Teledoc
Tchernov Cable
Отзывы
Благодарю компанию web-now.pro за помощь в разработке и запуске проекта POLITSECRETS.RU. Перед нами стояла задача – внедрить проект в сжатые сроки и по оптимальной цене. Порадовало то, что мне подроб...
Вера БлашенковаСекреты успешных выборов, Москва... апр.2016
Мне очень понравился подход с которым нас встретили "Ваша задача заниматься бизнесом, наша - сделать Вам представительство в сети". После этого ребята разработали полное тз на проект, мы внесли пожела...
МаксимIT-TASK, Москва... янв.2016
Работа проделана хорошо! Дизайнер и менеджер на отлично. Надеюсь на сотрудничество в дальнейшем. Есть шероховатости в деталях по задачам, но приятно сказывается оперативность и желание исправить, внес...
БруноСоциальная сеть След Жизни, Москва... янв.2016
Работой остались очень довольны. К работе подходят ответственно, аккуратно, открыто. Проект был сдан чуть раньше срока, по ходу работы возникали изменения, все они принимались безоговорочно, работа вы...
ЕвгенийМагазин текстиля, Москва... дек.2015
Сотрудничаем с 2007 года и сделали не один проект. Самое главное - команда умеет отстаивать своё мнение и постоянно развивается.
МарияМеждународные конференции, Москва... дек.2015
Спасибо всему коллективу компании! Разработали красивый и что самое главной рабочий интернет магазин! Реклама настроена и запущена, продажи идут, бизнес развивается! Нам постоянно подсказывают о новых...
ВадимИнтернет магазин Aromatic.pro, Москва... сен.2015
Большое спасибо команде за оперативность, качественные работы, отличный креатив и привлекательные цены!
Виктория, ОАО "Фармстандарт... июль.2015
Здравствуйте уважаемые партнеры! С наступающим Новым Годом! Желаю Вам дальнейшего процветания и успехов в Вашей благородной работе! С вами приятно сотрудничать! Очень благодарен Вам за своевременное о...
Сергей ЮрченкоКинотруд, Москва... дек.2014
Благодарим команду Brand Now и лично Дениса Логинова за оригинальное видение,разнообразие идей, четкость взаимодействия и безукоризненное соблюдение сроков выполнения проекта! Планируем продолжить сот...
ТатьянаBizness Linkerz... июль.2014
Компания КУН выражает благодарность за сотрудничество: непростая задача была выполнена в требуемые сроки и полностью удовлетворила заявленному ТЗ. Приятно удивила готовность Генерального директора нач...
Мария, Компания КУНhttp://www.kuhn.com/... апр.2014
Все отзывы
Добавить отзыв