I have a problem in my web app.
I'd like to make a menu, when menu clicked it'll be active in css.
Code below is my index.php
<?php
include 'menu.php';
$page = $_GET['page'];
switch ($page) {
case 'endCart':
include 'endCart.php';
break;
case 'trxLog':
include 'invoice.php';
break;
case 'graph':
include 'graph.php';
break;
case 'activeBasket':
include 'activeBasket.php';
break;
case 'logout':
include 'logout.php';
break;
default:
include 'endCart.php';
break;
}
?>
And code below is menu.php
<div class="column" id="sidebar">
<div class="ui secondary vertical fluid menu">
<?php
foreach($sidemenu as $arr){
echo '<a class="item" href="'.$arr[1].'">'.$arr[0].'</a>';
}
?>
</div>
</div>
I get variable $sidemenu from array with value below :
$sidemenu = array(
array('End Cart','index.php?page=endCart', 'endCart'),
array('Transaction Log','index.php?page=trxLog', 'trxLog'),
array('Graph','index.php?page=graph', 'graph'),
array('Active Basket','index.php?page=activeBasket', 'activeBasket')
);
As writen in file menu.php, there is tag <a> with item in its CSS class.
So my problem is when user clicked specific menu in that tag will append CSS class active.
Update!!
This problem has been solved, and here it is my update for menu.php. Big thanks for #Magnus and #Steve to help me solve this.
foreach($sidemenu as $arr){
echo ($page == $arr[2]) ? "<a class=\"item active\" href=\"".$arr[1]."\">".$arr[0]."</a>" : "<a class=\"item\" href=\"".$arr[1]."\">".$arr[0]."</a>";
}
First, change the order of the page and menu include. That way, $page will be available in your menu.php-file:
// I also added a check to see if that query string exists
$page = isset($_GET['page']) ? $_GET['page'] : '';
include 'menu.php';
In your menu.php, just check if the loop is printing the current url:
foreach($sidemenu as $arr){
echo '<a class="item ' . $arr[2] == $page ? "active" : null . '" href="'.$arr[1].'">'.$arr[0].'</a>';
}
This will give the current page link the class active.
Edit
I totally missed that $arr[2] already contains the page key. You don't need to build the url to compare it, as I did in my first example. Thanks #steve for pointing that out.
Related
I'm a front-end developer who is somewhat familiar with but rarely uses PHP. I'm working on a personal project where I'm mostly just using includes to link PHP files together. Here is my overall basic page structure:
<?php include('header.php'); ?>
<?php include('pagetitle.php'); ?>
Page content goes here.
<?php include('footer.php'); ?>
On pagetitle.php, I have an <h1>,<h2> and background image relating to which page you're on.
My question is, how do I use conditional statements to put all the page titles/subheadings on pagetitle.php and have them switch depending on what page you're on? So for example, I want
<div id="about">
<h1>About</h1>
<h2>About page subheading</h2>
</div>
to show up on about.php, and
<div id="contact">
<h1>Contact Me</h1>
<h2>Contact page subheading</h2>
</div>
to show up on contact.php, etc. etc. ...but only using pagetitle.php on those pages.
The site isn't huge. It would have no more than 10 pages. Also, I do realize I can just use that page title segment on the respective page, but if possible, I want to try this out.
Thanks!
I would do something like this (not tested, but should work with few, if any, changes.)
(Everyone says that, right? :D):
<?php
/*
create a map that contains the information for each page.
the name of each page maps to an array containing the
(div id, heading 1, & subheading for that page).
*/
$pageinfo = array(
"about.php" => array ("about", "About", "About Page Subheading"),
"contact.php" => array ("contact", "Contact Me", "Contact Page Subheading"),
);
function printinfo($pagename) {
/*
This function will print the info for the current page.
*/
global $pageinfo;
$pagename = basename($pagename);
#make sure we have info for this page
if (!array_key_exists($pagename, $pageinfo) {
echo "<p><b>You did not supply info for page $pagename</b></p>";
return;
}
#we do have info ... continue
$info = $pageinfo[$pagename];
#let's print the div (with its custom id),
echo "<div id='" . $info[0] . "'>\n";
#print the headings
echo "<h1>" . $info[1] . "</h1>\n";
echo "<h2>" . $info[2] . "</h2>\n";
#close the div
echo "</div>\n";
}
?>
Then in each page where you wanted your div, you would place this code:
printinfo($_SERVER['PHP_SELF']);
Other:
This way is more flexible than the other ways, at the sacrifice of no conditional statements. (You specifically requested a solution that had conditional statements; however, in the interest of flexibility & maintainability, this example does not use switch statements or if statements.)
Because there are no conditional statements, there is less code to maintain. Granted, you have to setup the array with the information, but if you decided to change the <h2> to an <h3>, you would have to make the change at only one location, etc.
On your pagetitle.php you could do something like this
<?php
$scriptname = basename($_SERVER["PHP_SELF"]);
if ($scriptname == "about.php") {
echo "<h1>About Page</h1>";
}else if($scriptname == "contact.php"){
echo "<h1>Contact Us</h1>";
}
?>
You have to get the string after the domain name so you can use $_SERVER['REQUEST_URI']
$page = $_SERVER['REQUEST_URI'];
if ($page == "about.php") {
echo "<h1>About</h1>"."<br />";
echo "<h2>About page subheading</h2>"."<br />";
}else if($page == "contact.php"){
echo "<h1>Contact Me</h1>"."<br />";
echo "<h2>Contact page subheading</h2>"."<br />";
}
$page = $_SERVER['REQUEST_URI'];
switch($page){
case 'about.php':
echo "<h1>About</h1>";
echo "<h2>About page subheading</h2>";
break;
case 'contact.php':
echo "<h1>Contact Me</h1>";
echo "<h2>Contact page subheading</h2>";
break;
default:
echo "Invalid Request";
}
I have a question about how I can dynamically change the content to display in the webpages.
I have few portions of the website fixed - header, nav, footer, and splash and a side bar.
I only want the middle portion of my website to change based on the menu link what user clicks on.
Below is my code for index.php
<?php
include "/templates/header.php";
include "templates/menu.php";
include "/templates/splash.php";
$action = "index";
$disallowed_paths = array('header','menu','splash','bottom_page', 'footer');
if (!empty($_GET['action']))
{
$tmp_action = basename($_GET['action']);
if (!in_array($tmp_action, $disallowed_paths) && file_exists("/content/$tmp_action.php"))
$action = $tmp_action;
}
include "/content/$action.php";
include "/templates/bottom_page.php";
include "/templates/footer.php";
?>
My menu.php contains links for Home, About, products, services and login links
I just want to change the main_index.php to include the above based on what user clicks on.
please advise if this approach is good.
or should I create similar file as index.php multiple times with includes to each file as per the link clicked on menu
Your Answer is
GET method
You can use get method for that
<ul>
<li>example 1</li>
<li>example 2</li>
<li>example 3</li>
<li>example 4</li>
</ul>
After User Clicks on the link
<?php
if(isset($_GET['page']) && $_GET['page']!=""){
$page = "";
switch ($_GET['page']) {
case 'example_1':
$page = "Page_1.php";
break;
case 'example_2':
$page = "Page_2.php";
break;
case 'example_3':
$page = "Page_3.php";
break;
case 'example_4':
$page = "Page_4.php";
break;
default:
$page = "any_default_page.php";
break;
}
include($page);
}
?>
And there are other ways also. but this is the most easy and efficient
I think better approach would be whitelisting instead of blacklisting.
$existing_pages = array('home', 'contact', 'terms-of-service');
if(isset($_GET['action'] && in_array($_GET['action'], $existing_pages)
{
// load action here
} else {
//show 404 error
}
Note that your overall approach is not ideal, you could look like into modern frameworks like Laravel or Symphony which has templating systems which helps alot.
But for learning purposes this is fine:)
In bootstrap 3 we have this <li> class set to active in order to display the current page highlighted on the navbar
<li class="active">
Link
</li>
the problem is when you are including the menu via include includes/header.php; on all your pages. i cant figure out how to put together a switch statement on the $actual_link and bring back some sort of call to insert the class active in the right place. this my so far attempt and im honestly stuck because i feel there is a better way. how can i can i put the li class to active with this switch
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$HTTPHost = $_SERVER[HTTP_HOST];
switch($actual_link)
{
case "http://{$HTTPHost}/index.php" ||
"http://{$_SERVER[HTTP_HOST]}/admin.php?edit_home":
//setToActive
break;
case "http://{$HTTPHost}/warrants.php" ||
"http://{$_SERVER[HTTP_HOST]}/admin.php?edit_warrants":
//setToActive
break;
case "http://{$HTTPHost}/faq.php" ||
"http://{$_SERVER[HTTP_HOST]}/admin.php?edit_faq":
//setToActive
break;
case "http://{$HTTPHost}/aboutus.php" ||
"http://{$_SERVER[HTTP_HOST]}/admin.php?edit_aboutus":
//setToActive
break;
}
?>
In your pages before including header set a variable to indicate the current page. For example in index page:
$active = 'index';
include('includes/header.php');
Now in your header.php while creating links use something like
<?php global $active ?>
<li <?php if( isset($active) && $active == 'index') echo 'class="active"'; ?>>
Index
</li>
you can't specify multiple expression in a case statement like this
case "http://{$HTTPHost}/index.php" ||
"http://{$_SERVER[HTTP_HOST]}/admin.php?edit_home":
the above expression evaluates to true.
use the following synatax
case "http://{$HTTPHost}/index.php":
case "http://{$_SERVER[HTTP_HOST]}/admin.php?edit_home":
//statements
break;
I have the following code to include pages dynamically:
<div id="content">
<div id="aside">
...
</div>
<div id="main">
<?php
$page = (isset($_GET['page'])) ? sanitize($_GET['page']) : 'home';
if (!include 'pages/'.$page.'.php') require 'pages/404.php';
?>
</div>
</div>
As you can see, the #aside has static content.
I want to include a specific content for the #aside depending on the page selected. For example, if the user goes to 'Home' and 'About', I want the 'default' aside. But if the user goes to 'Documents' I want a 'Sections' aside.
I know I can just include each aside from every page, but that's not effective. I also don't want the user to be hable to set the aside as the main content, so they have to be in different folders or something.
I'd like to know an effective and not so complicated way to do this.
Thanks for taking your time to read this.
You want to keep which sidebar goes on which page in a database, and then query that database for the correct sidebar to include.
A table structure may look like this:
Table sidebars: ID | path | name | more info on sidebar...
Table pages: ID | path | name | more info on page...
Table sidebars-to-pages: page_ID | sidebar_ID
This approach even allows you to place multiple sidebars on a specific page.
What if you did this?
<?php
ob_start();
$page = (isset($_GET['page'])) ? sanitize($_GET['page']) : 'home';
if (!include 'pages/'.$page.'.php') require 'pages/404.php';
$contents = ob_get_clean();
?>
<div id="content">
<div id="aside">
<?php include($aside); ?>
</div>
<div id="main">
<?php echo $contents; ?>
</div>
</div>
and $page.php would look like:
<?php $aside = "sidebars/default.php"; ?>
<p>HTML for #main<br />
goes here</p>
There are a few different ways to do this that are all more-or-less equal. I almost always use a config.php file for sites to hold whatever global information I want every page to have. At the top of every page, you just call
<?php
require_once('config.php');
?>
In that config.php file, you could have an array listing your page names and the file you want included for each page, as well as a function that returns the content, like so:
// this lets you call includes relative to the site root
set_include_path($_SERVER['DOCUMENT_ROOT']);
$defaultAsideContent = 'includes/default.php';
$asideContent = array(
'index.php' => 'includes/include-1.php',
'document.php' => 'includes/include-2.php'
);
function getAsideContent() {
global $asideContent;
global $defaultAsideContent;
$content = $defaultAsideContent;
// get the requested page
$pageFull = $_SERVER['REQUEST_URI'];
// strip URL variables
$pageParts = explode('?', $pageFull);
$page = $pageParts[0];
// loop throught the array and see if there is specific aside content for the page
foreach($asideContent as $key=>$value) {
if ($page == $key) {
$content = $asideContent[$key]);
}
}
include($content);
}
Lastly, wherever you want your aside content to show up, just do
<?php getAsideContent(); ?>
When you create a new page, if you want specific aside content, just edit your config file. Just FYI, didn't test this at all, probably has bugs, but you get the jist.
Thank you all for your answers and collaboration. Although none of the answers did exactly what I was looking for, they showed me other ways to approach this issue and guided me to decide what method to use.
I came up with what I think is the simpliest way to do this:
I set my folder structure as: pages/aside and pages/main
I set up an array($asides) with the aside files as the keys and the main content files as the values.
Then I check if the requested file exists in the main folder.
If it doesn't exist, I redirect the user to the 404 page. If it does exist, I loop through $asides to see which aside is asigned to that main content page.
If it doesn't belong to any of the establisged asides, then I include the default aside.
$asides = array(
'aside1' => array('page1', 'page2', 'page3', 'page4'),
'aside2' => array('page5', 'page6')
);
$page = (!empty($_GET['p'])) ? sanitize($_GET['p']) : 'page1';
if (file_exists("pages/main/{$page}.php")) {
foreach ($asides as $key => $value) {
if (in_array($page, $asides[$key])) {
$aside = $key;
break;
}
}
if (!isset($aside)) $aside = 'default';
?>
<div id="aside"><?php require "pages/aside/{$aside}.php"; ?></div>
<div id="main"><?php require "pages/main/{$page}.php"; ?></div>
<?php
} else {
header('Location: ?p=404');
}
The bounty goes to Madara Uchiha because in my opinion, his answer is simple an effective. Thanks again to all of you who helped me with this issue.
Im developing a website and I am trying to a foreach include for my header which includes my navigation menu (the main topic here).
My code inside the header.php file for the navigation menu is here:
<!-- topmenu -->
<div class="menu-header">
<div class="container">
<ul class="top menu">
<?php
$nav = array("Home","About","Portfolio","Products","Services","Contact");
foreach($nav as $item){
if($item == $title){
echo "<li class='current-menu-ancestor parent'><a href='$item.php'>$item</a></li>";
}else{
echo "<li><a href='$item.php'>$item</a></li>"; }
}
?>
</ul>
</div>
</div>
<!--/ topmenu -->
You may notice that in the code is the condition if($item == $title). In my index.php I have included $title="Home"; which I intended to be taken and used in this if statement.
On my index.php page I have included this with the following code:
<?php
include("header.php");
$title = "Home";
?>
Can anyone tell me where I am going wrong?
Not an answer, but comments aren't suitable for formatted code. You might want to de-duplicate some of your HTML:
$class = '';
if($item == $title) {
$class = ' class"current-menu-ancestor parent"';
}
echo "<li{$class}><a href='$item.php'>$item</a></li>";
Duplicating HTML as you did can lead to maintenance problems later on, if you decide to change something in the menu structure and change only one of the copies of the menu html.
header.php can not look into the future. If you want the variable to be set in the include, you need to set it before:
<?php
$title = "Home";
include("header.php");
?>
So you basically just switched the lines.
Additionally I suggest that you enable error reporting to the highest level when you develop, as it will give you warning on common mistakes that can happen while typing code.
You can do this by adding the following two lines to the top of your script:
error_reporting(~0);
ini_set("display_errors", "1″);
or by changing your PHP configuration.
You need to set $title before including header.php!
i.e.
<?php
$title = "Home";
include("header.php");
?>