PHP Code efficiency in menu - php

I currently have some VERY long winded code for the menu I use on my site.
My website
It's almost 2000 lines long lol. I think I may be able to use a switch but I've tried and cannot implement it to work properly.
On each menu when you click a button it stays highlighted, telling the user that they are on that page. The only way I could get this to work was like so...
if($subject == 'art') {
echo '<div id="spacer2"><br></div>';
echo '<div class="idName2" id="menu2">';
echo 'All';
echo '<div id="spacer2"><br></div>';
echo '</div>';
echo '<div class="idName3" id="menu3">';
echo 'Art';
echo '</div>';
echo '<div class="idName2" id="menu2">';
echo 'Biology';
echo 'English';
echo 'Chemistry';
echo 'Mathematics';
echo 'History';
echo 'Religion';
echo 'Geography';
echo 'Music';
echo 'Philosophy';
echo 'Psychology';
echo 'Economics';
echo 'Sociology';
echo 'Technology';
echo 'Electronics';
echo 'Food';
echo 'Law';
echo 'Politics';
echo '</div>';
}
elseif($subject == 'biology') {
and then there's however many 'elseifs' as there are menu items, which ends up totalling to 2000 lines of code which is obviously very inefficient and it also makes it unbelievably time consuming to change anything... can someone point me in the right direction in what I need to do please!

Navigation is always a pain. Here is a simple solution that might help.
Put everything in an array, like this:
$menu = array(
'All' => '/browse ...',
'Art' => '/browse ... art',
'Biology' => '/browse ... biology',
// etc.
)
Then, you can build all the links based on the current subject:
$subject = 'Art';
foreach ($menu as $title => $url) {
if ($title == $subject) {
echo "<b>$title</b><br>\n";
} else {
echo "$title<br>\n";
}
}
This is a rather simplistic solution, but it can be extended to create a more complicated menus structure.
Another solution you could look at is Zend_Navigation.
http://framework.zend.com/manual/en/zend.navigation.introduction.html

What about something like:
$subjects = array('art', 'biology', 'english', 'chemistry' /*, etc */);
foreach ($subjects as $current_subject)
{
if ($current_subject == $subject)
{
//write it the id="menu3" way
}
else
{
//write it another way
}
}
You can transform 'biology' to 'Biology' using the ucfirst function.
Also note that there can't be two or more elements with the same ID (menu2 in your case).

You should use an array to represent your menus. Even better, you could place it in a resource file (xml would be preferable), but explaining that exceeds the scope of this answer (nonetheless, you should look into it). Using an external resource for the menu has the added benefit that you can change your menu structure without modifying any code.
Sticking to the simple approach, this is how you should represent your menu without an external resource:
$menus = array('Art', 'Biology', 'English', ...);
You can generate the "A"-"Z" submenus with a simple range command: range('A', 'Z')
So your code echoing the menus would be something like:
<?php
$current_letter = $_REQUEST['letter'];
$current_menu = $_REQUEST['menu'];
$letters = range('A', 'Z');
foreach($letters as $letter) :
$class = $current_letter == $letter ? 'class="active"' : '';
?>
<a <?php echo $class; ?> href="browse.php?letter=<?php echo $letter; ?>&menu=<?php echo $current_menu; ?>&listtype=<?php echo $listtype"><?php echo $letter; ?></a>
<?php endforeach; ?>
This displays the top menubar (A-Z links). For the side menu, here is how to display your categories:
<?php
foreach($menus as $menu) :
$class = $current_menu == $menu ? 'class="active"' : '';
?>
<a <?php echo $class; ?> href="browse.php?letter=<?php echo $current_letter; ?>&menu=<?php echo $menu; ?>&listtype=<?php echo $listtype"><?php echo $menu; ?></a>
<?php endforeach; ?>
Haven'tested it, but apart from possible typos this approach should work for you.
Btw, please don't throw things at me for not validating input and using $_REQUEST directly. It should be done, but that is a whole other topic.

Related

'echo' a tag without a hyphen and Proper Case using str_replace?

I have a bit of a tricky situation here....
I am pulling bookmarks from a service called Pinboard using their API's which works great - but - the category of the 'tag' (i.e. bookmark tag) is echoed out in full with hyphens.
The difficulty I am having is that I'd like the $tag in one instance to retain the hyphens (to allow for an anchor link using markup to work) - whilst - changing the same $tag that is echoed in the < h1 >
So for example one of the $tag is 'Latest-News' - and I'd like that $tag to be printed like this:
for the anchor tag: $tag will echo 'latest-news'
for the < h1 > tag: $tag will echo 'Latest News'
Any ideas how this is done?
Something like this might be on the right track (I hope! - I'm still clearly a n00b):
$str = str_replace("-", " ", $tag);
echo $tag;
+++++
include 'pinboard-api.php';
$pinboard = new PinboardAPI('myusername', 'xxxxxxx');
$bookmarks_all = $pinboard->get_all();
$bookmarks_grouped_by_tags = array();
foreach ($bookmarks_all as $bookmark) {
if (! empty($bookmark->tags) && is_array($bookmark->tags)) {
foreach ($bookmark->tags as $tag) {
$bookmarks_grouped_by_tags[$tag][] = $bookmark;
}
} else {
$bookmarks_grouped_by_tags['no_tag'][] = $bookmark;
}
}
?>
<?php foreach ($bookmarks_grouped_by_tags as $tag => $bookmarks) { ?>
<a name="<?php echo $tag ?>">
***** <h1><?php echo $tag ?></a></h1> *******
<? foreach ($bookmarks as $bookmark) { ?>
<div>
<?php echo $bookmark->title ?>
</div>
<div><?php echo $bookmark->description ?></div>
<?php } ?>
<?php } ?>
++++

Grab first item of array through custom content types manager

I'm using Wordpress and Custom Content Types Manager, how do I go about editing the code below to only grab the first image from the array below?
<?php
$array_of_images = get_custom_field('slide_images:to_array');
foreach ($array_of_images as $img_id) {
?>
<div><?php print CCTM::filter($img_id, 'to_image_tag'); ?> </div>
<?php } ?>
I tried adding in array_slice($array_of_images, 0, 1); but no luck so far. Thanks!
If all else fails you could do the same as what you have except add an $i value. It's kind of dumb but it would work if you can't get a normal method to work. This would be a last ditch effort sort of thing...
<?php
$array_of_images = get_custom_field('slide_images:to_array');
$i = 0;
foreach ($array_of_images as $img_id) { ?>
<div><?php print CCTM::filter($img_id, 'to_image_tag'); ?> </div>
<?php if($i == 0) break; } ?>
$key = array_keys($array_of_images);
$value = $array_of_images[$key[0]];

whats the best way to echo a php tag inclusive in a while loop?

Edit |
This is a simple url...
The issue is I have to echo it in a while loop.
Which means I cant use php tags.
MY cancatenation sucks... I tried it for hours (noob) Please help
The issue is I have to echo it in a while loop. Which means I cant use php tags.
It doesn't mean that.
<?php
while ($condition) {
?>
Edit |
<?php
}
?>
(But if you have a list of links, then use list markup (ul/ol/li) not | characters).
try something like this
echo 'Edit'
It's pretty simple:
<?php
While(condition){
?>
Edit
<?php
}
?>
I would suggest to "prepare" the whole element in php. Something like this:
foreach ($arr as $key) {
print 'Edit';
}
<?php
while ($condition) {
echo 'Edit';
}
?>
You can also use heredoc syntax.
Sidenote, I would collect them all and echo it out once in the end
$text = '';
while ($foo) {
$text .= 'Edit';
}
echo $text;
// or heredoc
$text = '';
while ($foo) {
$text .= <<<_HTML
Edit
_HTML;
}
echo $text;
// or array
while ($foo) {
$data[] = 'Edit';
}
if(!empty($data)){
echo '<p>'.implode('</p><p>',$data).'</p>';
}
if it is a template file in php then always use this type of syntax
code:
<?php
$i=0;
while($i<10) : ?>
<div><?php echo $i;?></div>
<?php
$i++;
endwhile;?>

Php syntax for echoing multiple classes with a space between them

I'm am working on a Wordpress custom template and I'm filtering post by their classes.
Since Wordpress displays a LOT of unnecessary classes when I put <?php post_class(); ?> in a page, ( here is what it gives me class="post-54 post type-post status-publish format-standard hentry category-3d category-web" )
I'm trying to simplify that by echoing only the categories that relate to the post.
EDIT: This is what calls the post in my page <?php query_posts( 'showposts=99' ); ?>
Then this piece of code
<li class="<?php if ( in_category('category-3d')) { echo "3d"; }
if ( in_category('category-animation')) { echo "animation"; }
if ( in_category('category-motion')) { echo "motion"; }
if ( in_category('category-shortfilm')) { echo "shortfilm"; }?>"></li>
give me this <li class="motion"></li> if my post is in the "motion" category.
The problem is that if my post is in several categories, only the first is echoed... How can I tell WP to echo ALL the names of the categories my post is affected to, while adding a space between them?
Since I am a beginner in php syntax, I'm still learning how to get such a simple thing working in a clean and effective way (i.e. without writing 16 lines of code !)...
Can someone help me on this one?
SECOND EDIT:
Ok I'm still trying to figure out why, but today, my piece of code (above) is working and echoes all my listed classes, but without space between them... So to make my classes work, I'm adding a space at the end of the echo part like this { echo "3d "; }. But I feel like it's a dirty way to make things work...
How to add a space between each class tag in the proper way? I'm aiming for something like this foreach $categories as $cat { echo $cat . " "; } but where $categories and $cat would refer to each "if" statement.
I'm not familiar with WP but if you get your categories with some function like get_categories() then you can use implode to make a string from all categories.
<?php $categories = get_categories(); ?>
<?php $categories = implode(' ', $categories); ?>
<li class="<?php echo $categories; ?>">...</li>
Could you provide what is returning get_categories()?
EDIT:
function get_class_attr() {
$classes = get_post_class();
$classes = substr($classes, 7, -1);
$arr = array();
$arr = explode(' ', $classes);
$classes = 'class="';
foreach($arr as $class_name) {
if(strpos($class_name, 'category-') !== false) {
$classes .= substr($class_name, 9).' ';
}
}
$classes = substr_replace($classes, '"', -1, 1);
echo $classes;
}
get_class_attr(); // output: class="3d web"
Also note that 3d is not a valid class name, you can use something like movie3d or film3d.
Alternative way is to create your class value a little bit earlier and then echo it:
<?php
$classes = array();
if ( in_category('category-3d')) { $classes[] = "3d"; }
if ( in_category('category-animation')) { $classes[] = "animation"; }
if ( in_category('category-motion')) { $classes[] = "motion"; }
if ( in_category('category-shortfilm')) { $classes[] = "shortfilm";}
if(count($classes)) {
$classes = implode(' ', $classes);
} else {
$classes = '';
}
?>
<li class="<?php $classes ?>"></li>
As of the code you've posted, it should add all the categories if the product is in all the four specified ones. You could add the space between the quotes after each echo, e.g.: echo ' motion'.
I would use another approach, adding really all categories, without the need to check them by name:
<li class="<?php echo implode( ' ', get_categories() ); ?>"> … </li>
See: http://codex.wordpress.org/Function_Reference/get_categories on how to filter the output of the function get_categories().
I would suggest instead you use this function from the Wordpress API - something you should read a lot of.
Something like this should work:
<?php $categories = get_categories(); ?>
<li class="<?php foreach ($categories as $cat) {
echo $cat . " ";
}?>"> -- Your li text --
</li>

Symfony: recursive call in template

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>

Categories