Jump to content
louisstephens

Navigation Disaster

Recommended Posts

Well, after I thought I was near completion, a fun issue reared its ugly head. I have my tree set up like (names are just examples):

Home

Articles

- User 1

-- Article 1

-- Article 2

-- Article 3

-- Article 4

 - User 2

-- Article 1

-- Article 2

-- Article 3

-- Article 4

 

I have a drop down in my navigation called "User 1" (for when you are under User 1) that uses:

<?php
					foreach($page->siblings as $child) {
    					echo "<li><a href='{$child->url}'>{$child->title}</a></li>";
					}
				?>

This works great as long as you Stay in user 1. However if you go to the "User 2" dropdown, everything is replaced by user 2 and user 1 no longer displays. I realize it is because I am selecting the siblings, but is there a way to go about haveing both dropdowns contained and populated no matter which article I am currently viewing?

Share this post


Link to post
Share on other sites

If I understand well, you want to have a dropdown for each user. If so, you could do this:

foreach($pages->get("/articles/")->children as $writer) {

    echo "<ul>"; // your dropdowns are lists, right?

    foreach($child as $article) {
        echo "<li><a href='{$child->url}'>{$child->title}</a></li>";
    }

    echo "</ul>";
}

Share this post


Link to post
Share on other sites

Hmm, is there a way to achieve this without selecting a parent? The template was going to be used on multiple sections like:

Articles

- User 1

-- Article 1

-- Article 2

-- Article 3

-- Article 4

 

 - User 2

-- Article 1

-- Article 2

-- Article 3

-- Article 4

Events

- User 1

-- Event 1

-- Event 2

-- Event 3

-- Event 4

 - User 2

-- Event 1

-- Event 2

-- Event 3

-- Event 4

Sorry, I know this is a bit confusing.

Share this post


Link to post
Share on other sites

What about:

foreach($page->rootParent->children as $writer) {

Share this post


Link to post
Share on other sites

Sorry if I have been confusing (big learning opportunity for me to get comfortable with php), this is what I have for my nav. When I used what you showed I end up with a blank dropdown list. I understand that the foreach loops through the root parent which would show just "Articles" and "Events" ( need to populate with article 1 article 2 etc etc) and have it stay on each page no matter where you are within Articles and Events.

<nav class="navbar navbar-default navbar-static-top" data-offset-bottom="0" id="navbar">
  <div class="container">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse container" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
		<li><a href="">Home</a></li>
        <li class="dropdown">
          <a href="" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Articles <span class="caret"></span></a>
          <ul class="dropdown-menu">
           		<?php
					foreach($page->siblings as $child) {
    					echo "<li><a href='{$child->url}'>{$child->title}</a></li>";
					}
			  
			  
				?>
          </ul>
        </li>
		
		<li class="dropdown">
          <a href="" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Events <span class="caret"></span></a>
          <ul class="dropdown-menu">
           		<?php
					foreach($page->siblings as $child) {
    					echo "<li><a href='{$child->url}'>{$child->title}</a></li>";
					}
			  
			  
				?>
          </ul>
        </li>
        <li><a href="">Link</a></li>
		<li><a href="">Link</a></li>
		<li><a href="">Link</a></li>
		<li><a href="">Link</a></li>
		<li><a href="">Link</a></li>
      </ul>

      <ul class="navbar-right social">
        
	</ul>
            
                        
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>
</div> 

Share this post


Link to post
Share on other sites

Could something similar to

foreach($pages->find('parent.template=templatename, sort=sort') as $writer) {

be of some use?

I had to use it recently.

Share this post


Link to post
Share on other sites

Sorry, I'm on my phone so bare with me.

 

$results = $pages->get("/")->children("template=events|articles");
foreach($results as $result) {
   echo $result->title;
   foreach($results->children as $child) {
     echo $child->title;
     foreach($child->children as $child) {
       echo $child->title;
     }
   }
}
Edited by kongondo
wrapped code in code block
  • Like 1

Share this post


Link to post
Share on other sites

Thanks everyone for the speedy assistance! Just curious, is it possible to inc. a if/else statement in a for each statement? Ie:

$results = $pages->get("/")->children(

if {

"template=events"
}

else if {

"template=articles"
}

else {

"template=someothertemplate"
}


);

I just realized that I am might have many different instances of this on other templates

Share this post


Link to post
Share on other sites

You can use if / elseif / else, but you also can use switch().

foreach($pageArray as $child) {
    switch($child->template) {
        case: 'home':
            // your code here
            break;
        case: 'anothername':
            // your code here
            break;
        default:
            // your code here if there is a default for this, otherwise yiou can ommit it
    }
    // ...
}

Share this post


Link to post
Share on other sites

Thanks Horst. I went with the switch statement, but I think I may have hit a block here.

<?php
	foreach($page->siblings as $child) {
    	switch($child->template) {
			case 'articles':
				echo "<li><a href='{$child->url}'>{$child->title}</a></li>";
				break;
        					
			default:
			
			}
		}
			  
?>

<?php
	foreach($page->siblings as $child) {
    	switch($child->template) {
			case 'events':
				echo "<li><a href='{$child->url}'>{$child->title}</a></li>";
				break;
        	
			default:
			
			}
		}
			  
?>

I had tried using siblings to select, but I now see that it causes my biggest issue. When you are on one of the articles, it does pull in the other articles in the drop down. However, the events dropdown displays nothing. I understand that it is the "siblings" causing this. However, I really need the pages to display no matter where you are. Did I just miss a simple selector?

Share this post


Link to post
Share on other sites

$page is always relative to the current page. So if you are asking for the siblings of the current page, it would do just that. Instead you need to use get, to make sure that parent is always the same. To do this you use $pages->get()->siblings inside the () add your selector.

  • Like 1

Share this post


Link to post
Share on other sites

So just so I understand this, you are saying something like:

$pages get(parentName)->siblings as $child

How would this work though if you were dynamically trying to code this if there would be multiple "parentNames"? Sorry, I am just trying to get a grasp on all of this. I appreciate your help @tom @horst and everyone else. Thank you a bunch

Share this post


Link to post
Share on other sites

So just so I understand this, you are saying something like:

$pages get(parentName)->siblings as $child

How would this work though if you were dynamically trying to code this if there would be multiple "parentNames"? Sorry, I am just trying to get a grasp on all of this. I appreciate your help @tom @horst and everyone else. Thank you a bunch

This is cleared by the answer written by Tom.

Sorry, I'm on my phone so bare with me.

$results = $pages->get("/")->children("template=events|articles");
foreach($results as $result) {
   echo $result->title;
   foreach($results->children as $child) {
     echo $child->title;
     foreach($child->children as $child) {
       echo $child->title;
     }
   }
}

I will elaborate on his answer just trying to include the HTML you wrote a few posts back, I hope it makes it more clear. I'm not exactly sure the syntax of the nested dropwdowns is correct, hope you get the idea.

<?php $results = $pages->get("/")->children("template=events|articles"); 
//$result is one of your "content types", in this example, it could be Articles or Events page object.
?>
<?php foreach ($results as $result): ?> 
  <li class="dropdown">
    
    <a href=""
   class="dropdown-toggle"
   data-toggle="dropdown"
   role="button" aria-haspopup="true"
   aria-expanded="false"><?php echo $result->title //This would echo either "Article" or "Events" ?>
      <span class="caret"></span>
    </a>
    
    <ul class="dropdown-menu">
      <?php foreach($result->children as $user):?>
        <li><a href='<?php echo $user->url ?>'><?php echo $user->title ?></a>
          <?php foreach($user->children as $item): //This would be an article or event in itself?> 
              <li><a href='<?php echo $user->url ?>'><?php echo $user->title ?></a>
          <?php endforeach; ?>
          </li>
     <?php endforeach;?>
    </ul>
</li>
<?php endforeach; ?>

This could be included anywhere in any template and render the same, because $pages (whatch out for that plural!) variable that let's retrieve any page no matter where you are on the tree. The $pages->get() retrieves one page, in this case the root page, and the next method "children", returns the PageArray whose contained pages matches the selector.

The only thing I don't like about this is that I would need to specify the selector's parameters in case I add more "content types". But that's more of a topic on how you would plan your website. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By louisstephens
      I have not really had to make a site from the ground up in quite a bit as I have been mainly focused on internal apps using processwire. However, I have now been tasked with creating a site and I was quite excited. I started down the path of using bulma as it seemed like a good fit. I got the whole site coded statically and was not moving on to porting it over to processwire. I pretty much have the the whole site figured out save for tackling the navbar. My current navbar is set up as so:
      <section id="nav"> <nav class="navbar" role="navigation" aria-label="main navigation"> <div class="navbar-brand"> <a class="navbar-item is-size-3 has-text-primary" href="#">Logo goes here</a> <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample"> <span aria-hidden="true"></span> <span aria-hidden="true"></span> <span aria-hidden="true"></span> </a> </div> <div id="navbarBasicExample" class="navbar-menu"> <div class="navbar-end"> <a class="navbar-item">Home</a> <div class="navbar-item has-dropdown is-hoverable"> <a class="navbar-link">Services</a> <div class="navbar-dropdown"> <a class="navbar-item">Subpage</a> <a class="navbar-item">Subpage</a> <a class="navbar-item">Subpage</a> <a class="navbar-item">Subpage</a> </div> </div> <a class="navbar-item">Gallery</a> <a class="navbar-item">Contact Us</a> </div> </div> </nav> </section> I guess my question is how would you go about setting this up in processwire? All pages will obviously be subpages of Home with the following structure
      Home
      --Services
      ----Subpage
      ----Subpage
      ----Subpage
      ----Subpage
      --Gallery
      --Contact Us
       
    • By louisstephens
      So I reread my first draft, and it made absolutely no sense (I deleted it to hopefully better explain myself).  I am trying to make a system (that to me is a bit complicated) utilizing jquery and processwire together. My whole goal is to put a url like https://domain.com/launch?first_name=jim&occupation=builder in a script tag on another site(just a localhost .php page) to then pull out the data for that person and append to divs etc. Basically, the initial script tag would point to "launch" which has a content-type of "application/javascript". Using jquery, I would pull out the persons name and occupation and then make a specific ajax get request to "domain.com/api" (in json format) for a look up of the person. Essentially then I could pull that particular person's information from the json data, and do with it how I please in the "launch" page.  In processwire, I have a page structure like:
      People -Jim Bob (template: person ) --Occupations (template: basic-page) ---Builder (template: occupation) ---Greeter (template: occupation) It is really just a bunch of people with their occupations and a few fields to the occupation template. With the "api" (template: api) url, I was hoping to return all the data (of people) in json format like:
      Example Format:
      { "id": 1, "title": "Jim Bob", "occupations": { "builder": { "id": 44, "title": "Builder", "years_worked": 1, "etc": "ect", }, "Greeter": { "id": 44, "title": "Greeter", "years_worked": 1, "etc": "ect", }, } } Where I get lost is really outputting the page names and nesting in the occupations into json. I have used Pages2JSON before, but I was a bit lost on how to implement what i was thinking.
       
      I have access to all the local host files, but I was hoping to kind of build out a "system" where I could place the script tag/parameters in any project, and be able to interact with the data without doing an ajax call on the actual site. In a way, this would keep processwire handling all the data and requests, and my other "projects" just with a simple script tag. This might all be way too much/over complicated, but I couldn't quite wrap my head around how to achieve it. 
    • By anderson
      Hi,
      Please take a look at this:
      https://templatemag.com/demo/Good/
      The upper nav bar, including dropdowns like "pages" and "portfolios", what do you call this whole thing? At first I guess it's called "dropdown nav bar", but seems not.
      AND of course, what's the simplest way/module to achieve this in PW?
      Thanks in advance.
    • By ridgedale
      Reference: PW 3.0.111 and uikit3 based site using the Regular-Master profile.
      I was wondering if there is a way to restrict user navigation to specific pages.
      Login (home.php - not to be displayed)
          |__  About (not to be displayed)
          |__  Clubs (not to be displayed)
          |            |__ Club (to be displayed)
          |                       |__  Club Members (to be displayed)
          |__ League (not to be displayed)
          |            |__Season (not to be displayed)
          |                       |__  Match (not to be displayed)
          |__  News (blog.php -  to be displayed)
          |
      etc, etc
      Based on the above the navigation needs to appear simply as:
      ---------------------------------------------------------------------------
                           Club    Club Members    News    
      ---------------------------------------------------------------------------
      Any thoughts appreciated.
    • By joe_ma
      Hi
      Trying to setup a customized navigation.
      Page tree looks like this:
      home
      – upcoming exhibitions
      –– exhibition 1
      –– exhibition 2
      –– …
      – about
      – archive
      –– arch 1
      –– arch 2
      –– …
      – impressum
      Now I'd like to have a navigation, that lists only the subnav of "upcoming exhibitions" but not the one of "archive".
      I modified a snippet I found here in the forum. It looks like this so far:
      <nav class="mainNav"> <ul> <?php $homepage = $pages->get('/'); // first item links to the homepage echo "<li><a href='$homepage->url'>Aktuelle Ausstellung / current exhibition</a></li>"; $children = $homepage->children(); // render an <li> for each top navigation item foreach ( $children as $child ) { if ( $child->id == $page->rootParent->id ) { // this $child page is currently being viewed (or one of it's children/descendents) // so we highlight it as the current page in the navigation echo "<li class='active'><a href='$child->url'>$child->title</a></li>"; // if upcoming page has children, list them } elseif($child->id == 1020 && count($child->children)){ // build the subnav and list all items echo "<li><a href='$child->url'>$child->title</a><ul class='upcoming'>"; foreach($child->children as $c){ echo "<li><a href='$c->url'>$c->title<br>{$c->date_from}–{$c->date_to}</a></li>"; } echo "</ul><li>"; // otherwise list only main items } else { echo "<li><a href='$child->url'>$child->title</a></li>"; } } ?> </ul> </nav> This puts out the navigation as wanted, but only for main items (see fig. nav-open.png).
      As soon as "upcoming exhibitions" or one of its children is active, the navigation collapses (see fig. nav-closed.png).
      I cannot find out, where I went the wrong way.
      Thanks for help.


×
×
  • Create New...