I have a html project, with various template files. I want to display breadcrumbs, in all pages except on index.php and contact.php.
I have the breadcrumbs working; what I can't get it to work is the condition for only displaying it if the pages are not index.php or contact.php:
So far, I know I could do this if it was in the other way around, only display it on those pages:
$noBreadcrumbs = array("index.php", "contact.php");
foreach ($noBreadcrumbs as $page => $pageName) {
if (stripos(filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING), $pageName)){
echo '<div class="breadcrumbs container">';
require ("breadcrumbs.php");
echo '</div>';
}
}
But because it has to be in the other way around.... I don't know how to do it! If I echo de request uri it appears also with the project name (thousand_motors/index.php), and.... I am stuck. I can't print only "index.php" and even if so, I don't know how can I do the foreach but when they are not those pages...
Any suggestions?
Thank you
have you tried
if (!stripos( //....
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>
I have the following code to include pages dynamically:
<div id="content">
<div id="aside">
...
</div>
<div id="main">
<?php
$page = (isset($_GET['page'])) ? sanitize($_GET['page']) : 'home';
if (!include 'pages/'.$page.'.php') require 'pages/404.php';
?>
</div>
</div>
As you can see, the #aside has static content.
I want to include a specific content for the #aside depending on the page selected. For example, if the user goes to 'Home' and 'About', I want the 'default' aside. But if the user goes to 'Documents' I want a 'Sections' aside.
I know I can just include each aside from every page, but that's not effective. I also don't want the user to be hable to set the aside as the main content, so they have to be in different folders or something.
I'd like to know an effective and not so complicated way to do this.
Thanks for taking your time to read this.
You want to keep which sidebar goes on which page in a database, and then query that database for the correct sidebar to include.
A table structure may look like this:
Table sidebars: ID | path | name | more info on sidebar...
Table pages: ID | path | name | more info on page...
Table sidebars-to-pages: page_ID | sidebar_ID
This approach even allows you to place multiple sidebars on a specific page.
What if you did this?
<?php
ob_start();
$page = (isset($_GET['page'])) ? sanitize($_GET['page']) : 'home';
if (!include 'pages/'.$page.'.php') require 'pages/404.php';
$contents = ob_get_clean();
?>
<div id="content">
<div id="aside">
<?php include($aside); ?>
</div>
<div id="main">
<?php echo $contents; ?>
</div>
</div>
and $page.php would look like:
<?php $aside = "sidebars/default.php"; ?>
<p>HTML for #main<br />
goes here</p>
There are a few different ways to do this that are all more-or-less equal. I almost always use a config.php file for sites to hold whatever global information I want every page to have. At the top of every page, you just call
<?php
require_once('config.php');
?>
In that config.php file, you could have an array listing your page names and the file you want included for each page, as well as a function that returns the content, like so:
// this lets you call includes relative to the site root
set_include_path($_SERVER['DOCUMENT_ROOT']);
$defaultAsideContent = 'includes/default.php';
$asideContent = array(
'index.php' => 'includes/include-1.php',
'document.php' => 'includes/include-2.php'
);
function getAsideContent() {
global $asideContent;
global $defaultAsideContent;
$content = $defaultAsideContent;
// get the requested page
$pageFull = $_SERVER['REQUEST_URI'];
// strip URL variables
$pageParts = explode('?', $pageFull);
$page = $pageParts[0];
// loop throught the array and see if there is specific aside content for the page
foreach($asideContent as $key=>$value) {
if ($page == $key) {
$content = $asideContent[$key]);
}
}
include($content);
}
Lastly, wherever you want your aside content to show up, just do
<?php getAsideContent(); ?>
When you create a new page, if you want specific aside content, just edit your config file. Just FYI, didn't test this at all, probably has bugs, but you get the jist.
Thank you all for your answers and collaboration. Although none of the answers did exactly what I was looking for, they showed me other ways to approach this issue and guided me to decide what method to use.
I came up with what I think is the simpliest way to do this:
I set my folder structure as: pages/aside and pages/main
I set up an array($asides) with the aside files as the keys and the main content files as the values.
Then I check if the requested file exists in the main folder.
If it doesn't exist, I redirect the user to the 404 page. If it does exist, I loop through $asides to see which aside is asigned to that main content page.
If it doesn't belong to any of the establisged asides, then I include the default aside.
$asides = array(
'aside1' => array('page1', 'page2', 'page3', 'page4'),
'aside2' => array('page5', 'page6')
);
$page = (!empty($_GET['p'])) ? sanitize($_GET['p']) : 'page1';
if (file_exists("pages/main/{$page}.php")) {
foreach ($asides as $key => $value) {
if (in_array($page, $asides[$key])) {
$aside = $key;
break;
}
}
if (!isset($aside)) $aside = 'default';
?>
<div id="aside"><?php require "pages/aside/{$aside}.php"; ?></div>
<div id="main"><?php require "pages/main/{$page}.php"; ?></div>
<?php
} else {
header('Location: ?p=404');
}
The bounty goes to Madara Uchiha because in my opinion, his answer is simple an effective. Thanks again to all of you who helped me with this issue.
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...
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;
?>