PHP templates - with PHP [closed] - php

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;
?>

Related

php navigation displayed from multiple directories

Done a lot of searching but I can't really find what I'm searching for I think, or I don't understand it...
I have a site with probably 50-60 links in 5-6 dirs.. its a gaming site..like a 'guide' for the game...
say i have the following directories:
/basics/
/advanced/
/misc/
/support/
and each dir has the links..
/basics/gamebasics.php
/basics/pets.php
etc
/advanced/weaponfusing.php
/advanced/imbuing.php
etc
I'd rather not have to type out all the links, so I was thinking of making all the files in their approp. directories... and using something like
$files = scandir(dir/');
foreach ($files as $value){
$file = explode('.',$value);
}
etc...would that iterate through the 6 directories with my pages in them and could it be put in a simple li loop or something (i'd clean it with css) so that I dont have to type all the links out a second time (after creating each file)? how would i go about doing something like this? is there a better way?
EDIT:EDIT:EDIT:
So I just threw them all in an array like:
$pages = array('Home' => 'home.php',
'City Tour' => 'basics/tour.php',
'Daily Signin' => 'dailys/dailysignin.php',
'Game Mechanics' => 'misc/mechanics.php',
);
$currentPage = basename($_SERVER['REQUEST_URI']);
then i ran this:
<div id="mBox">
<h1>basics</h1>
<div class="mGroup">
<?php for each ($pages as $filename => $pageTitle) {
if($filename == $currentPage) { ?>
<ul>
<li class="current"><?php echo $pageTitle; ?></li>
<?php } else { ?>
<li><?php echo $pageTitle; ?></li>
<?php } } ?>
</ul></div>
Now my nav reads:
basics/tour.php
dailys/dailysignin.php
misc/mechanics.php
etc, as filenames...I'm on the right track, but I need the nav to display the first part of the array (the name), rather than the pathfilename.ext. Thats my first fix.
Secondly, is there a way to take out the paths and use them between my h1 tags, so that the menu titles are the folder paths? I'm still trying to figure out the arrays within directories or however I'd say it, so it's a bit confusing to me. Any help is appreciated.

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>

Trying to create a PHP function that only utilizes new instance of variable

I am trying to teach myself PHP. I have looked to find out how to make this work.
I have an online portfolio that I am posting my weekly school assignments and their grades when I receive them.
I currently have something that looks like this:
<?php
$page_title = "MATH203 | Journey to my Oasis";
$grade = "A = 185/185";
$course_title = "Applications of Discrete Mathematics";
$course_description = "Math. A fun four letter word. A lot of people have issues with this subject. I like math. I am not proficient by any stretch of the imagination, but I like it. It is challenging. Having this course after programming, I believe, will allow me to think of it in the manner in which it is intended. The professor is also teaches computer science. This should be interesting.";
?>
<?php include("../includes/header.php");?>
<?php include("../includes/navigation.php");?>
<?php include("../includes/classannounce.php");?>
<div id="content">
<div id="content_container">
<div class="one_half">
<h3>Discussion Board Posts</h3>
<h4><ul>
<li>
Week 1
Grade - A
</li>
<li>
Week 2
Not yet graded
</li>
<!--
<li>
Week 3
Grade - A
</li>
<li>
Week 5
Grade - B-
</li>
-->
<li>All links open a new window</li>
</ul></h4>
</div>
</div><!--end content_container-->
</div><!--end content-->
'<?php include("../includes/footer.php");?>
</body>
What I would like to do is have a separate PHP file that I include in the header PHP file so it goes everywhere with me just to cut down on the amount of code.
Currently what I am doing is just hiding the html for the weeks that I haven't come up to yet. I am using the original page as a template and just changing it as I go. I am trying to incorporate PHP more so that I can make changes easier and so that I can try to learn as much as I can. I figure that by calling a function an populating it with the variables needed I can cut down on the code needed and time required.
This separate file would have a function like:
<?php
function assignment()
{
$skydoc = '';
$week_no = '';
$grade_letter = '';
echo '<li><a href="', $skydoc, '" target="_blank">Week ', $week_no,
'</a> Grade - ', $grade_letter, '</li>';
}
?>
I try calling the function an include the variables in it so that it will fill in the appropriate sections.
assignment($skydoc = 'url', $week_no = '2', $grade_letter = '?')
I try that in the same file for testing purposes but all I get in HTML when I try it on my server is this
<li>
Week
Grade -
</li>
Thank you in advance. Any more questions or need clarification, please let me know.
your calling the function a bit incorrectly. function declaration should have the place holders for the variables you are passing into it.
function assignment($skydoc = 'url', $week_no = '2', $grade_letter = '?')
{
echo '<li>
Week ',$week_no,'
Grade - ',$grade_letter,'
</li>';
}
Then when you want to call the function you simply invoke the following
assignment('value', 1, 'A');
if you call assignment as follows then the default values you have placed in the variables will be assinged.
assignment(); // url, 2, ?
close...
function assignment($skydoc = '', $week_no = '', $grade_letter = ''){
echo '<li>
Week '.$week_no.'
Grade - '.$grade_letter.'
</li>';
}
assignment('url', '2', '?');

Add custom element to home menu item in Joomla

What i'm trying to do is quite simple as concept, but i'm not that good with php and the joomla framework.
Currently the home menu-item is generated like this:
<li class="item-101 current active">
<a class="hide-text" href="#some-link">Home</a>
</li>
What i'd like to achieve is to insert an <i> element inside only the home menu-item, something like this:
<li class="item-101 current active">
<a class="hide-text" href="#some-link"><i class="icon-home"></i>Home</a>
</li>
How can i achieve this? I'm using Joomla! 2.5 atm
I guess it's possible do something like "if this menu-item is the home link then add this code inside the <a> tags" but i really don't know how to do it, my php is not strong enough :P
Note: i'm doing this to achieve a simple home-icon instead of the litteral home menu-item.
As the classes syntax could suggest, i'm using the twitter bootstrap css-framework, but i've implemented the Icomoon font-set (as in joomla 3.0) instead of the tbs Glyph-icons sprites images.
Unfortunately, using font-based icons, text rules are applied to the icons also, and that is the reason i'm trying to insert a custom element inside the <a> tag, so that i can override the hide-text class hiding the home-icon.
Thanks for any suggestion!
Have a look in the template file of the menu module.
/modules/mod_menu/tmpl/default.php
The template builds the HTML for the menu module.
I just checked how it works in Joomla 2.5, and in the /modules/mod_menu/tmpl/default.php template the list is build. If you want to add to only the home link you'll have to add a little bit of code. Something like this :
if($item->home == '1'){ $item->title = '<i class="icon-home"></i>' . $item->title; };
Insert this just under the foreach loop and have a go, it should look something like this :
foreach ($list as $i => &$item) :
// THIS ADDS THE <i> to only the HOME LINK
if($item->home == '1'){ $item->title = '<i class="icon-home"></i>' . $item->title; };
$class = 'item-'.$item->id;
if ($item->id == $active_id) {
$class .= ' current';
}
Good Luck ;)
I have been following this guide as well, (Thanks Gruber and Mark Vink) but using the glyphicons instead of IcoMoon. I found there to be a syntax error in the example above. The version hat worked for me was
foreach ($list as $i => &$item) {
if($item->home == '1')$item->title = '<span class="glyphicon glyphicon-home" aria-hidden="true"></span>' .$item->title;
$class = 'item-' . $item->id
etc...

Adding classes with PHP echo, not replacing them

First of all, I know this is simple but I'm not a PHP developer by trade so I apologize if this is dumb for everyone. That being said, I've spent the last 3 hrs searching and can't find a way to do this without re-inventing my wheel so to speak. I use a simple command to mark the navigation on websites when the page is "current".
<li><a <?php if (strpos($_SERVER['PHP_SELF'], 'page')) echo 'class="current"';?> href="page.php" class="tp">Page</a></li>
Works great in most cases. However in this case, I need to concatenate the class string, not overwrite it with current. I've tried
...echo'class=" "."current".'
and several variations and can't get it to simply add the class not overwrite it. Thank you
Is the <li> not in a loop?
Ideally your menu would come from a table array through which you would loop. If that is the case; try this:
foreach(..){
$class = strpos($_SERVER['PHP_SELF'], 'page') ? " current" : "";
echo "<li>Page</li>";
}
Overall, for readability, I would recommend to not put if statements inline in the HTML.
But based on your code:
<?php
$class = strpos($_SERVER['PHP_SELF'], 'page') ? " current" : "";
?>
<li>Page</li>
What about something like this :
<li>
<a href="page.php"
class="<?php if (strpos($_SERVER['PHP_SELF'], 'page')) {echo 'current ';} ?>tp">
Page
</a>
</li>
This way, you'll always have at least class="tp", and, if the condition is met, a 'current ' (note the space at the end of this string : it's important and required so the two classes are separated by a space and not considered as one) will be inserted just before the 'tp', inside the class="..."

Categories