Hi,
I'm currently using jQuery to hide the empty <ul> and <li> onload.
Could it be done with PHP on the server-side?
1. Remove <li></li> that does not contain any text.
2. Remove <ul></ul> that does not contain any <li></li>.
Thanks.
Printable View
Hi,
I'm currently using jQuery to hide the empty <ul> and <li> onload.
Could it be done with PHP on the server-side?
1. Remove <li></li> that does not contain any text.
2. Remove <ul></ul> that does not contain any <li></li>.
Thanks.
how are the empty <ul>/<li>'s being generated? It would probably be simpler to just not write them in in the first place, but yes, they could be removed via php.
Hi Trag,
Thanks for your reply.
The <ul></ul> and <li></li> are hard-coded into the template and the content are generated dynamically by PHP and I do not wish to modify the original PHP source code.
Therefore, my option is to write my own PHP or Javascript to affect the HTML layout (<ul> and <li>).
I have done it easily with jQuery but with nearly 200 fields/<li></li> breaking into multiple <ul></ul>, it's really too heavy to process on the clients browser, furthermore with JavaScript turned off on the client's browser, it looked absolutely ugly.
Example:
<ul>
<li>{field1_value_tag}</li>
<li>{field2_value_tag}</li>
<li>{field3_value_tag}</li>
<li>{field4_value_tag}</li>
<li>{field5_value_tag}</li>
</ul>
Could you kindly tell me how it could be done with an example code so that I may take cue from?
Thanks.
Well, this is very simple if things don't get unpredicable.
1. Remove the string <li></li>... remove empty list items: but remember, this won't work if there are properties or anything like that.PHP Code:$html = 'your html here';
$html = str_replace('<li></li>','',$html);
$html = str_replace('<ul></ul>','',$html);
2. Remove the string <ul></ul>... remove empty lists: but again, this won't work if the string is not an exact match.
If you require this to work when there may be other properties like <ul class="....">, then you should probably try using Regex. It's very possible to do it, but regex is hard at first so find a good tutorial and see what you can work out. (I don't know Regex well enough to write this for you easily.)
Hi djr33,
Thanks!
You have provided a very good example which I could start with :)
I have read up on using Regex before I post here and most people won't recommend using Regex to manipulate HTML Elements as the result can be unpredictable.
Three questions to your reply:
1) Where must this code reside? In the PHP Include file or in the HTML template itself?
2) The first line of your sample code "$html = 'your html here';", what does it do?
3) In layman's terms, how does each line of code functions?
Thanks.
$htmlis your html code (about to be output to the browser - SO, where you put this code will depend partly on how your template is organized).
The str_replace functions look for empty tags and replace them with nothing (i.e., removes them). If the empty tags have anything between them (like the {field1_value_tag} you mentioned above, or even just a space), then this won't work.
regex is only "unpredictable" when you don't plan it out very well, or if you don't know how to build the expressions properly. I fall into the latter category, so I'm afraid I couldn't be of much help, but regex would be a good solution if djr's solution doesn't work. You should look into it.
Since those are such broad questions and a general part of using PHP, I recommend that you do a bit of background reading on the language and about how it can be implemented.
Regex is complex so I suppose "unpredictable", but if written correctly it is the only real way to do complex operations on variable pattern matching. It's easy enough to search for "123", but much harder to search for "1#3" where # is any number, or anything else like that. Regex is very powerful (and very hard to use).Quote:
I have read up on using Regex before I post here and most people won't recommend using Regex to manipulate HTML Elements as the result can be unpredictable.
It's certainly unpredictable if you don't use it well, but it's the right way to do it if you can do it well (it takes time, testing and patience).
As Traq says, it's worth looking into, but be careful as you do so.
Regex takes several complex string functions and makes them into one. While regex can be hard, the layering of string functions needed to imitate it can get longer and harder to read to the point where regex is easier.
1) It must be in a PHP file, but any will do. It must be after $html is set as your html and before $html is output to the browser. This is NOT an automated system for parsing a .htm file, but for parsing text in a variable. If you want to parse a whole file you could just do$html = file_get_contents('path/filename.htm');, then parse as above, and finallyecho $html;and that would work for a file-parsing-serving php page that does nothing more.
2) That's just an example, see traq's post above.
3) str_replace($search,$replace,$input); str_replace('2','@','123') => 1@3
This is a simple DIRECT matching method, unlike regex methods (used by preg_replace() and other functions in php) that can use variable matching.
Out of curiosity how are you using Javascript now to remove these elements? Can't you just apply the same logic on the server? (Different function names, but probably similar options, though it depends on how you are approaching the situation.)
--
Another way to approach this would be to try to parse the html as some sort of "html object". There are some built in xml functions in php and these can parse any sort of xml (including xhtml) into an array you can work with. So if you took your html and did that, you could simply remove any 'li' index that was empty and any 'ul' that is then empty. That would be a little more human-friendly, but it would be a lot slower to parse the whole page like that if you don't have to.
It would also require that your html has no errors or it could give unexpected results. If the text is user generated for example, that would be a little risky.
Thanks to traq and djr33 :)
Very much appreciate both of you for taking the time to explain to me in details.
I'll give it a try taking cue from the sample code traq provided and may consider using Regex too.
Again, Thanks!
Note: if I remember correctly, I may have read a tutorial by djr33 somewhere (Googled it) regarding Regex which was very helpful. Glad to meet you here. ;)
To djr33,
Currently I'm using jQuery in the following method:
Javascript:
HTML:Code:$(document).ready(function(){
$('ul').find('li').each(function (){
if ($.trim($(this).text()) == ""){
$(this).remove();
}
})
$('div.sample').find('ul').each(function (){
if ($.trim($(this).text()) == ""){
$(this).remove();
}
})
}
More info: I'm using Open-Realty Real Estate Listing Software to build the website - http://www.open-realty.orgCode:<div class="sample">
<ul id="ul-1">
<li>{field1_value_from_database}</li>
<li>{field2_value_from_database}</li>
<li>{field3_value_from_database}</li>
</ul>
<ul id="ul-2">
<li>{field4_value_from_database}</li>
<li>{field5_value_from_database}</li>
<li>{field6_value_from_database}</li>
</ul>
</div>
The website I'm working on:
http://www.chiangmaibesthome.com
and the page I'm using the code above is at
http://www.chiangmaibesthome.com/ind...ew&listingID=1
Try turning off the Javascript on your browser and you'll see how ugly it is :P
I could have easily done it if I were to modify the original PHP source code include file, but this isn't an option as I want to be able to update the software.
The template files are written in HTML file format while the tags are process by PHP in the backend.
What I'm trying to do now is to write a PHP function as an Addon to manipulate the HTML elements as if I were to use PHP conditional function based on the output of the tags to display the HTML elements would require modification to the original PHP source code.
I see. That's a much easier method because Javascript can operate on the page as an object, not just a long string of text. So the short answer to your original question is that you cannot do it "like you do with Jquery" because PHP would just have text and then have to parse it, rather than just removing components.
Using a method like I posted above is possible, but it can get confusing (because you have to figure out the parsing yourself), and the other option that would closely imitate Javascript would be to read the whole page as html (using xml functions), but that would make every page load slower since it's not otherwise needed. That would, however, allow you to do the same thing by removing elements as elements rather than just text within text.
Regarding the page specifically, that is more complex than a truly empty li and a truly empty ul.
Here is the code:1. Each element has a class, so this needs to be ignored while parsing and searching and not stop it from finding it as empty.Code:<ul id="ul_topleft4">
<!-- Hardcoded top_left4 listing details starts here -->
<li class="multi_caption"><span class="multi_caption_header">Building #1 -> Main House -> 2nd Floor -></span></li>
<li><span class="field_caption">Bedroom #3</span><span class="field_value"> </span></li>
<li><span class="field_caption">Bedroom #4</span><span class="field_value"> </span></li>
<li><span class="field_caption">Bedroom #5</span><span class="field_value"> </span></li>
<li><span class="field_caption">Balcony #1</span><span class="field_value"> </span></li>
<li><span class="field_caption">Balcony #2</span><span class="field_value"> </span></li>
<li><span class="field_caption">Bathroom #3</span><span class="field_value"> </span></li>
<li><span class="field_caption">Bathroom #4</span><span class="field_value"> </span></li>
<li><span class="field_caption"></span><span class="field_value"> </span></li>
<li><span class="field_caption"></span><span class="field_value"> </span></li>
<li><span class="field_caption"></span><span class="field_value"> </span></li>
<li><span class="field_caption"></span><span class="field_value"> </span></li>
<li><span class="field_caption"></span><span class="field_value"> </span></li>
<li><span class="field_caption"></span><span class="field_value"> </span></li>
<li><span class="field_caption"></span><span class="field_value"> </span></li>
<li><span class="field_caption"></span><span class="field_value"> </span></li>
<!-- Hardcoded top_left4 listing details ends here -->
</ul>
2. Since this is not a script meant to work for any website, but only for this very specific page, you can just make a list in PHP of what to remove and it can parse that for you. So it won't be a portable script, but it will solve your problem.
3. The biggest problem in this is the comments. While they are ignored by the browser, when PHP reads the file as a string (just a block of text) they will be just as 'important' as any of the actual html elements.
So, without using regex (which may be the best option here), I would recommend:
1. Remove all comments from the page. You can do this with a somewhat complex string functions operation, but it won't be that bad. Find every <!-- that is before a --> and then remove that entire string. This would be easier using regex, but possible with string functions alone (it would take about 5 layers, but that's not awful...).
2. Now search and replace " <li><span class="field_caption">Bedroom #5</span><span class="field_value"> </span></li>
" with an empty string ("") so that it goes away.
3. Now you are left with "empty" UL's that only have whitespace in them. I'm not sure about the best method to remove that whitespace, but it would be possible to deal with it, though again regex would be easier.
The main reason this is complex is because you need to put an extra layer on top of the coding. You need to NOT output anything in the browser and instead store it in a variable. There are two ways to do this:
1. You can just directly store things in a variable, like doing $html .= "...more text"; for every entry (the .= means 'add to current string').
But since that means recoding the entire site to not output but instead store as a variable, you may have to:
2. Use an output buffer. This is a high level function that will prevent EVERYTHING from being output to the browser and instead it will store it in memory. Then once you end the output buffer you can get the contents of what would have been output. Then just store that in a variable, parse it (stripping empty lists), and then finally output all of that text.
Info on the basics is available here:
http://www.php.net/manual/en/function.ob-start.php
Working with output buffers is usually a bad idea (because there is almost always a "right" way to do it that doesn't involve hijacking the entire processing sequence), but in cases like this where you don't want to modify a script in the middle, they can be the only way.
The easiest answer to all of this is to just modify the script. It is not hard at all to just have a conditional statement of roughly the form if(!empty) { do output; } for those ULs and LIs in the first place. Whoever coded the underlying PHP you are using made a mistake not doing that (because, yes, if Javascript is turned off, the page looks really messy).
The only problems in changing it are that you must find where this operation actually occurs (which can be annoying, but possible for someone who knows their way around PHP), and that if it is "updateable" you can't update it to the next version without first altering that as well. (For example I'm working on a site right now using forum software that I have greatly modified and now I can't do the updates of that forum software because my code is too mixed into theirs, though I can if I manually alter their updated code as well... it just takes longer.)
Hi djr33,
I can't thank you enough for how much you have helped me regard this issue.
Even commercially paid advice is nothing comparable to your input in this issue.
Now I'll need to read and reread (for there are so much information in your two replies) your advice/recommendations above and really try out each method to see which works best.
I'm very grateful for your time and effort :)
Again...Thanks!
Hi,
Not making any progress at all... :(
Having came to the conclusion that every Field Value would have a Field Caption Value if there is any value, I decided to display or not display the <li></li> by validating whether the Field Caption Tag has a value or not.
Tried the followings:
Problem is, the $var string is still parsed as a Template Tag instead of the Field Caption Value from Database; therefore, it isn't an empty string.Code:<ul>
<?php
$var = '{field1_caption_tag}';
if ($var != "")
echo '<li>{field1_caption_tag}<span>{field1_value_tag}</span></li>';
?>
</ul>
By the time the output was displayed, only then the Template Tag is displayed as the Field Value from Database.
Hence, the above method does not work and neither using djr33's worked either; as both methods requires that the HTML elements needs to be validate as empty is order to manipulate the output.
I have attempted to use Regex and found it to be very very powerful but on second thought, this website uses 4 languages (English, Chinese, Japanese, Thai) and I think it would a major problem using Regex to validate characters of different languages :confused:
Stuck :(
In order to be able to make any further attempt, I have to resolve this problem first.
So far, I have attempted preg_match, str_replace and ob_start() function; but was unsuccessful due to one same problem, that it was unable to parse the empty HTML tags as an empty element because of the Field Tags in the HTML elements.
Example:
:confused:Code:$val = '{field1_caption_tag}';
// {field1_caption_tag} is the Field tag which was parsed in the backend
// by the original PHP include file and return the value from Database if any.
echo strlen($val);
// returns the length count of the Field Tag itself
// even if there is or isn't any value for this tag in the database.
// hence it couldn't be parsed as an empty element..
echo $val
// returns the correct value of this field from the database
// and would return blank if no value.
Last attempt, If I'm unable to understand why is it parsing the Field Tags as a string itself instead of the returned value of the field tag, then I'm back to using jQuery again :(
Any suggestions?
It's possible to do this using Regex, and even with different characters, but the pattern matching will get complex.
The easiest way to do this is to fix the original script, as I said before.
It is much harder to modify existing HTML than to just fix it in the first place.
If you want to try to modify the existing html, that's fine, but I think you'd be able to fix the original code faster-- all you have to do is find it and add an "if (!empty) {...." to the beginning of that section. ("!empty" meaning whatever you are checking is empty-- probably info from the database.)
Finally did it :o
Here is how I did it...in case it may be of interest to others.
I'm sure this isn't the best method...but it gets the job done :pCode:// Function to get the current page URL //
function curPageURL() {
$pageURL = 'http';
if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
}
// $curPageURL to call for the current URL string later //
$curPageURL = curPageURL();
// Get the referrer //
$curPageReferer = $_SERVER['HTTP_REFERER'];
// If referrer is from cURL, load the template source code //
if ($curPageReferer == "SpecificReferrerNameHere") {
echo '
// Code of the whole page goes here //
';
} else {
// If the referrer is not from cURL as specified //
// Start the buffer //
ob_start();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $curPageURL); // Load the current page into the buffer //
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_REFERER, "SpecificReferrerNameHere"); // Referrer must be the same as specified above //
$contents = curl_exec ($ch);
curl_close ($ch);
// Reason I load the current page is because the template tags wouldn't be parsed as it's original value until it's been output to the browser. Therefore, this is the only method I could get the output html source code and load it into the buffer to be modified further //
// include the Simple HTML DOM Parser Script //
// Can be found here -> http://simplehtmldom.sourceforge.net //
require('php/simple_html_dom.php');
// Get the data from cURL //
$data = str_get_html($contents)
// Get the specific Div from the data //
$html = $data->getElementById("listing_details_container");
// Use Simple HTML Dom parser to remove all the empty span, div, ul, li, etc. //
foreach($html->find('comment') as $comment){
$comment->outertext = '';
}
foreach($html->find('del') as $del){
if(Trim($del->innertext) == '') $del->outertext = '';
}
foreach($html->find('span span span') as $xxxspan){
if(Trim($xxxspan->innertext) == '') $xxxspan->outertext = '';
}
foreach($html->find('span span') as $xxspan){
if(Trim($xxspan->innertext) == '') $xxspan->outertext = '';
}
foreach($html->find('span') as $xspan){
if(Trim($xspan->innertext) == '') $xspan->outertext = '';
}
foreach($html->find('li') as $li){
if(Trim($li->innertext) == '') $li->outertext = '';
}
foreach($html->find('ul') as $ul){
if(Trim($ul->innertext) == '') $ul->parent->parent->outertext = '';
}
// Output the modified HTML //
echo $html;
ob_end_flush();
};
Hopefully there isn't any security implications :confused:
Again, a BIG THANKS to djr33 and traq for your precious input. ;)
Note: Becareful with the code above...if you happen to load the template source code while initiating cURL function to return the template source code at the same time would cause a permanent loop and would crash your server; crashed my dedicated server twice before I got it right :P