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 rez - September 9, 2019 - edited: November 16, 2019

I see what I was doing wrong with the default code now that you have told me this.