HTML attributes and PHP - where to draw the line between conflicting principles - php

I have an HTML file which contains two tabs like this (besides lots of other stuff):
<div id="tabs">
<div id="tab1" class="">Tab 1</div>
<div id="tab2" class="">Tab 2</div>
</div>
This HTML file is used in several contexts, so it seems reasonable to have one single HTML file that I include with PHP in order not to violate the Don't Repeat Yourself principle.
Depending on various conditions these tabs need to have different classes when the page loads. This is achieved through PHP, either
$tab1Class = 'active';
$tab2Class = 'inactive';
or
$tab1Class = 'inactive';
$tab2Class = 'active';
with this mixed HTML and PHP:
<div id="tabs">
<div id="tab1" class="<?php echo $tab1Class;?>">Tab 1</div>
<div id="tab2" class="<?php echo $tab2Class;?>">Tab 2</div>
</div>
My question is what would be considered best practice when having to balance between repeating code or inserting PHP into the HTML file - how much repetition is ok and how deep into the HTML is it ok to bury PHP snippets?
Is, for example, the following degree of separation better? The PHP isn't as deeply buried into the HTML here, but there's more code that I have to repeat in the PHP file(s) in order to generate the div elements every time.
<div id="tabs">
<?php echo $tabs;?>
</div>
I understand that one possible answer is that this is something that has to be decided for each case individually, but if there are any principles that are more or less generally accepted it would be nice to hear about them.

IMHO first approach where you print just css classes is better. If you want to bring this to new level consider using some template engine, like Smarty or Twig. That way you can totally distinct your logic (code) from your presentation.

Related

Clean HTML Sourcecode with PHP

i'm looking for a way to keep my HTML code output via PHP clean.
If you look into the source code, the result looks like this:
<section><div class="card">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in</p>
Go somewhere </div>
</div>
</section><section><div class="card">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in content.</p>
Go somewhere </div>
</div></section>
I want it to look like this:
<section>
<div class="card">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in</p>
Go somewhere </div>
</div>
</section>
<section>
<div class="card">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in</p>
Go somewhere </div>
</div>
</section>
this is my php output code:
ob_start();
include_once ROOT.'/global/header.php';
print $content_output; // the included files
include_once ROOT.'/global/footer.php';
$output = ob_get_contents();
ob_end_clean();
echo $output;
The reason for this is that I am building a scaffold where blocks are created for a website. For example the start page consists of block2, block7, block1 and block5. At the end the customer gets a clean HTML, which consists of the above mentioned blocks.
If your PHP fully renders the HTML, why would you want it to look good? It is not like any other developer is going to look inside the compiled HTML, right?
The browser does not care how your HTML is formatted, if it is valid HTML, it is valid HTML. This should also not affect the SEO of your webpage.
In the case you are manually writing HTML in PHP code. You should avoid echoing full HTML strings. You can do this by using as much inline PHP as you can. For example:
<?php if(//Statement): ?>
<h1><?= $test ?></h1>
<?php endif; ?>
This way you know PHP is not going to affect the indentation of the markup.
You can use DOMDocument to process & format HTML. DOMDocument is tough to use & much of it could use better documentation.
If all you want to do is pretty print the html, something like this should do what you need:
$html = '<div>Happy Coding todayyy</div>';
$doc = new \DOMDocument($html);
$doc->formatOutput = true;
$cleanHtml = $doc->saveHTML();
You could also look for an html beautifier, but it doesn't look like there's any particularly mature projects for that.
I also want to add that running DOMDocument on every single request to format html adds additional overhead. More cpu cycles means more energy, so something to be mindful of. You probably won't see any real change in script execution time though.
Some existing projects that might make DOM work easier for you. Things to maybe try if DOMDocument doesn't do quite what you want (I'm not 100% sure the code above will do the trick, nor do I know if any of these repos can definitely solve your problem):
Voku's port of simple_html_dom <- simple_html_dom has been around for awhile. Haven't tried Voku's port, but his repos that I've reviewed are usually very good quality.
A DomDocument extension by ivopetkov <- I think this one is the most mature
Another option by scotteh <- Don't know anything about it
A DomDocument extension by me. Stable, small but nice feature set

PHP and HTML: Nested foreach loops with HTML interspersed

I'm trying to put together a layout of items with an Accordion layout (from Bootstrap). In order to fill the accordions, I reach into a pgsql db to gather the data, and I'm able to retrieve this data.
What I'm having issues with is getting the data to show up at all. Right now I'm getting an HTML 500. It might be a layout issue or it might be a PHP interpretation issue (maybe out of depth? or something not visible to PHP), but I'm having issues determining which is the culprit.
I say this because I have a fairly complicated arrangement I'm attempting to make.
A sample:
<?php
// db connection info goes here
// pgsql query info goes here
$i = 0;
$result = pg_fetch_all($getData);
?>
<!-- Starting the container accordion -->
<div class="panel-group" id="main-accordion">
<?php
foreach($result as $row):
$title1 = $row['title1'];
$title2 = $row['title2'];
?>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#main-accordion" href="#<?=$row['id']?>">
(<?=$row['category']?>) <?=$title1?> - <?=$title2?>
</a>
</h4>
</div>
<div id="<?=$row['id']?>" class="panel-collapse collapse">
<!-- The body of the accordion, contents go here. -->
<div class="panel-body">
<?php
// another pgsql query here
$newresult = pg_fetch_all($newgetData);
?>
<!-- In the accordion body, a new group of accordions. This is doable if hardcoded -->
<div class="panel-group" id="sub-accordion-<?=$i?>">
<?php
// I think this is where the issues start??
foreach($newresult as $newrow):
$subtitle = $newrow['subtitle'];
?>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a data toggle="collapse" data-parent="#sub-accordion" href="#<?=$newrow['subid']?>">
<?=$subtitle?>
</a>
</h4>
</div>
<div id="<?=$newrow['subid']?>" class="panel-collapse panel">
<div class="panel-body">
<!-- contents go here -->
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<?php
$i++;
endforeach; ?>
</div>
</div>
So, now my questions for the web dev people with HTML PHP and Bootstrap exp.:
Is it possible to nest foreach loops in this fashion without falling back to echo statements to print out the HTML (because ew)? Will it actually create (repeat) the HTML for the accordion objects this way or do I need to modify something here?
What might be triggering the HTML 500?
I realize this is a tough question to answer without live working code to mess with. If anyone knows a good resource to quickly sandbox a full stack for demo purposes I would be glad to know of it so I can put up some "working" code.
EDIT 1: User Sean pointed out that the sub-accordion is in a loop. Added in an iterator that modifies this id as the goal is to have multiple sub-accordions, not with the same id.
EDIT 2: Might have solved my own questions:
1. Turns out I used the wrong method when retrieving the ajax request: used PHP's $_POST['var'] instead of $_GET['var']
2. There was one syntax error on one of my shorthand PHP tags.
Now things are showing up! But, the formatting is still wrong. I can deal with that. Thank you all for all your help!
In your PHP.ini short tags might be turned off. In that case you either turned on or if you have no access to PHP.ini, then you should not use short echo tags `, try changing it to

php include only part of an external page not all of it

using php's include is possible to include part of another page without including all that entire content of that page?
From pageX.php i want Div #A not div #B the whole pageX.php
<div id="A">
<p>Don't show me</p>
</div>
<div id="B">
<p>Display Me</p>
</div>
i'm aware of JQuery's ajax Load but im wondering if there's a method like that in php.
I am not aware of any function that can include a specific part of a php file but typically this can be achieved in two ways.
Split your UI component markups into separate files so that can be included separately and easily re-used in many places. (example here)
Have all the UI components markups as different functions in a common file which can be called easily.
function printDivA() {
echo <<< DIV_A
<div id="A">
<p>Don't show me</p>
</div>
DIV_A;
}

Getting unstyled text using QueryPath in PHP

I'm just getting to grips with QueryPath after using HTML Simple Dom for quite some time and am finding that the QP documentation doesn't seem to offer much in the way of examples for all of its functions.
At the moment I'm trying to retrieve some text from a HTML doc that doesn't make much use of ID's or Classes, so I'm a little outside of my comfort zone.
Here's the HTML:
<div class="blue-box">
<div class="top">
<h2><img src="pic.gif" alt="Advertise"></h2>
<p>Some uninteresting stuff</p>
<p>More stuff</p>
</div>
</div>
<div class="blue-box">
<div class="top">
<h2><img src="pic2.gif" alt="Location"></h2>
**I NEED THIS TEXT**
<div style="margin:stuff">
<img src="img3.gif">
</div>
</div>
</div>
I was thinking about selecting the class 'box-blue' as the starting point and then descending from there. The issue is that there could be any number of box-blue classes in the HTML doc.
Therefore I was thinking that maybe I should try to select the image with alt="Location" and then use ->next()->text() or something along those lines?
I've tried about 15 variations os far and none are getting the text I need.
Assistance most appreciated!
Can you have a look to this example http://jsfiddle.net/Pedro3M/mujtk/
I made like you said using the alt attribute, if you confirm if this is always unique
$("img[alt='Location']").parent().parent().text();
How about:
$doc->find('div.top:has(img[alt="Location"])')->text();

Dynamic data in header in a symfony project

I have a Symfony 1.4 project. As you know the Template layout is defined independently, in the apps' templates' folder and then it is universally applied to all other templates. My layout is very simple, something like this:
<div id = "header">
</div>
<div id = "content">
<?php echo $sf_content ; ?>
</div>
<div id = "footer">
</div>
$sf_content, as most symfonians would know, essentially spits out the template for whatever web page is being viewed at the moment. If I needed some specific data for my header, such as logout, logo etc, I would simply include it within my header. THis works great because it is static in nature. The challenge I am facing is how I can include data that is dynamic in nature and specific to a page within the header tag because the UI demands that I include it there.
For instance, one of my webpages requires user specific data to be loaded in a dropdown/select menu. This is dynamic and could range from 0 to 100 and is specific to each user. To create this dropdown menu is not an issue, and I already have that part done. The challenge is, how do I load it in the header, given that my data becomes part of $sf_content and that is spit out in my content div.
Is there a way for me to move a specific part of my $sf_content into the header div ?
In your actions.php:
$this->getResponse()->setSlot('someData', 'and its value');
In layout.php:
<div id="header">
<?php echo get_slot('someData'); ?>
</div>
<div id="content">
<?php echo $sf_content ; ?>
</div>
<div id="footer">
</div>
Slots work for this. They can either be set in the action as in the first answer above or you can define them in the templates themselves. This is what I've done where I have dynamic data to define for the layout.
In your example:
<div id="header">
<?php include_slot('some slot name')?>
</div>
<div id="content">
<?php echo $sf_content() ?>
</div>
<div id="footer">
</div>
In the templates you would define the following:
<?php slot('some slot name')?>
//your code goes here
<?php end_slot() ?>
When the layout is then rendered Symfony will place the code between the slot() and end_slot() into the point at which you defined by using include_slot().
For ease I created a global partial that is included in all templates that defines the various common slots used through out the application. There is more info on slots and their usage here

Categories