Похожие статьи

[Hack] Один материал в нескольких категориях для Joomla 2.5 (мультикатегории)

Обратились ко мне в очередной раз помощью на тему мультикатегорий для Joomla 2.5, также как и в случае с мультикатегориями для Joomla 1.5, только заказчик...

[Hack] Сортировка материалов по их рейтингу в Joomla 2.5

Задача - сделать возможность сортировки по рейтингу материала. Система рейтингов в стандартной конфигурации Joomla 2.5 уже присутствует, но вот возможности сортировать материалы по этим рейтингам почему то нет. Следующими изменениями мы исправим эту досадную оплошность.

Проблема Opera с Joomla и файла mootools-more.js

После последних обновлений Opera 12 возникли проблемы с работой сайтов на движке Joomla, а если быть более точным, то перестала работать библиотека mootools и все что с ней связано соответственно. Проблема связана с сжатием файла mootools-more.js из-за содержания в нем локальных символов. Соответственно...

Последние обновления

Автоматизация получения бесплатных SSL сертификатов на хостинге RUCENTER

Можно долго ругаться на RUCENTER за нежелание дать клиентам виртуального хостинга бесплатные SSL сертификаты, но воз и ныне  там. В связи с этим пользователям остается либо уходить на другой хостинг, либо оставаться без HTTPS протокола и наблюдать неприятные пометки о небезопасности...

Исправление JA Comment для совеместимости с PHP 8 и Joomla 4

Обновление на PHP 8 ( поддержка PHP7 уже завершена) и Joomla 4 (та же причина) приперли к стене многих, но многие сталкиваются с проблемой несовместимости старых расширений для Joomla с новой версией, а многие и вовсе уже не поддерживаются и не обновляются. К таким и относится JA Comment - расширение...

Конвертируем загрузочный диск Windows из Legacy в UEFI

В режиме UEFI загрузка с дисков возможна только если они отформатированы в режиме GPT, в Legacy режиме же наоборот - возможна загрузка только с MBR разделов, поэтому для перехода со старого загрузчика на новый необходима конвертация загрузочного диска.

[Hack] Один материал в нескольких категориях для Joomla 1.5 (мультикатегории)

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

Что делает: каждому материалу можно присвоить несколько категорий, но в пределах одного раздела. При просмотре материала будут показаны все категории, в которых содержится материал (хотя это уже на ваше усмотрение, можете и не показывать). При просмотре раздела, дубликатов, естественно, никаких нет.

Хак требует изменения как базы данных так и нескольких файлов самой Joomla, так что перед тем как редактировать файлы, сделайте их копии.

Приступим: Описание сделано для возможности указания категорий, если нужно больше делайте по аналогии, принцип понять несложно.

Шаг 1 - Выполнить скрипт для БД, где # - префикс таблиц в вашей БД. Лучше всего это делать через phpMyAdmin.

ALTER TABLE `#_content` ADD `catid2` INT ( 11 ) NOT NULL DEFAULT '-1' AFTER `catid` ;
ALTER TABLE `#_content` ADD `catid3` INT ( 11 ) NOT NULL DEFAULT '-1' AFTER `catid2` ;
ALTER TABLE `#_content` ADD INDEX ( `catid2` );
ALTER TABLE `#_content` ADD INDEX ( `catid3` );

Шаг 2 - Обьясняем Joomla, что у нас в таблице content появились новые поля.

Редактируем файл libraries\joomla\database\table\content.php

Ищем

var $catid= null;

Добавляем после

var $catid2= null;
var $catid3= null;

Шаг 3 - Добавляем в админке возможность при создании/редактировании материала указывать несколько категорий
Редактируем файл administrator\components\com_content\admin.content.html.php
Ищем

<?php echo $lists['catid']; ?>

Добавляем после

                </br><?php echo $lists['catid2']; ?>
                </br><?php echo $lists['catid3']; ?>

Редактируем файл administrator\components\com_content\controller.php
Ищем

$javascript = "onchange=\"changeDynaList ( 'catid', sectioncategories, document.adminForm.sectionid.options[document.adminForm.sectionid.selectedIndex].value, 0, 0);\"";

Заменяем на

$javascript = "onchange=\"changeDynaList ( 'catid', sectioncategories, document.adminForm.sectionid.options[document.adminForm.sectionid.selectedIndex].value, 0, 0);changeDynaList ( 'catid2', sectioncategories, document.adminForm.sectionid.options[document.adminForm.sectionid.selectedIndex].value, 0, 0);changeDynaList ( 'catid3', sectioncategories, document.adminForm.sectionid.options[document.adminForm.sectionid.selectedIndex].value, 0, 0);\"";

Ищем

foreach ($cat_list as $cat)
{
if ($cat->section == $section->id) {
$rows2[] = $cat;
}
}

Добавляем после

$sectioncategories[$section->id][] = JHTML::_('select.option', '-1', JText::_( 'Select Category' ), 'id', 'title');

Ищем

$lists['catid'] = JHTML::_('select.genericlist',  $categories, 'catid', 'class="inputbox" size="1"', 'id', 'title', intval ($row->catid));

Добавляем после

$lists['catid2'] = JHTML::_('select.genericlist',  $categories, 'catid2', 'class="inputbox" size="1"', 'id', 'title', intval ($row->catid2));
$lists['catid3'] = JHTML::_('select.genericlist',  $categories, 'catid3', 'class="inputbox" size="1"', 'id', 'title', intval ($row->catid3));

Шаг 4 - Учим Joomla показывать материалы, в которых указано несколько категорий
Редактируем файл components\com_content\models\category.php
Ищем

$where .= ' AND a.catid = '.(int) $this->_id;

Заменяем на

$where .= ' AND (a.catid = '.(int) $this->_id.' OR a.catid2 = '.(int) $this->_id.' OR a.catid3 = '.(int) $this->_id.')';

Шаг 5 - Учим Joomla показывать при просмотре материала все категории, за которыми закреплен данный материал.
Редактируем файл components\com_content\models\article.php
Ищем

$this->_article = $this->_db->loadObject ();

Добавляем после

if ($this->_article->catid2 != -1) {
$query = 'SELECT title'.
' FROM #__categories' .
' WHERE id = '.$this->_article->catid2;
$this->_db->setQuery ($query);
$this->_cat2 = $this->_db->loadObject ();
$this->_article->category2= $this->_cat2->title;
}

if ($this->_article->catid3 != -1) {
$query = 'SELECT title'.
' FROM #__categories' .
' WHERE id = '.$this->_article->catid3;
$this->_db->setQuery ($query);
$this->_cat3 = $this->_db->loadObject ();
$this->_article->category3= $this->_cat3->title;
}

Редактируем файл components\com_content\views\article\tmpl\default.php
Ищем

<?php if ($this->params->get ('link_category')) : ?>
<?php echo '<a href="'.JRoute::_(ContentHelperRoute::getCategoryRoute ($this->article->catslug, $this->article->sectionid)).'">'; ?>
<?php endif; ?>
<?php echo $this->escape ($this->article->category); ?>
<?php if ($this->params->get ('link_category')) : ?>
<?php echo '</a>'; ?>
<?php endif; ?>

Добавляем после

             <?php if ($this->params->get ('link_category') && $this->article->category2) : ?>
<?php echo ',
<a href="'.JRoute::_(ContentHelperRoute::getCategoryRoute ($this->article->catid2, $this->article->sectionid)).'">'; ?>
<?php endif; ?>
<?php echo $this->escape ($this->article->category2); ?>
<?php if ($this->params->get ('link_category') && $this->article->category2) : ?>
<?php echo '</a>'; ?>
<?php endif; ?>
            <?php if ($this->params->get ('link_category') && $this->article->category3) : ?>
<?php echo ',
<a href="'.JRoute::_(ContentHelperRoute::getCategoryRoute ($this->article->catid3, $this->article->sectionid)).'">'; ?>
<?php endif; ?>
<?php echo $this->escape ($this->article->category3); ?>
<?php if ($this->params->get ('link_category') && $this->article->category3) : ?>
<?php echo '</a>'; ?>
<?php endif; ?>

Примечание: эту же операцию необходимо проделать и с используемыми вами шаблонами, если в них есть этот файл. Например его содержит шаблон ja_purity/html/com_content/article/default.php


Шаг 6 - Ну и наконец знакомим другие модули Joomla с нашим хаком (например модули mainmenu и breadcrumbs)
Редактируем файл components\com_content\views\category\view.html.php
Ищем

if (($item->params->get ('show_readmore') && @ $item->readmore) || $item->params->get ('link_titles'))
{

Добавляем после него

$itemid = JRequest::getInt ('id',0);

Далее ищем 

$item->readmore_link = JRoute::_(ContentHelperRoute::getArticleRoute ($item->slug, $item->catslug, $item->sectionid));

Заменяем на

$item->readmore_link = JRoute::_(ContentHelperRoute::getArticleRoute ($item->slug, $itemid, $item->sectionid));

Ищем 

$returnURL = JRoute::_(ContentHelperRoute::getArticleRoute ($item->slug, $item->catslug, $item->sectionid),false);

и заменяем на

$returnURL = JRoute::_(ContentHelperRoute::getArticleRoute ($item->slug, $itemid, $item->sectionid),false);

Шаг 7 - учим админку показывать при фильтрации по категории материалы привязанные к нескольким категориям
Редактируем файл administrator\components\com_content\controller.php
Найти   

$where[] = 'c.catid = ' . (int) $catid;

и заменить на

$where[] = '(c.catid = ' . (int) $catid .' OR c.catid2 = ' . (int) $catid .' OR c.catid3 = '. (int) $catid .')';

Шаг 8 - делаем возможность для материалов привязанных к нескольким категориям в столбце Категория показывать все категории, к которым привязан материал.
Редактируем файл administrator\components\com_content\controller.php
Ищем

// Get the articles
$query = 'SELECT c.*, g.name AS groupname, cc.title AS name, u.name AS editor, f.content_id AS frontpage, s.title AS section_name, v.name AS author' .
' FROM #__content AS c' .
' LEFT JOIN #__categories AS cc ON cc.id = c.catid' .
' LEFT JOIN #__sections AS s ON s.id = c.sectionid' .
' LEFT JOIN #__groups AS g ON g.id = c.access' .
' LEFT JOIN #__users AS u ON u.id = c.checked_out' .
' LEFT JOIN #__users AS v ON v.id = c.created_by' .
' LEFT JOIN #__content_frontpage AS f ON f.content_id = c.id' .
$where .
$order;

и заменяем на      

// Get the articles
$query = 'SELECT c.*, g.name AS groupname, cc.title AS name, cc2.title AS name2, cc3.title AS name3, u.name AS editor, f.content_id AS frontpage, s.title AS section_name, v.name AS author' .
' FROM #__content AS c' .
' LEFT JOIN #__categories AS cc ON cc.id = c.catid' .
' LEFT JOIN #__categories AS cc2 ON cc2.id = c.catid2' .
' LEFT JOIN #__categories AS cc3 ON cc3.id = c.catid3' .
' LEFT JOIN #__sections AS s ON s.id = c.sectionid' .
' LEFT JOIN #__groups AS g ON g.id = c.access' .
' LEFT JOIN #__users AS u ON u.id = c.checked_out' .
' LEFT JOIN #__users AS v ON v.id = c.created_by' .
' LEFT JOIN #__content_frontpage AS f ON f.content_id = c.id' .
$where .
$order;

Редактируем файл administrator\components\com_content\admin.content.html.php

Если хотите вывести список категорий просто в столбик, то делаем следующее. Разделение сделано горизонтальной линией для удобства. Удобно для небольшого колличества категорий, не более 3х.

Ищем (найдется две строки, сделать для обоих)

$row->cat_link = JRoute::_( 'index.php?option=com_categories&task=edit&cid[]='. $row->catid );

и добавляем после :         

$row->cat_link2 = JRoute::_( 'index.php?option=com_categories&task=edit&cid[]='. $row->catid2 );
$row->cat_link3 = JRoute::_( 'index.php?option=com_categories&task=edit&cid[]='. $row->catid3 );

Ищем (найдется две строки, сделать для обоих)      

<a href="/<?php echo $row->cat_link; ?>" title="<?php echo JText::_( 'Edit Category' ); ?>">
<?php echo $row->name; ?></a>

и добавить после них

                        <?php if ($row->catid2 && $row->catid2!=-1) : ?>
<hr><a href="/<?php echo $row->cat_link2; ?>" title="<?php echo JText::_( 'Edit Category' ); ?>">
<?php echo $row->name2; ?></a>
<?php endif; ?>
                        <?php if ($row->catid3 && $row->catid3!=-1) : ?>
<hr><a href="/<?php echo $row->cat_link3; ?>" title="<?php echo JText::_( 'Edit Category' ); ?>">
<?php echo $row->name3; ?></a>
<?php endif; ?>

Если хотите сделать в виде выпадающего списка по нажатию кнопки, то делаем следующее.

Ищем

<a href="/<?php echo $row->cat_link; ?>" title="<?php echo JText::_( 'Edit Category' ); ?>">
<?php echo $row->name; ?></a>

Заменяем на

<?php if (($row->catid2 && $row->catid2!=-1) || ($row->catid3 && $row->catid3!=-1)) : ?>
                    <div class="jpane-toggler"><span><?php echo JText::_( 'SELECT FROM LIST' ); ?></span></div>
                    <div class="jpane-slider">
<a href="/<?php echo $row->cat_link; ?>" title="<?php echo JText::_( 'Edit Category' ); ?>">
<?php echo $row->name; ?></a>
                        <?php if ($row->catid2 && $row->catid2!=-1) : ?>
<hr><a href="/<?php echo $row->cat_link2; ?>" title="<?php echo JText::_( 'Edit Category' ); ?>">
<?php echo $row->name2; ?></a>
<?php endif; ?>
                        <?php if ($row->catid3 && $row->catid3!=-1) : ?>
<hr><a href="/<?php echo $row->cat_link3; ?>" title="<?php echo JText::_( 'Edit Category' ); ?>">
<?php echo $row->name3; ?></a>
<?php endif; ?>
                        </div>
                        <?php else : ?>
                        <a href="/<?php echo $row->cat_link; ?>" title="<?php echo JText::_( 'Edit Category' ); ?>">
<?php echo $row->name; ?></a>
                    <?php endif; ?>

Ищем

<form action="index.php?option=com_content" method="post" name="adminForm">

Добавляем после 

  <script type="text/javascript">
window.addEvent('domready', function(){ new Accordion($$('div.jpane-toggler'), $$('div.jpane-slider'), {onActive: function(toggler, i) { toggler.addClass('jpane-toggler-down'); toggler.removeClass('jpane-toggler'); },onBackground: function(toggler, i) { toggler.addClass('jpane-toggler'); toggler.removeClass('jpane-toggler-down'); },duration: 300,opacity: false,alwaysHide: true}); });
  </script>

Если вы используете нестандартный шаблон админки, вам придется самостоятельно дорабатывать используемые стили jpane-toggler.

Шаг 9 - добавляем возможность указания нескольких категорий в fronted редакторе
Редактируем файл components\com_content\views\article\view.html.php
Ищем

$lists['catid'] = JHTML::_('select.genericlist',  $categories, 'catid', 'class="inputbox" size="1"', 'id', 'title', intval($article->catid));

Добавляем после 

$lists['catid2'] = JHTML::_('select.genericlist',  $categories, 'catid2', 'class="inputbox" size="1"', 'id', 'title', intval($article->catid2));
$lists['catid3'] = JHTML::_('select.genericlist',  $categories, 'catid3', 'class="inputbox" size="1"', 'id', 'title', intval($article->catid3));

найти

$javascript = "onchange=\"changeDynaList( 'catid', sectioncategories, document.adminForm.sectionid.options[document.adminForm.sectionid.selectedIndex].value, 0, 0);\"";

заменить на

$javascript = "onchange=\"changeDynaList ( 'catid', sectioncategories, document.adminForm.sectionid.options[document.adminForm.sectionid.selectedIndex].value, 0, 0);changeDynaList ( 'catid2', sectioncategories, document.adminForm.sectionid.options[document.adminForm.sectionid.selectedIndex].value, 0, 0);changeDynaList ( 'catid3', sectioncategories, document.adminForm.sectionid.options[document.adminForm.sectionid.selectedIndex].value, 0, 0);\"";

найти

foreach ($cat_list as $cat)
{
if ($cat->section == $section->id) {
$rows2[] = $cat;
}
}

Добавляем после

$sectioncategories[$section->id][] = JHTML::_('select.option', '-1', JText::_( 'Select Category' ), 'id', 'title');

Редактируем файл components\com_content\views\article\tmpl\form.php
Ищем

<?php echo $this->lists['catid']; ?>

Добавляем после

        </br><?php echo $this->lists['catid2']; ?>
        </br><?php echo $this->lists['catid3']; ?>

Шаг 10 - Учим Joomla показывать при просмотре раздела или категории все категории, за которыми закреплены материалы.
Редактируем файл components\com_content\models\section.php
найти

$limit= JRequest::getVar('limit', 0, '', 'int');
$limitstart= JRequest::getVar('limitstart', 0, '', 'int');

Добавляем после

$query = 'SELECT id, title'.
' FROM #__categories'.
' WHERE section = '.(int) $this->_id;
$this->_db->setQuery($query);
$this->_cat = $this->_db->loadObjectList();
foreach ($this->_cat as $data)
{
$cati[$data->id] = $data->title;
}

немного ниже найти

// check to determine if section or category has proper access rights
$rows[$i] = $row;

Добавляем после

if ($rows[$i]->catid2 != -1) $rows[$i]->category2= $cati[$rows[$i]->catid2];
if ($rows[$i]->catid3 != -1) $rows[$i]->category3= $cati[$rows[$i]->catid3];

найти

$query = 'SELECT a.id, a.title, a.alias, a.title_alias, a.introtext, a.fulltext, a.sectionid, a.state, a.catid, a.created, a.created_by, a.created_by_alias, a.modified, a.modified_by,' .
' a.checked_out, a.checked_out_time, a.publish_up, a.publish_down, a.attribs, a.hits, a.images, a.urls, a.ordering, a.metakey, a.metadesc, a.access,' .

заменить на

$query = 'SELECT a.*,' .

Редактируем файл components\com_content\models\category.php
найти

$limit= JRequest::getVar('limit', 0, '', 'int');
$limitstart= JRequest::getVar('limitstart', 0, '', 'int');

Добавляем после

$query = 'SELECT id, title'.
' FROM #__categories'.
' WHERE section = '.(int) $this->_category->section;
$this->_db->setQuery($query);
$this->_cat = $this->_db->loadObjectList();
foreach ($this->_cat as $data)
{
$cati[$data->id] = $data->title;
}

найти

// check to determine if section or category has proper access rights
$rows[$i] = $row;

Добавляем после

$rows[$i]->category1= $cati[$rows[$i]->catid];
if ($rows[$i]->catid2 != -1) $rows[$i]->category2= $cati[$rows[$i]->catid2];
if ($rows[$i]->catid3 != -1) $rows[$i]->category3= $cati[$rows[$i]->catid3];

найти

$query = 'SELECT cc.title AS category, a.id, a.title, a.alias, a.title_alias, a.introtext, a.fulltext, a.sectionid, a.state, a.catid, a.created, a.created_by, a.created_by_alias, a.modified, a.modified_by,' .
' a.checked_out, a.checked_out_time, a.publish_up, a.publish_down, a.attribs, a.hits, a.images, a.urls, a.ordering, a.metakey, a.metadesc, a.access,' .

заменить на

$query = 'SELECT cc.title AS category, a.*,' .

Редактируем файл components\com_content\views\section\tmpl\blog_item.php
найти

<?php if ($this->item->params->get('link_category')) : ?>
<?php echo '</a>'; ?>
<?php endif; ?>

Добавляем после

            <?php if ($this->item->params->get ('link_category') && $this->item->category2) : ?>
<?php echo ',
<a href="'.JRoute::_(ContentHelperRoute::getCategoryRoute ($this->item->catid2, $this->item->sectionid)).'">'; ?>
<?php endif; ?>
<?php echo $this->escape ($this->item->category2); ?>
<?php if ($this->item->params->get ('link_category') && $this->item->category2) : ?>
<?php echo '</a>'; ?>
<?php endif; ?>
            <?php if ($this->item->params->get ('link_category') && $this->item->category3) : ?>
<?php echo ',
<a href="'.JRoute::_(ContentHelperRoute::getCategoryRoute ($this->item->catid3, $this->item->sectionid)).'">'; ?>
<?php endif; ?>
<?php echo $this->escape ($this->item->category3); ?>
<?php if ($this->item->params->get ('link_category') && $this->item->category3) : ?>
<?php echo '</a>'; ?>
<?php endif; ?>

Редактируем файл components\com_content\views\category\tmpl\blog_item.php
найти

<?php echo $this->escape($this->item->category); ?>
<?php if ($this->item->params->get('link_category')) : ?>
<?php echo '</a>'; ?>
<?php endif; ?>

Заменить на

<?php echo $this->escape($this->item->category1); ?>
<?php if ($this->item->params->get('link_category')) : ?>
<?php echo '</a>'; ?>
<?php endif; ?>
            <?php if ($this->item->params->get ('link_category') && $this->item->category2) : ?>
<?php echo ',
<a href="'.JRoute::_(ContentHelperRoute::getCategoryRoute ($this->item->catid2, $this->item->sectionid)).'">'; ?>
<?php endif; ?>
<?php echo $this->escape ($this->item->category2); ?>
<?php if ($this->item->params->get ('link_category') && $this->item->category2) : ?>
<?php echo '</a>'; ?>
<?php endif; ?>
            <?php if ($this->item->params->get ('link_category') && $this->item->category3) : ?>
<?php echo ',
<a href="'.JRoute::_(ContentHelperRoute::getCategoryRoute ($this->item->catid3, $this->item->sectionid)).'">'; ?>
<?php endif; ?>
<?php echo $this->escape ($this->item->category3); ?>
<?php if ($this->item->params->get ('link_category') && $this->item->category3) : ?>
<?php echo '</a>'; ?>
<?php endif; ?>

Примечание: эту же операцию с файлами blog_item.php необходимо проделать и с используемыми вами шаблонами, если в них есть этот файл. Например его содержит шаблон ja_purity (ja_purity\html\com_content\section\blog_item.php и ja_purity\html\com_content\category\blog_item.php)

Всё, теперь можете идти в админку и смотреть результат.