Category Menu

5 posts by 2 authors in: Forums > CMS Builder
Last Post: September 9, 2019   (RSS)

By rez - September 5, 2019 - edited: September 6, 2019

I made a Category Menu and some root levels have children and some don't.

The html has to come out like below.

<ul class="dropdown menu" data-dropdown-menu>
  <li>
    <a href="#">Item 1</a>
    <ul class="menu">
      <li><a href="#">Item 1A</a></li>
      <!-- ... -->
    </ul>
  </li>
  <li><a href="#">Item 2</a></li>
  <li><a href="#">Item 3</a></li>
  <li><a href="#">Item 4</a></li>
</ul>

Notice the UL goes after the <a>, and not inside of it. So any root level that has children have the anchor and the whole UL inside of the li.  I don't seem to have control of where internal ul tags go so I'm lost My attempts are basically moving around the default CMSB category code. I figured the li had to go in each if statement? What I'm putting here is basically one of 10 attempts but is clearly wrong. I'm lost.

  // load records from 'menu_items'
  list($menu_itemsRecords, $menu_itemsMetaData) = getRecords(array(
    'tableName'   => 'menu_items',
    'loadUploads' => true,
    'allowSearch' => false,
  ));
  // load records from 'menu_cats'
  list($menu_catsRecords, $selectedMenu_cats) = getCategories(array(
    'tableName'            => 'menu_cats', //
    'categoryFormat'       => 'showall',  // showall, onelevel, twolevel, breadcrumb
    'defaultCategory'      => '',    // Enter 'first', a category number, or leave blank '' for none
    
    // advanced options (you can safely ignore these)
    'rootCategoryNum'      => '0',      // Only categories _below_ this one will be shown (defaults to blank or 0 for all)
    'ulAttributes'         => 'class="menu"',      // add html attributes to <ul> tags, eg: 'class="menuUL"' would output <ul class="menuUL">
    'selectedCategoryNum'  => '',      // this record number is returned as the "selected category", defaults to getLastNumberInUrl()
    'ulAttributesCallback' => '',      // ADVANCED: custom function to return ul attributes, eg: 'myUlAttr' and function myUlAttr($category) { return "id='ul_uniqueId_{$category['num']}'"; }
    'liAttributesCallback' => '',      // ADVANCED: custom function to return li attributes, eg: 'myLiAttr' and function myLiAttr($category) { return "id='li_uniqueId_{$category['num']}'"; }
    'loadCreatedBy'        => false,   // loads createdBy.* fields for user who created category record (false is faster)
    'loadUploads'          => true,    // loads upload fields, eg: $category['photos'] gets defined with array of uploads (false is faster)
    'ignoreHidden'         => false,   // false = hide records with 'hidden' flag set, true = ignore status of hidden flag when loading records
    'debugSql'             => false,   // display the MySQL query being used to load records (for debugging)
  ));




						<ul class="dropdown menu" data-dropdown-menu>
							<?php foreach ($menu_catsRecords as $categoryRecord): ?>

									<?php if($categoryRecord['_hasChild'] && $categoryRecord['depth'] == '0'): ?>
										<?php echo $categoryRecord['_listItemStart'] ?>							
											<a href="#"><?php echo $categoryRecord['name'] ?></a>
									<?php else: ?>
										<?php echo $categoryRecord['_listItemStart'] ?>
											<a href="<?php echo $categoryRecord['name'] ?>"</a>
									<?php echo $categoryRecord['_listItemEnd'] ?>
									<?php endif ?>

							<?php endforeach; ?>
						</ul>






By rez - September 6, 2019 - edited: September 6, 2019

Getting there but have extra /li and /ul tags (commented in my results). This is a Zurb Foundation 6 menu by the way. 

I guess the UL is inserted wherever a depth zero is... yet we put in the first / outer UL tags? Something like that. I've used a category menu before but it was basically snippets from the forum. I'm not sure if this all breaks with anything above 1 child or another situation I'm not thinking of either.

I know it's very basic for most of you. Any thoughts or tips welcomed.

						<ul class="dropdown menu" data-dropdown-menu>
							<?php foreach ($menu_catsRecords as $categoryRecord): ?>
									// If the category is depth zero and has children, put an opening li and a linked name. No closing li yet.
									<?php if($categoryRecord['_hasChild'] && $categoryRecord['depth'] == '0'): ?> 
										<?php echo $categoryRecord['_listItemStart'] ?>							
											<a href="#"><?php echo $categoryRecord['name'] ?></a>
							   // else if the category does not have children and is depth is greater than zero, put a linked name with opening and closing li
										<?php elseif(!$categoryRecord['_hasChild'] && $categoryRecord['depth'] > '0'): ?>
											<?php echo $categoryRecord['_listItemStart'] ?>
												<a href="#"><?php echo $categoryRecord['name'] ?></a>
												<?php echo $categoryRecord['_listItemEnd'] ?>
							   //also if the category is the last child in this current loop, that means we need an extra closing li for this depth zero
												<?php if($categoryRecord['_isLastChild']): ?>
													<?php echo $categoryRecord['_listItemEnd'] ?>
												<?php endif; ?>
								// otherwise, opening and closing li around a linked name should cover everything else
										<?php else: ?>
											<?php echo $categoryRecord['_listItemStart'] ?>	
												<a href="#"><?php echo $categoryRecord['name'] ?></a>
											<?php echo $categoryRecord['_listItemEnd'] ?>
									<?php endif; ?>
							<?php endforeach; ?>
						</ul>

I'm getting this. However, there are also a lot of blank lines I removed to display here. Unnecessary looping, I assume.

<ul class="dropdown menu" data-dropdown-menu>
	<li>
		<a href="#">Breakfast</a>
			<ul menu>
				<li> <a href="#">Pancakes, Waffles, & French Toast $9</a>
				</li>
				<li> <a href="#">Specialty Breakfast Dishes</a>
				</li>
				<li> <a href="#">Platters</a>
				</li>
				<li> <a href="#">Breakfast Combo Platters</a>
				</li>
				<li> <a href="#">Benedicts</a>
				</li>
				<li> <a href="#">Omelettes or Pita Wraps</a>
				</li>
				<li> <a href="#">Breakfast Sides</a>
				</li>
				<li> <a href="#">Breakfast Sammies</a>
				</li>
				<li> <a href="#">Soups and Salads</a>
				</li>
			</ul>
	</li>
// I believe these next 3 tags are unnecessary and my current issue.

	</li>
</ul>
</li>

<li>
	<a href="#">Bites Before You Sip & Bite</a>
</li>
<li>
	<a href="#">Sandwiches, Wraps & Subs</a>
</li>
<li>
	<a href="#">Guy Fieri's Favorite Crab Cakes</a>
</li>
<li>
	<a href="#">Entrees</a>
</li>
<li>
	<a href="#">Burgers</a>
</li>
<li>
	<a href="#">Sides</a>
</li>
<li>
	<a href="#">Georgio & Niko's Junior Menu</a>
</li>
<li>
	<a href="#">Sips</a>
</li>
<li>
	<a href="#">Cocktails</a>
</li>
<li>
	<a href="#">Beer on Draft</a>
</li>
<li>
	<a href="#">Wine on Tap</a>
</li>
</ul>

By rez - September 6, 2019 - edited: September 6, 2019

I removed else statements and I don't know how this works but it does. It seems to me I would have to detect a lastchild in depth 2 to add the closing _listItemEnd tag for that branch's depth zero. I have a _listItemStart without a listItemEnd.

I moved some categories around and it doesn't break. Obviously this won't work on a menu with more than a depth of 2. Maybe you can help me with that to future proof this with unlimited depths / sub categories?

Am I getting lucky here and somehow a mistake happens to work? I don't get why this works. I troubleshooted and just came up with it logically.  

						<ul class="dropdown menu" data-dropdown-menu>
							<?php foreach ($menu_catsRecords as $categoryRecord): ?>
									<?php // If the category is depth zero and has children, put an opening li and a linked name. No closing li yet.?>
									<?php if($categoryRecord['_hasChild'] && $categoryRecord['depth'] == '0'): ?>
										<?php echo $categoryRecord['_listItemStart'] ?>
											<a href="#"><?php echo $categoryRecord['name'] ?></a>
									<?php endif; ?>
							    <?php // if the category does not have children and is greater than depth zero, not last, must be depth 2, put a linked name with opening and closing li ?>
										<?php if(!$categoryRecord['_hasChild'] && $categoryRecord['depth'] > '0' && !$categoryRecord['_isLastChild']): ?>
											<?php echo $categoryRecord['_listItemStart'] ?>
												<a href="#"><?php echo $categoryRecord['name'] ?></a>
											<?php echo $categoryRecord['_listItemEnd'] ?>
										<?php endif; ?>
							    <?php //if the category is the last child in this current loop, greater than depth zero, that means we need an extra closing li for this branch's depth zero EDIT: removed it ?>
											<?php if($categoryRecord['_isLastChild'] && $categoryRecord['depth'] > '0'): ?>
												<?php echo $categoryRecord['_listItemStart'] ?>
													<a href="#"><?php echo $categoryRecord['name'] ?></a>
												<?php echo $categoryRecord['_listItemEnd'] ?>							
											<?php endif; ?>
								  <?php // otherwise, opening and closing li around a linked name should cover everything else ?>
										<?php if(!$categoryRecord['_hasChild'] && $categoryRecord['depth'] == '0'): ?>
											<?php echo $categoryRecord['_listItemStart'] ?>
												<a href="#"><?php echo $categoryRecord['name'] ?></a>
											<?php echo $categoryRecord['_listItemEnd'] ?>
									<?php endif; ?>
							<?php endforeach; ?>
						</ul>

By daniel - September 6, 2019

Hey rez,

The behaviour you're describing (nesting <ul> outside of the <a></a>) is - I believe - supposed to be the default category menu behaviour. It looks like that might be what you're recreated in your latest "working" attempt. I would suggest trying the code generator again and checking to see if/how the default output is different from your custom example. If the default output isn't getting what you want, then there might be a different issue at play.

In any case, if you want to customize the nesting in a category menu, I'd recommend inserting the tags (li, ul, etc.) themselves, rather than using the _listItemStart and _listItemEnd values, since these are generated in accordance with the default behaviour and won't be much help otherwise. This is, however, a much more complex method, and a bit beyond what I'd be able to demonstrate on the forum.

Let me know how it goes trying the default output, or if you have any other questions.

Thanks!

Daniel
Technical Lead
interactivetools.com