how to add active class in current page in CakePhp - php

i have a problem similar to this question
How to identify active menu link in CakePHP
i have a page in my default.ctp file in which i want to add 'active' class on links. how can i identify the current url of the page and then apply the class on link.. i have followed the answer also there which is
$url = $this->Html->url('INPUT_THE_URL') ;
$active = $this->request->here == $url? true: false;
i dont know how can i do this in my code .. sorry for asking as i am newbie in cakephp .. here is my code
**default.ctp file**
<li>
<?php echo $this->Html->link('Dashboard', array('controller'=>'users','action' => 'controlpanel'), array('title' => 'Dashboard','class' => 'shortcut-dashboard'));?></li>
<li> <?php echo $this->Html->link('Contacts', array('controller'=>'contacts','action' => 'index'), array('title' => 'Contacts','class' => 'shortcut-contacts'));?></li>
i want to add a class with li like this
<li class = 'active''>

This is a simple logic as follows
<li class="<?php echo (!empty($this->params['action']) && ($this->params['action']=='controlpanel') )?'active' :'inactive' ?>">
<?php echo $this->Html->link('Dashboard', array('controller'=>'users','action' => 'controlpanel'), array('title' => 'Dashboard','class' => 'shortcut-dashboard'));?>
</li>
<li class="<?php echo (!empty($this->params['action']) && ($this->params['action']=='index') )?'active' :'inactive' ?>">
<?php echo $this->Html->link('Contacts', array('controller'=>'contacts','action' => 'index'), array('title' => 'Contacts','class' => 'shortcut-contacts'));?></li>

If you have a different controller and you have declared a method with same name, and the above code is not working, then you can do the following:
<li class="<?php echo (($this->params['controller']==='hotels')&& ($this->params['action']=='view') )?'active' :'' ?>" >
<?php echo $this->Html->link('Hotels', array('controller' => 'hotels', 'action' => 'view')); ?>
</li>
<li class="<?php echo (($this->params['controller']==='packages')&& ($this->params['action']=='view') )?'active' :'' ?>" >
<?php echo $this->Html->link('Packages', array('controller' => 'packages', 'action' => 'view')); ?>
</li>
Here view method is declared in different controller. i hope it will be helpful for you.

Not to revive a dead post, but this is what I do (which I believe is a bit cleaner and faster and a bit more manageable)
I create an element that has an array of pages, then I check against each item in the array to see if it is the current page. If it is I add the active class.
I can then call this element from anywhere.
// Changed the line below to a multi-dimensional array to cater for different controllers and actions
//$mypages = array('Home','About','Pricing','FAQs','Contact');
$mypages = array(
array('controller'=>'controller1','action'=>'action1','name'=>'name1'),
array('controller'=>'controller2','action'=>'action2','name'=>'name2
')
);
foreach ($mypages as $page ){
// Changed to account for controller and action
//$currentPage = isset($this->params['pass'][0]) ?$this->params['pass'][0] : "";
$controller = isset($this->request->params['controller'])?$this->request->params['controller']: "";
$action= isset($this->request->params['action'])?$this->request->params['action']: "";
if (strtolower($page['controller']) == $controller && strtolower($page['action']) == $action) {
echo "<li class='active'>" . $this->Html->link($page,array("controller"=>"pages", "action"=>strtolower($page))) . "</li>" ;
}
else {
echo "<li>" . $this->Html->link($page,array("controller"=>"pages", "action"=>strtolower($page))) . "</li>";
}
}

Related

How can I remove nested nav from all top-level listed items, except for Services in a PHP array?

I am trying to remove the nested list ($subPages) from displaying under all of the top-level lists ($pages), except for Services; however my code is allowing the nested list items to display under all three top-level list items.
Can anyone help me remove the nested list items from all top-level list items, except for one?
NB. I am new to PHP, and would like to just stick to PHP without any other languages. My PHP code may be in efficient; if you spot room for improvement, let me know.
<nav class="navBar wAuto fRight positAb">
<?php
$pages = array(
'/about/' => 'About',
'/services/' => 'Services',
'/book-a-service/' => 'Book a service'
);
$subPages = array(
'/services/bathroom-installation' => 'Bathroom installation',
'/services/boiler-repair' => 'Boiler repair',
'/services/boiler-service' => 'Boiler service',
'/services/gas-oil' => 'Gas & oil',
'/services/heat-recovery' => 'Heat recovery',
'/services/heating-plumbing' => 'Heating and plumbing',
'/services/rainwater-harvesting' => 'Rainwater harvesting',
'/services/solar-solutions' => 'Solar solutions',
'/services/underfloor-heating' => 'Underfloor heating'
);
$activePage = $_SERVER['REQUEST_URI'];
echo '<ul>';//open nav
foreach( $pages as $url => $anchor){
$activeClass = ($_SERVER['REQUEST_URI'] == $url) ? " active" : "";
echo '<li class="fLeft"><a class="font13'.$activeClass.'" href="'.$url.'"';
if($url == '/services/'){
echo 'id="parent"';
}
if($url == '/book-a-service/')
echo 'id="ctaUHP"';
echo '>'.$anchor.'</a>';
//Open nested nav
if(isset($url) == '/services/'){
echo '<ul class="wAuto positAb">';
foreach ($subPages as $url => $anchor){
echo '<li class="fullWidth"><a class="font10" href="'.$url.'"';//open nested nav
echo '>'.$anchor.'</a></li>';
}
};
echo '</li></ul>'; //close nested nav
}
//Close submenu
echo '</ul>';
//close nav
?>
</nav>
In the code for open nested nav, change if(isset($url) == '/services/') to if($url == '/services/'){
Explanation: You don't need to verify if the $url is set, you just need to print the nested nav when your $url == '/services/', that's why you need to remove the function isset() :)
EDIT
You lacked some {} and I even rearranged some of your code, so now looks like this :)
echo '<ul>'; //open nav
foreach( $pages as $url => $anchor) {
$activeClass = ($_SERVER['REQUEST_URI'] == $url) ? " active" : "";
echo '<li class="fLeft"><a class="font13'.$activeClass.'" href="'.$url.'"';
if($url == '/services/') {
echo 'id="parent"';
}
if($url == '/book-a-service/') {
echo 'id="ctaUHP"';
}
echo '>'.$anchor.'</a>';
//verify if exists nested nav
if($url == '/services/') {
echo '<ul class="wAuto positAb">'; //open nested nav
foreach ($subPages as $url => $anchor) {
echo '<li class="fullWidth"><a class="font10" href="'.$url.'">'.$anchor.'</a></li>';
}
echo '</ul>'; //close nested nav
}
echo '</li>';
}
echo '</ul>'; //close nav

php navigation using get or include

index.php is controlling the site.
I have elseif include based on variable $p
right now $p does not have anything in it and i'm not understanding why.
Also is using include the industry standard or would GET be a better choice?
In the header file which is included on index.php but it just takes me to the page link instead of storing the page in $p
<?php
$pages = array(
"home" => "HOME",
"services" => "SERVICES",
"employees" => "EMPLOYEES",
"contact" => "CONTACT");
$p = (isset($_GET['p'])) ? $_GET['p'] : "";
foreach ($pages as $url => $label) {
echo '<li ';
if ($p == $url) { echo '<li><a class="active" href="' . htmlspecialchars(urlencode($url)). '.php">'
. htmlspecialchars($label) . '</a></li>'; } else { echo '<li>' . $label . '</li>'; }
}
?>
This is the index.php file:
<?php include('includes/header.php'); ?>
<?php
if ($p == "services") {
include("services.php");
} elseif($p == "employees") {
include("employees.php");
} elseif($p == "contact") {
include("contact.php");
} else {
include("home.php");
};
?>
<?php include('includes/footer.php'); ?>
It really depends on what you are trying to do. Maybe I am misunderstanding your question, however include and $_GET are two completely separate things.
$_GET is an array of the query string out of your URL. So, for instance, if your URL was mysite.com/index.php?a=rawr&p=services then $_GET would be array("a" => "rawr", "p" => "services"); If you don't have any parameters in your URL assigned to p, then $_GET["p"] would be empty
Source:
http://www.php.net/manual/en/reserved.variables.get.php
EDIT:
I think I'm starting to understand your question now. Using your current method would be fine, I would just change up the code slightly:
<?php
$pages = array(
"home" => "HOME",
"services" => "SERVICES",
"employees" => "EMPLOYEES",
"contact" => "CONTACT"
);
$p = (isset($_GET['p'])) ? $_GET['p'] : "";
foreach ($pages as $url => $label) {
?>
<li><a <?= $p == $url ? 'class="active"' : ""?> href="index.php?p=<?=$url?>" > <?=$label?> </a></li>
<?php
}
?>

Get current url excluding Included file names

I have a file named administrator1.php and inside it test.php is included. So code inside administrator1.php is
<?php include 'test.php'; ?>
I have a dynamic navigation menu inside test.php. Code is
<?php
$menu = array(
'users' => array('text'=>'USERS', 'url'=>'administrator1.php'),
'createProfile' => array('text'=>'CREATE PROFILE', 'url'=>'administrator2.php'),
'payment' => array('text'=>'PAYMENTS', 'url'=>'administrator3.php'),
'defense' => array('text'=>'DEFENSE', 'url'=>'administrator4.php'),
'progressReport' => array('text'=>'PROGRESS REPORT', 'url'=>'administrator5.php'),
);
class Nav {
function GenerateMenu($items) {
$html = "<ul>";
foreach($items as $item) {
if(stristr(__FILE__,$item['url'])===FALSE) {
$html .= "<li><a href='{$item['url']}' ><span><B>{$item['text']}</B></span> </a> </li>";
}
else {
$html .= "<li class='active'><a href='{$item['url']}' ><span><B>{$item['text']}.nnn</B></span> </a></li>";
}
}
$html .= "</ul>";
return $html;
}};
echo Nav::GenerateMenu($menu);
?>
And I have called the Nav method inside the same file.
Problem here is, the whole navigation bar will be printed, but selected item's ('USERS') CSS class active will not be called. But if I replace this whole code in administrator1.php file without including a test.php file it works fine. So I guess it is a problem to file path of the included file. And is it because I have used __FILE__ to get current path? Then how can I get current file path excluding included files names in the path?
For calling the static function we can use :: operator. But for accessing the non-static member of the class you should make the object, like -
$nav_ob = new Nav();
echo $nav_ob->GenerateMenu($menu);
And there s problem, when you are creating array -
$menu = array(
'users' => array('text'=>'USERS', 'url'=>'administrator1.php'),
'createProfile' => array('text'=>'CREATE PROFILE', 'url'=>'administrator2.php'),
'payment' => array('text'=>'PAYMENTS', 'url'=>'administrator3.php'),
'defense' => array('text'=>'DEFENSE', 'url'=>'administrator4.php'),
'progressReport' => array('text'=>'PROGRESS REPORT', 'url'=>'administrator5.php'), //Here
);
Comma after the last element. It should be -
$menu = array(
'users' => array('text'=>'USERS', 'url'=>'administrator1.php'),
'createProfile' => array('text'=>'CREATE PROFILE', 'url'=>'administrator2.php'),
'payment' => array('text'=>'PAYMENTS', 'url'=>'administrator3.php'),
'defense' => array('text'=>'DEFENSE', 'url'=>'administrator4.php'),
'progressReport' => array('text'=>'PROGRESS REPORT', 'url'=>'administrator5.php')
);
UPDATED
<?php
$menu = array(
'users' => array('text'=>'USERS', 'url'=>'administrator1.php'),
'createProfile' => array('text'=>'CREATE PROFILE', 'url'=>'administrator2.php'),
'payment' => array('text'=>'PAYMENTS', 'url'=>'administrator3.php'),
'defense' => array('text'=>'DEFENSE', 'url'=>'administrator4.php'),
'progressReport' => array('text'=>'PROGRESS REPORT', 'url'=>'administrator5.php')
);
class Nav {
function GenerateMenu($path, $items) {
$html = "<ul>";
foreach($items as $item) {
if(stristr($path,$item['url'])===FALSE) {
$html .= "<li><a href='{$item['url']}' ><span><B>{$item['text']}</B></span> </a> </li>";
}
else {
$html .= "<li class='active'><a href='{$item['url']}' ><span><B>{$item['text']}.nnn</B></span> </a></li>";
}
}
$html .= "</ul>";
return $html;
}};
?>
And on each administrator.php file after including the above php file call the method like -
$nav_ob = new Nav();
echo $nav_ob->GenerateMenu(__FILE__, $menu);
Hope this will help.
Found the answer!
Replaced __FILE__ with $_SERVER["PHP_SELF"]. So the code is;
class Nav {
function GenerateMenu($items) {
$html = "<ul>";
foreach($items as $item) {
if(stristr($_SERVER["PHP_SELF"],$item['url'])===FALSE) {
$html .= "<li><a href='{$item['url']}' ><span><B>{$item['text']}</B></span> </a> </li>";
}
else {
$html .= "<li class='active'><a href='{$item['url']}' ><span><B>{$item['text']}.</B></span> </a></li>";
}
}
$html .= "</ul>";
return $html;
}};
$nav_ob = new Nav();
echo $nav_ob->GenerateMenu($menu);
Now it works as i wanted! Thank you everyone for the help given!

Problems with an accordion menu using jquery and PHP to show 'active' links and keep menu slider open on current page

With my very little knowledge of jQuery and PHP, I have almost accomplished an accordion menu where the links display as 'active' when the active page is open, and the slider menu stays open on the correct section when on the active page.
I have added some php to the bottom links. The child links display as active when on the active page. However the parent element does not, and also closes itself.
I'd really appreciate any help!!!
Here's my code as it stands:
<ul id="accordion">
<ul class="parent">
<li>
CMS
<ul class="child">
<li>Intro to CMS</li>
<li>Specific CMS</li>
<li>Installing a CMS</li>
</ul>
</li>
</ul>
<ul class="parent">
<li>
<?php
if ($this_page=="Customising-Google-Forms" || $this_page=="Web-Event-Notes"){
echo "Other";
}else{
echo "Other";
}
?>
<ul class="child">
<?php
if ($this_page=="Customising-Google-Forms"){
echo "<li class=\"current\">Customising-google-forms</li>";
}else{
echo "<li>Customising Google Forms</li>";
}
?>
<?php
if ($this_page=="Web-Event-Notes"){
echo "<li class=\"current\">Web Event Notes</li>";
}else{
echo "<li>Web-Event-Notes</li>";
}
?>
</ul>
</li>
</ul>
<script type="text/javascript">
$(function(){
// hide all links on load
$('ul.child').hide();
// for image
// $("a.slide:first").css("background-image","url('path')");
$('ul.parent a.slide').click(function(){
$('ul.parent a.slide').css("color","#000");
$('ul.parent a.slide').hover(function(){
$(this).css("color","#ef492f");
});
$('ul.parent a.slide').mouseout(function(){
$(this).css("color","#000");
});
$(this).mouseout(function(){
$(this).css("color","#000");
});
$(this).css("color","#000");
// slide all up
$('ul.child').slideUp('slow');
// show the links of current heading
$(this).next().find('a').show();
// slide down current heading
$(this).next().slideDown('fast');
// prevent default action
return false;
});
if($("ul li a").hasClass("current")) {
$(this).closest("ul").slideDown("fast") //open the menu
}
});
</script>
In my opinion the best way to accomplish this is by making a PHP array that contains the links and then build a html menu out of it. In this way PHP can control which of the links will hold the 'current' class based on the url parameters. The last step will be jquery to just grab the '.current' listitem and make it visible. The below may seem like a lot of work, but when you get it, it will be powerful and reusable :)
//Grab the page parameter somehow.. below = example
$page = $_GET['page'];
//Build menu array containing links and subs
$items = Array(
//highest level
'cms' => Array(
'title' => 'CMS',
//Array containing submenu items for cms
'subs' => Array(
'intro-to-cms' => Array('title' => 'Intro to CMS'),
'specific-cms' => Array('title' => 'Specific CMS'),
'installing-a-cms' => Array('title' => 'Installing a CMS')
),
)
);
//Display the menu
echo navlinks($items, $page);
/**
* Recursive function creates a navigation out of an array
* #param type $items
* #return string containing navigationlist
*/
function navlinks($items, $page=false)
{
$html = '<ul>';
foreach ($items AS $uri => $info) {
//Check if the pagename is the same as the link name and set it to current when it is
$html .= '<li'.($info['title'] == $page ? ' class="current"' : '').'>';
echo ' ' . $info['title'] . '';
//If the link has a sub array, recurse this function to build another list in this listitem
if (isset($info['subs']) && is_array($info['subs'])) {
$html .= navlinks($info['subs']);
}
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}

Best way to highlight tabs according to the page you're on with CakePHP?

So prior to being introduced to CakePHP, I'd highlight the appropriate navigation tab according to the url with the following (rather sloppy) code I wrote (fyi absolute_url was a function I wrote to get the absolute path) :
$page = $_SERVER['PHP_SELF'];
// add all possible states for the navigation to an array
$checkNav = array(
"index" => "index",
"new" => "new",
"random" => "random",
"submit" => "submit"
);
$compareAgainst = strpos($page, $checkNav['index']);
if ($compareAgainst == 0) {
echo "<li><span class=\"navBorder\">Popular</span></li>\n";
} else {
echo "<li>Popular</li>\n";
}
$compareAgainst = strpos($page, $checkNav['new']);
if ($compareAgainst == 0) {
echo "<li><span class=\"navBorder\">New</span></li>\n";
} else {
echo "<li>New</li>\n";
}
$compareAgainst = strpos($page, $checkNav['random']);
if ($compareAgainst == 0) {
echo "<li><span class=\"navBorder\">Random</span></li>\n";
} else {
echo "<li>Random</li>\n";
}
$compareAgainst = strpos($page, $checkNav['submit']);
if ($compareAgainst == 0) {
echo "<li><span class=\"navBorder\">+ Submit a Link</span></li>\n";
} else {
echo "<li>+ Submit a Link</li>\n";
}
Now, I've noticed that in Cake, to determine the relative path, I can just go:
<?= $this->here; ?>
Is there a better way to do this, or should I just implement this (new) method with the old code?
You can do the following
Add this to app_helper.php if you need it in multiple pages. You feed this function with the controller and the action you want to check you want to compare against. The function compares it with the current page and return true if they match.
function isActive($controller, $actions = array())
{
foreach ($actions as $action)
{
if ($controller == $this->params['controller'] && $action == $this->params['action'])
{
return true;
}
}
return false;
}
And then generate your links like so:
<ul class="left">
<li <?php if($html->isActive('controller_name', array('index'))) { echo 'class="active"'; } ?>><?php echo $html->link('Index', '/index'); ?></li>
<li <?php if($html->isActive('controller_name', array('new'))) { echo 'class="active"'; } ?>><?php echo $html->link('New', '/new'); ?></li>
<li <?php if($html->isActive('controller_name', array('random'))) { echo 'class="active"'; } ?>><?php echo $html->link('Random', '/random'); ?></li>
<li <?php if($html->isActive('controller_name', array('submit'))) { echo 'class="active"'; } ?>><?php echo $html->link('Submit', '/submit'); ?></li>
</ul>
If the function returns true, the link will have class="active". Adapt it to your needs.
The way I've always done this is to give your body tag an id, and use css to target it. If your views are all separate then you can hard code the body id. If you are using some sort of template that adds in the header, content, footer etc., then just pass the id as a variable to the header view or wherever the body tag is (really any outer container/div that will be on every view and contain your navigation tabs). Also you will need to give your navigation tab id's to target each one.
Then just some css like this:
#homepage a#hometab,
#aboutpage a#abouttab,
#productpage a#productstab,
#contactpage a#contacttab
{
special active styling here
}

Categories