RSS   Twitter   Copiny   Copiny
Нашел ошибку? 

Выдели фрагмент текста с ошибкой или неточностью и нажми Ctrl+Enter!

Создание MVC компонента Joomla 1.5 - Шаг 5, Основы фреймворка для Back-end

Добавление функциональности

Итак, пока наш администраторский раздел не очень полезен. Пока он не делает ничего, кроме отображений содержимого базы данных.

Для добавления полезных функций необходимо добавить несколько кнопок и ссылок.

Панель инструментов

Возможно, вы обратили внимание на панель инструментов, отображаемую вверху панелей администратора компонент Joomla. Нашему компоненту она также необходима. Joomla облегчает ее создание. Добавим кнопки Удалить записи, Изменить записи, и Создать новые записи. Также добавим заголовок, который будет отображаться на нашей панели инструментов.

Это можно сделать, добавив немного кода в представление. Чтобы добавить кнопки, используем статические методы из класса JToolBarHelper. Код выглядит так:

JToolBarHelper::title(   JText::_( 'Hello Manager' ), 'generic.png' );
JToolBarHelper::deleteList();
JToolBarHelper::editListX();
JToolBarHelper::addNewX();

Эти три метода создают соответствующие кнопки. Метод deleteList() может принимать три параметра: первый параметр является строкой, спрашивающей пользователя о подтверждении удаления. Второй параметр является задачей, которая отправляется вместе с запросом (по умолчанию "remove"), а третий - текст, отображаемый под кнопкой.

Методы editListX() и addNewX() могут получать два дополнительных параметра. Первый - задача (по умолчанию - соответственно, edit и add), второй - текст, отображаемый под кнопкой.

*Возможно, вы обратили внимание на использование метода JText::_ как в прошлом шаблоне, так и здесь. Это функция, значительно облегчающая перевод компонента. Метод JText::_ ищет текстовую строку в языковом файле компонента и возвращает переведенную строку. Если перевод не найден, функция возвращает строку, переданную ей. Если компонент нужно перевести на другой язык, все, что нужно сделать - создать языковый файл, включающий строки и их перевод на требуемый язык.

Флажки и ссылки

Теперь у нас есть кнопки. Две из этих кнопок управляют существующими записями. Но как узнать, с какими именно записями необходимо работать? Пусть это определит пользователь. Для этого нам нужно добавить флажки в таблицу, чтобы пользователь мог выбрать необходимые записи. Это реализовано в нашем шаблоне.

Для добавления флажков нам необходимо добавить в таблицу дополнительный столбец. Мы добавим столбец между двумя имеющимися.

В заголовке столбца добавим флажок, который можно использовать для выбора или сброса всех флажков:

<th width="20">
    <input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count( $this->items ); ?>);" />
</th>

Функция Javascript checkAll встроена в основной пакет Joomla! Javascript, предоставляющий нужную нам функциональность.

Теперь необходимо добавить флажки в каждую строку. У класса JHTML есть метод JHTML::_(), который создаст для нас флажки. Добавим следующие строки в наш цикл:

$checked = JHTML::_('grid.id',   $i, $row->id );

После строки:

$row = $this->items[$i];

Затем добавим ячейку между двумя имеющимися:

<td>
    <?php echo $checked; ?>
</td>

Необходимость выбирать флажок, перемещаться вверх страницы и нажимать кнопку слишком обременительна. Мы добавим ссылку, позволяющую перейти непосредственно к форме редактирования. Следующие строки добавим после вызова метода JHTML::_() для создания ссылки HTML:

$link = JRoute::_( 'index.php?option=com_hello>controller=hello>task=edit>cid[]='. $row->id );

Добавляем ссылку в ячейку, отображая текст:

<td>
    <a href="/<?php echo $link; ?>"><?php echo $row->greeting; ?></a>
</td>

Обратите внимание, что ссылка указывает на контроллер hello. Этот контроллер обработает данные наших приветствий

Если вы помните, у нас были четыре скрытых поля внизу формы. Первое поле носило имя option. Вторым полем является поле task. Оно получает данные в случае нажатия одной из кнопок на панели инструментов. В случае удаления этого поля будет получена ошибка Javascript и кнопки не будут работать. Третье поле - boxchecked. Оно хранит количество отмеченных флажков. Кнопки редактирования и удаления проверяют условие превышения этой величиной нуля, в противном случае не позволяя отправление данных формы. Четвертое поле - это поле контроллера, используемое для определения того, что данные, отправленные из этой формы, будут обработаны контроллером hello.

Вот полный код файла default.php:

<?php 
/**
 * Default admin hello view for Hello World Component
 * 
 * @package    Joomla.Tutorials
 * @subpackage Components
 * @link http://dev.joomla.org/component/option,com_jd-wiki/Itemid,31/id,tutorials:modules/
 * @license        GNU/GPL
 */

defined('_JEXEC') or die('Restricted access');

?>
<form action="index.php" method="post" name="adminForm">
<div id="editcell">
    <table class="adminlist">
    <thead>
        <tr>
            <th width="5">
                <?php echo JText::_( 'ID' ); ?>
            </th>
            <th width="20">   <!-- checkbox to check all items -->
                <input type="checkbox" name="toggle" value="" onclick="checkAll( <?php echo count($this->items); ?> );" /> 
            </th>
            <th>
                <?php echo JText::_( 'Greeting' ); ?>
            </th>
        </tr>            
    </thead>

    <?php
    $k = 0;

    for ($i=0, $n=count( $this->items ); $i < $n; $i++)
    {
        $row = $this->items[$i];
        $checked = JHTML::_('grid.id', $i, $row->id );     //get checkbox HTML
        // get link HTML to edit task for this greeting
        $link = JRoute::_( 'index.php?option=com_hello&controller=hello&task=edit&cid[]='. $row->id );
    ?>
        <tr class="<?php echo "row$k"; ?>">
            <td>
                <?php echo $row->id; ?>
            </td>
            <td>
                 <?php echo $checked; ?> 
            </td>
            <td>
                <a href="/<?php echo $link; ?>"><?php echo $row->greeting; ?></a>
            </td>
        </tr>
    <?php
        $k = 1 - $k;    //switch row class
    }
    ?>
    </table>
</div>
<input type="hidden" name="option" value="com_hello" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<input type="hidden" name="controller" value="hello" />
</form>

Наше представление hellos закончено. Можно испытывать компонент, чтобы увидеть результаты. Теперь, когда представление Hellos завершено, время обратить внимание на представление и модель Hello. Настоящая работа выполняется именно здесь.

Контроллер Hello

Единственной работой контроллера по умолчанию является отображение представлений.

Вы должны иметь возможность выполнять задачи, запускаемые из представления Hellos: добавлять, изменять и удалять.

Фактически, добавление и изменение являются одним и тем же заданием: они оба отображают пользователю форму, позволяющую редактировать приветствие. Единственная разница в том, что при создании отображается пустая форма, а при изменении - форма с данными. Поскольку они являются похожими, мы будем выполнять задачу добавления с помощью обработчика задачи изменения. Это указывается в нашем конструкторе:

/**
 * constructor (registers additional tasks to methods)
 * @return void
 */
function __construct()
{
    parent::__construct();

    // Регистрация дополнительных задач 
    $this->registerTask( 'add'  ,     'edit' );
}

Первый параметр JController::registerTask является задачей, второй - метод ее выполнения

Начнем с обработки задачи изменения. В этом случае работа контроллера проста. Все, что ему нужно - указать представление и макет для загрузки (в нашем случае представление hello и макет формы). Мы также укажем Joomla отключить главное меню во время изменения приветствия. Это предотвращает оставление открытых несохраненных записей.

Наш обработчик задачи изменения выглядит следующим образом:

/**
 * display the edit form
 * @return void
 */
function edit()
{
    JRequest::setVar( 'view', 'hello' );
    JRequest::setVar( 'layout', 'form'  );
    JRequest::setVar('hidemainmenu', 1);

    parent::display();
}

Представление Hello

Представление Hello отображает форму, позволяющую пользователю редактировать приветствие. Метод display должен выполнять несколько простых операций:

  • получить данные из модели
  • создать панель инструментов
  • поместить данные в шаблон
  • вызвать метод display() для отрисовки шаблона

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

Когда мы получаем запись для отображения из модели, мы можем использовать эти данные для определения текущей задачи. Если задачей является редактирование, значит, поле id записи было изменено. Если это новая задача, значит, его значение не будет установлено. Эта деталь может помочь определить, создается ли новая запись, или редактируется существующая.

Также добавим на панель инструментов две кнопки: close и cancel. Функциональность будет практически одинаковой, но в зависимости от текущей задачи отображаться будут разные кнопки. В случае новой записи будет отображаться кнопка cancel, а в случае изменения существующей - кнопка close.

Итак, метод display будет выглядеть так:

/**
 * display method of Hello view
 * @return void
 **/
function display($tpl = null)
{
    //получаем приветствие
    $hello        = $this->get('Data');
    $isNew        = ($hello->id < 1);

    $text = $isNew ? JText::_( 'New' ) : JText::_( 'Edit' );
    JToolBarHelper::title(   JText::_( 'Hello' ).': <small><small>[ ' . $text.' ]</small></small>' );
    JToolBarHelper::save();
    if ($isNew)  {
        JToolBarHelper::cancel();
    } else {
        // для существующих записей кнопка переименовывается на `close`
        JToolBarHelper::cancel( 'cancel', 'Close' );
    }

    $this->assignRef('hello',        $hello);
    parent::display($tpl);
}

Модель Hello

Для нашего представления необходимы данные. Это значит, что нужно создать соответствующую модель.

У нашей модели будут два свойства: _id и _data. _id будет хранить идентификатор приветствия, data - данные.

Начнем с конструктора, который получает id из запроса:

/**
 * Constructor that retrieves the ID from the request
 *
 * @access    public
 * @return    void
 */
function __construct()
{
    parent::__construct();

    $array = JRequest::getVar('cid',  0, '', 'array');
    $this->setId((int)$array[0]);
}

Метод JRequest::getVar() используется для получения данных из запроса. Первым параметром является имя переменной формы. Второй параметр - значение по умолчанию для присвоения в случае, если значение не найдено. Третий параметр - это имя хэша для получения значения из get, post, и т.д., и последнее значение - тип данных, который следует установить для значения.

Конструктор получит первое значение из массива cid и присвоит его id.

Метод setId() может использоваться для установки id. Изменение id, на которое указывает наша модель, означает, что points указывает на неправильные данные. Следовательно, устанавливая значение id, мы очищаем свойство data:

/**
 * Method to set the hello identifier
 *
 * @access    public
 * @param    int Hello identifier
 * @return    void
 */
function setId($id)
{
    // Устанавливаем id и удаляем данные
    $this->_id        = $id;
    $this->_data    = null;
}

Наконец, нам нужен метод для получения data: getData()

getData проверит, установлено ли значение свойства _data. Если да, он просто возвратит его. В противном случае будут получены данные из базы данных.

/**
 * Method to get a hello
 * @return object with data
 */

function &getData()
{
    // Загружаем данные
    if (empty( $this->_data )) {
        $query = ' SELECT * FROM #__hello '.
                '  WHERE id = '.$this->_id;
        $this->_db->setQuery( $query );
        $this->_data = $this->_db->loadObject();
    }
    if (!$this->_data) {
        $this->_data = new stdClass();
        $this->_data->id = 0;
        $this->_data->greeting = null;
    }
    return $this->_data;
}

Форма

Наконец, все что нам осталось - создать форму для данных. Поскольку мы определили макет как форму, форма будет размещена в файле каталога tmpl представления hello под именем form.php:

<?php defined('_JEXEC') or die('Доступ ограничен!'); ?>
<form action="index.php" method="post" name="adminForm" id="adminForm">
<div class="col100">
    <fieldset class="adminform">
        <legend><?php echo JText::_( 'Details' ); ?></legend>
        <table class="admintable">
        <tr>
            <td width="100" align="right" class="key">
                <label for="greeting">
                    <?php echo JText::_( 'Greeting' ); ?>:
                </label>
            </td>
            <td>
                <input class="text_area" type="text" name="greeting" id="greeting" size="32" maxlength="250" value="<?php echo $this->hello->greeting;?>" />
            </td>
        </tr>
    </table>
    </fieldset>
</div>
<div class="clr"></div>
<input type="hidden" name="option" value="com_hello" />
<input type="hidden" name="id" value="<?php echo $this->hello->id; ?>" />
<input type="hidden" name="task" value="" />
<input type="hidden" name="controller" value="hello" />
</form>

Обратите внимание: в дополнение к полю ввода присутствует скрытое поле для id. Пользователь не должен изменять id, поэтому мы просто незаметно помещаем его в форму.

Смотрите также:
Комментарии (47) Добавить комментарий
  • Uphotaaccorce
    Uphotaaccorce
    16 Марта 2011, 00:48
     ↑  0  ↓     ответ

    Nice site . :)

  • Юрий
    Юрий
    27 Ноября 2011, 01:32
     ↑  +2  ↓     ответ

    вот в этой строчке ошибка:

    $link = JRoute::_( 'index.php?option=com_hello>controller=hello>task=edit>cid[]='. $row->id );

    нужно заменить > на &

  • Юрий
    Юрий
    27 Ноября 2011, 03:52
     ↑  +5  ↓     ответ

    Мда, конечно спасибо, но чем дальше в лес тем больше дров. Можно ж было всю статью перевести а не кусками да и перевод хромает. Если лениво всю статью переводить или пользуетесь автоматическим переводчиком, так хоть поставьте ссылку на оригинал, чтобы пользователь мог дочитать все что вы не перевели и не дописали.

    Для всех кто дошел до этого урока и чот недопонимает, вот ссылка на оригинал:

    docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_6_-_Adding_Backend_Actions

  • Сергей
    Сергей
    20 Декабря 2011, 22:56
     ↑  +1  ↓     ответ

    Юрий, огромное спасибо за ссылку, читать оригинал на много понятнее!

  • Илья
    Илья
    27 Февраля 2013, 23:52
     ↑  0  ↓     ответ

    Да. не аккуратно сделали!

  • Александр
    Александр
    25 Марта 2013, 20:57
     ↑  0  ↓     ответ

    Ничего не понял. Работаем вроде в административной части, потом резко прыгаем на фронт ? Может я не так понимаю что-то ?

  • http://tinyurl.com/quest-bars-cheap-77971
    http://tinyurl.com/quest-bars-cheap-77971
    24 Ноября 2019, 02:58
     ↑  0  ↓     ответ

    I loved as much as you will receive carried out right here.

    The sketch is attractive, your authored material stylish.

    nonetheless, you command get bought an nervousness over

    that you wish be delivering the following. unwell unquestionably come further

    formerly again since exactly the same nearly very often inside

    case you shield this increase.

  • tinyurl.com
    tinyurl.com
    25 Ноября 2019, 07:14
     ↑  0  ↓     ответ

    This info is invaluable. Where can I find

    out more?

  • coconut oil are
    coconut oil are
    25 Ноября 2019, 22:44
     ↑  0  ↓     ответ

    We're a group of volunteers and starting a new scheme

    in our community. Your web site provided us with valuable info to work on. You've done a

    formidable job and our entire community will be thankful to you.

  • plenty of fish dating site
    plenty of fish dating site
    26 Ноября 2019, 16:40
     ↑  0  ↓     ответ

    I like the valuable info you supply for your articles.

    I'll bookmark your blog and test again right here regularly.

    I'm fairly sure I will be informed many new stuff right here!

    Best of luck for the next!

  • ps4 games
    ps4 games
    29 Ноября 2019, 10:14
     ↑  0  ↓     ответ

    I am curious to find out what blog platform you are working with?

    I'm having some minor security problems with my latest blog and I'd

    like to find something more risk-free. Do you have any suggestions?

  • quest bars cheap
    quest bars cheap
    30 Ноября 2019, 14:10
     ↑  0  ↓     ответ

    It's nearly impossible to find experienced people for this subject, however,

    you seem like you know what you're talking about! Thanks

  • quest bars cheap
    quest bars cheap
    01 Декабря 2019, 17:53
     ↑  0  ↓     ответ

    Hello to all, how is the whole thing, I think every one is getting more from this

    web site, and your views are fastidious designed for new people.

  • quest bars cheap
    quest bars cheap
    02 Декабря 2019, 17:20
     ↑  0  ↓     ответ

    An impressive share! I have just forwarded this onto a colleague who had been doing a little homework on this.

    And he in fact bought me lunch because I found

    it for him... lol. So let me reword this.... Thanks

    for the meal!! But yeah, thanx for spending time

    to discuss this topic here on your site.

  • quest bars cheap coupon twitter
    quest bars cheap coupon twitter
    03 Декабря 2019, 06:53
     ↑  0  ↓     ответ

    Hey! Do you know if they make any plugins to safeguard against hackers?

    I'm kinda paranoid about losing everything I've worked hard on. Any

    suggestions?

  • quest bars cheap coupon twitter
    quest bars cheap coupon twitter
    03 Декабря 2019, 14:13
     ↑  0  ↓     ответ

    I'm really loving the theme/design of your website. Do you ever run into any

    browser compatibility issues? A small number of my blog visitors have complained about my site not working correctly in Explorer but looks great in Opera.

    Do you have any tips to help fix this issue?

  • ps4 games
    ps4 games
    06 Декабря 2019, 03:37
     ↑  0  ↓     ответ

    Highly descriptive article, I loved that bit.

    Will there be a part 2?

  • ps4 games
    ps4 games
    06 Декабря 2019, 10:42
     ↑  0  ↓     ответ

    Excellent site. Plenty of helpful info here.

    I am sending it to a few buddies ans also sharing in delicious.

    And obviously, thanks in your effort!

  • ps4 games
    ps4 games
    06 Декабря 2019, 20:08
     ↑  0  ↓     ответ

    I have read a few just right stuff here. Certainly worth bookmarking for

    revisiting. I surprise how much attempt you put to make one of these magnificent informative website.

  • ps4 games
    ps4 games
    07 Декабря 2019, 08:46
     ↑  0  ↓     ответ

    Hi there colleagues, fastidious paragraph and fastidious arguments commented here, I am genuinely

    enjoying by these.

  • quest bars cheap
    quest bars cheap
    09 Декабря 2019, 19:46
     ↑  0  ↓     ответ

    I take pleasure in, result in I discovered just what I was having

    a look for. You have ended my four day long hunt! God Bless you man. Have a great day.

    Bye

  • ps4 games
    ps4 games
    13 Декабря 2019, 15:19
     ↑  0  ↓     ответ

    It's not my first time to pay a visit this web

    page, i am visiting this web site dailly and obtain pleasant

    information from here every day.

  • ps4 games
    ps4 games
    14 Декабря 2019, 06:35
     ↑  0  ↓     ответ

    If you are going for best contents like myself, only go to see this web

    site everyday as it gives quality contents, thanks

  • coconut oil
    coconut oil
    16 Декабря 2019, 11:40
     ↑  0  ↓     ответ

    I just like the valuable info you supply in your articles. I'll bookmark your weblog and take a look at once more here regularly.

    I am moderately certain I will be told lots of new stuff right right here!

    Good luck for the following!

  • coconut oil
    coconut oil
    16 Декабря 2019, 12:15
     ↑  0  ↓     ответ

    I really like looking through a post that will make men and women think.

    Also, thank you for allowing me to comment!

  • coconut oil
    coconut oil
    18 Декабря 2019, 07:16
     ↑  0  ↓     ответ

    Do you have any video of that? I'd want to find out more details.

  • coconut oil
    coconut oil
    21 Декабря 2019, 17:40
     ↑  0  ↓     ответ

    It's awesome to visit this site and reading the views of all mates concerning this post, while I am also zealous of getting

    experience.

  • http://sinnedbeyondhelp.tumblr.com/
    http://sinnedbeyondhelp.tumblr.com/
    28 Декабря 2019, 12:09
     ↑  0  ↓     ответ

    I got this website from my pal who shared with me

    regarding this site and now this time I am visiting this site and reading very informative articles at this place.

  • match.com free trial
    match.com free trial
    30 Декабря 2019, 05:34
     ↑  0  ↓     ответ

    These are really fantastic ideas in concerning blogging.

    You have touched some fastidious things here. Any way keep up wrinting.

  • plenty of fish vs match.com free trial
    plenty of fish vs match.com free trial
    30 Декабря 2019, 19:30
     ↑  0  ↓     ответ

    Good day I am so delighted I found your site, I really

    found you by error, while I was looking on Askjeeve for something else,

    Nonetheless I am here now and would just like to say thanks

    a lot for a marvelous post and a all round thrilling blog (I also love the theme/design),

    I don't have time to read it all at the minute but I have saved it and also added your RSS feeds, so when I

    have time I will be back to read a great deal more, Please do

    keep up the excellent job.

  • match.com free trial
    match.com free trial
    31 Декабря 2019, 09:00
     ↑  0  ↓     ответ

    Hmm it seems like your site ate my first comment (it was super long) so I guess

    I'll just sum it up what I wrote and say, I'm thoroughly enjoying your blog.

    I as well am an aspiring blog writer but I'm still new to the whole thing.

    Do you have any tips and hints for inexperienced blog

    writers? I'd genuinely appreciate it.

  • https://russellwebster.tumblr.com/
    https://russellwebster.tumblr.com/
    01 Января 2020, 02:59
     ↑  0  ↓     ответ

    This is really fascinating, You're an excessively professional blogger.

    I have joined your feed and stay up for in quest

    of more of your excellent post. Also, I have shared your website in my social networks

  • sling tv
    sling tv
    01 Января 2020, 17:51
     ↑  0  ↓     ответ

    Thank you for the good writeup. It in fact was a amusement account it.

    Look advanced to more added agreeable from you! However,

    how can we communicate?

  • tinyurl.com
    tinyurl.com
    02 Января 2020, 18:54
     ↑  0  ↓     ответ

    Pretty! This has been an incredibly wonderful post.

    Thanks for supplying this information.

  • sling tv
    sling tv
    03 Января 2020, 13:50
     ↑  0  ↓     ответ

    What's up to every one, the contents present at this web page are genuinely amazing for people knowledge,

    well, keep up the good work fellows.

  • sling tv https://asksylphoflight.tumblr.com/
    sling tv https://asksylphoflight.tumblr.com/
    05 Января 2020, 11:18
     ↑  0  ↓     ответ

    Remarkable things here. I'm very glad to look your article.

    Thanks so much and I am taking a look ahead to contact

    you. Will you please drop me a e-mail?

  • sling tv
    sling tv
    07 Января 2020, 07:13
     ↑  0  ↓     ответ

    You need to be a part of a contest for one of the greatest sites on the web.

    I most certainly will recommend this web site!

  • sling tv
    sling tv
    07 Января 2020, 20:14
     ↑  0  ↓     ответ

    Your style is very unique in comparison to other folks I've read stuff from.

    Thank you for posting when you've got the opportunity, Guess I'll just book

    mark this site.

  • sling tv
    sling tv
    08 Января 2020, 02:23
     ↑  0  ↓     ответ

    After checking out a handful of the blog articles on your site, I really like your technique of

    writing a blog. I book-marked it to my bookmark site

    list and will be checking back in the near future. Take a look at my website as well and let me know your opinion.

  • sling tv
    sling tv
    14 Января 2020, 12:47
     ↑  0  ↓     ответ

    A fascinating discussion is definitely worth comment. I do

    think that you should publish more about this subject, it may not be

    a taboo matter but usually folks don't speak about these subjects.

    To the next! Best wishes!!

  • sling tv
    sling tv
    15 Января 2020, 18:36
     ↑  0  ↓     ответ

    What's up, just wanted to say, I enjoyed this article.

    It was practical. Keep on posting!

  • sling tv
    sling tv
    17 Января 2020, 07:13
     ↑  0  ↓     ответ

    If you want to improve your experience just keep visiting this web site and be

    updated with the hottest news posted here.

  • sling tv
    sling tv
    18 Января 2020, 15:43
     ↑  0  ↓     ответ

    Very nice post. I just stumbled upon your blog and wished to

    say that I've really enjoyed surfing around your blog

    posts. After all I'll be subscribing to your feed and I hope you write again very

    soon!

  • sling tv
    sling tv
    19 Января 2020, 09:17
     ↑  0  ↓     ответ

    My brother suggested I might like this website. He was totally right.

    This post truly made my day. You can not imagine simply how

    much time I had spent for this info! Thanks!

  • sling tv best package 2020
    sling tv best package 2020
    25 Января 2020, 02:50
     ↑  0  ↓     ответ

    Thanks for finally writing about >Создание MVC компонента Joomla 1.5 - Шаг

    5, Основы фреймворка для Back-end / Создание компонентов .:.

    Документация Joomla! CMS <Loved it!

  • sling tv
    sling tv
    29 Января 2020, 05:38
     ↑  0  ↓     ответ

    you are actually a just right webmaster.

    The web site loading pace is amazing. It kind of feels that you're doing any distinctive trick.

    In addition, The contents are masterpiece. you have performed

    a great activity in this topic!

  • cbd oil that works 2020
    cbd oil that works 2020
    04 Апреля 2020, 21:31
     ↑  0  ↓     ответ

    I am curious to find out what blog platform you have been working with?

    I'm experiencing some small security problems with my latest site and I'd like to find something more safe.

    Do you have any solutions?

Оставить комментарий




* обязательно для заполнения

1 введенный почтовый адрес используется только для обратной связи при ответах в комментариях и сервиса gravatar.com
.