Consider this:
$menuItems = array (
"page1" => "1.php",
"page2" => "2.php",
"page3" => "3.php",
"page4" => "4.php",
"page5" => "5.php",
);
and now I create the menu like this:
<ul class="menu">
<?php
foreach($menuItems as $name => $url) {
echo "<li><a href='$url' class='$class'>$name</a></li>";
}
?>
</ul>
Works great. But now I need to add a class .current on the current page.
To get the current page I do this:
<?php
function curPageName() {
return substr($_SERVER["SCRIPT_NAME"],strrpos($_SERVER["SCRIPT_NAME"],"/")+1);
}
$curpage = curPageName();
?>
And it also works great.
SO I guess the question is how do I assign $curpage to the ... current page? :)
Thank you.
Alex
<ul class="menu">
<?php
foreach($menuItems as $name => $url) {
if ($url === $curpage){
$class.=' .current';
}
echo "<li><a href='$url' class='$class'>$name</a></li>";
}
?>
</ul>
Easy, inside your loop, check if $url == $curpage, and append appropriately.
Example:
<?php
$menuItems = array(
"page1" => "1.php",
"page2" => "2.php",
"page3" => "3.php",
"page4" => "4.php",
"page5" => "5.php",
);
$current_item = "2.php"; //Assume we got this from the function
?>
<ul class="menu">
<?php
foreach ($menuItems as $name => $url) {
echo "<li><a href='$url'";
if ($url == $current_item) {
echo " class='current'";
}
echo ">$name</a></li>\n";
}
?>
</ul>
<ul class="menu">
<?php
foreach($menuItems as $name => $url) {
$class = 'default';
if (curPageName() == $name) {
$class.='.current';
}
echo "<li><a href='$url' class='$class'>$name</a></li>";
}
?>
</ul>
So I made it work with your help! Thanks guys.
Special thanks for Adel - although you had a mistake there I fixed it like this:
foreach($menuItems as $name => $url) {
$class = 'default';
if (curPageName() == $url) {
$class.=' \. current';
}
echo "<li><a href='$url' class='$class'>$name</a></li>";
}
Awesome! Thanks again!
<?php
$menuItems = array(
'page1' => '1.php',
'page2' => '2.php',
'page3' => '3.php',
'page4' => '4.php',
'page5' => '5.php',
);
$current_page = curPageName();
?>
<ul class="menu">
<?php
foreach ($menuItems as $name => $url) {
?>
<li><a href="<?php=$url?>"
<?php
if ($url == $current_page) {
?>
class="current"
<?php
}
?>
><?php=$name?></a></li>
<?php
}
?>
</ul>
Why use the curPageName () at each iteration?
You can use a ternary syntax to solve your problem. It consists in this syntax:
(if condition ? true : false)
So we can use this way on your answer comparing the curPageName with the url inside the foreach loop.
$url == curPageName() ? 'current' : 'notCurrent'
Now you just need to use this in your favor.
I like the syntax of printf. So the code is more clean. Try this:
<?php
/**
* curPageName() is defined in question
* my_links() is a shortcut to array defined in question
*/
$template = "<li%s>%s</li>";
$links = my_links();
$current = curPageName();
print '<ul class="menu">';
foreach ($likns as $name => $url) {
$class = $current == $url ? ' class="current"' : '';
printf($template, $class, $url, $name);
}
print '</ul>';
Each %s item in $template will be changed by sequential variable. So, if you need to change the template the code is clean and easyest to give a maintance.
Or, if you want another easiest template way, use the php template syntax. Note the use of : after the foreach statement and the use of endforeach. You can see that I am using the short code of echo <?=$var?> that is more compreensible than <?php echo $var ?>.
<?php
/**
* curPageName() is defined in question
* my_links() is a shortcut to array defined in question
*/
$links = my_links();
$current = curPageName();
?>
<ul class="menu">
<?php foreach ($links as $name => $url): ?>
<li<?=($current == $url ? ' class="current"' : '')?>>
<?=$name?>
</li>
<?php endforeach ?>
</ul>
Related
I have a script that lists all the directories as links.
<?php
$dirs = array_filter(glob('../*'), 'is_dir');
?>
<ul style="float:left;">
<?php
foreach ($dirs as $nav) {
echo "<li><a href='$nav'>".basename($nav)."</a></li>";
}
?>
</ul>
I want to highlight the current directory, or give the current link a class or id. I understand that i need if statement to accomplish this like if(currentLink=thisLink) { // add span class somehow} else {// continue looping} , but I am not completely sure how to do this.
What would be the correct way to implement this ?
Yes you are right you need if condition in your loop.
Save your current link in a variable before loop.
<?php
$dirs = array_filter(glob('../*'), 'is_dir');
?>
<ul style="float:left;">
<?php
$currentlink='abc';
foreach ($dirs as $nav) {
if($nav==$currentlink)
$class='current';
else
$class='';
echo "<li><a class='$class' href='$nav'>".basename($nav)."</a></li>";
}
Without knowing the variables to compair, syntax wise you want to do something like this
<?php
foreach ($dirs as $nav){
$class = '';
if( $currentLink == $thisLink ) {
$class = 'class="highlight"';
}
echo '<li><a href="'.$nav.'" '.$class.' >'.basename($nav).'</a></li>';
}
?>
You can look in $_SERVER to get the current url in the browser and use some of that and the basename to fill those variables in.
http://php.net/manual/en/reserved.variables.server.php
to find out the current directory name you need:
basename(getcwd())
in foreach loop use this:
if(basename($nav) == basename(getcwd()))
{
// add span class
}
First you have to get current link. Store as $current_link
<?php
$dirs = array_filter(glob('../*'), 'is_dir');
$current_dir = 'store current directory here';
?>
<ul style="float:left;">
<?php
foreach ($dirs as $nav) {
if($nav == $current_dir) {
$class_name = 'active';
}
else {
$class = '';
}
echo "<li class='$class'><a href='$nav'>".basename($nav)."</a></li>";
}
?>
</ul>
Hope it will works.
I'm working on a simple CMS for a pet project. I currently have a JSON string that contains a list of page ID's and Parent page ID's for a menu structure.
I want to now convert this string into a nested or hierarchical list (ordered list).
I've tried looking looping through but seem to have ended up with an overly complex range of sub classes. I'm struggling to find a suitable light-weight solution in PHP.
Here's the JSON:
**[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]**
Here's the desired output:
<ol>
<li>3
<ol>
<li>4</li>
<ol>
<li>5</li>
</ol>
</ol>
</li>
<li>6</li>
<li>2</li>
<li>4</li>
</ol>
Is there anything built in to PHP that can simplify this process? Has anyone had any experience of this before?
I'm a newbie to PHP and SE. Looking forward to hearing from you.
Here's my current progress (it's not working too well)
<ol>
<?php
$json = '[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]';
$decoded = json_decode($json);
$pages = $decoded;
foreach($pages as $page){
$subpages = $decoded->children;
echo "<li>".$page->id."</li>";
foreach($subpages as $subpage){
echo "<li>".$subpage->id."</li>";
}
}
?>
</ol>
You can use recursion to get deep inside the data. If the current value is an array then recursion again. Consider this example:
$json_string = '[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]';
$array = json_decode($json_string, true);
function build_list($array) {
$list = '<ol>';
foreach($array as $key => $value) {
foreach($value as $key => $index) {
if(is_array($index)) {
$list .= build_list($index);
} else {
$list .= "<li>$index</li>";
}
}
}
$list .= '</ol>';
return $list;
}
echo build_list($array);
Using a function that can recursively go through your JSON, you can get the functionality you wish. Consider the following code: (this only accounts for an attribute of id as getting listed, as your desired code shows)
$json = '[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},{"id":2},{"id":4}]';
function createOLList($group) {
$output = (is_array($group)) ? "<ol>" : "";
foreach($group as $attr => $item) {
if(is_array($item) || is_object($item)) {
$output .= createOLList($item);
} else {
if($attr == "id") {
$output .= "<li>$item</li>";
}
}
}
$output .= (is_array($group)) ? "</ol>" : "";
return $output;
}
print(createOLList(json_decode($json)));
This will produce the following HTML output.
<ol>
<li>3</li>
<ol>
<li>4</li>
<ol>
<li>5</li>
</ol>
</ol>
<li>6</li>
<li>2</li>
<li>4</li>
</ol>
What you're looking for is called recursion, which can be done by a function calling itself.
If you solved once to list all nodes of the list in one function, you can then apply the same function for all child-lists. As then those child-lists will do the same on their children, too.
call_user_func(function ($array, $id = 'id', $list = 'children') {
$ul = function ($array) use (&$ul, $id, $list) {
echo '<ul>', !array_map(function ($child) use ($ul, $id, $list) {
echo '<li>', $child[$id], isset($child[$list]) && $ul($child[$list])
, '</li>';
}, $array), '</ul>';
};
$ul($array);
}, json_decode('[{"id":3,"children":[{"id":4,"children":[{"id":5}]}]},{"id":6},
{"id":2},{"id":4}]', TRUE));
As this example shows, the $ul function is called recursively over the list and all children. There are other solutions, but most often recursion is a simple method here to get the job done once you've wrapped your head around it.
Demo: https://eval.in/153471 ; Output (beautified):
<ul>
<li>3
<ul>
<li>4
<ul>
<li>5</li>
</ul>
</li>
</ul>
</li>
<li>6</li>
<li>2</li>
<li>4</li>
</ul>
<?php
$json_array = array();
array_push($json_array, array(
'id' => 3,
'children' => array(
'id' => 4,
'children' => array(
'id' => 5,
)
)
));
array_push($json_array, array('id' => 6));
array_push($json_array, array('id' => 2));
array_push($json_array, array('id' => 4));
//your json object
$json_object = json_encode($json_array);
//echo $json_object;
//here is where you decode your json object
$json_object_decoded = json_decode($json_object,true);
//for debug to see how your decoded json object looks as an array
/*
echo "<pre>";
print_r($json_object_decoded);
echo "</pre>";
*/
echo "<ol>";
foreach($json_object_decoded as $node){
if(isset($node['id'])){
echo "<li>" . $node['id'];
if(isset($node['children'])){
echo "<ol>";
echo "<li>" . $node['children']['id'] . "</li>";
if(isset($node['children'])){
echo "<ol>";
echo "<li>" . $node['children']['children']['id'] . "</li>";
echo "</ol>";
}
echo "</ol>";
}
echo "</li>";
}
}
echo "</ol>";
?>
I have found that i have to fix or simplify almost every of the functions above.
So here i came with something simple and working, still recursion.
function build_list($array) {
$list = '<ul>';
foreach($array as $key => $value) {
if (is_array($value)) {
$list .= "<strong>$key</strong>: " . build_list($value);
} else {
$list .= "<li><strong>$key</strong>: $value</li>";
}
}
$list .= '</ul>';
return $list;
}
build_list(json_encode($json_string),true);
I am making a breadcrumb for my codeigniter using bootstrap but would like to know how to get the current url and so it show the page on my breadcrumbs current_url() not sure how to use this
Displayed On Controller Index
$data['breadcrumbs'] = array();
$data['breadcrumbs'][] = array(
'text' => $this->lang->line('language_key'),
'href' => $this->url->link
);
Displayed On View
<div class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<li><?php echo $breadcrumb['text']; ?></li>
<?php } ?>
</div>
Working now
Controller file
$data['breadcrumbs'] = array();
$data['breadcrumbs'][] = array(
'text' => $this->lang->line('heading_title'),
'href' => $this->uri->uri_string()
);
View File
<div class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<li><?php echo $breadcrumb['text']; ?></li>
<?php } ?>
</div>
yep for example what i would do is create a helper "breadcrumb_helper.php" and place it in your helpers folder (application/helpers/breadcrumb_helper.php). Load it with the auto load config file so that it is loaded via the entire site and can be called inside a view file.
<?php
/* This is breadcrumb_helper.php */
function breadcrumbs() {
//get codeigniter instance as object
$ci =& get_instance();
$linkBuild = '';
$breadcrumbs = '';
//http://ellislab.com/codeigniter/user-guide/libraries/uri.html
//the uri class is loaded by the system automatically
$count = 1;
$segs = $ci->uri->segment_array();
//no need to run this on the main page and only show a link to the main page.
if(count($segs) >= 1) :
$breadcrumbs .= '<ol class="breadcrumb">';
$breadcrumbs .= '<li class="home"><i class="fa fa-home"></i></li>';
foreach ($segs as $segment)
{
$linkBuild .= $ci->uri->segment($count) . '/';
if($count <= count($segs)) :
$breadcrumbs .= '<li>' . $segment . '</li>';
else :
$breadcrumbs .= '<li>' . $segment . '</li>';
$count++;
endif;
}
$breadcrumbs .= '</ol>';
endif;
return $breadcrumbs;
}
Then in your view file you would just need to run the function like this:
<?= breadcrumbs(); ?>
And this will give you the current breadcrumb to the page you are on.
I need to render a nested set tree as a li-structure with unlimited depth. While I understand how to do it in plain php (like here: PHP: How to generate a <ul><li> tree in an xml2assoc array result?), I hate echoing html tags and would like to have it done in a template. Is it possible with PHP as a templating language? Where should I define a recursive function?
For me, I depends on how much 'code' is needed in each iteration.
For simple trees, I would just declare a function at the top of the view-file. (Since I think that function has only real value in that separate file).
For trees with a bit more rendering, I would create a separate partial file. That file could be called in the view file and in the partial file itself.
You could also create a helper file, which you use on that specific page, put than the partial would make more sense and is easier to implement (and you can use all other helper functions and symfony functions)
hm, here is my sollution:
<?php
/**
* #var $records
* #var $field
*/
?>
<?php if( isset($records) && is_object($records) && count($records) > 0 ): ?>
<div id="document-nested-set">
<ul class="nested_set_list">
<?php $prevLevel = 0; $is_first = true; ?>
<?php foreach($records as $record): ?>
<?php if($prevLevel > 0 && $record['level'] == $prevLevel) echo '</li>';
if($record['level'] > $prevLevel) echo '<ul>';
elseif ($record['level'] < $prevLevel) echo str_repeat('</ul></li>', $prevLevel - $record['level']); ?>
<?php $rel = $record['lft']=='1'?'root':($record['is_approved'] && $record['is_checked']?'document':'document_grey') ?>
<li id ="phtml_<?php echo $record->id ?>" rel="<?php echo $rel ?>" <?php echo $is_first?'class="open"':'' ?>>
<ins> </ins><?php echo $record->$field;?>
<?php $prevLevel = $record['level']; $is_first = false; ?>
<?php endforeach; ?>
</ul>
</div>
<?php endif;?>
an easy example:
<?php
$input = array('c' => array('c1' => 't1', 'c2' => array('c21' => array('c211' => 't2'), 'c22' => 't3')));
$iterate = function($array) use (&$iterate) {
$out = '<ul>';
foreach($array as $key => $child)
$out .= '<li>'.$key.': '.( is_array($child) ? $iterate($child) : $child ).'</li>';
return $out.'</ul>';
}
?>
<html><body><?php echo $iterate($input); ?></body></html>
I am trying to make a php navbar sort of thing. I have the html code and what I want to do is to use a php dictionary ("Home"=>"http://www.domain.com/") and turn it into html code.
<ul>
<?php foreach ($links as $title => $url): ?>
<li><?php echo htmlentities($title); ?></li>
<?php endforeach; ?>
</ul>
foreach($arr as $key=>$value) {
// your code here
}
I have no idea how you want to make your navbar, but with any knowledge of HTML you should be able to go from here.
foreach (dict as $key => $value){
echo "<a href='$value'>$key</a>";
}
Fastest
<?php
foreach($array as $name => $link){
echo '',$name,'\n';
}
?>
Easier to read and understand but slower
<?php
foreach($array as $name => $link){
echo "<a href='$link'>$name</a>\n";
}
?>
I don't know if i understand the question but you can use an hash like this:
<?php
$navBar = array(
"Home" => "http://www.domain.com/",
"Info" => "http://www.domain.com/info/",
);
foreach($navBar as $key => $val){
echo "<li>$key => $val<li>";
}
?>