Parse and re-write HTML with PHP - php

I am using Joomla 1.5 and have copied the mod_mainmenu to create a custom menu module. The menu has submenu items (inner UL tags). Here the menu's HTML:
<ul id="sub-menu">
<li class="parent item10"><span>Arts</span>
<ul>
<li class="item29">
<span>Arts Show</span></li>
<li class="item29">
<span>Another Arts Show</span></li>
</ul>
</li>
<li class="parent item15"><span>News</span>
<ul>
<li class="item18">
<span>News Show</span></li>
</ul>
</li>
</ul>
I need to take the above HTML and rewrite it to look like this before it reaches the page:
<div id="sub-menu">
<h3 class="parent item10"><span>Arts</span></h3>
<div>
<a class="item29" href="link2.php"><span>Arts Show</span></a><br />
<a class="item29" href="link3.php"><span>Another Arts Show</span></a>
</div>
<h3 class="parent item15"><span>News</span></h3>
<div>
<a class="item18" href="link7.php"><span>News Show</span></a>
</div>
</div>
How do you do this in PHP? Thanks.

Since jQuery UI Accordion don't handle nested list, you can use other jquery plugins that does (giyf).
If you want to modify html output from your duplicated mod_mainmenu, then simply locate/modify corresponding code (it should be in a view since joomla use mvc).

PHP has a Document Object Model class which can be used for this purpose.
However it would be a whole lot easier to just change the template that drives the output in Joomla and make the change at its source.

Here's a full script to do the job. It's in pure php.
<?php
$dataStr = '<ul id="sub-menu">
<li class="parent item10"><span>Arts</span>
<ul>
<li class="item29">
<span>Arts Show</span></li>
<li class="item29">
<span>Another Arts Show</span></li>
</ul>
</li>
<li class="parent item15"><span>News</span>
<ul>
<li class="item18">
<span>News Show</span></li>
</ul>
</li>
</ul>';
$tempStr = str_replace('<ul ','<div ',$dataStr);
$dataStr = str_replace('<li class="parent','<h3 class="parent ',$tempStr);
$tempStr = str_replace('<ul>','<div>',$dataStr);
$dataStr = str_replace('</ul>','</div>',$tempStr);
$tempStr = str_replace('</li>','',$dataStr);
$dataStr = str_replace('><a ','><a_keep ',$tempStr);
$tempStr = str_replace('<a ','',$dataStr);
$dataStr = str_replace('<li ','<a ',$tempStr);
$tempStr = str_replace('><a_keep ','><a ',$dataStr);
$dataStr = $tempStr;
$newDataStr = "";
$startIndex = 0;
$endIndex = strpos($dataStr, "\n", $startIndex);
$trimNextLine = false;
while (1==1){
if($endIndex == false){
break;
}
$currentLine = substr($dataStr,$startIndex,$endIndex-$startIndex);
$trimCurrentLine = ltrim($currentLine);
$subStrCurrentLine = substr($trimCurrentLine,0,5);
if($subStrCurrentLine==""){
;//do nothing
}
else if($subStrCurrentLine=="<h3 c"){
$tempString = ' '.ltrim(substr($currentLine,0,strlen($currentLine)));
$newDataStr = $newDataStr . $tempString . "</h3>\n";
}
else if($subStrCurrentLine=="<a cl"){
$tempString = ' '.ltrim(substr($currentLine,0,strlen($currentLine)-1));
$newDataStr = $newDataStr . $tempString;
$trimNextLine = true;
}
else if($subStrCurrentLine=="<div>"){
$tempString = ' '.ltrim(substr($currentLine,0,strlen($currentLine)));
$newDataStr = $newDataStr . $tempString."\n";
$trimNextLine = true;
}
else if($subStrCurrentLine=="</div"){
$tempString = ' '.ltrim(substr($currentLine,0,strlen($currentLine)));
$newDataStr = $newDataStr . $tempString."\n";
$trimNextLine = true;
}
else{
if ($trimNextLine == true){
$trimNextLine = false;
$nextStartIndex = $endIndex+1;
$nextEndIndex = strpos($dataStr, "\n", $nextStartIndex);
$nextLine = substr($dataStr,$nextStartIndex,$nextEndIndex-$nextStartIndex);
$trimNextLine = ltrim($nextLine);
$subStrNextLine = substr($trimNextLine,0,5);
if($subStrNextLine=="<a cl"){
$newDataStr = $newDataStr . ' ' . ltrim($currentLine)."<br />\n";
}
else{
$newDataStr = $newDataStr . ' ' . ltrim($currentLine)."\n";
}
}
else{
$newDataStr = $newDataStr . $currentLine."\n";
}
}
$startIndex = $endIndex+1;
$endIndex = strpos($dataStr, "\n", $startIndex);
}
$tempString = substr($dataStr,$startIndex,strlen($dataStr)-$startIndex);
$newDataStr = $newDataStr . $tempString . "\n";
echo($newDataStr);
?>

Related

Drupal 7 bootstrap dropdown menu

I'm a newbie of Drupal. I'm trying to develop a bootstrap 3 template, but I have a problem with the navbar dropdown menu implementation. I followed these steps:
in my mytheme/templates folder I create a page.tpl.php file with the following code:
if ($page['header'])
...
$main_menu = variable_get('menu_main_links_source', 'main-menu');
$tree = menu_tree($main_menu);
print drupal_render($tree);
...
in mytheme folder I create a template.php file with these functions:
function mytheme_menu_tree($variables) {
return '<ul class="nav navbar-nav">' . $variables['tree'] . '</ul>';
}
function mytheme_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';
$dropdown = '';
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
$dropdown = 'class="dropdown"';
$element['#localized_options']['attributes']['class'][] = 'dropdown-toggle';
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
return '<li ' .$dropdown. ' >' . $output . $sub_menu . "</li>\n";
}
with this code I'm at a good point, but I need to remove classes "nav navbar-nav" from children and add the class "dropdown-menu".
This is the result of my code:
<ul class="nav navbar-nav">
<li>XYZ</li>
<li>ASD</li>
<li class="dropdown">XXX
<ul class="nav navbar-nav">
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
</li>
</ul>
and this is what I would like to obtain:
<ul class="nav navbar-nav">
<li>XYZ</li>
<li>ASD</li>
<li class="dropdown">XXX
<ul class="dropdown-menu"> <!-- HERE IS THE DIFFERENCE -->
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
</li>
</ul>
Maybe I can do something like this:
function mytheme_menu_tree($variables) {
if ( [check if I'm at the first level] ) {
return '<ul class="nav navbar-nav">' . $variables['tree'] . '</ul>';
} else {
return '<ul class="dropdown-menu">' . $variables['tree'] . '</ul>';
}
}
but I don't know how... Any idea?
I too am a bit of a newbie when it comes to Drupal and was also having this problem. I have tweaked your function and it works for me:
function SeatradeKorea_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';
$dropdown = '';
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
$sub_menu = str_replace('nav navbar-nav', 'dropdown-menu', $sub_menu);
$dropdown = 'class="dropdown"';
$element['#localized_options']['attributes']['class'][] = 'dropdown-toggle';
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
return '<li ' .$dropdown. ' >' . $output . $sub_menu . "</li>\n";
}
I have added a str_replace() into your #below element to replace the "nav navbar-nav" with "dropdown-menu"

Change the default HTML output for a menu [duplicate]

I created a custom menu called "sub-top-nav" and now I'd like to override the html output. In particular I would like to add an unique class to each item like.
This is how it looks atm:
<div class="clear-block block block-menu" id="block-menu-menu-sub-top-nav">
<div class="content">
<ul class="menu">
<li class="leaf first"><a title="Test 1" href="/test1">Test 1</a></li>
<li class="leaf"><a title="Test 2" href="/test2">Test 2</a></li>
<li class="leaf active-trail"><a class="active" title="Test 3" href="/test3">Test 3</a></li>
<li class="leaf last"><a title="Test 4" href="/test4">Test 4</a></li>
</ul>
</div>
</div>
And I'd like to change it into:
<div class="clear-block block block-menu" id="block-menu-menu-sub-top-nav">
<div class="content">
<ul class="menu">
<li class="leaf test1 first"><a title="Test 1" href="/test1">Test 1</a></li>
<li class="leaf test2"><a title="Test 2" href="/test2">Test 2</a></li>
<li class="leaf test3 active-trail"><a class="active" title="Test 3" href="/test3">Test 3</a></li>
<li class="leaf test4 last"><a title="Test 4" href="/test4">Test 4</a></li>
</ul>
</div>
</div>
This would give me more styling power.
Any idea how that works?
Thanks in advance!
Drupal 7 uses theme_menu_link instead of theme_menu_item
<?php
function theme_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
?>
I got it to work now. This piece of code might help someone else as well!
It goes into yourtheme/template.php
function phptemplate_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
$class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf'));
if (!empty($extra_class))
$class .= ' '. $extra_class;
if ($in_active_trail)
$class .= ' active-trail';
$class .= ' ' . preg_replace('/[^a-zA-Z0-9]/', '', strtolower(strip_tags($link)));
return '<li class="'. $class .'">'. $link . $menu ."</li>\n";
}
After looking through the API I finally found an easy solution to tag the root menu with the same class (this is useful to style only the top level menus uniquely, while maintaining them dynamically friendly). Simply use the plid instead of mlid. I noticed the plid is always 0 for top level menus.
function theme_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';
$element['#attributes']['class'][] = 'menu-' . $element['#original_link']['plid'];
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
$count = 1;
return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
You can use the theme_menu_item function in your theme's template.php to do pretty much whatever you want to those menu items, including adding classes, ID's, etc.

Group SQL posts with each other in lists using recursive function

Problem:
I am trying to group related posts from SQL with each other using the ul and li-elements. However, I am stuck as I can't get the output correct.
PHP code (1st level):
$query = "SELECT CID, Item AS Name, Parent, Weight FROM betyg_category";
$result = mysql_query($query) or die ('Error (' . mysql_errno() . ') ' . mysql_error());
$ctree .= '<ul>';
while ($row = mysql_fetch_assoc($result))
{
$ctree .= '<li class="category">'.$row['Name'] . '';
$ctree .= getLowerRanks($row['CID'], 1, true);
}
$ctree .= '</li></ul>';
echo $ctree;
Recursive function in PHP:
function getLowerRanks( $id, $level, $option = false )
{
if ( $option )
{
$response = '';
$query = "SELECT CID, Item AS Name, Parent, Weight FROM betyg_category WHERE Status = 1 AND Parent= " . $id . " ORDER BY CID ASC";
$result = mysql_query($query) or die ('Error (' . mysql_errno() . ') ' . mysql_error());
$response .= '<ul>';
while ($row = mysql_fetch_assoc($result))
{
for ($i = 0; $i < ($level-1); $i++) $response .= ' ';
$response .= '<li class="category"> '.$row['Name'] . '</li>';
$response .= getLowerRanks($row['CID'],$level+1, true);
}
$response .= '</ul>';
}
return $response;
}
Desired output:
<ul>
<li class="category">Litteratur
<ul>
<li class="category"> Integration av källorna</li>
<li class="category"> Belysning av egna resultat</li>
<li class="category"> Referenser</li>
</ul>
</li>
<li class="category">Validitet
<ul>
<li class="category"> Huvudsyfte</li>
<li class="category"> Oberoende och beroende variabler</li>
<li class="category"> Analysmetoderna</li>
</ul>
</li>
<li class="category">Reliabilitet
<ul>
<li class="category"> Metodval</li>
<li class="category"> Metodbeskrivning</li>
<li class="category"> Databearbetning</li>
</ul>
</li>
<li class="category">Språk, stil och struktur
<ul>
<li class="category"> Språk och stil</li>
<li class="category"> Struktur</li>
</ul>
</li>
<li class="category">Arbetssätt
<ul>
<li class="category"> Försvar och opposition</li>
<li class="category"> Etiska och samhälleliga aspekter</li>
</ul>
</li>
</ul>
In your PHP code (1st level): you need to close your <li> in the while loop.
$ctree .= '<ul>';
while ($row = mysql_fetch_assoc($result))
{
$ctree .= '<li class="category">'.$row['Name'] . '';
$ctree .= getLowerRanks($row['CID'], 1, true);
$ctree .= '</li>';
}
$ctree .= '</ul>';

How do I add different class for my ordered lists

I want add left, center & right class to my ordered lists while loop.
Code
<?php while ($fetch) { ?>
<li>haha</li>
<?php } ?>
Results should be
<ul>
<li class="left">haha</li>
<li class="center">haha</li>
<li class="right">haha</li>
<li class="left">haha</li>
<li class="center">haha</li>
<li class="right">haha</li>
</ul>
Let me know
<?php $classes = array("left","center","right");
$i = 0;
while ($fetch) {
?>
<li class="<?php echo $classes[$i++ % 3] ?>">haha</li>
<?php } ?>
$cnt=0;
while ($fetch)
{
switch ($cnt%3)
{
case 0 : $class = 'left'; break;
case 1 : $class = 'center'; break;
case 2 : $class = 'right'; break;
}
echo '<li class="', $class, '">haha</li>';
++$cnt;
}
I've just tested the following code and verified that it produces the desired output:
<?php
$items = array('haha', 'haha', 'haha', 'haha', 'haha', 'haha');
$cssClasses = array('left', 'center', 'right');
echo "<ul>\n";
$i=0;
foreach ($items as $item) {
echo "\t<li class=\"" . $cssClasses[$i++ % 3] . '">' . $item . "</li>\n";
}
echo "</ul>\n";
?>
The output is:
<ul>
<li class="left">haha</li>
<li class="center">haha</li>
<li class="right">haha</li>
<li class="left">haha</li>
<li class="center">haha</li>
<li class="right">haha</li>
</ul>

Show and count categories in OpenCart

I have this issue with OpenCart where I want to display my shop categories in a custom way and count the parent categories.
I currently modified the code so far that I get the following output
<ul id="catOpContainer">
<li id="switchCatOp1">Parent Cat 1
<ul id="catOp1">
<li>Child cat 1</li>
Child Cat 2</li>
</ul>
</li>
Parent Cat 2
<ul id="catOp1">
<li>Child cat 1</li>
Child cat 2</li>
</ul>
</li>
Parent Cat 3</li>
</ul>
</ul>
instead of the desired
<ul id="catOpContainer">
<li id="switchCatOp1">Parent Cat 1
<ul id="catOp1">
<li>Child Cat 1</li>
<li>Child Cat 2</li>
</ul>
</li>
<li id="switchCatOp2">Parent Cat 2
<ul id="catOp2">
<li>Child Cat 1</li>
<li>Child Cat 2</li>
<li>Child Cat 3</li>
</ul>
</li>
</ul>
It's obvious that there are some missing elements, but I have no clue about a possible solution. I also don't have a clue how to count the parent categories, so that I can toggle the subcategories.
I currently have the following code snippet:
<?php
class ControllerModuleCategory extends Controller {
protected $category_id = 0;
protected $path = array();
protected function index() {
$this->language->load('module/category');
$this->data['heading_title'] = $this->language->get('heading_title');
$this->load->model('catalog/category');
$this->load->model('tool/seo_url');
if (isset($this->request->get['path'])) {
$this->path = explode('_', $this->request->get['path']);
$this->category_id = end($this->path);
}
$this->data['category'] = $this->getCategories(0);
$this->id = 'category';
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/module/category.tpl')) {
$this->template = $this->config->get('config_template') . '/template/module/category.tpl';
} else {
$this->template = 'default/template/module/category.tpl';
}
$this->render();
}
protected function getCategories($parent_id, $current_path = '') {
$category_id = array_shift($this->path);
$output = '';
$results = $this->model_catalog_category->getCategories($parent_id);
if ($results) {
if ($parent_id == 0) {
$output .= '<li id="switchCatOp1">';
} else {
$output .= '<ul id="catOp1"><li>';
}
}
foreach ($results as $result) {
if (!$current_path) {
$new_path = $result['category_id'];
} else {
$new_path = $current_path . '_' . $result['category_id'];
}
$output .= '';
$children = '';
// if ($category_id == $result['category_id']) {
$children = $this->getCategories($result['category_id'], $new_path);
// }
if ($this->category_id == $result['category_id']) {
$output .= '<a href="' . $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $new_path) . '">' . $result['name'] . '</a>';
} else {
$output .= '<a href="' . $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $new_path) . '">' . $result['name'] . '</a>';
}
$output .= $children;
$output .= '</li>';
}
if ($results) {
$output .= '</ul>';
}
return $output;
}
}
?>
I really hope someone knows a solution.
You do not need to customize controller. It has already Parent and child category listing, Just open the category module, and past below code.
<div class="box-category">
<ul>
<?php foreach ($categories as $category) { ?>
<li>
<?php if ($category['category_id'] == $category_id) { ?>
<?php echo $category['name']; ?>
<?php } else { ?>
<?php echo $category['name']; ?>
<?php } ?>
<?php if ($category['children']) { ?>
<ul>
<?php foreach ($category['children'] as $child) { ?>
<li>
<?php if ($child['category_id'] == $child_id) { ?>
<?php echo $child['name']; ?>
<?php } else { ?>
<?php echo $child['name']; ?>
<?php } ?>
</li>
<?php } ?>
</ul>
<?php } ?>
</li>
<?php } ?>
</ul>
</div>

Categories