I'm using Simple HTML Dom Parser to correct some links in my output to good effect but have found some strange behaviour when calling content via Ajax. I'm using the parser on a WordPress site so feed the $content variable into the following function:
function add_trailing_slash( $content ) {
$content = str_get_html( $content );
if( $content ):
foreach( $content->find('a') as $a ):
if( isset( $a->href ) && '' !== $a->href && '#' !== $a->href ):
// replace http with https on all link hrefs
$a->href = str_replace('http:', 'https:', $a->href);
// checks if link lacks trailing slash and appends it if no extension (file)
$ext = pathinfo( $a->href, PATHINFO_EXTENSION );
if( '/' !== substr( $a->href, -1 ) && ! $ext ) $a->href = $a->href . '/';
endif;
endforeach;
endif;
return $content;
}
This is working great when added to the_content filter with add_filter( 'the_content', 'add_trailing_slash' ) and even when called directly like return add_trailing_slash( $output ) however, when I call the same function via Ajax I get a 'success' response but which is completely empty. Stranger still, I found that if I return the output via wpautop( $output ) it comes back just fine. wpautop (link) is essentially a bunch of preg_replace functions to replace double line breaks with <p> tags so I tested returning my output via return preg_replace('<blah>', '', $content) and it worked!
Oh, I also tested removing all my changes from the add_trailing_slash() function above and the same issue persisted so I guess that something to do with the way str_get_html( $content ) parses the input makes it not play well with the Ajax callback. But why does preg_replace make it returnable?
function add_trailing_slash( $content ) {
$content = str_get_html( $content );
return $content;
}
I'm wondering if anyone else has come across this issue, whether I'm missing something and this is expected or whether this is a bug? I could leave in my preg_replace which appears to 'fix' the issue but it feels like something of a hack.
The only thing that come to my mind is that when you do $content = str_get_html( $content ); you are getting an object as result. Maybe when it goes through wp functions it get interpreted like a string but when you are json_encoding it, something may go wrong and kill it. You can either try to force-cast it to string with
return (string) $content;
or try to use
// Dumps the internal DOM tree back into string
$str = $html->save();
as described in the docs
Related
\Blade::directive('specialReplace', function($expression){
$expression = explode(',', $expression);
$exception = $expression[0];
$output = htmlspecialchars($expression[1]);
if ($exception == "img") {
$output = str_replace("<img", "<img", $output);
$output = str_replace("/>", "/>", $output);
} else {
$output = str_replace("<".$exception.">", "<".$exception.">",$output);
$output = str_replace("</".$exception.">", "</".$exception.">",$output);
}
return "<?PHP echo $output?>";
});
#specialReplace(img, <img src=....)
I try to make a custom function for html out image from database without htmlentites in laravel.
My problem is I get an error syntax error, unexpected '&' which I have no idea
anyone know how to fix this?
Try that, it should fix the error
return "<?PHP echo \"$output\"?>";
Also as an argument to your function, given the input
#specialReplace(img, <img src=....)
You'll receive an exact string you passed to the direcive (together with the brackets)
(img, <img src=....)
It doesn't look like you parse it properly.
I'm trying to fill a rich text editor field (TinyMCE) within my acceptance test in Codeception.
Using the fillField() function doesn't work as this 'field' isn't really an input field. It's an iframe, styled to look like a fancy textarea.
How can I set some text into the body of the TinyMCE box? I think I'm looking for the addition of a $I->setContent(xpathOrCSS) function. Or does something else already exist to do this?
It is best to do this by adding re-usable actions to your Actor class (AcceptanceTester, by default). You can then use the actions in your tests to set the content of rich text editor fields without reducing the readability of your tests. More details on this are available in the Codeception documentation.
I have included solutions for TinyMCE and CKEditor below. The solution uses the executeInSelenium() call to give us access to Facebook's underlying WebDriver bindings. From there, we simply use the frame switching/Javascript injection technique described here to set the content of our target editor.
Note that the final call to $webDriver->switchTo()->defaultContent() is very important - this switches WebDriver's focus back from the RTE iframe to the page that contains it.
Actor functions:
<?php
class AcceptanceTester extends \Codeception\Actor {
use _generated\AcceptanceTesterActions;
public function fillCkEditorById($element_id, $content) {
$this->fillRteEditor(
\Facebook\WebDriver\WebDriverBy::cssSelector(
'#cke_' . $element_id . ' .cke_wysiwyg_frame'
),
$content
);
}
public function fillCkEditorByName($element_name, $content) {
$this->fillRteEditor(
\Facebook\WebDriver\WebDriverBy::cssSelector(
'textarea[name="' . $element_name . '"] + .cke .cke_wysiwyg_frame'
),
$content
);
}
public function fillTinyMceEditorById($id, $content) {
$this->fillTinyMceEditor('id', $id, $content);
}
public function fillTinyMceEditorByName($name, $content) {
$this->fillTinyMceEditor('name', $name, $content);
}
private function fillTinyMceEditor($attribute, $value, $content) {
$this->fillRteEditor(
\Facebook\WebDriver\WebDriverBy::xpath(
'//textarea[#' . $attribute . '=\'' . $value . '\']/../div[contains(#class, \'mce-tinymce\')]//iframe'
),
$content
);
}
private function fillRteEditor($selector, $content) {
$this->executeInSelenium(
function (\Facebook\WebDriver\Remote\RemoteWebDriver $webDriver)
use ($selector, $content) {
$webDriver->switchTo()->frame(
$webDriver->findElement($selector)
);
$webDriver->executeScript(
'arguments[0].innerHTML = "' . addslashes($content) . '"',
[$webDriver->findElement(\Facebook\WebDriver\WebDriverBy::tagName('body'))]
);
$webDriver->switchTo()->defaultContent();
});
}
}
Example Usage:
$content = '<h1>Hello, world!</h1>';
// CKEditor
$I->fillCkEditorByName('rich_content', $content);
$I->fillCkEditorById('my_ckeditor_textarea', $content);
// TinyMCE
$I->fillTinyMceEditorByName('rich_content', $content);
$I->fillTinyMceEditorById('my_tinymce_textarea', $content);
In all cases, the first parameter refers to the name/id attribute of the original textarea element, and the second parameter is the HTML content to fill it with.
Best way:
$I->executeJS('$("#selector").val("Value")');
If you have a simple setup and only need to test one instance in tinyMCE 4, this worked for me.
$I->executeJS('tinyMCE.activeEditor.setContent(" your content goes here ");');
IF you have and iframe like this:
<iframe id="myFrameID" allowtransparency="true"></iframe>
notice, that Codeception switches to the iframe using
$I->switchToIFrame("myFrameID");
Keep in mind, to omit the # in front of "myFrameID", as switch to iframe does not use a css selector but rather just the name of the iframe.
Then do
$I->executeJS('document.getElementById("tinymce").innerHTML = "<p>Some Text Here!</p>";');
and don't forget to switch back to previous window:
$I->switchToIFrame();
as stated in
https://codeception.com/docs/modules/WebDriver#switchToIFrame
Tried and following solution works:
$I->switchToIFrame('#frameName');
$I->executeJS('document.getElementById("tinymce").innerHTML = "<p>Test abc def</p>";');
try this
$x = $I->grabAttributeFrom('//iframe', 'id');
$I->switchToIframe($x);
$I->fillField('//*[#id="tinymce"]', '<p>Test abc</p>');
I am using SMARTY and I need to put <b> tag in string in the following php code i can put tag in string
$search = 'this is my sample strangŲ§';
$dbContent = 'this strang is for sample hello world';
$search = explode( ' ' , $search );
function wrapTag($inVal){
return '<b>'.$inVal.'</b>';
}
$replace = array_map( 'wrapTag' , $search );
$dbContent = str_replace( $search , $replace , $dbContent );
echo $dbContent;
how to use this code in smarty template or how to convert this code for smarty
In my opinion there's no need put such code into Smarty template, so the only thing you should do is
$smarty->assign('dbContent', $dbContent);
and in Smarty template file:
{$dbContent}
You should separate logic and display. In this case you shouldn't rather move this code to Smarty. If Your wrapTag function contained a lot of HTML you could do it this way ( I know global is not nice solution but probably it could be done also in the other way):
function wrapTag($inVal){
global $smarty;
$smarty->assign('inVal', $inVal);
return $smarty->fetch('bold_template.tpl');
}
and inside bold_template.tpl you could have:
<b>{$inVal}</b>
But if you only add <b> tags there's no point to put it in Smarty template
I can't call member functions on objects that I pass to custom control structures in Laravel 4.1.23.
My custom control structure:
Blade::extend(function($view, $compiler){
$pattern = $compiler->createMatcher('paginatePretty');
$code =
'$1<?php
echo $2->getCurrentPage();
?>';
return preg_replace($pattern, $code, $view);
});
My blade view code that instantiates paginatePretty:
// $articles = Articles::orderBy('created_at', 'desc')->paginate($per_page);
#paginatePretty($articles)
At compile time, I get this error:
syntax error, unexpected '->' (T_OBJECT_OPERATOR), expecting ',' or ';'
And the custom control structure was compiled like this:
echo ($articles)->getCurrentPage();
How can I pass an object to the custom control structure?
Use list() and array to solve:
Blade::extend(function($view, $compiler){
$pattern = $compiler->createMatcher('paginatePretty');
$code =
'$1<?php
#echo $2->getCurrentPage(); --> the bad code
list($_paginator) = array$2;
echo $_paginator->getCurrentPage();
?>';
return preg_replace($pattern, $code, $view);
});
I prefix variables declared inside of custom control structures with an underscore to avoid collisions in the view.
please help, I've a problem with Joomla's function renderModule.. I am trying to render module with this function, but it unfortunately strips javascript from the the rendered module.
I use the function in my own module which includes other modules according to current article..
The code is as following:
<?php
$moduleType = "j15html";
$moduleName = "test";
$option = JRequest::getVar( 'option', '' );
$view = JRequest::getVar( 'view', '' );
$id = JRequest::getInt( 'id', 0 );
$moduleName .= $id;
//echo $view;
if ( $option == "com_content" && $view == "article" ) {
//echo $moduleName;
$module = JModuleHelper::getModule($moduleType, $moduleName);
//print_r($module);
if ( ! empty( $module ) ) {
$attribs = array();
echo JModuleHelper::renderModule( $module, $attribs );
}
}
When I set the position of the included module to any position used in my template and set it to displat in particular menu section, it renders properly even with javascript and so on..
Any advices how to make this thing working?
You didn't mention which version of Joomla you're using - but you may want to check out SOURCERER it keeps coding how you put it and does not strip out extra coding.
Make sure you read the how-to so you know how to use it because it can seem a little confusing at first, but it has a button to 'change the tags' from < to << or [ which do not get stripped out by the WYSIWYG editor in Joomla!.
Of course, that could be your issue also, if your WYSIWYG editor is on (by default it is) and you're inputting code - it strips it. An easy way is to just turn it off under global options, then when you save the code doesn't get stripped. Just turning off the WYSIWYG editor is the quick/easy/simple solution - but if you turn it back on and open that module again, the code will be gone. So it can be a tricky solution if others may like using the editor or if you're using lots of custom code around your side. In that case the plugin I mentioned above is a great solution.