Всем доброго времени суток! Уважаемые "знающие и понимающие" очень нужна Ваша помощь! Постараюсь максимально обрисовать проблему: Меню сайта работает на JoomlaXTC JMenu Plus Beta 2.0, какие я не пробовал известные способы вставки rel="nofollow" как со стандартным mod_mainmenu (там всё закрывается отлично известными способами!), у меня с этим детищем JoomlaXTC ничего не получается. На сколько я понял меню работает с применением JS. Увы, с программированием у меня пока туго, но поправимо - есть желание учится. На сайте включен sh404SEF, отключение ничего не дало. Выкладываю коды файлов меню с надеждой на то, что кто-то ткнёт носом где копать. Итак: helper.php: Код (CODE): <?php /* JoomlaXTC JMenu Module version 1.0 Copyright (C) 2009 Monev Software LLC. All Rights Reserved. based on work done by Open Source Matters This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA See COPYRIGHT.php for more information. See LICENSE.php for more information. Monev Software LLC www.joomlaxtc.com */ // no direct access defined('_JEXEC') or die('Restricted access'); jimport('joomla.base.tree'); jimport('joomla.utilities.simplexml'); if (!class_exists('modJxtcMenuHelper')) { class modJxtcMenuHelper { function buildXML(&$params) { $menu = new JxtcMenuTree($params); $items = &JSite::getMenu(); // Get Menu Items $rows = $items->getItems('menutype', $params->get('menutype')); $maxdepth = $params->get('maxdepth',10); // Build Menu Tree root down (orphan proof - child might have lower id than parent) $user =& JFactory::getUser(); $ids = array(); $ids[0] = true; $last = null; $unresolved = array(); // pop the first item until the array is empty if there is any item if ( is_array($rows)) { while (count($rows) && !is_null($row = array_shift($rows))) { if (array_key_exists($row->parent, $ids)) { $row->ionly = $params->get('menu_images_link'); $menu->addNode($params, $row); // record loaded parents $ids[$row->id] = true; } else { // no parent yet so push item to back of list // SAM: But if the key isn't in the list and we dont _add_ this is infinite, so check the unresolved queue if(!array_key_exists($row->id, $unresolved) || $unresolved[$row->id] < $maxdepth) { array_push($rows, $row); // so let us do max $maxdepth passes // TODO: Put a time check in this loop in case we get too close to the PHP timeout if(!isset($unresolved[$row->id])) $unresolved[$row->id] = 1; else $unresolved[$row->id]++; } } } } $buttonClasses=explode(',',$params->get('ButtonClasses')); return $menu->toXML($buttonClasses); } function &getXML($type, &$params, $decorator) { static $xmls; if (!isset($xmls[$type])) { $cache =& JFactory::getCache('mod_jxtc_jmenu'); $string = $cache->call(array('modJxtcMenuHelper', 'buildXML'), $params); $xmls[$type] = $string; } // Get document $xml = JFactory::getXMLParser('Simple'); $xml->loadString($xmls[$type]); $doc = &$xml->document; $menu = &JSite::getMenu(); $active = $menu->getActive(); $start = $params->get('startLevel'); $end = $params->get('endLevel'); $sChild = $params->get('showAllChildren'); $path = array(); // Get subtree if ($start) { $found = false; $root = true; if(!isset($active)){ $doc = false; } else{ $path = $active->tree; for ($i=0,$n=count($path);$i<$n;$i++) { foreach ($doc->children() as $child) { if ($child->attributes('id') == $path[$i]) { $doc = &$child->ul[0]; $root = false; break; } } if ($i == $start-1) { $found = true; break; } } if ((!is_a($doc, 'JSimpleXMLElement')) || (!$found) || ($root)) { $doc = false; } } } if ($doc && is_callable($decorator)) { $doc->map($decorator, array('end'=>$end, 'children'=>$sChild)); } return $doc; } function render(&$params, $callback) { $doc =&JFactory::getDocument(); switch ( $params->get( 'menu_style', 'list' ) ) { case 'list_flat' : $doc->addStyleSheet("modules/mod_jxtc_jmenu/css/standardmenu.css"); // Include the legacy library file require_once(dirname(__FILE__).DS.'legacy.php'); mosShowHFMenu($params, 1); break; case 'horiz_flat' : $doc->addStyleSheet("modules/mod_jxtc_jmenu/css/standardmenu.css"); // Include the legacy library file require_once(dirname(__FILE__).DS.'legacy.php'); mosShowHFMenu($params, 0); break; case 'vert_indent' : $doc->addStyleSheet("modules/mod_jxtc_jmenu/css/standardmenu.css"); // Include the legacy library file require_once(dirname(__FILE__).DS.'legacy.php'); mosShowVIMenu($params); break; case 'vert_2col' : $doc->addStyleSheet("modules/mod_jxtc_jmenu/css/standardmenu.css"); // Include the legacy library file require_once(dirname(__FILE__).DS.'legacy.php'); mosShowHFMenu($params, 2); break; default : $menuSpeed = $params->get('menuSpeed',300); $mooStyle = $params->get('mooStyle','Bounce.easeOut'); switch ( $params->get( 'menu_style', 'list' ) ) { case 'horz_moo' : // Include the legacy library file $doc->addStyleSheet("modules/mod_jxtc_jmenu/css/moodropin.css"); $doc->addScriptDeclaration('var menuSpeed = '.$menuSpeed.';var mooStyle = '.$mooStyle.';'); $doc->addScript("modules/mod_jxtc_jmenu/js/moodropin.js"); break; case 'horz_dropline' : // Include the legacy library file $doc->addStyleSheet("modules/mod_jxtc_jmenu/css/moodropline.css"); $doc->addScriptDeclaration('var menuSpeed = '.$menuSpeed.';var mooStyle = '.$mooStyle.';'); $doc->addScript("modules/mod_jxtc_jmenu/js/moodropline.js"); break; case 'horz_column' : // Include the legacy library file $doc->addStyleSheet("modules/mod_jxtc_jmenu/css/moocolumns.css"); $doc->addScriptDeclaration('var menuSpeed = '.$menuSpeed.';var mooStyle = '.$mooStyle.';'); $doc->addScript("modules/mod_jxtc_jmenu/js/moocolumns.js"); break; } function _getItemData(&$params, $item) { $data = null; // Menu Link is a special type that is a link to another item $item->name = htmlentities($item->name); if ($item->type == 'menulink') { $menu = &JSite::getMenu(); if ($newItem = $menu->getItem($item->query['Itemid'])) { $tmp = clone($newItem); $tmp->name = '<span><![CDATA['.$item->name.']]></span>'; $tmp->mid = $item->id; $tmp->parent = $item->parent; } else { return false; } } else { $tmp = clone($item); $tmp->name = '<span><![CDATA['.$item->name.']]></span>'; } $iParams = new JParameter($tmp->params); if ($params->get('menu_images') && $iParams->get('menu_image') && $iParams->get('menu_image')!= -1) { $imgalign = $params->get('menu_images_align', 0) == 1 ? 'right' : 'left'; $image = '<img src="'.JURI::base(true).'/images/stories/'.$iParams->get('menu_image').'" align="'.$imgalign.'" alt="'.$item->alias.'" style="display:none"/>'; if($tmp->ionly){ $tmp->name = null; } } else { $image = null; } switch ($tmp->type) { case 'separator' : return '<span class="separator">'.$image.$tmp->name.'</span>'; break; case 'url' : if ((strpos($tmp->link, 'index.php?') === 0) && (strpos($tmp->link, 'Itemid=') === false)) { $tmp->url = $tmp->link.'&Itemid='.$tmp->id; } else { $tmp->url = $tmp->link; } break; default : $router = JSite::getRouter(); $tmp->url = $router->getMode() == JROUTER_MODE_SEF ? 'index.php?Itemid='.$tmp->id : $tmp->link.'&Itemid='.$tmp->id; break; } // Print a link if it exists if ($tmp->url != null) { // Handle SSL links $iSecure = $iParams->def('secure', 0); if ($tmp->home == 1) { $tmp->url = JURI::base(); } elseif (strcasecmp(substr($tmp->url, 0, 4), 'http') && (strpos($tmp->link, 'index.php?')!== false)) { $tmp->url = JRoute::_($tmp->url, true, $iSecure); } else { $tmp->url = str_replace('&', '&', $tmp->url); } switch ($tmp->browserNav) { default: case 0: // _top $data = $image.'<a href="'.$tmp->url.'">'.$tmp->name.'</a>'; break; case 1: // _blank $data = $image.'<a href="'.$tmp->url.'" target="_blank">'.$tmp->name.'</a>'; break; case 2: // window.open $attribs = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,'.$this->_params->get('window_open'); // hrm...this is a bit dickey $link = str_replace('index.php', 'index2.php', $tmp->url); $data = $image.'<a href="'.$link.'" onclick="window.open(this.href,\'targetWindow\',\''.$attribs.'\');return false;">'.$tmp->name.'</a>'; break; } } else { $data = $image.'<a>'.$tmp->name.'</a>'; } return $data; } // Include the new menu class $xml = modJxtcMenuHelper::getXML($params->get('menutype'), $params, $callback); if ($xml) { $class = $params->get('class_sfx'); $xml->addAttribute('class', 'menu'.$class); if ($tagId = $params->get('tag_id')) { $xml->addAttribute('id', $tagId); } $result = JFilterOutput::ampReplace($xml->toString((bool)$params->get('show_whitespace'))); $result = str_replace(array('<ul/>', '<ul />'), '', $result); echo $result; } break; } } } } /** * Main Menu Tree Class. * * @package Joomla * @subpackage Menus * @since 1.5 */ if (!class_exists('JxtcMenuTree')) { class JxtcMenuTree extends JTree { /** * Node/Id Hash for quickly handling node additions to the tree. */ var $_nodeHash = array(); /** * Menu parameters */ var $_params = null; /** * Menu parameters */ var $_buffer = null; function __construct(&$params) { $this->_params =& $params; $this->_root = new JxtcMenuNode(0, 'ROOT'); $this->_nodeHash[0] =& $this->_root; $this->_current =& $this->_root; } function addNode(&$params, $item) { // Get menu item data $data = $this->_getItemData($params, $item); // Create the node and add it $node = new JxtcMenuNode($item->id, $item->name, $item->access, $data); if (isset($item->mid)) { $nid = $item->mid; } else { $nid = $item->id; } $this->_nodeHash[$nid] =& $node; $this->_current =& $this->_nodeHash[$item->parent]; if ($item->type == 'menulink' && !empty($item->query['Itemid'])) { $node->mid = $item->query['Itemid']; } if ($this->_current) { $this->addChild($node, true); } else { // sanity check JError::raiseError( 500, 'Orphan Error. Could not find parent for Item '.$item->id ); } } function toXML(&$buttonClasses) { // Initialize variables $this->_current =& $this->_root; // Recurse through children if they exist $colidx=0; while ($this->_current->hasChildren()) { $this->_buffer .= '<ul>'; foreach ($this->_current->getChildren() as $child) { $buttonClass = ' class="'.trim($buttonClasses[$colidx++]).'"'; if ($colidx > count($buttonClasses)) $colidx = 0; $this->_current = & $child; $this->_getLevelXML(0,$buttonClass); } $this->_buffer .= '</ul>'; } if($this->_buffer == '') { $this->_buffer = '<ul />'; } return $this->_buffer; } function _getLevelXML($depth,&$buttonClass) { $depth++; // Start the item $rel = (!empty($this->_current->mid))? ' rel="'.$this->_current->mid.'"' : ''; $this->_buffer .= '<li access="'.$this->_current->access.'" level="'.$depth.'" id="'.$this->_current->id.'"'.$rel.$buttonClass.'>'; // Append item data $this->_buffer .= $this->_current->link; // Recurse through item's children if they exist while ($this->_current->hasChildren()) { $this->_buffer .= '<ul>'; foreach ($this->_current->getChildren() as $child) { $this->_current = & $child; $this->_getLevelXML($depth,$buttonClass); } $this->_buffer .= '</ul>'; } // Finish the item $this->_buffer .= '</li>'; } function _getItemData(&$params, $item) { $data = null; // Menu Link is a special type that is a link to another item if ($item->type == 'menulink') { $menu = &JSite::getMenu(); if ($newItem = $menu->getItem($item->query['Itemid'])) { $tmp = clone($newItem); $tmp->name = '<span><![CDATA['.$item->name.']]></span>'; $tmp->mid = $item->id; $tmp->parent = $item->parent; } else { return false; } } else { $tmp = clone($item); $tmp->name = '<span><![CDATA['.$item->name.']]></span>'; } $iParams = new JParameter($tmp->params); if ($params->get('menu_images') && $iParams->get('menu_image') && $iParams->get('menu_image')!= -1) { $imgalign = $params->get('menu_images_align', 0) == 1 ? 'right' : 'left'; $image = '<img src="'.JURI::base(true).'/images/stories/'.$iParams->get('menu_image').'" align="'.$imgalign.'" alt="'.$item->alias.'" style="display:none"/>'; if($tmp->ionly){ $tmp->name = null; } } else { $image = null; } switch ($tmp->type) { case 'separator' : return '<span class="separator">'.$image.$tmp->name.'</span>'; break; case 'url' : if ((strpos($tmp->link, 'index.php?') === 0) && (strpos($tmp->link, 'Itemid=') === false)) { $tmp->url = $tmp->link.'&Itemid='.$tmp->id; } else { $tmp->url = $tmp->link; } break; default : $router = JSite::getRouter(); $tmp->url = $router->getMode() == JROUTER_MODE_SEF ? 'index.php?Itemid='.$tmp->id : $tmp->link.'&Itemid='.$tmp->id; break; } // Print a link if it exists if ($tmp->url != null) { // Handle SSL links $iSecure = $iParams->def('secure', 0); if ($tmp->home == 1) { $tmp->url = JURI::base(); } elseif (strcasecmp(substr($tmp->url, 0, 4), 'http') && (strpos($tmp->link, 'index.php?')!== false)) { $tmp->url = JRoute::_($tmp->url, true, $iSecure); } else { $tmp->url = str_replace('&', '&', $tmp->url); } switch ($tmp->browserNav) { default: case 0: // _top $data = '<a href="'.$tmp->url.'">'.$image.$tmp->name.'</a>'; break; case 1: // _blank $data = '<a href="'.$tmp->url.'" target="_blank">'.$image.$tmp->name.'</a>'; break; case 2: // window.open $attribs = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,'.$this->_params->get('window_open'); // hrm...this is a bit dickey $link = str_replace('index.php', 'index2.php', $tmp->url); $data = $image.'<a href="'.$link.'" onclick="window.open(this.href,\'targetWindow\',\''.$attribs.'\');return false;">'.$tmp->name.'</a>'; break; } } else { $data = $image.'<a>'.$tmp->name.'</a>'; } return $data; } } } /** * Main Menu Tree Node Class. * * @package Joomla * @subpackage Menus * @since 1.5 */ if (!class_exists('JxtcMenuNode')) { class JxtcMenuNode extends JNode { /** * Node Title */ var $title = null; /** * Node Link */ var $link = null; /** * CSS Class for node */ var $class = null; function __construct($id, $title, $access = null, $link = null, $class = null) { $this->id = $id; $this->title = $title; $this->access = $access; $this->link = $link; $this->class = $class; } } } moodropin.php: Код (CODE): window.addEvent('domready', function() { var menuli = $$('#topmenu ul li'); menuli.each(function(li,i){ var sub = li.getElement('ul'); var parw = li.getSize().size.x; if(sub != null){ var subw = sub.getSize().size.x; //alert(parw + ' ' + subw); if(subw < parw){ sub.setStyle('width', parw); } var subfx = new Fx.Styles(sub, {duration:menuSpeed, transition: mooStyle, wait:false}); var subh = sub.getSize().size.y; sub.setStyles({ 'height': '0px', 'width': subw + 'px', 'opacity': 1 }); li.addEvent('mouseenter', function(){ subfx.start({ 'height': subh }); }); li.addEvent('mouseleave', function(){ subfx.start({ 'height': 0 }); }); } }); var submenuli = $$('#topmenu ul li ul li'); submenuli.each(function(sli,i){ var ss = sli.getParent(); //sli.setStyle('width', ss.getSize().size.x); //ss.setStyle('width', ss.getSize().size.x); var subli = sli.getElements('ul'); if(subli!=''){ var subliPar = sli.getParent(); subli.setStyle('margin-left', (sli.getParent()).getSize().size.x - 2 + 'px'); subli.setStyle('margin-top', -sli.getSize().size.y + 0 + 'px'); sli.addEvent('mouseenter', function(){ subliPar.setStyle('overflow','visible'); }); sli.addEvent('mouseleave', function(){ subliPar.setStyle('overflow','hidden'); }); } }); }); ЗЫ Если понадобиться - выложу ещё legacy.php Заранее благодарен всем, кто может помочь!
Тому, кто поможет - вознаграждение в размере 5 wmz за уделённое время и решение вопроса. Спецы, очень нужна Ваша помощь!