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

[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 из-за содержания в нем локальных символов. Соответственно...

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

Рутина MySQL

Небольшая заметка по регулярной работе с MySQL.

Китайский Xbox 360 Wireless Reciever и Windows 10 2004 и выше

Начиная с версии Windows 10 2004 обычным способом драйвера на китайский ресивер для джойстиков Xbox 360 не ставятся. Под обычным способом подразумевается установка через ручной выбор устройства из списка, даже если выбрать более старые официальные драйвера.

Outlook 2003 не открывает ссылки

Несколько раз сталкивался с проблемой, что Outlook 2003 отказывается открывать ссылки, предлагая, вместо этого, сохранить на диск...

[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)

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

 
© 2020 Legion Leonhart. При полном или частичном копировании материалов сайта - активная ссылка на сайт обязательна.