SitePoint Sponsor

User Tag List

Results 1 to 6 of 6

Thread: Menu Item Count

  1. #1
    SitePoint Member
    Join Date
    Jun 2012
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Menu Item Count

    I am writing my own theme and I came up on a PHP problem. Here is the original default.php i was working with which worked well for what it did:

    Code:
    public function process($module, $element) {
      self::_process($module, $element->first('ul:first'));
      return $element;
    }
    
    
    /*
      Function: _process
    
    
      Returns:
       Void
    */
    protected static function _process($module, $element, $level = 0) {
    
    
      if ($level == 0) {
       $element->attr('class', 'menu '.$module->menu_style);
      
      } else {
       $element->addClass('level'.($level + 1));
      }
    
      
      foreach ($element->children('li') as $li) {
     
     
       // is active ?
       if ($active = $li->attr('data-menu-active')) {
        $active = $active == 2 ? ' active current' : ' active';
       }
      
       // is parent ?
       $ul = $li->children('ul');
       $parent = $ul->length ? ' parent' : null;
    
    
    
       // set class in li
       $li->attr('class', sprintf('level%d item%s'.$parent.$active, $level + 1, $li->attr('data-id')));
      
       // set class in a/span
       foreach ($li->children('a,span') as $child) {
    
    
        // get title
        $title = $child->first('span:first');
    
    
        // set subtile
        $subtitle = $title ? explode('||', $title->text()) : array();
       
        if (count($subtitle) == 2) {
         $li->addClass('hassubtitle');
         $title->html(sprintf('<span class="title">%s</span><span class="subtitle">%s</span>', trim($subtitle[0]), trim($subtitle[1])));
        }
    
    
        // set image
        if ($image = $li->attr('data-menu-image')) {
         $title->prepend(sprintf('<span class="icon" style="background-image: url(\'%s\');"> </span>', $image));
        }
    
    
        $child->addClass(sprintf('level%d'.$parent.$active, $level + 1));
       }
    
    
       // process submenu
       if ($ul->length) {
        self::_process($module, $ul->item(0), $level + 1);
       }
      }
    The problem is, I am changing my menu style and I now need to differentiate between the first menu item, the last, and any in between (to add in a CSS class). So here is what I did with the code but it is not working:

    Code:
    public function process($module, $element) {
      self::_process($module, $element->first('ul:first'));
      return $element;
    }
    
    
    /*
      Function: _process
    
    
      Returns:
       Void
    */
    protected static function _process($module, $element, $level = 0) {
    
    
      if ($level == 0) {
       $element->attr('class', 'menu '.$module->menu_style);
      
      } else {
       $element->addClass('level'.($level + 1));
      }
    
      
      foreach ($element->children('li') as $li) {
     
     
       // is active ?
       if ($active = $li->attr('data-menu-active')) {
        $active = $active == 2 ? ' active current' : ' active';
       }
      
       // is parent ?
       $ul = $li->children('ul');
       $parent = $ul->length ? ' parent' : null;
    
                            // is first or last ?
       $lis = $element->children("ul");
       for($forl=0,$imax=count($lis);
    
    
                            $forl<$imax;$forl++){
       $forl = array();
       if (forl==0) $position_n = 'first';
       elseif ($forl==$imax-1) $position_n = 'last';
       else $position_n = null;
       }
    
    
       // set class in li
       $li->attr('class', sprintf('level%d item%s'.$parent.$active, $level + 1, $li->attr('data-id'), $position_n));
      
       // set class in a/span
       foreach ($li->children('a,span') as $child) {
    
    
        // get title
        $title = $child->first('span:first');
    
    
        // set subtile
        $subtitle = $title ? explode('||', $title->text()) : array();
       
        if (count($subtitle) == 2) {
         $li->addClass('hassubtitle');
         $title->html(sprintf('<span class="title">%s</span><span class="subtitle">%s</span>', trim($subtitle[0]), trim($subtitle[1])));
        }
    
    
        // set image
        if ($image = $li->attr('data-menu-image')) {
         $title->prepend(sprintf('<span class="icon" style="background-image: url(\'%s\');"> </span>', $image));
        }
    
    
        $child->addClass(sprintf('level%d'.$parent.$active, $level + 1));
       }
    
    
       // process submenu
       if ($ul->length) {
        self::_process($module, $ul->item(0), $level + 1);
       }
      }

  2. #2
    From Italy with love silver trophybronze trophy
    guido2004's Avatar
    Join Date
    Sep 2004
    Posts
    9,408
    Mentioned
    149 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Nick Bogatin View Post
    but it is not working
    Could you please explain what "is not working means" ? An error? A result that isn't what you want? And if so, what is the result you're getting and what's wrong with it?

  3. #3
    SitePoint Member
    Join Date
    Jun 2012
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry for not being more clear. The goal is to have the first menu item be appended with the class "first" and the last menu item be appended with the class "last". There will be other class elements present which are currently working with the code as it is such as the items listed under //set class for li. so to add in this first and last class addition where appropriate, I tried to add in a variable, $position_n in that line. And I defined it in the lines above - under //is first or last? - but when I check, it does not append the class of the menu items with first or last in the appropriate menu items (not in any of them, but more specifically, not in the first and last menu item.

    It may help you to understand what I'm doing by explaining the goal. I have a boxed menu item that floats in my header. To make it more graphically pleasing, the first and last menu item need a different style, one that rounds the edges (left edges for first). See pics

    Here is an image of what I am trying to achieve by adding the class the first and last menu item:

    Curved-Edges-Class-Image.png

    And then here is what I get on my actual website because of not being able to append that class:

    Straight-Edges-Website.png

  4. #4
    From Italy with love silver trophybronze trophy
    guido2004's Avatar
    Join Date
    Sep 2004
    Posts
    9,408
    Mentioned
    149 Post(s)
    Tagged
    4 Thread(s)
    Code:
    // is first or last ?
    $lis = $element->children("ul");
    for ($forl=0,$imax=count($lis); $forl<$imax; $forl++) {
      $forl = array();
       if (forl==0) $position_n = 'first';
       elseif ($forl==$imax-1) $position_n = 'last';
       else $position_n = null;
    }
    I don't understand the first line I marked in red. If you put an empty array in $forl, that for loop doesn't work anymore does it?
    And in the second red marked line there is a $ missing.

  5. #5
    SitePoint Member
    Join Date
    Jun 2012
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the tip on the empty array. I just read a book on PHP last week so I am still pretty new at this stuff. I will keep that in mind from now on. And I can't believe I forgot the "$" sign. Thanks for pointing that out too.

    I made the corrections and nothing. But then I looked at the sprintf and realized that was off too. I changed:

    Code:
    $li->attr('class', sprintf('level%d item%s'.$parent.$active, $level + 1, $li->attr('data-id'), $position_n));
    To:

    Code:
    $li->attr('class', sprintf('level%d item%s '. $position_n .$parent.$active, $level + 1, $li->attr('data-id')));
    That seems to have helped get me 1/3 of the way there. What I mean is that I am now successfully appending the class for all LIs. Unfortunately, they are all being appended with "first" regardless of whether they are the first, middle or last. See the pic below for the developer tools window of the page's code:

    Menu-Issue-Update.jpg

    So it appears that something is wrong in my lines below and that is causing only the class "first" to be added to every LI:

    Code:
    $lis = $element->children("li");	
    for($forl=0,$imax=count($lis);
    $forl<$imax;$forl++){
    	if ($forl==0) $position_n = 'first';
    	elseif ($forl==$imax-1) $position_n = 'last';
    	else $position_n = null;
    }
    Any suggestions on this? And thanks again for your helping a newbie.

    Nick

  6. #6
    From Italy with love silver trophybronze trophy
    guido2004's Avatar
    Join Date
    Sep 2004
    Posts
    9,408
    Mentioned
    149 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Nick Bogatin View Post
    So it appears that something is wrong in my lines below and that is causing only the class "first" to be added to every LI:

    Code:
    $lis = $element->children("li");	
    for($forl=0,$imax=count($lis);
    $forl<$imax;$forl++){
    	if ($forl==0) $position_n = 'first';
    	elseif ($forl==$imax-1) $position_n = 'last';
    	else $position_n = null;
    }
    Can you explain what you are doing in that loop? Because I've read it a couple of times, but I can't figure out how you're deciding if the li your handling is first, middle or last.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •