I'm trying to build a personal website, (fairly new to HTML and PHP) and am having trouble building a dynamic menu bar. By dynamic, I mean that I want the page that the use is on be highlighted.
Right now I have a horizontal menu on my page (Home, Contact, etc...), and have the CSS set up so that when one of the links has the attribute class="active", then the item remains highlighted (so the user knows which page he or she is on).
For example, in a static HTML page I would copy and paste the following code to each other static page and just change where the class="active" attribute is to align with the proper page:
Home
Page Two
Contact
I obviously want to use PHP to be able to minimize the amount of duplicated code I have scattered around.
So far, I have followed the first answer on this page It has worked great. I am able to click on a menu item and the content comes up in the body of the page. However:
I can't get it to dynamically highlight the menu since the menu options (the <a href /> lines) are not being dynamically created through PHP.
When I go to the page directly through index.php, I get an error:
Notice: Undefined index: 'page' in C:\xampp\htdocs\index.php on line 43
Obviously, when I go the page directly, the ?page=home variable is not set in the line:
Home
So, the 'page' variable in GET has not been set. I've gotten around that with an if statement that checks if it is not set and sends the home page html. However, I don't think this is the best way to do it, and when I try to tackle part b), I'm thinking I need to change this completely. My entire PHP script is like this:
<?php
$current_page = 'home';
$pages = array('home', 'pagetwo', 'contact');
function setActiveHeader() {
global $current_page;
global $pages;
$arr_length = count($pages);
for($x=0;$x<$arr_length;$x++) {
if($pages[$x] == $current_page) {
echo "$pages[$x]";
} else {
echo "$pages[$x]";
}
}
}
function putPage($page) {
// put a list of allowed pages here
global $pages;
$page = trim($page);
$page = (in_array($page, $pages)) ? $page : 'home';
// set current page global variable
$GLOBALS['current_page'] = $page;
// output contents of page selected
echo #file_get_contents('.\html\\' . $page . '.html');
}
?>
I just try to call setActiveHeader() from the HTML, but that doesn't work right. The menu is output correctly, but the the correct item doesn't get highlighted, it just stays stuck on the home option highlighted. Not sure why it is not being updated. Is there a better way to go about doing this?
Your code only goes up to 37 lines, and we can't much without the line that the error is referencing, but I'll try my best.
Basically, what Undefined Index means, is that you're trying to access an element in an array that isn't set. I'm guessing that you're trying to access $pages['page'].
There are two ways to fix this. Add page to the $pages array on the fourth line:
pages = array('home', 'pagetwo', 'contact', 'page');
Or wrap the 43rd line with an if statement:
<?php
$pages = array('home', 'about');
if (isset($pages['page'])) {
echo $pages['page'];
}
?>
However, a far easier method would be to use CSS:
home.php
<html>
<head>
<title>Foo</title>
</head>
<body id="home">
<ul class="menu">
<li id="link-home"><a>Home</a></li>
</ul>
</body>
</html>
style.css
body#home {
// active link styling here
}
Related
My website has a simple navigation using a styled <ul> list, with the current page's link highlighted. Currently, I do this by giving the <a> object a CSS class like this:
<ul class="bd-nav">
<li>Home</li>
<li>Contact</li>
</ul>
with the corresponding CSS:
.bd-nav-active {
background-color: #563a64;
}
This works perfectly. However, I would like to build the website with PHP and have a seperate file for the header/navigation and then just <?php include ?> that file on every other page.
Is there a way to dynamically set the class of the navigation links, depending on which page you're on? What would be the best approach here?
Solved after some fiddling! I simply put the class attribute into a variable like this: (make sure to escape the quotation marks!)
<?php
$nav_active = "class=\"bd-nav-active\""
?>
Then used that variable in my navigation like this:
<ul class="bd-nav">
<li><a href="index.html" <?php if ($pid == 1) echo $nav_active; ?>>Home</a></li>
<li><a href="contact.html" <?php if ($pid == 2) echo $nav_active; ?>>Contact</a></li>
</ul>
And then on the respective pages, I simply set the $pid variable:
<?php $pid = 1; ?>
Works perfectly! Thanks for the helpful answers!
#Arrabidas92 had a nice way to automatically do this by getting the page URL, but I think I'll be doing it like this to have better control over how the navigation looks.
The menu needs to be dynamically generated and each page needs to have a unique id or something at the top of the page.
When you dynamically generate the menu, insert and if clause that will echo the active class if generated menu item is the same with current page.
I have not coded in php for some time now but i use to do something like this, in each page give a unique file name at the top. For example in the home page:
<?php
$file_name = "index.php";
?>
and then in the included file apply a logic like this:
<?php
if($file_name == "index.php"){
//Your navigation for the home page
}
else if($file_name == "about.php"){
//Your navigation for the about page
}
?>
Alright so I will give you some tips. First, to know on wihch page of your website you are you can use in PHP a superglobal called $SERVER with this attribute : $_SERVER['REQUEST_URI'].
By calling this, PHP is going to return the parts of the url after your domain.com. For example, if the current url was domain.com/home, echo will return only '/home'.
Then, you can place your logic about highlighting your links :
if($_SERVER['REQUEST_URI' == '/home') {
//Add active class to the link HOME
}...
You can try this one, but this is a Jquery, just put the CDN in your file.
$(document).ready(function(){
if(window.location.href === "index.php") {
$(".bd-nav").addClass("active-bgRed");
}
else if(window.location.href === "about.php") {
$(".bd-nav").addClass("active-bgBlue");
}
else if(window.location.href === "contact.php") {
$(".bd-nav").addClass("active-bgGreen");
}
});
// CSS
.active-bgRed{
background-color: red;
}
.active-bgBlue{
background-color: blue;
}
.active-bgGreen{
background-color: green;
}
// JQuery CDN
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
I have a html project, with various template files. I want to display breadcrumbs, in all pages except on index.php and contact.php.
I have the breadcrumbs working; what I can't get it to work is the condition for only displaying it if the pages are not index.php or contact.php:
So far, I know I could do this if it was in the other way around, only display it on those pages:
$noBreadcrumbs = array("index.php", "contact.php");
foreach ($noBreadcrumbs as $page => $pageName) {
if (stripos(filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING), $pageName)){
echo '<div class="breadcrumbs container">';
require ("breadcrumbs.php");
echo '</div>';
}
}
But because it has to be in the other way around.... I don't know how to do it! If I echo de request uri it appears also with the project name (thousand_motors/index.php), and.... I am stuck. I can't print only "index.php" and even if so, I don't know how can I do the foreach but when they are not those pages...
Any suggestions?
Thank you
have you tried
if (!stripos( //....
I have 3 links that all point to the same page but to different sections.
This is what the page sections look like, they are all similar- just read from different tables.
<h1>Networking</h1>
<?php
include 'inc/connect.php';
$data = mysqli_query($link, "SELECT * FROM networking WHERE id = 1")or
die(mysqli_error($link));
while($info = mysqli_fetch_array( $data )) {
echo nl2br($info['info']);}
?>
</article>
This is the part of the menu file that has a link to 'Networking'.
if ($page == 'system') {
$output .="<li><a href='system.php#networking' class='active'>Networking</a></li>";}
else{
$output .="<li><a href='system.php#networking'>Networking</a> </li>";}
All the page section are in a page called system.php.
In the head of system.php I have this line
<?php $page = 'system'; ?>
This so I can apply the css class 'active' to the active link.
The way it is now, when I click on any 1 of my same page different section link the the class 'active' is applied to all 3 menu items.
Is there a way that I can apply the class to only the clicked link?
I understand your problem, you could do something like this:
system.php?section=networking#networking
And do this at the top:
<?php $page = 'system'; $section=$_GET['section']; ?>
And then change your if statement to:
if ($page == 'system' AND $section == 'networking') {
Note: this is not the best solution, but uses your style, I hope this will help you!
you can try something like
<?php $page = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_FRAGMENT ); ?>
But there is an additionnal issue you will need to have in mind. When you are already on the page and using a link to get on another section, the page won't reload.
If you want to update the active class in that case, you need something in javascript to do that.
Maybe that question can help you jQueryMobile add click event to a button instead of changing page
I currently have a header.php page which stores all the styles and positions of my header and layout. I then have a contactus.php page which includes the header.php page.
-----CONTACTUS.PHP:
<?php
include 'header.php'
$classnamehere='"linkStyleTwo"' //Here is where I want to update the value
?>
The main links at the top of my page are styled in a certain way using:
------HEADER.PHP:
<?php
$classnamehere= '"linkStyleOne"' ?>
<a href="http://www.google.com" class= <?php echo $classnamehere ; ?>......
I want to alter the style of the link that the person has clicked, so that it pops out indicating to the person which page they are on. Currently, when I try altering the value of $classnamehere inside of contactus.php (by simply assigning it a new value) to change the class printed inside the <a href> tag, nothing happens. It executes the include command, and outputs the value that was stated inside header.php, ignoring my attempts to change the value on the new page.
Is there any way to change the value within contactus.php only, while still keeping the initial value inside header.php so that all the other pages can still use the 'default' style?
Edit: Inside contactus.php, can I change the value of a variable obtained (included) from header.php without actually 'changing' the global variable?
Looking at your code:
-----CONTACTUS.PHP:
<?php
include 'header.php'
$classnamehere='"linkStyleTwo"' //Here is where I want to update the value
?>
The main links at the top of my page are styled in a certain way using:
------HEADER.PHP:
<?php
$classnamehere= '"linkStyleOne"' ?>
<a href="http://www.google.com" class= <?php echo $classnamehere ; ?>......
your code does the following:
contactus.php is executed.
header.php is included, setting the $classnamehere to
'"linkStyleOne"' and creating the actual link with classname
linkStyleOne.
After that $classnamehere is set to linkStyleTwo
This means that you have to assign classname BEFORE including the header.php.
Instead of including it in contactus.php you could do the logic within header.php:
<?php
if ($currentPage) == 'contact') {
//Set this class when user is on a specific page
$classnamehere='"linkStyleTwo"';
}
else {
$classnamehere= '"linkStyleOne"';
}
?>
and just do this in contactus.php
<?php
$currentPage = 'contact';
include 'header.php'
?>
change this
class= <?php echo '"$classnamehere"' ; ?>.
to
class= "<?php echo $classnamehere ; ?>"
Or use it this way
<?php echo '"', $classnamehere ,'"' ; ?>
Or this way(im not sure this works)
<?php echo '"{$classnamehere}"' ; ?>
If you include code, all variables within included code are global and therefore all chnages are reflected in all parts.
in header.php
$a = 10;
in contactus.php
include "header.php"
$a = 0;
And there is no way of changing $a only inside contactus. All code after $a change will be using the new value.
You can create temporary variable $a_copy inside contactus and then change this variable:
$a_copy = $a;
....class= <?php echo '"$a_copy"'...
You should create a PHP class and include it in your header, or make it your header. Invoke it on the page then assign the value for the class variable which you can then echo a separate class function which uses the variable values you require. I can provide an example if you're unfamiliar with the process.
Header.php simple example:
<?php
class Template
{
private $active_nav;
private __construct()
{
}
public function set_active($page = '') // set page test value
{
$this->active_nav = $page;
}
public function get_active() // return page test value
{
return $this->active_nav;
}
public function nav_links() // this could be changed to return an entire header or part or whatever -- change the scope accordingly
{
// active link CSS is linSktyleOne
$current_page = $this->get_active();
$nav_links = '<ul>';
$nav_links .= '<li>Index</li>';
$nav_links .= '<li>Contact</li>';
$nav_links .= '</ul>';
return $nav_links;
}
}
contact.php simple example:
<?php
require_once('includes/header.php');
$template = new Template;
$template->set_active('contact');
// put all your html or other code here
echo $template->nav_links();
?> <!-- blah blah code finished --> <?
// you can always echo a footer out here through a function in the template as well
index.php simple example:
<?php
require_once('includes/header.php');
$template = new Template;
$template->set_active('index');
// put all your html or other code here
echo $template->nav_links();
?> <!-- blah blah code finished --> <?
// you can always echo a footer out here through a function in the template as well
Does all that help make more sense? You only add 1 line of code to each page, and if you really wanted to get fancy you could remove the set function invocation on each page by using a substring of the$_SERVER['REQUEST_URI'] value for a conditional test and put the condition to set the value in the constructor of the class.
I've followed the documentation here (at the bottom) to create next and back buttons at the bottom of my page.
It seems to work fine until I get to the last page where the link just redirects me back to the first page. Is there a way to say if there isn't a next page to not show the link? I assumed thats what the if statement was supposed to do!!
<?php
$pagelist = get_pages('sort_column=menu_order&sort_order=asc');
$pages = array();
foreach ($pagelist as $page) {
$pages[] += $page->ID;
}
$current = array_search(get_the_ID(), $pages);
$prevID = $pages[$current-1];
$nextID = $pages[$current+1];
?>
<?php if (!empty($prevID)) { ?>
<a class="back" href="<?php echo get_permalink($prevID); ?>">BACK</a>
<?php } ?>
<?php if (!empty($nextID)) { ?>
<a class="next" href="<?php echo get_permalink($nextID); ?>">NEXT</a>
<?php } ?>
p.s Please don't move my question to the Wordpress Stack - that seems to be dying a bit of a death and doesn't get many responses!
My Pages are setup like this:
Parent page
Sub page 1
Sub page 2
Sub page 3
I've created a link on the parent page to goto the first subpage. Then on the subpage template I've got the code above. I just want the next link to appear on each page then when it gets to page 3 it shouldn't show the next link.
If you are saying that this is effectively looping around then $nextID must never be empty, which would be why the link was always displayed.
You could set a $firstID, ie
$firstID = pages[0];
and then check;
if ($firstID != $nextID ) {
// Display link
}