1C Bitrix: remove from the code hidden sub-items in the menu


26-07-2018
Денис Л.
Cms
1C Bitrix: remove from the code hidden sub-items in the menu

1C Bitrix is ​​an interesting CMS, with a lot of nuances and "pitfalls." Not so long ago, a seo-specialist was invited to the team where I work, and he said that we have a lot of internal links on our site. About 350 on each page. And this reduces the weight of other links that he planned to use for relinking inside our site. I'm not a SEO specialist, but a web developer, therefore, there is a task - it is necessary to carry out! I found a lot of links in the block with the carousel of the partners' logos. Deleted them very quickly, assigned the data-src attribute to the pictures, into which the real url was written, and after building the markup, he javascripted images with links. So I solved the problem with the first hundred links. The main mass of links was generated in the left menu of the site displayed by the standard component of the templates bitrix/templates/.default/components/bitrix/menu/services_left_menu/template.php. Moreover, the company where I work, the number of services is more than 150. Each service is divided into a category. As a result, the structure of the left menu in the sidebar is:


<ul>
  <li class="active"> - active menu item at the moment
    <ul>
      <li></li> - sub-active category, visible at the moment
      <li></li> - same subparagraph
      .........
    </ul>
  </li>
  <li> - menu item is currently inactive category, always visible
    <ul>
      <li></li> - a sub-item inactive for the current category. It is not visible, but the code is present!
      <li></li> - the same hidden in the styles, but the present sub-item. And such sub-paragraphs are very, very many!
      .........
    </ul>
  </li>
  .....
  .....
</ul>

The result is a huge menu structure, in which all active menu items + sub-items of the active category are actually displayed, and inactive sub-items are hidden by styles, but continue to be present in the code.


I rewrote the menu output component, here's the code below.

You can use it on your site at your discretion.

Only those menu sub-items that are relevant to the active category now fall into the markup.

As a result, on our project, the number of links on one page from 250 is close to 100. Plus, the site is loaded faster, since the browser does not need to build such a large amount of unnecessary, invisible markup eye.

So, how to display in the code only the necessary sub-items of the menu


<? 

$innerMenu = []; // create an array in which we will place the sub-items of the active category

for($i=0; $i<count($arResult); $i++) {
  if($arResult[$i]['SELECTED']) {
    if($arResult[$i]['DEPTH_LEVEL']==1 && ($arResult[$i]['IS_PARENT'] || $arResult[$i+1]['DEPTH_LEVEL']==1)) {
      $number = $i; $numberParent = $i;
    }
    elseif($arResult[$i]['DEPTH_LEVEL']!=1) {
      $number = $i; 
      for($j=$number-1; $j>=0; $j--) {
        if($arResult[$j]['IS_PARENT'] && $arResult[$j]['DEPTH_LEVEL']==1) {
          $numberParent = $j; break;
        }
      }
    }
    for($k=$numberParent+1; $k<count($arResult); $k++) {
      if($arResult[$k]['IS_PARENT'] && $arResult[$k]['DEPTH_LEVEL']==1) {
        $numberNextParent = $k; break;
      }
    }
  }
}
for($l=$numberParent+1; $l<$numberNextParent; $l++) { // being in the interval between the current parent element and the next parent element
  $innerMenuText = $arResult[$l]['TEXT']; // write a variable to the text of the link
  $innerMenuLink = $arResult[$l]['LINK']; // write a variable reference path
  $innerMenuResult = "<li class='sm'><a href='{$innerMenuLink}'>{$innerMenuText}</a></li>"; // form the output line
  array_push($innerMenu, $innerMenuResult); // fill the array with ready-made sub-menu items
}
?>

<ul class="uslugi_inner">
  <?foreach($arResult as $arItem):?>
    <?if($arItem['DEPTH_LEVEL']==1):?>
      <li <?if($arItem['SELECTED'])echo"class='active'"?>><a href='<?=$arItem['LINK']?>'><?=$arItem['TEXT']?></a></li>
    <?endif?>
    <?if($arItem['SELECTED'] && $arItem['IS_PARENT']):?>
      <? // when we are inside the selected menu item of our category, insert an array with the list of references of subitems and convert this array into a string ?>
      <ul class="submenu"><?=implode('', $innerMenu)?></ul>
    <?endif?>
  <?endforeach?>
</ul>

<script>
  // and finally, a script that will highlight the active menu sub-menu
  // I suggest to insert it here, instead of in a separate file with scripts,
  // since it is in this case that the eye will not see a change in the style of this element
  let leftMenuLinks = document.querySelectorAll('ul.uslugi_inner .submenu a');
  leftMenuLinks.forEach(function(item) {
    let leftMenuLink = item.getAttribute('href');
    if(leftMenuLink == window.location.pathname) {
      item.style.fontWeight = 'bold';
    }
  })
</script>

?>