I need to generate a table (HTML/CSS) with 4 cells inside (think 4 boxes one on top of another).
I have two questions-
How can i fix the width and height of each box (they may all have different heights) without no scroll bars if text overflows. If text does overflow, the cell height (& width) must stay same size and hide any overflowing text.
Using PHP (No frameworks) I populate these 4 cells with 4 different strings in a database. How can I assign
the text to each one of the 4 cells? e.g. $string[1] does into cell#1, $string[2] goes into cell#2 etc.
Thankyou.
Here is HTML/PHP that generates the table (in a calandar)
<table width="700" border="0" align="center" cellpadding="0" cellspacing="0" bgcolor="#000000"> '
<tr>'
<td><table width="100%" border="0" cellpadding="0" cellspacing="1">'
for ($i = 1; $i <= $days_in_month; $i++) {'
echo "<td width=\"100\" height=\"100\" class=\"$class\">\n";
echo "<div align=\"right\"><span class=\"daynumber\">$i</span></div>\n";'
// keep count of cells across row, and if=7 end the row and start again '
}'
etc. (My calendar code works well, unlike my futile attempts to format my code here)
I store "events" in a mySql db, and when i=date in db, I output the text. The complex bit is trying to put 4 different event "data" into their corresponding boxes (see Q2 above).
to fix the width and height and to stop overflowing you can use css class.
.something{
width: 200px;
height : 100px;
overflow : hidden;
}
and also you can limit the text length using php substr() function
$limitedText = substr($yourstring, 0, 100);
to do this you have to use a foreach or while loop
foreach($queryResult as $rs){
echo "$rs['stringOne']";
echo "$rs['stringTwo']";
echo "$rs['stringThree']";
echo "$rs['stringFour']";
}
How to remove table's attributes like height, border-spacing and style="";
<table style="border-collapse: collapse" border="0" bordercolor="#000000" cellpadding="3" cellspacing="0" height="80" width="95%">
to this -->
<table>
strip_tags works for ripping tags off, but what about preg_replace?
FYI: loading stuff from database and it has all these weird styling and I want to get rid of them.
If you really want to use preg_replace, this is the way to go, but keep in mind that preg_replace isn't reliable
$output = preg_replace('/(<[^>]+) style=".*?"/i', '$1', $html);
I recommend you to use php DOM that exists for this kind of operation :
// load HTML into a new DOMDocument
$dom = new DOMDocument;
$dom->loadHTML($html);
// Find style attribute with Xpath
$xpath = new DOMXPath($dom);
$styleNodes = $xpath->query('//*[#style]');
// Iterate over nodes and remove style attributes
foreach ($styleNodes as $styleNode) {
$styleNode->removeAttribute('style');
}
// Save the clean HTML into $output
$output = $dom->saveHTML();
I have a very weird issue with table cell.
My previous post
How to append element to another element using php
My code is like the following
$dom = new DomDocument();
$dom->loadHTML($html]);
$tbodies = $dom->getElementsByTagName('tbody');
foreach ($tbodies as $tbody) {
$table = $dom->createElement('table');
$table->setAttribute('width',500);
$table->setAttribute('style','border:2px solid #8C8C8C;text-align:center;table-layout:fixed; border-collapse:separate;');
$tbody->parentNode->replaceChild($table, $tbody);
$table->appendChild($tbody);
}
$returnText .=$dom->saveHTML();
From my previous pose, I got my answer but it seems like the new html table doesn't have border in the table cell.
So my table like
___________
|cell cell |
|cell cell |
|___________|
but I want every cell has border.
I am sure my original html table cell has no inline style addressing cell border too.
Can anyone helps?
Thanks!
There is no border on the cells because in css the table tag is styled separately from the cells td or th tag. See here: http://www.quackit.com/html/codes/tables/html_table_border.cfm
edit: Better link.
I have never used domdocument but i see this line :
$table->setAttribute('style','border:2px solid #8C8C8C;text-align:center;table-layout:fixed; border-collapse:separate;');
Instead of adding style attribute that will stylish your table and not td cells , try to add a class for your table that will stylish both table and cells :
$table->setAttribute('class','test');
and add a css file or a style that containts your class :
<style type='text/css'>
.test{
border:2px solid #8C8C8C;
text-align:center;
table-layout:fixed;
border-collapse:separate;
}
.test th,.test td{border:2px solid #8C8C8C;}
</style>
I am writing a simple HTML email design editor in PHP and also show a demo of how this will look.
I think it would also be very useful to show the user how this will look in an email client such as gmail with images turned off.
What is my best approach for this? Anybody know how this is done in gmail/hotmail etc?
Do I simple remove img -> src and css background: url with a reg expression?
I would like to remove the background parts from:
background="url" used in tables and
background-image:url(url); used inline css
I found this question which has the same kind of idea, although I would like to actually remove the img and backrgound-images from the HTML text.
Or could this code be modified to work with background images also?
I would also suggest using PHP DOM instead of regex, which are often inaccurate. Here is an example code you could use to strip all the img tags and all the background attributes from your string:
// ...loading the DOM
$dom = new DOMDocument();
#$dom->loadHTML($string); // Using # to hide any parse warning sometimes resulting from markup errors
$dom->preserveWhiteSpace = false;
// Here we strip all the img tags in the document
$images = $dom->getElementsByTagName('img');
$imgs = array();
foreach($images as $img) {
$imgs[] = $img;
}
foreach($imgs as $img) {
$img->parentNode->removeChild($img);
}
// This part strips all 'background' attribute in (all) the body tag(s)
$bodies = $dom->getElementsByTagName('body');
$bodybg = array();
foreach($bodies as $bg) {
$bodybg[] = $bg;
}
foreach($bodybg as $bg) {
$bg->removeAttribute('background');
}
$str = $dom->saveHTML();
I've selected the body tags instead of the table, as the <table> itself doesn't have a background attribute, it only has bgcolor.
To strip the background inline css property, you can use the sabberworm's PHP CSS Parser
to parse the CSS retrieved from the DOM: try this
// Selecting all the elements since each one could have a style attribute
$alltags = $dom->getElementsByTagName('*');
$tags = array();
foreach($alltags as $tag) {
$tags[] = $tag;
} $css = array();
foreach($tags as &$tag) {
$oParser = new CSSParser("p{".$tag->getAttribute('style')."}");
$oCss = $oParser->parse();
foreach($oCss->getAllRuleSets() as $oRuleSet) {
$oRuleSet->removeRule('background');
$oRuleSet->removeRule('background-image');
}
$css = $oCss->__toString();
$css = substr_replace($css, '', 0, 3);
$css = substr_replace($css, '', -2, 2);
if($css)
$tag->setAttribute('style', $css);
}
Using all this code togheter, for example if you have a
$string = '<!DOCTYPE html>
<html><body background="http://yo.ur/background/dot/com" etc="an attribute value">
<img src="http://your.pa/th/to/image"><img src="http://anoth.er/path/to/image">
<div style="background-image:url(http://inli.ne/css/background);border: 1px solid black">div content...</div>
<div style="background:url(http://inli.ne/css/background);border: 1px solid black">2nd div content...</div>
</body></html>';
The PHP will output
<!DOCTYPE html>
<html><body etc="an attribute value">
<div style="border: 1px solid black;">div content...</div>
<div style="border: 1px solid black;">2nd div content...</div>
</body></html>
In order to fully mimic the behavior of gmail or similar web mails would be to replace the tags, and background: css attributes accordingly so that they display a placeholder, making clear to the user that here lies an image.
Since usually the message is being loaded in an iframe I believe that your best guess, would be to clean the message server side removing all unwanted tags and replacing images accordingly on preview.
I will agree with Michal that it is not wise to use just regex to validate your HTML and you probably should traverse the DOM tree just to be safe.
Why don't you take a look at washtml by Frederic Motte used by roundcube to get you started?
Using regular expressions to parse html is usually not recommended.
I think a better approach would be to parse the html server-side, and manipulate it to remove the images or the image src attributes. A library I've had success with is http://simplehtmldom.sourceforge.net/, but I think you can use official PHP DOM extensions.
The removal of background images might be more tricky. You might have to use something like http://www.pelagodesign.com/sidecar/emogrifier/ to apply something like {background: none} to the html elements. However, CSS background images are not supported in the latest versions of Microsoft Outlook, so I would recommend not using them at all from the get-go in order to have the emails to be consistent for most email clients.
Like tkone mentioned: perhaps JavaScript / jQuery is the answer.
This will look at all images in your preview area and change the source to a placeholder image. The 'placeholder' class sets the background image to the placeholder as well
jQuery
$("#previewArea img").each(function(){
$(this).attr("src","placeholder.jpg");
$(this).addClass("hideBG");
});
CSS
.hideBG{
background: url("placeholder.jpg");
}
Not tested, but should work - depending on your setup and needs.
I've asked a similar question (in solution, not actual problem): How to strip specific tags and specific attributes from a string? (Solution)
It's a server side library which cleans (and formats) HTML input according to predefined settings. Have it remove any src attributes and all background properties.
You could always do this on the client end as well.
Using this hypothetical code, you should be able to do something like this, pretending that modern browsers all work the same: (or use jQuery or something)
var email;
var xhr = new XMLHttpRequest();
xhr.open('GET', URL_FOR_EMAIL, true);
xhr.onreadystatechange = function(event){
if(xhr.readyState === 4 && xhr.status === 200){
email = HTMLParser(xhr.responseText);
}
}
var imgs = email.getElementsByTagName('img');
for(var i = 0; i > imgs.length; i++){
email.removeChild(imgs[i]);
}
// attach the email body to the DOM
// do something with the images
HTMLParser from MDN
function HTMLParser(aHTMLString){
var html = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", null),
body = document.createElementNS("http://www.w3.org/1999/xhtml", "body");
html.documentElement.appendChild(body);
body.appendChild(Components.classes["#mozilla.org/feed-unescapehtml;1"]
.getService(Components.interfaces.nsIScriptableUnescapeHTML)
.parseFragment(aHTMLString, false, null, body));
return body;
},
I think that the best way to do it and keep the change reversible its using a tag who not process the "src" attribute.
Ex: Change all the "img" with "br"
So print the filtered HTML 1st and reverse it with ajax, search for all the br with a src attribute.
I create this code until now:
<?php
$url=" SOME HTML URL ";
$html = file_get_contents($url);
$doc = new DOMDocument();
#$doc->loadHTML($html);
$tags = $doc->getElementsByTagName('a');
foreach ($tags as $tag) {
echo $tag->getAttribute('href');
}
?>
I have html pages with tables so i want the link the title and the date. Example of html code:
<TR>
<TD align="center" vAlign="top" bgColor="#ffffff" class="smalltext">3</TD>
<TD class="plaintext" >THIS IS THE TITLE </TD>
<TD align="center" class="plaintext" >THIS IS DATE</TD>
</TR>
It works fine for me for the link, but i don't know how to take the others.
Tnx.
Where you are doing this:
$tags = $doc->getElementsByTagName('a');
You are getting back all the A tags. There only happens to be one.
If you want to get the text "THIS IS DATE", you're aren't going to get it by looking in A tags because the text is not inside an A tag - it is in a TD tag.
$tds = $doc->getElementsByTagName('td');
... would work to get all the TD elements, or you could assign an ID to the element you want to target and use getElementById instead.
Basically, though, this information is all in the documentation, which you absolutely should read before asking questions. Happy reading!
Once again, that's: http://php.net/manual/en/class.domdocument.php