Include directive with page variable doesn't work inside markup - php

I have some markup such as:
Markup('talk', '<include',
'/\\(:talk:\\)/i',
'MarkupTalk');
function MarkupTalk($m) {
return 'Talk page: (:include {$BaseName}-talk:)'
}
but when I use it, it does nothing!
Example text (:talk:) more text
outputs
<div id="wikitext">
<p>Example text Talk page: more text</p>
almost as if the (:include:) directive is a comment! It seems like (:include:) doesn't work when defined in other markup.
How can I make this work properly?

The reason that this doesn't work properly is that your markup:
talk <include B>=><
is evaluated after one of its dependencies:
{$var} >$[phrase] B=>>
To fix this, you could change when your markup is evaluated:
Markup('talk', '<{$var}',
'/\\(:talk:\\)/i',
'MarkupTalk');
but this can be undesirable if you have any markup that outputs ("depends on") yours. Instead, you can modify your function to use the PageVar() function as noted in PmWiki.PageVariables, like so:
function MarkupTalk($m) {
global $pagename;
$pagename = ResolvePageName($pagename);
return 'Talk page: (:include '. PageVar($pagename, '$BaseName') .'-talk:)'
}
This removes {$var} as a dependency and allows your markup to be safely evaluated after {$var} is.

Related

WP Thumbail not rendered correctly

I'm trying to add a thumbail to a div using the_post_thumbnail() function.
The code I'm using is the following:
<div class="sc-col sc-s12 sc-m3 sc-card sc-card-basic">
<figure>'.the_post_thumbnail(array('370', '188')).'</figure>
</div>
But when the code is rendered in a browser the code becomes (just took a part of the rendered code):
<img width="370" height="182" src="/wp-content/uploads/2016/05/image.png">
<div class="sc-col sc-s12 sc-m3 sc-card sc-card-basic">
<figure></figure>
</div>
As you can see the image is rendered outside the div and figure. My question is why is it doing this? Because now my whole layout is breaking now and, the problem is that I have to use that function else I would have used an other function. Can I somehow rewrite the function so it only returns the src link using add_filter function?
https://developer.wordpress.org/reference/functions/the_post_thumbnail/ shows that the function the_post_thumbnail is designed to actually output something to the page, not return a string.
So change your code to something more like this:
$html = '<div class="sc-col sc-s12 sc-m3 sc-card sc-card-basic">
<figure>';
echo $html;
the_post_thumbnail(array('370', '188'))
$html = '</figure>
</div>';
echo $html;
This solved it for me:
<figure><?php the_post_thumbnail(array('370', '188')); ?></figure>
As staded by #ChrisLear the_post_thumbail() doens't return a string and there for fails.

How to extract HTML element from a source file

I need to replace a HTML section identified by a tag id in a source code, which is combination of HTML and PHP using PHP. In case it's pure HTML, DOM parser could be used; in case there is no DIV in DIV, I can imagine how to use preg_match. This is what I am trying to do - I have a code (loaded into a string) like:
<div>
<img >
</div>
<? include(); ?>
<div id="mydiv">
<div>
<div>
<img >
</div>
</div>
</div>
and my task is to replace content of "mydiv" DIV with a new one e.g.
<div id="newdiv>
some text
</div>
so the string will look like this after the change:
<div>
<img >
</div>
<? include(); ?>
<div id="mydiv">
<div id="newdiv>
some text
</div>
</div>
I have already tried:
1) parsing the code using DOMdocument's loadHTML => it produces a lot of errors in case PHP code is included.
2) I played around a bit with regexes like preg_match_all('/<div id="myid"([^<]*)<\/div>/', $src, $matches), which fails in case more child divs are included.
The best approach I have found so far is:
1) find id="mydiv" string
2) search for '<' and '>' chars and count them like '<'=1 and '>'=-1 (not exactly, but it gives the idea)
3) once I get sum == 0 I should be on position of the closing tag, so I know, which portion string I should exchange
This is quite "heavy" solution, which can stop working in some cases, where the code is different (e.g. onpage PHP code contains the chars as well instead of just simple "include"). So I am looking so some better solution.
You could try something like this:
$file = 'filename.php';
$content = file_get_contents($file);
$array_one = explode( '<div id="mydiv">' , $content );
$my_div_content = explode("</div>" , $array_one[1] )[0];
Or use preg_match like you said:
preg_match('/<div id="mydiv"(.*?)<\/div>/s', $content, $matches)
Yes there is. First you need to use a function that will get the content of the file. Lets call the file homepage.php:
$homepageString = file_get_contents('homepage.php');
Now you have a string with all the content. The next thing you would do is use the preg_replace() function to take out the part of code that you want to take out:
$newHomepageString = preg_replace('/id="mydiv"/',"", $homepageString);
Now you overwrite the existing homepage.php file with the new source code:
file_put_contents("homepage.php", $newHomepageString);
Let me know if it worked for you! :)

Functions value is not defined in PHP and HTML

I create this div in PHP and I want to call a function when I double=click on it. However, it tells me that my value isn't defined. Can someone please tell me why?
(Here's the important part of my code in php:
"..//Some mor HTML...value='".$DatabaseID.";' ondblclick='delete_selected(value, 'all', 'child'); ..//Some more HTML.."
I can call a function that doesn't have a value. What am I doing wrong?
Here's the rest if you're interested:
$Object = "<div id='".$DatabaseID."' onclick='sendid(id); highlight(id);' title='".$title."' data-parent='".$ParentID."'data-itemCategory='".$ItemCategory."' value='".$DatabaseID.";' ondblclick='delete_selected(value);' onmouseup='position(id);' style='border:".$border_size."px solid ".$border_color."; top:".$pos_y."px; left:".$pos_x."px; position:".$positionType."; background:".$color.";' class='".$class."'>
<!-- <img src='$img' class='img_status_rwp' style='width:".$img_size."px; height:".$img_size."px; margin-left:-".$img_size."px; margin-top:-".$img_size."px; '></img> --> <div class='item_header'><div class='header_text_cont'><div class='header_span'>".$ItemName."</div><div style='clear:both';></div></div></div>";
Update
I changed the quotation and removed te img-part (since it isn't active):
$Object = '<div id="'.$DatabaseID.'" onclick="sendid('.$DatabaseID.'); highlight('.$DatabaseID.')"; title="'.$title.'" data-parent="'.$ParentID.'" data-itemCategory="'.$ItemCategory.'" value="'.$DatabaseID.'" onclick="show_children(value, "all", "child");" style="border:'.$border_size.'px solid '.$border_color.'; top:'.$pos_y.'px; left:'.$pos_x.'px; position:'.$positionType.'; background:'.$color.';" class="'.$class.'">
<div class="item_header"><div class="header_text_cont"><div class="header_span">'.$ItemName.'</div><div style="clear:both";></div></div></div>';
I belive that the quotationmarks around all and child might be the ones creating some trouble but I don't know what to use instead.
show_children is defined in a JavaScript file that is included to the index.php and I can call other functions in it from index. I don't get any errors when double clicking, however the function is not called. When I successfully call the function using a button I have the following HTML:
<div class="sidebar_button" id="childAll" value="" onclick="show_children(value, 'all', 'child'); " style="font-size:10px">Show All Child Nodes (To RWP)</div>
I think your problem lies here onclick='sendid(id); highlight(id);' your passing id which isn't defigned anywhere. You need to change the code to onclick='sendid(".$DatabaseID."); highlight(".$DatabaseID.");' and then it should work.

simple html dom - space in class name

I'm using PHP Simple HTML DOM to get element from a source code of a site (not mine) and when I find a ul class that is called "board List",this is not found.I think it might be a problem of space but I don't know how to solve it.
this is a piece of php code:
$html = str_get_html($result['content']); //get the html of the site
$board = $html->find('.board List'); // Find all element which class=board List,but in my case it doesn't work,with other class name it works
and this is a piece of html code of the site:
<!-- OTHER HTML CODE BEFORE THIS --><ul class="board List"><li id="c111131" class="skin_tbl">
<table class="mback" cellpadding="0" cellspacing="0" onclick="toggleCat('c111131')"><tr>
<td class="mback_left"><div class="plus"></div><td class="mback_center"><h2 class="mtitle">presentiamoci</h2><td class="mback_right"><span id="img_c111131"></span></table>
<div class="mainbg">
<div class="title top"><div class="aa"></div><div class="bb">Forum</div><div class="yy">Statistiche</div><div class="zz">Ultimo Messaggio</div></div>
<ul class="big_list"><!-- OTHER HTML AFTER THIS -->
I solved it by removing board from the find parameter,as this:
$board = $html->find('.List');
now the parser seems to work correctly
With simple you would probably want to use:
$html->find('*[class="board List"]', 0);
If you really want to use:
$html->find('.board.List', 0);
Then use this one.
The answer is that: You cannot use spaces in classnames. spaces are the seperaters of classes
if you have <div class="container wrapper-something anothersomething"></div> then you can use .container, .wrapper-something or .anothersomething as a selector and you allways match that div.
So in your code you have <ul class="board List">, so to get a match in a css-selector ($html->find('{here_comes_the_css_selector}');) you can use eather .board or .List as the selctor
Therefor your line $board = $html->find('.board List'); should look more like this:
$board = $html->find('.board.List');
// maches every element who has class 'board' AND 'List'
// Here it is really important that there is no spaces between those 2 selectors
// or
$board = $html->find('.List');
// maches every element who has class 'List'
// or
$board = $html->find('.board');
// maches every element who has class 'board'
$board = $html->find('[class="board List"]');
With this syntax SimpleHTMLDOM finds elements with multiple class attribute

How to code PHP function that displays a specific div from external file if div called by getElementById has no value?

Thank you for answering my question so quickly. I did some more digging and ultimately found a solution for grabbing data from external file and specific div and posting it into another document using PHP DOMDocument. Now I'm looking to improve the code by adding an if condition that will grab data from a different div if the one called for initially by getElementById has now data. Here is the code for what I got so far.
External html as source.
<div id="tab1_header" class="cushycms"><h2>Meeting - 12:00pm to 3:00pm</h2></div>
My PHP file calling from source looks like this.
<?php
$source = "user_data.htm";
$dom = new DOMDocument();
$dom->loadHTMLFile($source);
$dom->preserveWhiteSpace = false;
$tab1_header = $dom->getElementById('tab1_header');
?>
<html>
<head>
<title></title>
</head>
<body>
<div><h2><?php echo $tab1_header->nodeValue; ?></h2></div>
</body>
</html>
The following function will output a message if a div id can't be found but...
if(!tab1_header)
{
die("Element not found");
}
I would like to call for a different div if the one called for initially has no data. Meaning if <div id="tab1_header"></div> then grab <div id="alternate"><img src="filler.png" /></div>. Can someone help me modify the function above to achieve this result.
Thanks.
either split up master.php so div1\2 are in a file each or set them each to a var, them include master.php, and use the appropriate variable
master.php
$d1='<div id="description1">Some Text</div>';
$d2='<div id="description2">Some Text</div>';
description1.php
include 'master.php';
echo $d1;
You can't do this solely with PHP includes unless you put the divs into separate files. Look into PHP templating; it's probably the best solution for this. Or, since you're new to the language, try using variables:
master.php
$description1 = '<div id="description1">Some Text</div>';
$description2 = '<div id="description2">Some Text</div>';
board1.php
include 'master.php';
echo $description1;
board2.php
include 'master.php';
echo $description2;
Alternatively, you could use JavaScript, but that might get a little messy.
Short answer is: although it's possible it's probably very bad idea taking this approach.
Longer answer: the solution may turn out to be too complicated. If in your master.php file is only HTML markup, you could read content of that file with file_get_contents() function and then parse it (i.e. with DOMDocument library functions). You would have to look for a div with given id.
$doc = new DOMDocument();
$doc->loadHTMLFile($file);
$divs = $doc->getElementsByTagName('div');
foreach ($divs as $div)
{
if( $div->getAttribute('id') == 'description1' )
{
echo $div->nodeValue."\n";
}
}
?>
If your master.php file has also some dynamic content you could do following trick:
<?php
ob_start();
include('master.php');
$sMasterPhpContent = ob_get_clean();
// same as above - parse HTML
?>
Edit:
$tab_header = $dom->getElementById('tab1_header') ? $dom->getElementById('tab1_header') : $dom->getElementById('tab2_header');

Categories