I have this page where a text might change, and each part has it's color.
I could have done it with PHP, but it kinda seemed like it's not practical.
I tried to read some javascript and jquery, thought they would help, but nothing.
so, is there a practical way to do this ?
here's my code:
index.php
<?php
$k=1;
if($k==0){
echo"<h class=client> Client </h>";
}
else if($k==1){
echo
"<h class=designer> Designer</h>" ;
}
else if($k==2){
echo
"<h class=developer> Developer</h>";
}
else if($k==3){
echo
"<h class=designer> Designer</h> & <h class=developer> Developer</h>";
}
?>
stylesheet.css:
.client {
color: blue;
}
.designer {
color: yellow;
}
.developer {
color: red;
}
so the output should be a a Blue "client" or Yellow "designer" or Red "developer", or a Yellow "designer" and a Black "&" and a Yellow "designer", depending on the k.
Classes are written in quotes.
Try:
<h class='developer'> Developer</h>
The use of javascript is overkill, you should probably just stick to a php only solution.
As I mentioned in the comments, you could alter your database design so that it compliments your application.
It's hard to say the best way to do this without knowing in detail the workings of you program - but as I mentioned, as an example you could store a more semantic value for $k (i.e. "client" or "designer" or "designer,developer"), or you could have 4 different booleans for each of your "titles" - but again the best way really depends on how you will need to interact with this information across the application as a whole.
A quick implementation for the first suggestion could look like this:
// $k = "designer,developer";
if (strpos($k, ',') !== FALSE){
$titles = explode(",",$k);
$output = "";
foreach($titles as $title){
$output .= "<h class='". $title ."'>". ucfirst($title) ."</h> & ";
}
echo rtrim($output, ' & ');
} else {
echo "<h class='". $k ."'>". ucfirst($k) ."</h>";
}
Related
I want to put a div around all images which are in the content section of a specific custom post type. I tried to stitch together some answeres to questions i found here. But since i don't know the syntacs that well, i don't know what i'am doing wrong. Maybe someone can help me.
Thanks in advance.
Hmm try this
add_filter("the_content", "my_content_modification");
function my_content_modification($content) {
$post_type = get_post_type();
$post_type_to_check = "MY_POST_TYPE";
if ($post_type == $post_type_to_check) {
$content = preg_replace('/<img(.*?)>/', '<div class="my-div"><img$1/></div>', $content);
}
return $content;
}
I just added the class for the img if somebody needs it in there as well. Thank you again Jordan Carter.
add_filter("the_content", "my_content_modification");
function my_content_modification($content) {
$post_type = get_post_type();
$post_type_to_check = "MY_POST_TYPE";
if ($post_type == $post_type_to_check) {
$content = preg_replace('/<img(.*?)>/', '<div class="MY_DIV"><img class="MY_IMG" $1/></div>', $content);
}
return $content;
}
I'm having an issue with a PHP page that generates an HTML document. On the page, there is a form that has a <select> box, and each <option> inside has a value with the URL parameters to use when changing the window location when the form is "submitted". The issue is that I noticed is that one of the parameters is a name, and when that name has a space in it, it breaks the window location because the space remains in the URL.
I've tried simply doing a str_replace() on the string before it generates the <option> tag, and when I view the <option> in Firefox' inspector, it DOES contain a %20 instead of a space, but when I look at the URL bar after clicking the <option>, it still retains the space instead of the %20. Can anyone tell me what's wrong with the following snippet?
print("<form name=sel1>");
print("<select size=10 style='width:200;font-family:courier,monospace;
font-weight:bold;color:black;' ");
print("onchange=\"location = this.options[this.selectedIndex].value;\">");
for($i = 0; $i < count($allGroups); $i++)
{
print("<option value='groups.php?action=");
if($advancedPermissions)
{
if($modGroups)
{
print("edit");
}
else
{
print("view");
}
}
else
{
print("edit");
}
print("&group_id=");
print(str_replace(" ", "%20", $allGroups[$i][0])."'>");
print($allGroups[$i][0]);
if($allGroups[$i][2] != 'Y')
{
print(" - inactive");
}
}
print("</select></form>");
The relevant lines are the line with location = and the line just after the group_id parameter is added, where the str_replace() is done.
I do the str_replace() on just the value, not the display text, so it will show normally to the user, but contain the %20 character for when it is passed to the window location, but regardless, it either ignores it, or something else is happening I am not aware of.
This code is a whole mess of bad practices. First, separation of code (PHP) and presentation (HTML) is essential for making sense of things. You should be doing logic in a separate code block at the very least, if not a separate file. Definitely not in the middle of an HTML element. Exiting PHP and using alternative syntax and short echo tags make this separation much clearer.
You should be building HTTP query strings using the http_build_query() function, which will handle escaping issues like the one you're having, and you should always escape HTML for output using htmlspecialchars().
print is not commonly used, but note that it's a language construct and not a function. Parentheses are not needed, and rarely used.
Inline CSS and JavaScript declarations are very 20th century and should be avoided wherever possible.
Here's how I would start to rework this code...
<?php
// assuming $allGroups is created in a loop
// the following code could be incorporated into that loop
$options = [];
foreach ($allGroups as $group) {
$action = ($advancedPermissions && !$modGroups) ? "view" : "edit";
$group_id = $group[0];
$url = "groups.php?" . http_build_query(compact("action", "group_id"));
$options[$url] = $group[0] . ($group[4] !== "Y" ? " - inactive" : "");
}
?>
<!doctype html>
<html>
<head>
<style>
#location_select {
width: 200px; font-family: monospace; font-weight: bold; color: black;
}
</style>
</head>
<body>
<form name=sel1>
<select id="location_select" size="10">
<?php foreach ($options as $value => $option): ?>
<option value="<?= htmlspecialchars($value) ?>">
<?= htmlspecialchars($option) ?>
</option>
<?php endforeach ?>
</select>
</form>
<script>
document
.getElementById("location_selector")
.addEventListener("change", function() {
window.location = this.options[this.selectedIndex].value;
});
</script>
</body>
</html>
But if you are looking for the quick fix:
for($i = 0; $i < count($allGroups); $i++)
{
$action = ($advancedPermissions && !$modGroups) ? "view" : "edit";
$group_id = $allGroups[$i][0];
$url = "groups.php?" . http_build_query(compact("action", "group_id"));
print("<option value='$url'>");
print($allGroups[$i][0]);
if($allGroups[$i][2] != 'Y')
{
print(" - inactive");
}
print("</option>");
}
Another stupid question.
I believe I understand this right but it doesn't seem to work.
function parseCustomCommands($text, $textParts) {
if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR) {
switch($textParts[0]) {
case '/takeover':
$this->insertChatBotMessage( $this->getChannel(), $text );
return true;
default:
return false;
}
}
}
ajaxChat.replaceCustomCommands = function(text, textParts) {
switch(textParts[0]) {
case '/takeover':
text=text.replace('/takeover', ' ');
return '<span class="chatBotMessage">' + text + '</span>';
default:
return text;
}
}
It's executed when /takeover is this sent and the way I'm looking at it the '/takeover' part is meant to be replaced with nothing leaving just the . This does not seem to be the case..
Is anyone able to point out the mistake in it? I've tried several things with $ in variable names and using different variables to remove it.
$re="/takeover";
$str=text.replace(re, ' ');
I've tried too.
Thanks in advance.
This is really a PHP question
github source
Review the other "insertParsedMessage*" PHP methods
I'm not a PHP developer but it should be something like this based on the documentation
$text = str_replace("/takeover","", $text);
Last time I asked for help in PHP and I got great response. Thanks to all of you for that. Now I am learning and creating website using MVC PHP. I want to ask you that can I create a custom function to use html tags? I am trying to remember that where I saw an example of it. Actually I've seen it before in and open source project.
It was like something this:
htmltag(script(src=address, type=javascript))
Its output was in html like:
<script src="address" type="javascript"></script>
So can I create something like this? I am trying to do this way:
public function script($var1, $var2){
$var1 = array(
'type'=>'',
'charset' => '',
'src' => ''
);
$var2 = false;
print("<script $var1>$var2</script>");
}
So can anyone guide me with this? Do I need to create class first? I will be waiting for your reply friends.
Javascript works with DOM, see the reference
function htmltag(name,atts) {
var tag = document.createElement(name);
for(var i in atts) tag.setAttribute(i, atts[i]);
return tag;
}
var img = htmltag("img", {
src: "https://kevcom.com/images/linux/linux.logo.2gp.jpg",
alt: "linux logo"
});
document.body.appendChild(img);
Note that img here is object (XML Node), not just plain text, so you can attach events on it etc. If you want to extract just the plain html code from it, use img.outerHTML. Test it on the fiddle.
Note: print is the equivalent of Ctrl+P in the browser :-) it is not the print equivalent in PHP.
In PHP you can use DOM::createElement and other methods from DOM which are quite similar to those from javascript. Personaly I prefer something more simple:
function tag($name,$atts="",$content="") {
$str_atts = "";
if(is_array($atts)) {
foreach($atts as $key=>$val) if(!($val===null || $val===false)) $str_atts.= " $key=\"$val\"";
} else $str_atts = " ".preg_replace("/=(?!\")(\S+)/m","=\"\\1\"",$atts);
if($name=="img" && !strpos($str_atts,"alt=")) $str_atts.= " alt=\"\"";
if(in_array($name,array("input","img","col","br","hr","meta"))) $name.= "/";
if(substr($name,-1)=="/") { $name = substr($name,0,-1); return "<{$name}{$str_atts}/>"; }
else return "<{$name}{$str_atts}>$content</$name>";
}
Examples
echo tag("p","class=foo id=bar1","hello");
echo tag("p",'class="foo" id="bar2"',"hey");
echo tag("p",array("class"=>"foo","id"=>"bar3"),"heya");
echo tag("img","src=https://kevcom.com/images/linux/linux.logo.2gp.jpg");
Whenever we are fetching some user inputed content with some editing from the database or similar sources, we might retrieve the portion which only contains the opening tag but no closing.
This can hamper the website's current layout.
Is there a clientside or serverside way of fixing this?
Found a great answer for this one:
Use PHP 5 and use the loadHTML() method of the DOMDocument object. This auto parses badly formed HTML and a subsequent call to saveXML() will output the valid HTML. The DOM functions can be found here:
http://www.php.net/dom
The usage of this:
$doc = new DOMDocument();
$doc->loadHTML($yourText);
$yourText = $doc->saveHTML();
I have solution for php
<?php
// close opened html tags
function closetags ( $html )
{
#put all opened tags into an array
preg_match_all ( "#<([a-z]+)( .*)?(?!/)>#iU", $html, $result );
$openedtags = $result[1];
#put all closed tags into an array
preg_match_all ( "#</([a-z]+)>#iU", $html, $result );
$closedtags = $result[1];
$len_opened = count ( $openedtags );
# all tags are closed
if( count ( $closedtags ) == $len_opened )
{
return $html;
}
$openedtags = array_reverse ( $openedtags );
# close tags
for( $i = 0; $i < $len_opened; $i++ )
{
if ( !in_array ( $openedtags[$i], $closedtags ) )
{
$html .= "</" . $openedtags[$i] . ">";
}
else
{
unset ( $closedtags[array_search ( $openedtags[$i], $closedtags)] );
}
}
return $html;
}
// close opened html tags
?>
You can use this function like
<?php echo closetags("your content <p>test test"); ?>
You can use Tidy:
Tidy is a binding for the Tidy HTML clean and repair utility which allows you to not only clean and otherwise manipulate HTML documents, but also traverse the document tree.
or HTMLPurifier
HTML Purifier is a standards-compliant
HTML filter library written in
PHP. HTML Purifier will not only remove all malicious
code (better known as XSS) with a thoroughly audited,
secure yet permissive whitelist,
it will also make sure your documents are
standards compliant, something only achievable with a
comprehensive knowledge of W3C's specifications.
For HTML fragments, and working from KJS's answer I have had success with the following when the fragment has one root element:
$dom = new DOMDocument();
$dom->loadHTML($string);
$body = $dom->documentElement->firstChild->firstChild;
$string = $dom->saveHTML($body);
Without a root element this is possible (but seems to wrap only the first text child node in p tags in text <p>para</p> text):
$dom = new DOMDocument();
$dom->loadHTML($string);
$bodyChildNodes = $dom->documentElement->firstChild->childNodes;
$string = '';
foreach ($bodyChildNodes as $node){
$string .= $dom->saveHTML($node);
}
Or better yet, from PHP >= 5.4 and libxml >= 2.7.8 (2.7.7 for LIBXML_HTML_NOIMPLIED):
$dom = new DOMDocument();
// Load with no html/body tags and do not add a default dtd
$dom->loadHTML($string, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$string = $dom->saveHTML();
In addition to server-side tools like Tidy, you can also use the user's browser to do some of the cleanup for you. One of the really great things about innerHTML is that it will apply the same on-the-fly repair to dynamic content as it does to HTML pages. This code works pretty well (with two caveats) and nothing actually gets written to the page:
var divTemp = document.createElement('div');
divTemp.innerHTML = '<p id="myPara">these <i>tags aren\'t <strong> closed';
console.log(divTemp.innerHTML);
The caveats:
The different browsers will return different strings. This isn't so bad, except in the the case of IE, which will return capitalized tags and will strip the quotes from tag attributes, which will not pass validation. The solution here is to do some simple clean-up on the server side. But at least the document will be properly structured XML.
I suspect that you may have to put in a delay before reading the innerHTML -- give the browser a chance to digest the string -- or you risk getting back exactly what was put in. I just tried on IE8 and it looks like the string gets parsed immediately, but I'm not so sure on IE6. It would probably be best to read the innerHTML after a delay (or throw it into a setTimeout() to force it to the end of the queue).
I would recommend you take #Gordon's advice and use Tidy if you have access to it (it takes less work to implement) and failing that, use innerHTML and write your own tidy function in PHP.
And though this isn't part of your question, as this is for a CMS, consider also using the YUI 2 Rich Text Editor for stuff like this. It's fairly easy to implement, somewhat easy to customize, the interface is very familiar to most users, and it spits out perfectly valid code. There are several other off-the-shelf rich text editors out there, but YUI has the best license and is the most powerful I've seen.
A better PHP function to delete not open/not closed tags from webmaster-glossar.de (me)
function closetag($html){
$html_new = $html;
preg_match_all ( "#<([a-z]+)( .*)?(?!/)>#iU", $html, $result1);
preg_match_all ( "#</([a-z]+)>#iU", $html, $result2);
$results_start = $result1[1];
$results_end = $result2[1];
foreach($results_start AS $startag){
if(!in_array($startag, $results_end)){
$html_new = str_replace('<'.$startag.'>', '', $html_new);
}
}
foreach($results_end AS $endtag){
if(!in_array($endtag, $results_start)){
$html_new = str_replace('</'.$endtag.'>', '', $html_new);
}
}
return $html_new;
}
use this function like:
closetag('i <b>love</b> my <strike>cat');
#output: i <b>love</b> my cat
closetag('i <b>love</b> my cat</strike>');
#output: i <b>love</b> my cat
Erik Arvidsson wrote a nice HTML SAX parser in 2004. http://erik.eae.net/archives/2004/11/20/12.18.31/
It keeps track of the the open tags, so with a minimalistic SAX handler it's possible to insert closing tags at the correct position:
function tidyHTML(html) {
var output = '';
HTMLParser(html, {
comment: function(text) {
// filter html comments
},
chars: function(text) {
output += text;
},
start: function(tagName, attrs, unary) {
output += '<' + tagName;
for (var i = 0; i < attrs.length; i++) {
output += ' ' + attrs[i].name + '=';
if (attrs[i].value.indexOf('"') === -1) {
output += '"' + attrs[i].value + '"';
} else if (attrs[i].value.indexOf('\'') === -1) {
output += '\'' + attrs[i].value + '\'';
} else { // value contains " and ' so it cannot contain spaces
output += attrs[i].value;
}
}
output += '>';
},
end: function(tagName) {
output += '</' + tagName + '>';
}
});
return output;
}
I used to the native DOMDocument method, but with a few improvements for safety.
Note, other answers that use DOMDocument do not consider html strands such as
This is a <em>HTML</em> strand
The above will actually result in
<p>This is a <em>HTML</em> strand
My Solution is below
function closeDanglingTags($html) {
if (strpos($html, '<') || strpos($html, '>')) {
// There are definitiley HTML tags
$wrapped = false;
if (strpos(trim($html), '<') !== 0) {
// The HTML starts with a text node. Wrap it in an element with an id to prevent the software wrapping it with a <p>
// that we know nothing about and cannot safely retrieve
$html = cHE::getDivHtml($html, null, 'closedanglingtagswrapper');
$wrapped = true;
}
$doc = new DOMDocument();
$doc->encoding = 'utf-8';
#$doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
if ($doc->firstChild) {
// Test whether the firstchild is definitely a DOMDocumentType
if ($doc->firstChild instanceof DOMDocumentType) {
// Remove the added doctype
$doc->removeChild($doc->firstChild);
}
}
if ($wrapped) {
// The contents originally started with a text node and was wrapped in a div#plasmappclibtextwrap. Take the contents
// out of that div
$node = $doc->getElementById('closedanglingtagswrapper');
$children = $node->childNodes; // The contents of the div. Equivalent to $('selector').children()
$doc = new DOMDocument(); // Create a new document to add the contents to, equiv. to "var doc = $('<html></html>');"
foreach ($children as $childnode) {
$doc->appendChild($doc->importNode($childnode, true)); // E.g. doc.append()
}
}
// Remove the added html,body tags
return trim(str_replace(array('<html><body>', '</body></html>'), '', html_entity_decode($doc->saveHTML())));
} else {
return $html;
}
}