Jump to content

Can $session->redirect open in a new window?


joer80
 Share

Recommended Posts

I have a template called redirectPage.php and it only has one line of code.

$session->redirect($page->redirectTo_URL);

How would I go about telling this to open the link in a new window instead of the current one?

(In my navigation if I want to link to a different address than itself, I set the page to this template and paste in the url into the redirectTo_URL field.  I also want to add a checkbox for if it is a new window or not.  To get my top level nav links, I search for this:  $pages->find('parent=1, sort=sort');)

Thanks!

Link to comment
Share on other sites

It sounds like adding the javascript to pop open a new window to this template wouldnt work, because you will still have this page open also, which would be blank.  Sounds like I just need to do it with a blank target before I get to this page/template?

Link to comment
Share on other sites

Custom code that uses the bootstrap format.

One query finds top level links by getting the children of the homepage

$TopLevelNavLinks = $pages->find('parent=1, sort=sort');
 
 
And then I do a second query to loop through each of those
 
$SecondLevelNavLinks = $pages->find("parent=$TopLevelNavLink->id, sort=sort");
 
Link to comment
Share on other sites

Yeah, I will have to add it to all of my templates that can be in the nav though I think, as well as a url box to all templates.   In the past, I just had one template that was a redirect template.  I think this is my best option though...  Just not as neat and clean.

Link to comment
Share on other sites

I'm not sure I follow.

If you have a "redirect" template with 2 fields: URL, New Window

Each page that is just a redirect would use that template.

So then you can change the output based on template and the value of the checkbox.

Link to comment
Share on other sites

Written in browser, but something like: 

foreach ($TopLevelNavLinks as $p){
    $url = $p->url;
    $title = $p->title;
    $attr = '';
    if ($p->template == "redirect"){
        $url = $p->redirect //redirect is the name of the URL field
        if($p->new_window == 1){
            $attr = "target=blank";
        }
    }
echo "<li><a href='$url' $attr>$title</a></li>";
  • Like 2
Link to comment
Share on other sites

Here's a more complete answer. Tested and works as expected.

function navList($items, $level = 1){
   $max_levels = 2;
   $level == 1 ? $class = "parent" : $class = "child";
   $out = '';
   
   if ($level <= $max_levels){
       $out = "<ul class='$class'>";
       foreach ($items as $item){
          $out .= navItem($item, $level);
       }
       $out .= "</ul>";
   }
   
   $level++; // increment level each time this function is called.
   
   return $out;
}

function navItem($item, $level){
   $url = $item->url;
   $attr = '';
   if ($item->template == "redirect"){
       if (trim($item->redirect) == "") return; // skip because the field is blank.
       $url = $item->redirect; 
       if($item->new_window == 1){
           $attr = "target=_blank";
       }
   }

   $out = "<li><a href='$url' $attr>$item->title</a>";
   if ($item->numChildren > 0){
       $out .= navList($item->children(), $level + 1); // get recursive
   }
   $out .= "</li>";

   return $out;
}

echo navList($p);

No need to do anything other than get the top level nav items and set the $max_levels if different than 2.

You can of course probably do all of this as easy/easier with MarkupSimpleNavigation, but it's not necessary if all you need is this.

  • Like 4
Link to comment
Share on other sites

The reason why I do not do the $item->children method, is if someone has a database of products under a page tied to the navigation, it makes it a lot slower and uses more memory.  Especially if there are thousands of products.

ie.  A layout using  Home -> Inventory -> All Inventory -> Item1  would not be good.

I noticed a huge speed boost when I went to 2 queries.  (Bootstrap only supports 2 levels, so no need to go deeper.)

Link to comment
Share on other sites

This is what I am using right now to make bootstrap menus with active link colors and drop downs before I add the above new window redirect code:

<?php
$LogoImage = 'logo.png';
$NavColor = 'navbar-default'; //navbar-default or navbar-inverse

//Make the menu
//echo the starting code
echo '<nav class="navbar ' . $NavColor . ' navbar-fixed-top" role="navigation">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
  <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
	<span class="sr-only">Toggle navigation</span>
	<span class="icon-bar"></span>
	<span class="icon-bar"></span>
	<span class="icon-bar"></span>
  </button>
  <a class="navbar-brand" href="' . $config->urls->root . '"><img src="' . $config->urls->templates . 'images/' . $LogoImage . '" class="Logo" alt="' . $LocationPage->title . ' Logo" /></a>
</div>

<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="navbar-collapse-1">';

echo '<div id="AboveNav"><i class="fa fa-phone"></i>  ' . $LocationPage->Location_PhoneNumber_Switchboard . '     <i class="fa fa-flag"></i>  ' . $LocationPage->Location_AddressStreet . ' ' . $LocationPage->Location_City . ', ' . $LocationPage->Location_StateAbrv . '</div><!--      -->';
echo '<ul class="nav navbar-nav navbar-right">';

//Make the top level links
$TopLevelNavLinks = $pages->find('parent=1, sort=sort');

//add home link
echo '<li><a href="/">Home</a></li>'; //could use $config->urls->root

//Build Top Level Links
foreach($TopLevelNavLinks as $TopLevelNavLink){
	
	//Look up this top level link to build a drop down if it needs it
	$SecondLevelNavLinks = $pages->find("parent=$TopLevelNavLink->id, sort=sort");
	$SecondLevelTotal = $SecondLevelNavLinks->getTotal();
	
	//If I am on this page, add the active class
	if($page->id == $TopLevelNavLink->id){
	  $classTag = ' active';
	} else {
	  $classTag = '';  
	}
	
	//if there is atleast one sublink, put me in a dropdown
	if($SecondLevelTotal > 0){
	  //Dont make link take user to page.  Instead, open a dropdown menu.
	  echo '<li class="dropdown' . $classTag . '">';
	  echo '<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' . $TopLevelNavLink->title . ' <span class="caret"></span></a>';
	  echo '<ul class="dropdown-menu" role="menu">';	
	  
	  //loop through the second level
	  foreach($SecondLevelNavLinks as $SecondLevelNavLink){
		  
	  //If I am on this page, add the active class
	  if($page->id == $SecondLevelNavLink->id){
		$classTag2ndlevel = ' class="active" ';
	  } else {
		$classTag2ndlevel = '';  
	  }
	  
		echo '<li' . $classTag2ndlevel . '><a href="' . $SecondLevelNavLink->url . '">' . $SecondLevelNavLink->title . '</a></li>';
		
	  }
	  
	  echo '</ul>';	
		  
	} else {
	  //Make link take user to page	  
	  echo '<li class="nodropdown' . $classTag . '"><a href="' . $TopLevelNavLink->url . '">' . $TopLevelNavLink->title . '</a></li>';
	}
	
} //end of built top level nav links

		
//echo the ending code
echo '</ul></div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>';
?>
  • Like 1
Link to comment
Share on other sites

You can restrict it to one level, or you can also do $item->children($selector) to filter out certain template types.

If you use markup cache for your menus, then it won't matter, the slowdown will be minor for the one view that retriggers the cache.

That said, whatever works for you. I like to keep these things as dry as possible.

Link to comment
Share on other sites

That is a handy addition!  I would be curious if I did it this way, if it would still have the delay or not?  Does it still pull all 2k pages and populate it into the $item var and this just doesn't loop through it anymore?  I used to be about 3-5 seconds extra on all page loads but I can test it.  But like you said, caching helps for most of the time..

Link to comment
Share on other sites

I just quickly built a menu using:

$navItems = $pages->get("/")->children("template!=syllabi");

That creates a 2 level menu with 15 parents, and about 65 children.

Without any markupCache

total time: 0.6733

With MarkupCache

total time: 0.0018

I tested them like so:

$t = Debug::timer(); 
echo navList($p);
echo Debug::timer($t);

$t = Debug::timer(); 
$cache = $modules->get("MarkupCache");
if(!$data = $cache->get("menu-test")) {
     $data = navList($p);
     $cache->save($data);
}
echo $data;
echo Debug::timer($t);
  • Like 2
Link to comment
Share on other sites

Very handy!  Thanks for taking your time to look into all of this.  I havn't even had the chance to add the checkbox logic and you have all of the sample code.  I will use that timer code to start timing things on future snippets.   :D

  • Like 1
Link to comment
Share on other sites

MarkupCache clears at a default interval of an hour, but you can specify less time if you want.

$cache->get("menu-test",120); // 2 minutes

No worries, I suspect it will be useful to someone else as well, so I figured I'd leave a solid example here.

  • Like 2
Link to comment
Share on other sites

I needed a break from a project I was stumped on, so here's a version that creates a bootstrap menu (at least the best I can tell, since I don't use bootstrap, I just went by your sample code). I stripped out a few of the things to make it more general, but you could easily use it to create your menu. Renders lightning fast here.

<?php

function navList($items, $level = 1){
    $max_levels = 2;
    $level == 1 ? $attrs = 'class="nav navbar-nav navbar-right"' : $attrs = 'class="dropdown-menu" role="menu"';
    $out = '';

    if ($level <= $max_levels){
        $out = "<ul $attrs'>";
        foreach ($items as $item){
            $out .= navItem($item, $level);
        }
        $out .= "</ul>";
    }
    
    $level++; // increment level each time this function is called.
    return $out;
}

function navItem($item, $level){
    $url = $item->url;
    $attrs = '';
    $itemClass = 'nodropdown';
    if ($item->template == "redirect"){
        if (trim($item->redirect) == "") return; // skip because the field is blank.
        $url = $item->redirect; 
        if($item->new_window == 1){
            $attr = "target=_blank ";
        }
    }

    if ($item->numChildren()){
        $itemClass = 'dropdown';
        $attrs = 'class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" ';
    }
    
    $out = "<li class='$itemClass'><a href='$url' $attrs>$item->title</a>";
    if ($item->numChildren > 0){
        $out .= navList($item->children(), $level + 1); // get recursive
    }
    $out .= "</li>";

    return $out;
}
?>

<nav class="navbar navbar-fixed-top" role="navigation">
    <div class="container">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
          <a class="navbar-brand" href="<?=$config->urls->root;?>"><img src="" class="Logo" alt="Logo" /></a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="navbar-collapse-1">
            <?php
            $cache = $modules->get("MarkupCache");
            if(!$data = $cache->get("main-nav")) {
                 $data = navList($pages->get("/")->children());
                 $cache->save($data);
            }
            echo $data;
            ?>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>
  • Like 1
Link to comment
Share on other sites

The caveat here is that new pages won't be immediately added to the menu because of the markupCache. It's just cleared at the interval, not via page save. I haven't ever looked into it, but it might be possible to clear the markupCache from a hook.

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...