I have this approach for now:
ctop = $cnew = $cmine = '';
if($actual == 'top') $ctop = 'class="active"';
if($actual == 'last') $new = 'class="active"';
if($actual == 'mine') $cmine = 'class="active"';
$html = '<aside class="panel_derecho">
<div class="tabs"><h4>$donde</h4>
<ul>';
$js = "refrescar_submenu('last_$donde')";
$js_t = "refrescar_submenu('top_$donde')";
$js_r = "refrescar_submenu('mine_$donde')";
$html .= '<li '.$ctop.'>top</li>';
$html .= '<li '.$cnew.'>ultimos</li>';
$html .= '<li '.$mine.'>like</li>';
$html .= ' </ul>
</aside>';
return $html;
wich works as expected:
It generates a list with the desired copy, the desired javascript function parameter, and the active class (for the wanted one)
But i feel it could be less repetitive; and i can already see that it will be expensive to add/edit/remove copys, params, elements, etc.. i just don't know where to beggin..
In case it helps:
$donde represents the type of data (articles, songs, videos, ..)
$actual represents one atribute (new articles, top articles,
articles i like)
// Menu: link => text
$menu = array(
"top" => "top",
"last" => "ultimos",
"mine" => "like"
);
$html = '<aside class="panel_derecho">
<div class="tabs"><h4>$donde</h4>
<ul>';
foreach ($menu as $link => $text)
{
$html .= '<li '.( $link==$actual ? 'class="active"' : '').'>'.$text.'</li>';
}
$html .= ' </ul>
</aside>';
return $html;
$attributes = array("top" => "top", "last" => "ultimos", "mine" => "like");
$html = "<aside class=\"panel_derecho\">
<div class=\"tabs\"><h4>{$donde}</h4>
<ul>";
foreach ($attributes as $key=>$value)
$html .= " <li ". ($actual == $key ? "class=\"active\"" : "") .">{$value}</li>";
$html .= " </ul>
</div>
</aside>";
return $html;
Related
I have an array in php that looks kind of like this:
array[x][0]=item name
array[x][1]=level
so, for example,
array[0][0]="Node 1"
array[0][1]=0
array[1][0]="Node 2"
array[1][1]=0
array[2][0]="Node 2.1"
array[2][1]=1
array[3][0]="Node 2.1.1"
array[3][1]=2
array[4][0]="Node 2.2"
array[4][1]=1
I need to turn it into an html ul list, but one that looks like this:
<ul>
<li>
<input type="checkbox" /><span>Node 1</span>
</li>
<li>
<input type="checkbox" /><span>Node 2</span>
<ul>
<li>
<input type="checkbox" /><span>Node 2.1</span>
<ul>
<li><input type="checkbox"><span>Node 2.1.1</span></li>
</ul>
</li>
<li>
<input type="checkbox" /><span>Node 2.2</span>
</li>
</ul>
</li>
</ul>
The biggest catch is the position of the </li> tag - it needs to be after the next <ul> tag. So it's <li> current node <ul><li> child node </li></ul></li>. It's that last </li> that gets me.
This format is necessary to work with the jquery plugin I'm using (https://github.com/daredevel/jquery-tree).
I've seen the suggestions here: create html list from array with levels but that doesn't work due to the extra .
I think there's a solution to this using recursion and array slicing, but that seems inefficient. So far, my attempts at an iterative solution have failed...
You can use this function to convert your array to a nested HTML list (echo nestedHtmlList($array);)
function nestedHtmlList($array) {
$depth = 0;
$result = "";
foreach ($array as $node) {
$newDepth = $node[1];
if ($newDepth > $depth) {
$result .= "<ul><li>";
} else if ($newDepth < $depth) {
for ($d = $newDepth; $d < $depth; $d++) {
$result .= "</li></ul>";
}
$result .= "</li><li>";
} else if ($result == "") {
$result .= "<ul><li>";
} else {
$result .= "</li><li>";
}
$result .= "<input type='checkbox' /><span>";
$result .= $node[0];
$result .= "</span>";
$depth = $newDepth;
}
while ($depth > 0) {
$result .= "</li></ul>";
$depth -= 1;
}
return $result;
}
Tell me what you think:
Code
$array = [];
$array[0][0]="Node 1";
$array[0][1]=0;
$array[1][0]="Node 2";
$array[1][1]=0;
$array[2][0]="Node 2.1";
$array[2][1]=1;
$array[3][0]="Node 2.1.1";
$array[3][1]=2;
$array[4][0]="Node 2.2";
$array[4][1]=1;
function makeList( &$array, $level = null ) {
$html = '<ul>';
$html .= '<li>Level: ' . $level;
while( $element = array_shift( $array ) ) {
if( $level == $element[1] ) {
$html .= '</li><li><label><input type="checkbox"/> ' . $element[0] . '</label>';
} else if( $level < $element[1] ) {
array_unshift( $array, $element );
$html .= makeList( $array, $element[1] ) . '</li>';
} else {
array_unshift( $array, $element );
break;
}
}
$html .= '</ul>';
return $html;
}
echo '<pre>';
echo makeList($array);
Output (human rendered html :D)
Level:
[] Node 1
[] Node 2
Level: 1
[] Node 2.1
Level: 2
[] Node 2.1.1
[] Node 2.2
I need to display my category tree as a list in a responsive menu.
The idea is to display the highest level categories. and create dynamically a list that will be displayed for each category that has children.
I stumbled upon a code that helped me a bit, but i can't figure how to get the job done.
Here is the code:
<?php
$rootCatId = Mage::app()->getStore()->getRootCategoryId();
function getTreeCategories($parentId, $isChild){
$allCats = Mage::getModel('catalog/category')->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('is_active','1')
->addAttributeToFilter('include_in_menu','1')
->addAttributeToFilter('parent_id',array('eq' => $parentId));
$class = ($isChild) ? "sub-cat-list" : "cat-list";
$html .= '<ul class="'.$class.'">';
$children = Mage::getModel('catalog/category')->getCategories(7);
foreach ($children as $category) {
{
$html .= '<li>'.$category->getName()."";
$subcats = $category->getChildren();
if($subcats != ''){
$html .= getTreeCategories($category->getId(), true);
}
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}
$catlistHtml = getTreeCategories($rootCatId, false);
echo $catlistHtml;
?>
Thank you in advance.
you can use this to create category tree:
<?php
$rootCatId= Mage::app()->getStore()->getRootCategoryId();
$categories = Mage::getModel('catalog/category')->getCategories($rootCatId);
$output= '<ul>';
foreach($categories as $category) {
$cat = Mage::getModel('catalog/category')->load($category->getId());
$count = $cat->getProductCount();
$output .= '<li>' . '' . $category->getName() . "";
if ($category->hasChildren()) {
$children = Mage::getModel('catalog/category')->getCategories($category->getId());
$array .= get_categories($children);
}
$output .= '</li>';
}
echo $output . '</ul>';
?>
For the effects of showing / hiding categories and subcategories, you can use plain css or jQuery / Prototype.
I have an array with some items. Each array could have (or not) an subarray, also with some items.
How can I call the subarray in a loop? It is difficult to describe, here is the code. I know the code/syntax is not correct, but the syntax should clarify my problem:
<?php
$subitemsA = array(
'subA1' => array('num'=>65, 'text'=>'Labor', 'url'=>'#'),
'subA2' => array('num'=>44, 'text'=>'Rare', 'url'=>'#'),
);
$subitemsB = array(
'subB1' => array('num'=>0, 'text'=>'subB1', 'url'=>'#'),
'subB2' => array('num'=>0, 'text'=>'subB2', 'url'=>'#'),
'subB3' => array('num'=>0, 'text'=>'subB3', 'url'=>'#')
);
$navArray = array(
'Home' => array('num'=>0, 'text'=>'Home', 'url'=>'#'),
'Info' => array('num'=>0, 'text'=>'Info', 'url'=>'#', 'subArray'=>$subitemsA),
'Sport' => array('num'=>0, 'text'=>'Sport', 'url'=>'#', 'subArray'=>$subitemsB),
);
$html = '';
foreach($navArray as $item) {
$html .= "<li>";
$html .= "<a href='{$item['url']}'><i class='abc'></i>{$item['text']}</a>\n";
if (count($navArray) > 3) {
foreach($navArray.subArray as $subitem) {
$html .= "<li>";
$html .= "<a href='{$subitem['url']}'>{$subitem['text']}</a>\n";
$html .= "</li>";
}
}
$html .= "</li>";
}
The first foreach loop works. But how can I access the subArray of Info and Sport?
You need a three level foreach for this to work -
foreach($navArray as $key => $item) {
$html .= "<li>";
$html .= "<a href='{$item['url']}'><i class='abc'></i>{$item['text']}</a>\n";
foreach ($item as $itemkey => $value) {
if (is_array($value)) { //Now Check if $value is an array
foreach($value as $valuekey => $subitem) { //Loop through $value
$html .= "<li>";
$html .= "<a href='{$subitem['url']}'>{$subitem['text']}</a>\n";
$html .= "</li>";
}
}
}
$html .= "</li>";
}
This is an answer to your question in more general way: How to deal with multi-level nested array using recursion and template.
function parseArray(array $navArray, &$html, $depth = 0) {
foreach ($navArray as $item) {
$html .= "<li>";
// this function use template to create html
$html .= toHtml($item['url'], $item['text'], $depth);
foreach ($item as $subItem) {
if (is_array($subItem)) {
// use recursion to parse deeper level of subarray
parseArray($item, $html, $depth + 1);
}
}
$html .= "</li>";
}
}
function toHtml($url, $text, $depth)
{
$template = '';
if ($depth == 0) {
$template = '<a href=\'{{url}}\'><i class=\'abc\'></i>{{text}}</a>\n';
} elseif ($depth >= 1) {
$template = '<a href=\'{{url}}\'>{{text}}</a>\n';
}
// define more template for deeper level here if you want
$template = str_replace('{{url}}', $url, $template);
$template = str_replace('{{text}}', $text, $template);
return $template;
}
$html = '';
parseArray($navArray, $html);
Just hurrily forge this code out of mind, haven't test it yet. Hope it help.
Regards,
i have a very long article created by a user in Wordpress , i want to show a navigation on every article page with links to the titles of the current article.
e.g:
<h1 id='title1'>Title 1</h1>
bla bla bla
<h1 id='title2'>Title 2</h1>
bla bla
my navigation on this page would be Anchor link to title 1
The example above is how you would hardcode it, but my article text is obviously variable and so are my links, what is the best way to tackle this with php?
Edit: the situation is not exactly like the example, the user puts text into a wordpress text editor field and doesnt want to write html tags, so the navigation needs to be filled with the titles that the user has put in the text field and those link to the variable titles on the page. (with an anchor i assume)
the functionality would be something like Microsoft word:
You can filter the content in order to target the different titles, add an ID in a form of a slug using sanitize_title on each of them and build a hierarchical array of those titles in order to display the anchor menu on top of the post.
I just wrote this filter for the example, but it is totally not tested so you may have to debug it a bit and change it depending of your needs. Please note that it works for a 3 level hierarchy maximum.
function add_anchor_menu($content) {
// First you may want to do some check here to see if this filter should be trigger on the current post...
$arrayTitles = array();
// Generate the ids...
$content = preg_replace_callback(
'#<h([1-3])>(.*?)<\/h[1-3]>#',
function($matches) {
$id = sanitize_title($matches[2]);
$meta = array('id' => $id, 'title' => $matches[2], 'childs' => array());
if((int)$matches[1] == 1) {
array_push($arrayTitles, $meta);
} elseif((int)$matches[1] == 2) {
end($arrayTitles);
array_push($arrayTitles[key($arrayTitles)]['childs'], $meta);
} else {
end($arrayTitles);
end($arrayTitles[key($arrayTitles)]['childs']);
array_push($arrayTitles[key($arrayTitles)]['childs'][key($arrayTitles[key($arrayTitles)])], $meta);
}
return '<h' . $matches[1] . ' id="' . $id . '">' . $matches[2] . '</h' . $matches[1] . '>';
},
$content
);
// And generate the menu...
if(count($arrayTitles) > 0) {
$menu = '<ul id="anchor-menu">';
foreach($arrayTitles as $level1) {
$menu .= '<li>';
$menu .= '' . $level1['title'] . '';
if(count($level1['childs']) > 0) {
$menu .= '<ul>';
foreach($level1['childs'] as $level2) {
$menu .= '<li>';
$menu .= '' . $level2['title'] . '';
if(count($level2['childs']) > 0) {
$menu .= '<ul>';
foreach($level2['childs'] as $level3) {
$menu .= '<li>' . $level3['title'] . '</li>';
}
$menu .= '</ul>';
}
$menu .= '</li>';
}
$menu .= '</ul>';
}
$menu .= '</li>';
}
$menu .= '<ul>';
$content = $menu . $content;
}
return $content;
}
add_filter('the_content', 'add_anchor_menu');
In your mark up
<h1 id="<?php echo get_the_title(); ?>">Title 1</h1>
Anchor link to title 1
You should esc_url() in the href attribute as well.
trying to get some thing like that dynamically
<ul>
<li>Home</li>
<li>About Us</li>
<li>Academics
<ul style="overflow: hidden; display: block; height: 0px; z-index: 51; opacity: 0.00980392;">
<li>Bs Computer Science</li>
<li>Diplomas (DIT & DCHE)</li>
<li>MBAIT</li>
</ul>
</li>
<li><a class=" " href="#">College</a>
</ul>
the code is
<?php
//========================================================
$result = mysql_query(" SELECT id, parentId, name
FROM
menu
ORDER BY
parentId, name");
$menuData = array(
'items' => array(),
'parents' => array()
);
while ($menuItem = mysql_fetch_assoc($result))
{
$menuData['items'][$menuItem['id']] = $menuItem;
$menuData['parents'][$menuItem['parentId']][] = $menuItem['id'];
}
function buildMenu($parentId, $menuData)
{
$html = '';
if (isset($menuData['parents'][$parentId]))
{
$html = '<ul id="main_menu">';
foreach ($menuData['parents'][$parentId] as $itemId)
{
$html .= '<li>' . $menuData['items'][$itemId]['name'];
// find childitems recursively
$html .= buildMenu($itemId, $menuData);
$html .= '</li>';
}
$html .= '</ul>';
}
return $html;
}
// output the menu
echo buildMenu(0, $menuData);
//=======================================================
?>
above code is showing only first parents elements in the menu and the remaing elements are not showing.. the menu is not working correctly becoz of the class id is not given in the ul tag.. and by writing this
echo '<ul id="main_menu">';
// output the menu
echo buildMenu(0, $menuData);
echo "</ul>";
it shows nothing in the menu
Ok, try this:
<?php
//========================================================
$result = mysql_query(" SELECT id, parentId, name, link
FROM
menu
ORDER BY
parentId, name");
$menuData = array(
'items' => array(),
'parents' => array()
);
while ($menuItem = mysql_fetch_assoc($result)) {
$menuData['items'][$menuItem['id']] = $menuItem;
$menuData['parents'][$menuItem['parentId']][] = $menuItem['id'];
}
function buildMenu($parentId, $menuData)
{
$html = '';
if (isset($menuData['parents'][$parentId]) && count( $menuData['parents'][$parentId] ) > 0 ) {
if( $parentId == "0" ){
$html = '<ul id="main_menu">';
}else{
$html = '<ul id="sub_menu">';
}
foreach ($menuData['parents'][$parentId] as $itemId) {
$html .= '<li>';
$html .= strlen($menuData['items'][$itemId]['link']) > 2?
''.$menuData['items'][$itemId]['name'].'':
$menuData['items'][$itemId]['name'];
$html .= buildMenu($itemId, $menuData);
$html .= "</li>";
}
$html .= '</ul>';
} else {
$html .= '<li>' . $menuData['items'][$parentId]['name'].'</li>';
}
return $html;
}
// output the menu
echo buildMenu(0, $menuData);
//=======================================================
?>