Новости Joomla

0 Пользователей и 1 Гость просматривают эту тему.
  • 9 Ответов
  • 2402 Просмотров
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
Решил поделится решением для формирования ЧПУ ссылок от бэкенда к фронтэнду Joomla средствами PHP
Дело в том что с помощью JRoute::_(..) метода, это сделать не получится. Поэтому написал вот такой костыль:
Код: php
function buildSefLink($link) //в качестве параметра ссылка в формате "index.php?option=com_xxx&view=xxx..."
{
    $router = JRouter::getInstance('site');
    $router->setMode(JROUTER_MODE_SEF);
    $uri = $router->build($link);
    //еще подстава. этого бы не потребовалось если бы роутер формировал абсолютный путь на основе его класса(JRouterSite или JRouterAdministrator)
    $path = str_replace(JURI::base(true).'/', JURI::root(), $uri->getPath());
    $uri->setPath($path);
    $url = $uri->toString(array('path', 'query', 'fragment'));
    return $url;
}
echo buildSefLink('index.php?&option=com_content&view=article&id=1');

Если у кого-то есть более простые решения, предлагайте ^-^
интернет-блог: http://websiteprog.ru
*

Aleks.Denezh

  • Живу я здесь
  • 3406
  • 428 / 4
Все это конечно хорошо, но ссылка то никак не связанна с меню, а это дубли, я уже молчу о том что например у меня в компоненте есть такая хрень:
Код: php
$menu = JMenuSite::getInstance( 'site' )->getActive();
$catId = 0;
if ( $menu->query['view'] === 'category' ) {
$catId = $menu->query['id'];
}
$alias = str_replace( ':', '-', $this->input->getString( 'id' ) );
$query = $this->getDbo()->getQuery( true )
->select( '*' )
->from( '#__article' )
->where( 'catid=' . $catId )
->where( 'alias=' . $this->getDbo()->q( $alias ) );
$item = $this->getDbo()->setQuery( $query )->loadObject();

if ( empty( $item->id ) ) {
throw new Exception( 'Материал не найден', 404 );
}

То есть как видите id категории берется из текущего пункта меню, если ссылка будет без пункта меню, то получим ошибку вот вам даже пример:  http://ссылка вырезана, так как домен распространяет вирусы/component/news/ajax-v-joomla-3-2
Так что надо продумать как строить ссылку с учетом ещё и процесса формирования ссылок
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
дык itemid передавайте в билдер buildSefLink('index.php?&option=com_content&view=article&id=1&itemid=101');
id наверное даже можно опустить при этом..собственно тут все те же операции выполняются что и в JRoute::_(...), Ну кроме добавления https суффикса в случае ssl 
« Последнее редактирование: 08.05.2014, 16:39:55 от zomby6888 »
интернет-блог: http://websiteprog.ru
*

Aleks.Denezh

  • Живу я здесь
  • 3406
  • 428 / 4
дык itemid передавайте в билдер buildSefLink('index.php?&option=com_content&view=article&id=1&itemid=101');
id наверное даже можно опустить при этом..
А вы думаете я не догадался? но ссылка тоже не так что у меня! naseleniyu/goryachaya-liniya.html?id=1
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
ну это я просто плохой пример привел, вобще ссылки на материалы com_content формирует его собственный хелпер, что типа этого
ContentHelperRoute::getArticleRoute($this->item->slug, $this->item->catid)
это более частный случай уже. Эта ссылка потом в Jroute::_(...) помещается вроде как
интернет-блог: http://websiteprog.ru
*

Aleks.Denezh

  • Живу я здесь
  • 3406
  • 428 / 4
ну это я просто плохой пример привел, вобще ссылки на материалы com_content формирует его собственный хелпер, что типа этого
ContentHelperRoute::getArticleRoute($this->item->slug, $this->item->catid)
это более частный случай уже
Вот в том то и проблема основная в пользовательской части это:
echo JRoute::_( 'index.php?&option=com_content&view=article&id=1&Itemid=150' ); отдаст naseleniyu/goryachaya-liniya.html
в админке же ваш код naseleniyu/goryachaya-liniya.html?id=1
*

Aleks.Denezh

  • Живу я здесь
  • 3406
  • 428 / 4
Вот помню нужно было с под админки формировать ссылки в рассылке, и там также был навороченный чпу, с привязкой к Itemid, у меня была подобная конструкция:

Код: php
class NewsRoute{
private static $items = null;
static function articleRoute( $alias, $catId )
{
if ( is_null( self::$items ) ) {
$menuItems = JMenu::getInstance( 'site' )->getItems( 'component', 'com_news' );
foreach ( $menuItems as $menuItem ) {
if ( isset( $menuItem->query['view'] ) && $menuItem->query['view'] === 'category' ) {
self::$items[$menuItem->query['id']] = $menuItem->route;
}
}
}
return JUri::root(). self::$items[$catId] . '/' . $alias;
}
}
echo NewsRoute::articleRoute( 'ajax-v-joomla-3-2', 25 );

Выдает корректную ссылку: http://ссылка вырезана, так как домен распространяет вирусы/blog/joomla/ajax-v-joomla-3-2

Но мой вариант как и ваш тоже для частных случаев, не думаю что получится написать универсальный для всего!
« Последнее редактирование: 08.05.2014, 17:18:56 от Istaan »
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
Да действительно с меню есть проблемка. Но я думаю и это тоже лечится, сейчас подумаю что можно сделать..
интернет-блог: http://websiteprog.ru
*

zomby6888

  • Завсегдатай
  • 1473
  • 171 / 3
А ну в общем то все работает просто в com_content как я выше писал по другому линк формируется:
Код: php
echo buildSefLink('index.php?option=com_content&view=article&id=1:test&catid=2&Itemid=101');
Попробуйте и в админке тоже нормальная ссылка формируется. Здесь 1:test - это так называемый slug,  который формируется из id и алиаса материала. Вобще сам линк можно хелпером получить, который я выше упоминал:
Код: php
$article->slug = $article->alias ? ($article->id . ':' . $article->alias) : $article->id;
$article->catid;
ContentHelperRoute::getArticleRoute($article->slug, $article->catid);

и этот линк можно дальше билдить для ЧПУ
интернет-блог: http://websiteprog.ru
*

VsVoland

  • Осваиваюсь на форуме
  • 43
  • 1 / 0
  • Путь рождается под ногами идущего.
Внесу и свою лепту в обсуждение.:)
Решение, которое я применил, тоже не универсальное, оно конкретно в данном случае, применимо только к компоненту com_content. Но как принцип может быть использовано и в других похожих случаях.

Суть в том, что даже если я в каком-нибудь своем коде, исполняемом в админке (например плагин расширяющий редактор) внесу конструкцию:

Код: php
$nonSefUrl = ContentHelperRoute::getArticleRoute($articleSlug,$categoryId);
$app = JApplicationCms::getInstance('site');
$router = $app::getRouter('site');
$this->articleUrl =  str_replace('administrator//administrator/','',JURI::base().$router->build($nonSefUrl));

то на выходе у меня (joomla 3.3), получается SEF ссылка, но с ошибкой: в алиас подкатегории дописывался алиас родительской категории. Это могло выглядеть так:
/video/13-video/dances/3-first-video-dance
хотя правильной ссылкой будет:
/video/13-dances/3-first-video-dance
Вариантов кода перепробовал много, все какие давали SEF - все с одинаковой ошибкой.

В общем, покопался в коде,  и нашел что проблему создает роутер компонента материалов, тем что он в своей работе использует ссылку на объект приложения "administrator", из-за этого в дальнейшем проблемно получить правильные ссылки. Для правильных ссылок он должен работать с объектом фронтенда. То есть, если в файле components/com_content/router.php в строке 35 вместо:
JFactory::getApplication();
написать:
JApplicationCms::getInstance('site');
то указанная выше конструкция возвращает правильную чпу-ссылку.

Редактировать сам роутер - не дело, поэтому проблему решил тем, что создал новый системный плагин, который в админке, в контексте "com_content" переопределяет код роутера материалов. При этом роутер на лицевой панели сайта - действует родной. Сам код системного плагина может быть примерно таким:

Код: php
<?php
defined("_JEXEC") or die("Access denied.");
defined("DS") or define(DS,DIRECTORY_SEPARATOR);
$application = JFactory::getApplication();
if("com_content" == JRequest::getCMD("option") && $application->isAdmin()) {
    require_once dirname(__FILE__).DS."contentrouter".DS."router.php";
}
где require_once dirname(__FILE__).DS."contentrouter".DS."router.php" - это отредактированный файл роутера компонента материалов, размещенного в файловой системе плагина.
Если хотите более подробно посмотреть, то я это описал здесь: http://webengineer.pro/refinement-of-joomla-and-her-extensions/23-generatsiya-sef-url-v-administrativnoy-chasti-sistemy-joomla-3.

Конечно, пока не могу сказать насколько это хорошее решение и стабильное (срок работы пока маленький), но пока никаких проблем не обнаружил.
Может кому пригодится.
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться