generating <li> elements in php - php

This should be relatively straightforward but none of the solutions I've found here or elsewhere work at all.
I'm trying to display a table containing all the elements of a list of brands. I added two manually (Adidas and Nike) just to test the display, and these show correctly. I then tried to generate a list using an array of brands (the array brandList has two items, id and name). The output is garbage.
<ul class="brand-list">
<li>Adidas</li>
<li>Nike</li>
<?php
foreach ($brandList as $item) {
$text = '<li>'.$item[1].'</li>';
echo("$text\n");
}
?>
</ul>
expected output:
Adidas
Nike
Puma
Asics
actual output
Adidas
Nike
'.$item[1].''; echo("$text\n"); } ?>
I've tried formatting a dozen different ways (with single and double-quotes, backslashes etc.) but it always just displays half of the line of code instead of the variable. I know it's something simple, but I've spent too much time messing with it for no result.

One way to do this is to let PHP generate the HTML instead of echoing the string. I think that's more clear than echoing.
<ul class="brand-list">
<li>Adidas</li>
<li>Nike</li>
<?php
foreach ($brandList as $item) {
?>
<li><?=$item[1]?></li>
<?php
}
?>
</ul>

A lot is wrong with your snippet and frankly I am not surprise it doesn't work.
You are using the wrong syntax in your foreach loop.
The <li></li> you are creating has no opening tag just an anchor tag <a></a> and a closing list item tag </li>.
$test is a variable with quotes in it, using quotation marks around it during echo is just wrong as the " in your href will close the first quote around the variable outputting others as a string rather than HTML tags.
Though not so important but ditch the \n character. Your browser will render the list in block format with or without it.
Change your snippet to look like this instead
<ul class="brand-list">
<li>Adidas</li>
<li>Nike</li>
<?php
foreach($brandList as $item) {
?>
<li><?=$item[1]?></li>
<?php
}
?>
</ul>
If you prefer your current syntax then change it to this
<ul class="brand-list">
<li>Adidas</li>
<li>Nike</li>
<?php
foreach($brandList as $item) {
$text = '<li>'.$item[1].'</li>';
echo($text);
}
?>
</ul>

Hi I think you have missed starting li tag in side the loop.
Please check this for your solution.
<ul class="brand-list">
<li>Adidas</li>
<li>Nike</li>
<?php
$text="";
foreach ($brandList as $item){
$text .= '<li>'.$item[1].'</li>';
}
echo($text);
?>

Related

Echo a PHP function with condition inside HTML tag using concatenation

This is my first question.
I'm building a simple dynamic menu using <li>
I'm working on a PHP based CMS (Kirby)
Kirby has predefined PHP functions (helpers)
I'm trying to output a <li> for each page on the website:
<li class='active'><a href='page1'></a></li>
<li><a href='page2'></a></li>
<li><a href='page3'></a></li>
...
Im using a PHP function e($condition, $value) to style the menu item only if that page isOpen()
// I need help here
<?php
foreach ($pages->visible() as $p):
echo "<li" . e($p->isOpen(), ' class="active"') . "><a href='" . $p->url() . "'></a></li>";
endforeach;
?>
The function is working but the css part class="active" is printing OUTSIDE the <li> on the final code
class="active"
<li>...</li>
<li>...</li>
<li>...</li>
I had this previous code that worked fine, but since i'm using display: inline-block the menu had spaces betwes each block, since the following code was placing each <li>in a new line.
// This code works
<?php foreach($pages->visible() as $p): ?>
<li <?php e($p->isOpen(), ' class="active"') ?> ></li>
<?php endforeach ?>
The reason i'm rewrinting the code is to remove the white space between the inline: blockelements.
I'm failing to concatenate the string in a way that the function works and print its results inside the <li>tag.
I've searched here and also have read lots of Docs in php.net but nothing worked to me, I'm struggling with this for 2 days.
I'm expecting to learn better how and when to use concatenation and string operators.
The problem is that Kirby's e() function already has the echo in the routine, instead of just simply returning the value.
http://getkirby.com/docs/cheatsheet/helpers/e
If you were to change your output loop to something more like this, echoing separately, you'll get the results in the desired order:
foreach($pages->visible() as $p)
{
echo "<li";
e($p->isOpen(), ' class="active"');
echo "> and the rest of your line </li>";
}
That said, perhaps using e() isn't the most elegant in this case. Maybe try the r() function instead:
http://getkirby.com/docs/cheatsheet/helpers/r
foreach($pages->visible() as $p)
{
echo "<li ".r($p->isOpen(), ' class="active"').">more text</li>";
}

How do I insert variables within html in a php array?

EDIT: I've updated this question with the working code, but I've left the content of the text alone so you can see what I was trying to do in the future and also because there were a few other things I wanted to do aside of the initial question.
I have an array that has an html list in it, the php is shuffling the list to echo a random order. Within the list items in the array, I want to include a php variable, right now this is what I have:
<?php include('includes/header_topright_content.php'); ?>
<ul data-options="animation:fade; slide_number:false; pause_on_hover:false; timer_speed:5500; navigation_arrows:false; next_on_click:true; timer:true; bullets:false;" data-orbit>
<?php
$links = array(
'<li data-orbit-slide="headline-1"><img /><div>'.$Slide1.'</div></li>',
'<li data-orbit-slide="headline-2"><img /><div>'.$Slide2.'</div></li>',
'<li data-orbit-slide="headline-3"><img /><div>'.$Slide3.'</div></li>',
);
shuffle($links);
foreach ($links as $link) { echo $link; }
?>
</ul>
I could have up to 10 or even 20 of these slides. The information the variables are linking to would be from a separate .php page that I "included." The information on that page is:
<?php
$Slide1 = "<h5>Slide 1</h5><h6>This is the content for slide 1!</h6>";
$Slide2 = "<h5>Slide 2</h5><h6>This is the content for slide 2!</h6>";
$Slide3 = "<h5>Slide 3</h5><h6>This is the content for slide 3!</h6>";
?>
If I scrap the variable idea and insert the html directly into the list item it works perfectly. If I try to put the variables in there, the slide will just be blank. I'm stuck on where to go from here, I'm great with html and css, but not so good with php, so any help is appreciated! I'm also open to any formatting tips and best practices, the cleaner the better.
Thanks in advance!
MORE INFO: There's a few complications behind as to why I'm looking to do this. The orbit image slider doesn't support a random order, and I found it much easier to just use php to randomize the order of the list items. The reason I want to use variables in these list items is because I'm using a cms (CouchCMS) to make that content editable - a simple solution would be to insert editable tags around that content, but that would only make one page editable, and this content is going to be 'included' in the header of every page. So I'm trying to find a way to put those variables on a separate page (I know 'including' it doesn't do that - maybe I can link it to the page like a css or js file?) to make that editable. If anyone has any ideas for this I'm open!
With string concatenation, your also need to include the variables file before assigning them variables to the array. You also dont need to wrap PHP variables in quotes when echoing.
<?php include('includes/variables.php'); ?>
<ul data-options="[orbit options go here]" data-orbit>
<?php
$links = array(
'<li data-orbit-slide="headline-1"><img /><div>'.$Slide1.'</div></li>',
'<li data-orbit-slide="headline-2"><img /><div>'.$Slide2.'</div></li>',
'<li data-orbit-slide="headline-3"><img /><div>'.$Slide3.'</div></li>',
);
shuffle($links);
foreach ($links as $link) { echo $link; } //<<< notice no quotes
?>
</ul>
Edit:
Can I make a suggestion to your code, by assigning to a slides array directly be it in an external file or not, you will be able to eventually dynamically or easily add new slides to the slider and not need to hard code into a second sub array before the loop. So something like. Also by changing to alternative syntax your keep a nice HTML structure.
<?php
$slide[] = "<h5>Slide 1</h5><h6>This is the content for slide 1!</h6>";
$slide[] = "<h5>Slide 2</h5><h6>This is the content for slide 2!</h6>";
$slide[] = "<h5>Slide 3</h5><h6>This is the content for slide 3!</h6>";
shuffle($slide);
?>
<ul data-options="animation:fade; slide_number:false; pause_on_hover:false; timer_speed:5500; navigation_arrows:false; next_on_click:true; timer:true; bullets:false;" data-orbit>
<?php foreach ($slide as $key=>$value):?>
<li data-orbit-slide="headline-<?php echo $key?>"><img /><div><?php echo $value; ?></div></li>
<?php endforeach;?>
</ul>

PHP show text up to /*show more text*/

I would like to only show the text that is before /*SHOW MORE TEXT*/ However I am unsure how to do such a thing because my text is like this:
<ul>
<li>show this</li>
<li>show this</li>
/*SHOW MORE TEXT*/
<li>don't show this</li>
</ul>
I have tried
$texts = explode("/*SHOW MORE TEXT*/", $text);
But the issue with this is then it won't fix the </ul>
How can I fix this small issue?
Just try with Jquery toggle functions it's more easier and faster. Here you find details: http://api.jquery.com/toggle/
Using php you can do this like
<ul>
<li></li>
<?php
if(condition is true){
echo "<li>text will be displayed if condition is true otherwise it will not displayed</li>";
}
?>
</ul>
using javascript you can use
<li style="display:none;">this will not visible</li>
you can use display:none; property for that and later when you need it you can display it using java script.
<li style="display:none;">don't show this</li>
One possible solution is as follows:
Don't include ul tags in the text string, and then use explode and take the first element of array using array[0] and close </ul> tag.

ForEach multiply issue

This is probably a stupid gotcha that I'm overlooking but I'm hoping one of you can help me!
I've got a loop to list a grid of Products in my DB.
So far so good, everything is displaying roughly OK except this one little issue.
Within a list I'm doing the following:
<ul>
<?php $i=0; foreach ($products as $product) : $i++; ?>
<li <?php
if(($i%4) ==0){
echo 'class="last"';
} elseif($i%2==0){
echo 'class="second"';
}
?>>
// Then I've got the image thumbnail etc coming in....
All looks good except for the LAST row...
So for instance if I have 8 products... the first 7 will display on the page correctly, but then there is a gap at the end where the 8th product moves onto the next page.
At first I thought it was CSS widths or something but it's not. Even if I have 20 products...always the last row only shows 3 across and puts the last product on the next page.
Any ideas anyone?
Cheers M
<ul>
<?php $i=count($products); ?>
<li
<?php
if(($i%4) ==0){
echo 'class="last"';
} elseif($i%2==0){
echo 'class="second"';
}
?>>
Let's try it..

limit to only posts that are tagged using PHP

I am trying to only get the posts that are tagged on a tumblr blog. I can get each post depending on what type of post it is (regular, link, photo, etc) but instead, I want to get each post that has a certain tag on it. For example, only get the posts that are tagged 'file'
Here is my code so far:
<?php
$xml = simplexml_load_file('http://stocklamp.tumblr.com/api/read');
$posts = $xml->xpath("/tumblr/posts/post[#type='photo']");
foreach($posts as $post) {
}
?>
<ul>
<li> Post 1(PHP should be here)</li>
</ul>
and here is tumblrs API http://www.tumblr.com/docs/en/api/v2
First, you'll need to have your markup within the curly braces that belong to the foreach loop. Otherwise, the scope of the $post object you're referencing will not be available, and it give you an error.
This is what I came up with:
<ul>
<?php
$xml = simplexml_load_file('http://stocklamp.tumblr.com/api/read');
$posts = $xml->xpath("/tumblr/posts/post/tag/..");
foreach($posts as $post) {
echo "
<li>
<a href='{$post['url-with-slug']}'>".($post->{'regular-title'}?$post->{'regular-title'}:$post->{'link-text'})."</a>
</li>
";
}
?>
</ul>
And if you want to limit the tags matched, you can do the following:
<ul>
<?php
$xml = simplexml_load_file('http://stocklamp.tumblr.com/api/read');
$posts = $xml->xpath("/tumblr/posts/post/tag[contains(text(),'xml') or contains(text(),'php') or contains(text(),'firefox')]/..");
foreach($posts as $post) {
echo "
<li>
<a href='{$post['url-with-slug']}'>".($post->{'regular-title'}?$post->{'regular-title'}:$post->{'link-text'})."</a>
</li>
";
}
?>
</ul>
Of course, that's a little messy. I'm not necessarily an XPath guru, so there should be a cleaner way than that I would think.
And since I wasn't really digging on the ternary for the link text, or the fact I don't know if one or the other will always be available, this should be more descriptive with a fallback to the url.
<ul>
<?php
$xml = simplexml_load_file('http://stocklamp.tumblr.com/api/read');
$posts = $xml->xpath("/tumblr/posts/post/tag[contains(text(),'xml') or contains(text(),'php') or contains(text(),'firefox')]/..");
foreach($posts as $post) {
if ($post->{'regular-title'}) {
$slug = $post->{'regular-title'};
} else if ($post->{'link-text'}) {
$slug = $post->{'link-text'};
} else {
$slug = $post['url-with-slug'];
}
echo "
<li>
<a href='{$post['url-with-slug']}'>".$slug."</a>
</li>
";
}
?>
</ul>
EDIT
And, you also might want to make a match of the entire text of the TAG element, so that you don't get matches on things like xml-is-for-noobs when you want xml tags only. contains() will match both, while the below will only match xml.
/tumblr/posts/post/tag[text() = 'xml']/..
So, according to your comment, if you're looking for posts tagged events but don't want to catch tags like bowling-events, prevents fun, other events, etc..., you would want to make the text() = 'events' match. On the other hand, if you DID want to match anything with events in the text of the TAG node, use the contains(text(), 'events') method.
EDIT 2
And if you're trying to limit the results, use position():
(/tumblr/posts/post/tag[text() = 'xml']/..)[position() <= 3]
Note, the example on my webpage does not include the text() match, since there are not enough entries to support a submatch and still be productive. However, that should work.
http://jfcoder.com/test/tumblrtest.php
The XPath selects all TAG elements that belong to a POST element, then selects the parent (..) of that TAG, which gives you a SimpleXML object containing the relevant POST elements you're looking for.
Then, it iterates over each element, printing the $post's information into a UL element.

Categories