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);
?>
I collaborate with a web-programmer on a php project based in kirby cms, and he wants to open and close every line as such:
<main>
<?php /*php code here/* ?>
<?php /*more php here*/ ?>
...
Trying to follow this style, I found some errors in my code. The first is that it seems I canNOT do this in the middle of an array as such:
BAD CODE
<?php $oo = array( ?>
<?php 'h' => 100, ?>
<?php 'v' => 100, ?>
<?php ); ?>
but I can do it in the middle of a foreach loop as such:
<?php foreach ($p as $subp): ?>
<div id='<?= $subp->title() ?>'>
<?php endforeach; ?>
Are there any other cases such as array in which I canNOT do this?
/edit
According to the answer, there can only be tag-breaks within 'foreach', 'while', or 'if' blocks.
How about a 'foreach', 'while' or 'if' within a function? is that 'legal'?:
<?php
function myFunction($arg){
if($arg === 'this'): ?>
<?= '<p>yep</p>' ?>
<?php else: ?>
<?= '<p>nop</p>' ?>
<?php endif;
};
?>
And how about nesting if within foreach within function?:
<?php
function myFunction($arr){
foreach($arr as $val): ?>
<p><?= $val ?> <p>
<?php if($val === 'this'): ?>
<?= '<p>yep</p>' ?>
<?php else: ?>
<?= '<p>nop</p>' ?>
<?php endif;
endforeach;
};
?>
edit/
Thank you
you cannot "break out of php" mid statement. wline defining an array for example you cannot close the php tags. The only time when you can "break out" of php is between opening and closing a loop or an if/else statement. This actualy does not break the statement as <?php foreach: ?> is a complete statement whereas <?php foreach{ ?> is not. Here some examples of what you can do:
<?php if($this!=$that): ?>
{something}
<?php endif ?>
<?php foreach($things as $thing): ?>
{something}
<?php endforeach ?>
<?php $while($this): ?>
{something}
<?php endwhile ?>
I think you get the message. you must have complete statements within php tags, without interruptions.
P.S. Also avoid using the shorthand <? instead of <?php at all cost, moving your project to a different hosting or an upgrade of your hosting might break your project as per default short tags are not activated. <?= ?> shorthand is safe as this is unaffected by the setting for newer php versions.
P.P.S Do not listen to the guy who wants php in one line, this will make your code hard to read and maintain. Stand strong and write beautiful code :)
UPDATE: (after the update on the question from #Jaume Mal)
I did not mean the examples in my answer as exclusive but as examples of statements that are complete vs statements that are incomplete. (I also forgot to mention closing php tags mid fuction, wich also work but I despise and woudl strongly advise against.) So for example <?php function foo(){ is a complete statement of starting a function but (as the other cases with loops etc..) it needs a closing statement, in this case }. This is true for if / else or foreach and so on:
<?php if($this){ ?>
some code
<?php } ?>
is a valid code, as the code pieces within the php tags are complete statements.
Sorry if this seems very simple I'm rather new to php.
I'm drawing data from the database using a for each loop and want to add a list item for each result to a side bar while adding a new container div to the body.
What is the best way to code this?
Any help is much appreciated.
Thanks A
Edit...
My code so far...
<?php
$iidcoversheets = $wpdb->get_results(
"
SELECT *
FROM $wpdb->trm_iid_cover_sheet
WHERE Return_ID_FK = '$trmrtnid->Return_ID_PK'
"
);
$gadcoversheets = $wpdb->get_results(
"
SELECT *
FROM $wpdb->trm_gad_cover_sheet
WHERE Return_ID_FK = '$trmrtnid->Return_ID_PK'
"
);
?>
<ul>
<?php
foreach ( $iidcoversheets as $iidcoversheet )
{
?>
<li><?php echo $iidcoversheet->business name; ?></li>
<?php
}
?>
<?php
foreach ( $gadcoversheets as $gadcoversheet )
{
?>
<li><?php echo $gadcoversheet->business name; ?></li>
<?php
}
?>
</ul>
I understand how to add the <li> items but I'm strugging on how to add a div containing some html to another div not in the <ul> tag as it seems to me this will interrupt the code for the <ul>.
Any help would be really appreciated.
Thanks A
<div>
<ol>
<?php
foreach ($uls as $ul) {
?>
<li>
<?php echo $ul; ?>
</li>
<?php
}
?>
</ol>
</div>
Ok I came to the realisation that I could simply do another exact same loop later on in the page in the div I wanted but with different output. I was trying to do it all up front save the results and output them somewhere else, unnecessary.
Clearly I was having a daft moment earlier.
Thanks for all the input.
Regards
A
this is my first post here. I spent all of yesterday searching the net for an answer, but I think I've got a fairly unusual application of the while loop here so I didn't have much success.
Essentially I have a several categories, for example titled "Kosove" and "Shqiperi". Each of these has a number of sub-sections. Those sub-sections may or may not have content inside them.
I'm using while loops to display the sub-sections, providing they DO have content inside.
This is my code:
<ul>
<?php while(osc_has_list_regions($country = 'kv') ) { ?>
<li><?php echo osc_list_region_name(); ?> <em>(<?php echo osc_list_region_items(); ?>)</em></li>
<?php } ?>
</ul>
Notice the " $country = 'kv' " identifies the category as 'Kosove' in this case.
What is generated is:
Prishtine(1)
Vushtrri(1)
Which is fine.
The problem occurs when I want to also display the subsections for another category, e.g. Shqiperi. The code for this:
<ul>
<?php while(osc_has_list_regions($country = 'kv') ) { ?>
<li><?php echo osc_list_region_name(); ?> <em>(<?php echo osc_list_region_items(); ?>)</em></li>
<?php } ?>
</ul>
<br><br>
<ul>
<?php while(osc_has_list_regions($country = 'al') ) { ?>
<li><?php echo osc_list_region_name(); ?> <em>(<?php echo osc_list_region_items(); ?>)</em></li>
<?php } ?>
</ul>
Again notice the " $country = 'al' " identifies the category as 'Shqiperi' in this case.
What is generated is:
Prishtine(1)
Vushtrri(1)
Prishtine(1)
Vushtrri(1)
Which is not correct. The second part of the code has ignored the 'al' and just repeated the previous while loop content (i.e. the subsections for 'kv').
It SHOULD read:
Prishtine(1)
Vushtrri(1)
Berat(1)
As 'Berat' is the appropriate subsection for the 'Shqiperi' category.
If I have " $country = 'al' " as the first while loop condition, then it shows:
Berat(1)
Berat(1)
So obviously the order is important. It seems that the previous loop hasn't been properly closed.
I'm pretty new to PHP and I'm not even sure if I'm using the while loop appropriately here. Any suggestions how to fix this would be hugely appreciated.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
What's the most elegant templating (preferably in pure PHP!) solution you've seen?
Specifically i'm interested in handling:
Detecting in a repeating block whether it's the first or last element
Easy handling of odd/even cases, like a zebra striped table, or similar
Other modulos logic, where you'd do something every n'th time.
I'm looking for something that makes this less of a pain:
<?php
$persons = array('John', 'Jack', 'Jill', 'Jason');
?>
<?php $i = 0; ?>
<?php if (isset($persons)): ?>
<ul>
<?php foreach ($persons as $name): ?>
<li class="<?= ($i++ % 2 === 0) ? 'odd' : 'even' ?>"><?= $name ?></li>
<?php endforeach ?>
</ul>
<?php endif ?>
Does it really take the mess above to create something like this below?
<ul>
<li class="odd">John</li>
<li class="even">Jack</li>
<li class="odd">Jill</li>
<li class="even">Jason</li>
</ul>
Is it only me that find the above near hideous?
All those starting and closing of php-tags makes me cringe.
You don't need to open the tags more than once. You can also make a function out of it if you do the same thing multiple times:
<?php
function makeul($items, $classes) {
$c = count($classes);
$out = "";
if (isset($items) && count($items) > 0) {
$out = "<ul>\n";
foreach ($items as $item) {
$out .= "\t<li class=\"" . $classes[$i++%$c] . "\">$item</li>\n";
}
$out .= "</ul>\n";
}
return $out;
}
?>
other page content
<?php
$persons = array('John', 'Jack', 'Jill', 'Jason');
$classes = array('odd', 'even');
print makeul($persons, $classes);
?>
Also, if you don't mind using Javascript, Jquery makes things done mod 2 pretty easy (e.g., for zebra striping a table):
$("tr:odd").addClass("odd");
$("tr:even").addClass("even");
Tiny But Strong
www.tinybutstrong.com
It doesn't make the smarty mistake of embedding another macro language in the page, but does allow you to handle every practical web display issue I've ever thrown at it. In particular the above odd/even constructs are a doddle. For something like your code selecting from a database table
In the PHP file
$TBS->MergeBlock('blk1',$sqlconnect, "SELECT name from people ");
And in the HTML file
<ul>
<li class="odd">[blk.name;block=ul]</li>
<li class="even">[blk.name;block=ul]</li>
</ul>
And that's it. Notice that the HTML is completely Dreamweaver compatible. Furthermore if I wanted to make that alternate over three line styles all I'd need to do is add the extra line, maybe with different classes, so
<ul>
<li class="linestyle1">[blk.name;block=ul]</li>
<li class="linestyle2">[blk.name;block=ul]</li>
<li class="linestyle3">[blk.name;block=ul]</li>
</ul>
A small help on the looping:
<? $b=false; foreach($MyList as $name) { ?>
<li class="row<?= $b=!$b ?>"><?= htmlspecialchars($name); ?></li>
<? } ?>
By saying $b=!$b, it automatically alternates between true and false. Since false prints as "", and true prints as "1", then by defining css classes row and row1, you can get your altering rows without any trouble.
consider using :first-child css to style the first one differently.
It ain't pure PHP (the templating syntax then), but it works realy nice; Smarty.
For loops you can do:
<ul>
{foreach from=$var name=loop item=test}
{if $smarty.foreach.loop.first}<li>This is the first item</li>{/if}
<li class="{cycle values="odd,even"}">{$var.name}</li>
{if $smarty.foreach.loop.last}<li>This was the last item</li>{/if}
{/foreach}
</ul>
have you considered phptal?. one main benefit of it (or something similar) is that you get templates which can pass validation. most php template engines seem to ignore this.
I use PHPTAL for templating because it is written in 100% actual HTML with placeholder data, so it even works in a WYSIWYG editor for a web designer. That and it's just way easy to understand.
Here's what it would look like for me. Please forgive the markup, I'm new here and the four spaces block wasn't working right for me (the list was a list, not the markup).
PHP Code:
$tal = new PHPTAL;
$tal->setTemplate('people.htm')
->set('people', array('John', 'Jack', 'Jill', 'Jason'));
echo $tal->execute();
Template:
<ul>
<li tal:repeat="person people" tal:content="person">John Doe</li>
</ul>
Output:
JohnJackJillJason
Now obviously I wouldn't make a template for this little, but I could use a macro for it or build a whole page and include that variable. But you get the idea. Using PHPTAL has just about tripled my speed at templating and programming, just by the simplicity (no new syntax to learn like smarty).
How's about XSLT? The only template system that has a standards body behind it. Works the same across programming languages. Learn it once, use it everywhere!
Symfony Components: Templating
(source: symfony-project.org)
Symfony intends on moving to a new templating system based on the lightweight PHP templating system twig.
The lead developer Fabien Potencier, explains the decision here: http://fabien.potencier.org/article/35/templating-engines-in-php-follow-up
Symfony can usually be replied upon to make very informed decisions on such matters, so this framework should be something to look into.
The component is here: http://components.symfony-project.org/templating/
I've used Smarty Template Engine in the past. It's Pretty solid. And as you can probably tell from the website; it has quite the large user-base and is updated regularly.
It's in pure PHP as well.
Savant is a lightweight, pure PHP templating engine. Version 2 has a cycle plugin similar to the Smarty one mentioned earlier. I haven't been able to find a reference to the same plugin in version 3, but I'm sure you could write it fairly easily.
If is just to apply a CSS style, why don't you use the :nth-of-type(odd) selector.
For example:
li:nth-of-type(odd) {
background: #f2f6f8;
background: linear-gradient(top, #f2f6f8 0%, #e0eff9 100%);
}
http://jsfiddle.net/melonangie/nU7qK/enter code here
I use Modulo like you did in your example all the time.
If what cringes you is the opening and closing tags, write a function that creates the html string and then have it return it. At least it will save you some tags.
I have been a fan of HAML for quite a while, it looks like PHP folk have HAML now: see http://phphaml.sourceforge.net/
<?= ($i++ % 2 === 0) ? 'odd' : 'even' ?>
You're doing it the other way around. Your first item is now called even instead of odd. Use ++$i.
I'm having the same problem. But I think your original solution is the neatest. So I'll go with that.
I created a simple templating system in PHP to solve this problem a while ago:
http://code.google.com/p/templatephp/
It takes a multidimensional array, and requires the addition of some extra tags to the HMTL to create the combined template.
It's not as complicated (albeit powerful) as Smarty and some other solutons, but wins out in simplicity a lot of the time. A demo of the menu creation:
<p>Main Menu</p>
<ul>
{block:menu_items}
<li>{var:name}</li>
{/block:menu_items}
</ul>
Merged with...
array (
'menu_items' => array (
array (
'link' => 'home.htm',
'name' => 'Home'
),
array (
'link' => 'about.htm',
'name' => 'About Us'
),
array (
'link' => 'portfolio.htm',
'name' => 'Portfolio'
),
array (
'link' => 'contact.htm',
'name' => 'Contact Us'
)
)
);
Will create the menu...
<p>Main Menu</p>
<ul>
<li>Home</li>
<li>About Us</li>
<li>Portfolio</li>
<li>Contact Us</li>
</ul>
<?php
define ('CRLF', "\r\n");
$persons = array('John', 'Jack', 'Jill', 'Jason');
$color = 'white'; // Init $color for striped list
$ho = '<UL>' . CRLF; // Start HTML Output variable
foreach ($persons as $name)
{
$ho .= ' <li class="' . $color . '">' . $name . '</li>' . CRLF;
$color = ($color == 'white') ? 'grey' : 'white'; // if white, make it grey else white
}
$ho .= '</ul>' . CRLF;
echo $ho;
?>