[Помощь] Модификация вывода Offlajn accordion menu

silmarion

Полезный
Регистрация
21 Июн 2012
Сообщения
194
Реакции
19
Доброго времени суток всем гуру сайта.
Есть сайт Joomla 2.5 virtuemart 2
Скрытое содержимое доступно для зарегистрированных пользователей!
 
Да, в настройках есть Start Level (начальный уровень) и Level (колличество уровней).
Уже пробовал с ними играть, не подходит. По умолчанию оба этих пункта стоят на 0 (неограниченно).
Играя со Start Level (1,2,3 и т.д) убираешь вообще отображение уровней которые выше указанного.
Играя с Level (1,2,3 и т.д) убираешь вообще отображение уровней которые ниже указанного.
Т.е. в текущем случае если поставлю Level к примеру на 2 а Start Level на 0 то в меню останется только 2 уровня Страна и производитель, коллекция уже не будет выводится в меню даже если переходишь в пункт меню - производитель
---
0,5-0,8 это нормально.
Да, при выключенном полностью меню.

какой хостинг?


Изначально настраивался и тестировался на Выделенном сервере Dell R210 / 1x Intel Quad-Core Xeon E3-1220 / 4GB / 1x500GB SATA Там конечно побыстрее было, но он как бы "немного" дороже стоит чем обычный хостинг.

тут надо профилирование смотреть, сколько реально делается запросов в базу, какие именно, и как кеш работает.
-----
Где именно это можно сделать?

Они в цикле выполняются, и они уже разбиты... тут больше внимания надо кешу уделить.
Древовидные структуры одним запросом как правило не выбираются, за исключением nested sets
---
Я и не думаю что тут все в 1 запросе.
Как раз наоборот. Вот и думаю может можно сделать триггер в цикле.
Т.е. подгрузилась видимая в меню инфа, стоп, и ждет клика по + чтобы запустить еще кусок цикла.

Вот кстати код, который выводит категории, может сюда можно всунуть паузы?
Код:
<?php

// Check to ensure this file is within the rest of the framework
defined('JPATH_BASE') or die();

if(!class_exists('JElementOfflajnMultiSelectList')) {
  require_once( (dirname(__FILE__)) . DS . 'offlajnmultiselectlist.php');
}

if (!class_exists( 'VmConfig' ) && file_exists(JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_virtuemart'.DS.'helpers'.DS.'config.php') ) require(JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_virtuemart'.DS.'helpers'.DS.'config.php');
else return;
$config= VmConfig::loadConfig();
if(!class_exists('TableCategories')) require(JPATH_VM_ADMINISTRATOR.DS.'tables'.DS.'categories.php');
if (!class_exists( 'VirtueMartModelCategory' )) require(JPATH_VM_ADMINISTRATOR.DS.'models'.DS.'category.php');

class fixedVirtueMartModelCategory extends VirtueMartModelCategory{
    function GetTreeCat($id=0,$maxLevel = 1000) {
        self::treeCat($id ,$maxLevel) ;
        return $this->container ;
    }
 
    function treeCat($id=0,$maxLevel =1000) {
        static $level = 0;
        static $num = -1 ;
        $db = & JFactory::getDBO();
        $q = 'SELECT `category_child_id`,`category_name` FROM `#__virtuemart_categories_'.VMLANG.'`
        LEFT JOIN `#__virtuemart_category_categories` on `#__virtuemart_categories_'.VMLANG.'`.`virtuemart_category_id`=`#__virtuemart_category_categories`.`category_child_id`
        WHERE `category_parent_id`='.(int)$id;
        $db->setQuery($q);
        $num ++;
        // if it is a leaf (no data underneath it) then return
        $childs = $db->loadObjectList();
        if ($level==$maxLevel) return;
        if ($childs) {
            $level++;
            foreach ($childs as $child) {
                $this->container[$num]->id = $child->category_child_id;
                $this->container[$num]->name = $child->category_name;
                $this->container[$num]->level = $level;
                self::treeCat($child->category_child_id,$maxLevel );
            }
            $level--;
        }
    }
}

class JElementOfflajnVm2Categories extends JElementOfflajnMultiSelectList {

  function getItems() {
/*
    if($value == NULL) {
      $value = array();
    } elseif (!is_array($value)) {
      $value = array($value);
    }
    $values = array_flip($value);
    array_walk($values, 'ofSetOne');
*/
    $categoryModel = new fixedVirtueMartModelCategory();
    $cats = $categoryModel->GetTreeCat();

  // $multiple = 1 ? "multiple=\"multiple\"" : "";
    ob_start();
    //    echo "<select class=\"inputbox\" size=\"10\" $multiple name=\"".$name."[]\" id=\"".$this->generateId($name)."\">\n";
        if( 1 ) {
        //    $selected = (@$values[0] == "1") ? "selected=\"selected\"" : "";
        //    echo "<option ".$selected." value=\"0\">Top Level</option>\n";
        }
        foreach($cats AS $cat){
          $selected = '';
          if( $selected == "" && @$values[$cat->id] == "1") {
            //$selected = "selected=\"selected\"";
          }
      //echo "<option $selected value=\"$cat->id\">\n";
      echo "///".$cat->id."///";
          for ($i=0;$i<$cat->level;$i++) {
              echo "&#160;";
          }
          echo "|$cat->level|";
          //echo "&nbsp;" . $cat->name . "</option>";
          echo "&nbsp;" . $cat->name;
        }
        //echo "</select>\n";
    $elements = ob_get_clean();
    $el = explode("///", $elements);

    $items = array();

    for($i=1;$i<count($el);$i += 2) {
      $items[$el[$i]] = $el[$i+1];
    }

   
    $groupedList = array();
    $i = 0;
    foreach($items as $k => $element) {
      $item = new stdClass();
      $item->treename = $element;
      $item->id = $k;
      //$groupedList['vm1'][$k] = $item;
      $groupedList['vm1'][$i] = $item;
      $i++;
    }
   
   
    //return ob_get_clean();

        // assemble into menutype groups
/*        $n = count( $list );
        $groupedList = array();
        foreach ($list as $k => $v) {
            $groupedList[$v->menutype][] = &$list[$k];
        }
*/
return $groupedList;
  }
 
/* if(!function_exists('ofSetOne')){
    function ofSetOne(&$item, $key){
      $item = 1;
  }
}*/
}

if(!function_exists('ofSetOne')){
  function ofSetOne(&$item, $key){
      $item = 1;
  }
}

if(version_compare(JVERSION,'1.6.0','ge')) {
  class JFormFieldOfflajnVm2Categories extends JElementOfflajnVm2Categories {}
}
 
Последнее редактирование:
тут надо профилирование смотреть, сколько реально делается запросов в базу, какие именно, и как кеш работает.
-----
Где именно это можно сделать?

Надо включить плагин отладки, и в основных настройках joomla включить отладку, после чего внизу сайта появится консоль джумлы.

1391177527-clip-121kb.jpg


где будет указано время выполнения, и все запросы.

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

Кеширование бывает как запросов, так и результатов запросов.

Для старой вирты было решение, установка доп классов, и включение кеширования именно запросов к базе.
Для 1,5 я это решение использовал, для 2,5 и второй вирты пока нет, ибо встроенное кеширование в 2,5 версии позволяет справиться с проблемой.

вот тут было решение для кеширования запросов под joomla
Скрытое содержимое доступно для зарегистрированных пользователей!


но когда я разбирался с этим вопросом, оно не поддерживалось и его надо было допиливать.
а так же оно требует наличие мемкеша например или APC

Другими словами требуется допил, и не факт что на вашем хостинге оно заработает.
 
Последнее редактирование:
Первая загрузка страницы
Код:
Application 0.348 seconds (+0.038); 17.49 MB (+1.243) - beforeRenderModule mod_accordion_menu (По назначению: (2))
Application 9.424 seconds (+9.076); 30.52 MB (+13.031) - afterRenderModule mod_accordion_menu (По назначению: (2))

На сайте включен Gzip и кэш joomla встроенные
повторная загрузка (F5)
Код:
Application 0.131 seconds (+0.040); 13.86 MB (+1.669) - beforeRenderModule mod_accordion_menu (По назначению: (2))
Application 1.118 seconds (+0.987); 22.37 MB (+8.514) - afterRenderModule mod_accordion_menu (По назначению: (2))

Код:
Application 0.000 seconds (+0.000); 1.22 MB (+1.218) - afterLoad
Application 0.054 seconds (+0.054); 6.54 MB (+5.327) - afterInitialise
Application 0.095 seconds (+0.041); 10.09 MB (+3.549) - afterRoute
Application 0.269 seconds (+0.174); 16.76 MB (+6.667) - afterDispatch
Application 0.330 seconds (+0.061); 18.11 MB (+1.352) - beforeRenderModule mod_accordion_menu (По назначению: (2))
Application 1.351 seconds (+1.021); 25.20 MB (+7.089) - afterRenderModule mod_accordion_menu (По назначению: (2))
Application 1.360 seconds (+0.009); 19.91 MB (-5.294) - beforeRenderModule mod_anycode (По назначению:)
Application 1.361 seconds (+0.000); 19.91 MB (+0.006) - afterRenderModule mod_anycode (По назначению:)
Application 1.362 seconds (+0.001); 19.92 MB (+0.010) - beforeRenderModule mod_genius_vm_ajax_search (Genius VM ajax search)
Application 1.373 seconds (+0.011); 19.96 MB (+0.033) - afterRenderModule mod_genius_vm_ajax_search (Genius VM ajax search)
Application 1.374 seconds (+0.001); 19.96 MB (+0.006) - beforeRenderModule mod_virtuemart_cart (Корзина)
Application 1.630 seconds (+0.256); 27.64 MB (+7.674) - afterRenderModule mod_virtuemart_cart (Корзина)
Application 1.826 seconds (+0.196); 28.64 MB (+1.005) - afterRender

Менюшка вырывается вперед...:pop:
 
Последнее редактирование:
Первая загрузка страницы
Код:
Application 0.348 seconds (+0.038); 17.49 MB (+1.243) - beforeRenderModule mod_accordion_menu (По назначению: (2))
Application 9.424 seconds (+9.076); 30.52 MB (+13.031) - afterRenderModule mod_accordion_menu (По назначению: (2))

На сайте включен Gzip и кэш joomla встроенные
повторная загрузка (F5)
Код:
Application 0.131 seconds (+0.040); 13.86 MB (+1.669) - beforeRenderModule mod_accordion_menu (По назначению: (2))
Application 1.118 seconds (+0.987); 22.37 MB (+8.514) - afterRenderModule mod_accordion_menu (По назначению: (2))

Вы немного путаете ситуации.
Речь не про кеширование всей джумлы!
А про кеширование именно этого модуля!
Вам надо чтобы этот модуль закешировался надолго.
а не вся джумла.

1391179068-clip-54kb.jpg


любой выод модуля можно закешировать разными способами и на разное время.
 
Я знаю где настраивается кеширование модуля. В том то и дело что в этом модуле нет такой функции, погуглил и нашел только как исправлять данную ситуацию в J1.5

Так что, есть идеи триггеры всунуть в цикл?
 
Я знаю где настраивается кеширование модуля. В том то и дело что в этом модуле нет такой функции, погуглил и нашел только как исправлять данную ситуацию в J1.5

Так что, есть идеи триггеры всунуть в цикл?

С этим не факт что так просто можно справиться, вы не первый и не последний кто с подобной проблемой столкнулся именно с меню категорий.
Если бы так просто можно было ее решить, давно бы уже решили.
Триггеры тут не помогут, тут скорее аяксом подгружать надо подразделы, то есть в корне переделывать весь модуль.
По крайней мере я не вижу как это реализовать.

Насчет кеширования, вот стандартный кусок кода xml для любого модуля


Код:
<field
                    name="cache"
                    type="list"
                    default="1"
                    label="COM_MODULES_FIELD_CACHING_LABEL"
                    description="COM_MODULES_FIELD_CACHING_DESC">
                    <option    value="1">JGLOBAL_USE_GLOBAL</option>
                    <option    value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
                </field>
                <field
                    name="cache_time"
                    type="text"
                    default="900"
                    label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
                    description="COM_MODULES_FIELD_CACHE_TIME_DESC" />
                <field
                    name="cachemode"
                    type="hidden"
                    default="static">
                    <option value="static"></option>
                </field>

но с учетом того что в модуле у них свое решение для вывода настроек и весь xml переписан под их систему, вставка этого стандартного блока ничего не меняет.
ребята постарались...

надо пробовать править по их правилам файл
mod_accordion_menu.xml

только не факт что прокатит, неизвестно что они там намудрили.

и эта версия мне пишет

This is an illegal version!
This extension can contains files that may harm your website and server!

и не факт что она еще что то попортить может)



в набор вижу входит
cache.class.php

видимо внутри встроено кеширование, и надо с ним разбираться.


стоп) нет это кеширование JS и CSS
 
Последнее редактирование:
Да, в настройках есть Start Level (начальный уровень) и Level (колличество уровней).
Уже пробовал с ними играть, не подходит. По умолчанию оба этих пункта стоят на 0 (неограниченно).
Играя со Start Level (1,2,3 и т.д) убираешь вообще отображение уровней которые выше указанного.
Играя с Level (1,2,3 и т.д) убираешь вообще отображение уровней которые ниже указанного.
Т.е. в текущем случае если поставлю Level к примеру на 2 а Start Level на 0 то в меню останется только 2 уровня Страна и производитель, коллекция уже не будет выводится в меню даже если переходишь в пункт меню - производитель

Попробуйте поменять сочетания настроек

Opened item(s)
и
Always opened levels

в этом же блоке настроек
и если вклчено отображение количества товаров в категориях, отключить.
и всетаки сколько запросов делает модуль к базе?
 
Думаю все же нужно как то разграничить подгрузку данных
Чтобы не подгружалось и рендерилось как сейчас у меня каждый раз 1700 пунктов меню.
А подгрузка нижних уровней происходила после нажатия +

К примеру тут видимых изначально всего 10, а подгружено с бд этих строк уже 1688 (выдели текст меню, ctrl+c и вставь в текстовик, увидишь сразу все пункты меню)
Для просмотра ссылки Войди или Зарегистрируйся
Было бы супер, если открываешь
Для просмотра ссылки Войди или Зарегистрируйся
подгрузилось 10 пунктов меню из бд
германия, испания, италия, китай, польша, португалия, россия, турция, украина, чехия

нажал на плюсик к примеру возле германии

подгрузилось аяксом еще 4 пункта, и так далее
Agrob Buchtal, Boizenburg, Jasba, Steuler design

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

Но может быть можно его вообще как то вывести в afterpageload?
Страница сгенерировалась за 0,6 с, а потом аяксом плавно меню появилось после его фоновой загрузки.
  • Система - AjaxModuleLoader (загрузка модулей через Ajax)
Вставлял модуль меню в него. Грузится меню начинает после загрузки всей страницы, но слетает JS от меню, который его разворачивает, т.е. появляется меню полностью развернутое. Если бы меню грузилось нормальным после загрузки страницы через этот аякс то думаю проблема бы решилась и с большим меню, мало кто будет обращать внимание что меню немного после загрузки страницы появляется, если страница грузится быстро


13165 SQL-запросов зафиксированоo_O
думаю что 13100 запросов от меню)


Код:
[/B][/B][/B][/B]
[B][B][B][B]SELECT `category_child_id` AS `child`, `category_parent_id` AS `parent`
  FROM plitka4_virtuemart_category_categories AS `xref`
  WHERE `xref`.`category_child_id`= 2391

SELECT `category_child_id` AS `child`, `category_parent_id` AS `parent`
  FROM plitka4_virtuemart_category_categories AS `xref`
  WHERE `xref`.`category_child_id`= 2144
и тд
Т.е. каждый генерируемый пункт меню запрашивается отдельным запросом, эххх, растригерить его бы как выше написал.



Ребята, есть какие еще мысли у кого?

Кэш отпадает.
Пробовал, меню с кэша все равно минимум 1 сек генерируется, надо именно сделать обычное меню из него.
Тогда макс за 1 раз будет 100-200 пунктов вместо 1700 генерироваться. А уже при нажатии на плюсик пускай подгружается что спрятано.



Ребята есть идеи у кого еще какие?
Реально нужно




Как вариант радикальный метод, отключить аккордеон. Сделать меню при нажатии на + чтобы перезагружалась страница.

Как тут к примеру(меню слева)


Вариант с использованием стандартного меню жумлы, и заполнением пунктов меню вручную не вариант.
Категорий более !!!2500!!!
 
Последнее редактирование:
Назад
Сверху