Let's say I have an array containing these items:
$test = array(Item1, Item2, Item3, Item4, Item5, Item6, Item7, Item8, Item9);
How can I print this structure using for, or foreach?
<ul>
<li>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</li>
<li>
<ul>
<li>Item 5</li>
<li>Item 6</li>
<li>Item 7</li>
<li>Item 8</li>
</ul>
</li>
<li>
<ul>
<li>Item 9</li>
</ul>
</li>
</ul>
You could split the array into chunks, using array_chunk():
$chunks = array_chunk($test, 4);
This will give you an array containing sub-arrays of 4 items each. You could then loop through these to create the list items:
<ul>
<?php foreach ($chunks as $chunk): ?>
<li>
<ul>
<?php foreach ($chunk as $item): ?>
<li><?php echo htmlspecialchars($item) ?></li>
<?php endforeach ?>
</ul>
</li>
<?php endforeach ?>
</ul>
use array_chunk to split your values
$test = array('Item1','Item2','Item3','Item4','Item5','Item6','Item7','Item8','Item9');
$chunk = array_chunk($test, 4);
echo '<ul>';
foreach($chunk as $pieces) {
echo '<li>';
echo '<ul>';
foreach($pieces as $item) {
echo '<li>'.$item.'</li>';
}
echo '</ul>';
echo '</li>';
}
echo '</ul>';
Try this
<?php
$test = array(Item1, Item2, Item3, Item4, Item5, Item6, Item7, Item8, Item9);
$ChunkedTestarray = array_chunk($test, 4);
echo "<ul>";
foreach($ChunkedTestarray as $Data) {
echo "<li><ul>";
for ($i = 0; $i <= count($Data)-1;) {
echo "<li>".$Data[$i]."</li>";
$i++;
}
echo "</ul></li>";
}
echo "</ul>";
?>
Related
I am using the following custom WordPress shortcode to display a list on a page, I am trying to find the 5th LI element and inject a DIV at this point.
[expander]
<ul>
<li>step1</li>
<li>step 2</li>
<li>step 3</li>
<li>step 4</li>
<li>step 5</li>
<li>step 6</li>
<li>step 7</li>
</ul>
[/expander]
Shortcode:
add_shortcode( 'expander', 'my_function' );
function my_function($atts, $content) {
echo substr_count($content, '<li>'); // 7
return $content;
}
Intended Output:
<ul>
<li>step1</li>
<li>step 2</li>
<li>step 3</li>
<li>step 4</li>
<li>step 5</li>
<div>
<li>step 6</li>
<li>step 7</li>
</div>
</ul>
There are multiple ways to set this up. The following code will wrap a <div> tag around the last two <li> tags starting after the 5th element exactly like you requested in your "Intended Output" section of your question, BUT please notice that you could use the shordcode attributes to make it dynamic NOT hard-coded by passing the starting and ending numbers as attributes.
The following code is the hard-coded version as you've asked it!
add_shortcode('expander', 'my_function');
function my_function($atts, $content)
{
$lists_itmes = substr_count($content, '<li>');
$list_array = explode('<li>', $content); // This will return an array containing of the values between each <li> tag starting from index 1
$main_content = "";
for ($i = 0; $i < $lists_itmes + 1; $i++) {
switch ($i) {
case 6:
$main_content .= "<div><li>" . $list_array[6] . "</li>";
break;
case 7:
$main_content .= "<li>" . $list_array[7] . "</li></div>";
break;
default:
$main_content .= "<li>" . $list_array[$i] . "</li></div>";
break;
};
}
return $main_content;
}
And it'll output:
<ul>
<li>step 1</li>
<li>step 2</li>
<li>step 3</li>
<li>step 4</li>
<li>step 5</li>
<div>
<li>step 6</li>
<li>step 7</li>
</div>
</ul>
I have a result like this:
Using foreach loop i can get the output like this:
<ul>
<li>1 group1 group1_title group1_link 2</li>
<li>2 group1 group1_title group1_link 1</li>
<li>3 group2 group2_title group2_link 2</li>
<li>4 group2 group2_title group2_link 1</li>
<li>5 group3 group3_title group3_link 2</li>
<li>6 group3 group3_title group3_link 1</li>
<li>7 group3 group3_title group3_link 2</li>
</ul>
But I need to make the result like this:
<ul data-group="1">
<li>1 group1 group1_title group1_link 2</li>
<li>2 group1 group1_title group1_link 1</li>
</ul>
<ul data-group="2">
<li>1 group2 group2_title group2_link 2</li>
<li>2 group2 group2_title group2_link 1</li>
</ul>
<ul data-group="3">
<li>1 group3 group3_title group3_link 2</li>
<li>2 group3 group3_title group3_link 1</li>
<li>3 group3 group3_title group3_link 2</li>
</ul>
Here is my simple php code
if ($getlinks->num_rows() > 0)
{
$x = 0;
foreach ($getlinks->result() as $group)
{
$x++;
echo '<ul group="'.$x.'">';
echo '<li>'.$group->id.' - '.$group->group.' - '.$group->title.' - '.$group->link.' - '.$group->value.'</li>';
echo '</ul>';
}
}
Update:
using bellow code i can group by value but i need make something like this by key not value
$people = array("Peter", "Peter", "Joe", "Glenn", "Cleveland");
//echo current($people) . "<br>";
//echo end($people);
foreach ($people as $p){
echo ($p);
if (current($people) !== next($people)){
echo " bah<br>";
}
}```
You need to track when the group changes:
if ($getlinks->num_rows() > 0)
{
$x = 0;
$prev_group = null;
foreach ($getlinks->result() as $group)
{
// I am assuming $group->id can't be null for an actual group
if ( $group->id !== $prev_group ) {
if ( $x > 0 ) {
// Close previous group
echo '</ul>';
}
echo '<ul group="'.$group->id.'">';
$x = 0;
$prev_group = $group->id;
}
$x++;
echo '<li>'$x.' - '.$group->id.' - '.$group->group.' - '.$group->title.' - '.$group->link.' - '.$group->value.'</li>';
}
if ( $x > 0 ) {
// Close last group
echo '</ul>';
}
}
I'm not clear what your data structures are and if it's $group->id or $group->group that should be compared, but you see the idea I hope.
There was a question raised by Log1x about Comparing JSON after foreach loop for a Discord Channel Viewer
This is the link: Comparing JSON after foreach loop In his viewer he wanted to output something like:
<ul>
<li>Channel 1
<ul>
<li>User 1</li>
<li>User 2</li>
</ul>
</li>
<li>Channel 2</li>
<li>Channel 3
<ul>
<li>User 3</li>
</ul>
</li>
</ul>
There was an excellent answer on how to do this, from Mojtaba which was:
$discord = json_decode(file_get_contents('https://discordapp.com/api/servers/'.$id.'/widget.json'));
if ($discord->channels) {
usort($discord->channels, function($a, $b) {
return $a->position > $b->position ? 1 : -1;
});
echo '<ul>';
foreach ($discord->members as $member) {
if (!empty($member->channel_id)) {
$channel_members[$member->channel_id][] = $member->username;
}
}
foreach ($discord->channels as $channel) {
echo "<li>{$channel->name}";
if (!empty($channel_members[$channel->id])) {
echo '<ul>';
foreach ($channel_members[$channel->id] as $username) {
echo "<li>$username</li>";
}
echo '</ul>';
}
echo "</li>";
}
echo '</ul>';
}
I have already completed my viewer but you will be able to see from this screen-shot link that my available space is limited and taken up by too many empty channels. So I am interested to know if there is a way to hide channels that are empty i.e.
<ul>
<li>Channel 1
<ul>
<li>User 1</li>
<li>User 2</li>
</ul>
</li>
<li>Channel 3
<ul>
<li>User 3</li>
</ul>
</li>
</ul>
As I have said, my interest is also for a Discord Channel Viewer , so the above information from both Mojtaba and the first link are directly relevant to my code too.
Thanks in advance.
I think you should be able to just move your <li> tag inside the if.
foreach ($discord->channels as $channel) {
// outside the if, the channel shows even if it's empty
if (!empty($channel_members[$channel->id])) {
// inside the if, you'll only see the channel if it's not empty
echo "<li>{$channel->name}<ul>";
foreach ($channel_members[$channel->id] as $username) {
echo "<li>$username</li>";
}
echo '</ul></li>';
}
}
I want to add my ul & li every two loop.. Example
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<ul>
<li> <?php the_title() ?> - <?php the_content() ?></li>
</ul>
<?php endwhile; ?>
Let's say I have 4 posts and I want the result should be like this
<ul>
<li>Title 1 - content 1</li>
<li>Title 2 - content 2</li>
</ul>
<ul>
<li>Title 3 - content 3</li>
<li>Title 4 - content 4</li>
</ul>
add a counter variable (start =0) that increments at the end of each pass through the loop. Then at the beginning of each pass, test if($counter%2==0){ echo "</ul><ul>";}and put the first <ul> and last </ul> outside of the loop
I would do something like this:
for($i = 0; $i < $numberOfUls; $i++)
{
$result = '<ul>';
for($j = 0; $j < $numberOfLis; $j++)
{
$result .= '<li>Title content</li>'; // Perhaps an array with the whole list $listContent[$i][$j];
}
$result .= '</ul>';
}
echo $result;
I have the following HTML output;
<ul>
<li>Test 1</li>
<li>Test 2.</li>
<li>Test 3</li>
<li>Test 4</li>
<li>Test 5</li>
<li>Test 6</li>
<li>Test 7</li>
</ul>
What I need to do, is display the same HTML, but with only the first 4 <li> tags, i.e.
<ul>
<li>Test 1</li>
<li>Test 2.</li>
<li>Test 3</li>
<li>Test 4</li>
</ul>
Is there an easy way I can do this in PHP?
Thanks
EDIT:
The data is coming from:
$data = $product->getDescription();
It is stored in the DB as the HTML content, I am currently displaying it using the above code;
Thanks
Umm yes..
Depending on where the data is coming from, I am going to assume it is a db of some sort and you have it in an array():
$databasevalue = array(); //stuff from database goes here / dragons
echo "<ul>";
for ( $counter = 0; $counter < 4; $counter ++) {
echo "<li>".$databasevalue[$counter]."</li>";
}
echo "</ul>";
Can't offer more without better question details.
How is data coming from ?
If this data comes from an array you can slice it with array_slice function
$list = array_slice($input, 0, 4);
// $list now only having first 4 item.
<?php
echo '<ul>' . PHP_EOL;
for ($i = 1; $i <= 4; $i++)
{
echo '<li>' . $i . '</li>' . PHP_EOL;
}
echo '<ul>' . PHP_EOL;
?>
Outputs:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<ul>
Someone else answered with a good one (requires SimpleXMLElement, PHP5) but has been deleted:
<?php
$data = '<ul>
<li>Test 1</li>
<li>Test 2.</li>
<li>Test 3</li>
<li>Test 4</li>
<li>Test 5</li>
<li>Test 6</li>
<li>Test 7</li>
</ul>';
$ul = new SimpleXMLElement($data);
$li = $ul->li;
echo '<ul>'.PHP_EOL;
for($i = 0 ; $i < 4 ; $i++)
{
echo '<li>'.$li[$i].'</li>'.PHP_EOL;
}
echo '</ul>'.PHP_EOL;
?>
if you're using database, you should use "LIMIT" in your SQL, otherwise array_slice will do the job.
don't forget: documentation is your best friend (especially in php)