WordPress plugin: finding the <!--more--> in the_content - filter

I'm writing a WordPress plugin that filters the_content, and I'd like to make use of the <!--more--> tag, but it appears that it has been stripped out by the time it reaches me. This appears to be not a filter, but a function of the way WordPress works.
I could of course resort to reloading the already-loaded content from the database, but that sounds like it might cause other troubles. Is there any good way for me to get the raw content without the <!--more--> removed?

Chances are, by the time your plugin runs, <!--more--> has been converted to <span id="more-1"></span>
This is what I use in my plugin, which injects some markup immediately after the <!--more--> tag:
add_filter('the_content', 'inject_content_filter', 999);
function inject_content_filter($content) {
$myMarkup = "my markup here<br>";
$content = preg_replace('/<span id\=\"(more\-\d+)"><\/span>/', '<span id="\1"></span>'."\n\n". $myMarkup ."\n\n", $content);
return $content;
}

You can use the follow code:
The !is_single() will avoid display the more link in the View Post page.
add_filter('the_content', 'filter_post_content');
function filter_post_content($content,$post_id='') {
if ($post_id=='') {
global $post;
$post_id = $post->ID;
}
// Check for the "more" tags
$more_pos = strpos($filtered_content, '<!--more-->');
if ($more_pos && !is_single()) {
$filtered_content = substr($filtered_content, 0, $more_pos);
$replace_by = '<a href="' . get_permalink($post_id) . '#more-' . $post_id
. '" class="more-link">Read More <span class="meta-nav">→</span></a>';
$filtered_content = $filtered_content . $replace_by;
}
return $filtered_content;
}

Based on Frank Farmer's answer I solved to add thumbnail photo after the generated more tag (<span id="more-...) in single.php file with this:
// change more tag to post's thumbnail in single.php
add_filter('the_content', function($content)
{
if(has_post_thumbnail())
{
$post_thumbnail = get_the_post_thumbnail(get_the_ID(), 'thumbnail', array('class'=>'img img-responsive img-thumbnail', 'style'=>'margin-top:5px;'));
$content = preg_replace('/<span id\=\"(more\-\d+)"><\/span>/', '<span id="\1"></span>'.$post_thumbnail, $content);
}
return $content;
}, 999);

Related

Laravel Nova: how to display image from binary string?

I save PNG's binary content in database.
I want display this PNG's on page without temporary save file on disk.
I think need generate img tag like <img src="data:image/png;base64,......
But I do not understand how it is better to implement it and what type of field to take as a basis.
Image::make('Image')->displayUsing(function($item) {
$mime_type = 'image/png';
return 'data: ' . $mime_type . ';base64,' . base64_encode($item);
}),
But Laravel Nova generated:
<img src="http://172.18.0.3/storage/data: image/png;base64,......" class="rounded-full w-8 h-8" style="object-fit: cover;">
Added unnecessary http://172.18.0.3/storage/and rounded class.
How to prevent it adding?
Work code for Laravel Nova 2.0.1:
Image::make('QRCode', 'qrcode')->thumbnail(function($value, $disk) {
return 'data: image/png;base64,' . $value;
})->preview(function($value, $disk) {
return 'data: image/png;base64,' . $value;
})->displayUsing(function($value) {
return base64_encode($value);})
Also need remove rounded-full from field.thumbnailUrl?t("img",{staticClass:"rounded-full w-8 h-8", in file public\vendor\nova\app.js
Override thumbnail & preview for image url
Try below code snippet
Image::make('Image')->thumbnail(function($value, $disk) {
return 'data: image/png;base64,' . base64_encode($value);
})->preview(function($value, $disk) {
return 'data: image/png;base64,' . base64_encode($value);
}),

How to fill a rich text editor field for a Codeception Acceptance test

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>');

How do I stop Joomla from including jQuery?

I've recently upgraded from Joomla 3.2.1 to Joomla 3.2.2.
In Joomla 3.2.1, I manually unset jQuery from being included:
$doc = JFactory::getDocument();
$dontInclude = array(
'/media/jui/js/jquery.js',
'/media/jui/js/jquery.min.js',
'/media/jui/js/jquery-noconflict.js',
'/media/jui/js/jquery-migrate.js',
'/media/jui/js/jquery-migrate.min.js',
'/media/jui/js/bootstrap.js',
'/media/system/js/core-uncompressed.js',
'/media/system/js/tabs-state.js',
'/media/system/js/core.js',
'/media/system/js/mootools-core.js',
'/media/system/js/mootools-core-uncompressed.js',
);
foreach($doc->_scripts as $key => $script){
if(in_array($key, $dontInclude)){
unset($doc->_scripts[$key]);
}
}
But this isn't working in Joomla 3.2.2. Is there a way to not include Joomla's jQuery in 3.2.2?
Another variation which works well for me with Joomla 3.4 is to edit the template > index.php file with something like:
$doc = JFactory::getDocument();
$headData = $doc->getHeadData();
$scripts = $headData['scripts'];
//scripts to remove, customise as required
unset($scripts[JUri::root(true) . '/media/system/js/mootools-core.js']);
unset($scripts[JUri::root(true) . '/media/system/js/mootools-more.js']);
unset($scripts[JUri::root(true) . '/media/system/js/core.js']);
unset($scripts[JUri::root(true) . '/media/system/js/modal.js']);
unset($scripts[JUri::root(true) . '/media/system/js/caption.js']);
unset($scripts[JUri::root(true) . '/media/jui/js/jquery.min.js']);
unset($scripts[JUri::root(true) . '/media/jui/js/jquery-noconflict.js']);
unset($scripts[JUri::root(true) . '/media/jui/js/bootstrap.min.js']);
unset($scripts[JUri::root(true) . '/media/jui/js/jquery-migrate.min.js']);
$headData['scripts'] = $scripts;
$doc->setHeadData($headData);
You need to add a prefix of JUri::root(true) before each of those file names - relative paths will not work
I've added:
$doNotInclude = array(
'jquery',
'bootstrap',
'behavior',
);
if(in_array($file, $doNotInclude)){
return;
}
immediately after:
list($key, $prefix, $file, $func) = static::extract($key);
in libraries/cms/html/html.php, in the "_" function.
I don't like it since its a modification to the Joomla core but it works. I'm still looking for a better solution.
You can also try something like this:
$removeScripts = [
'/media/jui/js/jquery.min.js',
'/media/jui/js/jquery-noconflict.js',
'/media/jui/js/jquery-migrate.min.js',
'/media/system/js/caption.js',
];
foreach ($removeScripts as $removeScript) {
unset($this->_scripts[JURI::root(true).$removeScript]);
}
The problem is with your in_array.
If you remove it by changing this:
foreach($doc->_scripts as $key => $script){
if(in_array($key, $dontInclude)){
unset($doc->_scripts[$key]);
}
}
to this:
foreach($doc->_scripts as $key => $script){
unset($doc->_scripts[$key]);
}
Then it works fine. It's pretty pointless checking if the array key exists as I gathered you haven't manually deleted any of these files yourself.
Hope this helps
Joomla 3.3.6 loads scripts in different way so $doc->_scripts will return nothing... so there is nothing to unset.
I recommend to use this plugin: https://github.com/Poznakomlus/joomla_options
It allows you to remove bootstrap, jQuery and mootools (you can choose what to disable).
Disclaimer: I'm not affiliated any way with plugin developer or plugin itself in any way.
If you are writing a custom template or a component, where you need to remove all the scripts loaded by default inside Joomla you can create a simple plugin and bind the execution to the onBeforeCompileHead event.
My implementation was as below. Its very simple. You can further play around with the search list, by being specific to file names or just plain blacklisting the parent folder.
protected $app;
public function onBeforeCompileHead() {
// Front end
if ($this->app instanceof JApplicationSite) {
$doc = JFactory::getDocument();
$search = array(
'jui/js/',
'system/js/'
);
foreach ($doc->_scripts as $key => $script) {
foreach ($search as $findme) {
if (stristr($key, $findme) !== false) {
unset($doc->_scripts[$key]);
}
}
}
}
}
This worked for me in joomla 3.9
<?php
defined('_JEXEC') or die('Restricted access');
$unset_scripts = [
'/media/jui/js/jquery.min.js',
'/media/jui/js/jquery-noconflict.js',
'/media/jui/js/jquery-migrate.min.js',
'/media/system/js/caption.js',
];
foreach ($unset_scripts as $script) {
unset($this->_scripts[JURI::root(true) . $script]);
}
if (isset($this->_script['text/javascript'])) {
$captionJsStr = '%jQuery\(window\)\.on\(\'load\',\s*function\(\)\s*{\s*new\s*JCaption\(\'img.caption\'\);\s*}\);\s*%';
$this->_script['text/javascript'] = preg_replace($captionJsStr, '', $this->_script['text/javascript']);
if (empty($this->_script['text/javascript'])) {
unset($this->_script['text/javascript']);
}
}
$this->_scripts = array();
?>
<!DOCTYPE html>

how to open pdf file to another tab in browser using codeigniter

im making currently making my thesis about a record management of our university secretary.. in which all papers inside the office will be scanned and uploaded in the system.. i am using codeigniter..one of the feature in my system is to view the pdf file in other window of the browser. but my problem is, when i click the title. only blank page will be displayed in the other tab.. can you help me solve this one?? here is my code
controller:
function viewMinutesFile(){
if(isset($_GET['id'])){
$id = $_GET['id'];
$file = $this->minutes_model->getFile($id);
$fp= fopen($file->path, "r");
header("Cache-Control: maxage=1");
header("Pragma: public");
header("Content-type: application/pdf");
header("Content-Disposition: inline; filename=".$file->filename."");
header("Content-Description: PHP Generated Data");
header("Content-Transfer-Encoding: binary");
header('Content-Length:' .filesize($file->path));
ob_clean();
flush();
while (!feof($fp)){
$buff = fread($fp,1024);
print $buff;
}
exit;
}
}
code to open the file: this is my syntax to be clicked by the user so that pdf file will be open in the new tab
File
index.php/admin/viewMinutesFile?
id=" target="_tab">
try this one with a static url. no need any extra words for that.
Show My Pdf
New Update
if its work for you then fetch pdf name from database and put the name in the view like
Show My Pdf
now in the controller
$this->load->helper('download');
if($this->uri->segment(3))
{
$data = file_get_contents('./file_path/'.$this->uri->segment(3));
}
$name = $this->uri->segment(3);
force_download($name, $data);
well, you could add a link to file with target="_blank", like
<a href="<?php echo base_url(). 'your_controller/viewMinutesFile'; ?>" target="_blank">
View Pdf
</a>
and in controller function:
function viewMinutesFile(){
....
$file = $this->minutes_model->getFile($id);
$this->output
->set_content_type('application/pdf')
->set_output(file_get_contents($your_pdf_file));
}
you can try this on your view :
Filename
and on your controller, you can try this, because this is works for me :
function viewfile(){
$fname = $this->uri->segment(3);
$tofile= realpath("uploaddir/".$fname);
header('Content-Type: application/pdf');
readfile($tofile);
}
hope this might help you...
Just create a link to a blank page and use this code in your controller:
public function myPdfPage(){
$url = base_url('assets/your.pdf');
$html = '<iframe src="'.$url.'" style="border:none; width: 100%; height: 100%"></iframe>';
echo $html;
}
Enjoy!
There is no any problem with your code you can open easily on next tab, like other pages only difference you have to change header description and it is make sure on your browser pdf reader add-ons are available, otherwise it will give you option to download.
You may just follow this.
<?php echo form_open_multipart('your_controller/your_function','target="_blank"') ;?>
//other input fields
<?php form_close();?>

Magento, show image on custom frontend block

I've a module up and running. On the backend side I can upload images with several attributes and I'm saving image path and other information on a custom table. On frontend I already managed to detect when I need to show these images. I've used an Observer that adds a new layout handle when the displayed product is found on the custom created table. Then on that layout handle I call a phtml template file and from here I call a function inside a block that will be in charge of doing all the checks to be sure wich image to show.
My problem is that I can not find how to show these images. Everything I found references how to add image tag on a phtml file doing some extra verifications on the inserted php code. Buy on my case everything is on php code outside any phtml file.
My phtml file code:
<div>
<h3><?php $this->showCampaign(); ?></h3>
</div>
My block code for now:
<?php
class Dts_Banners_Block_Front extends Mage_Core_Block_Template {
/**
* Shows a campaign banner according to the current selected product
* Seeks on main banners table to see if it is an image/html/product alone campaign
* Once knows the campaign type search on needed table the needed fields
*/
public function showCampaign() {
//Zend_Debug::dump($this->getLayout()->getUpdate()->getHandles());
$product = Mage::registry('current_product');
$currentProdID = $product->getId();
if (Mage::registry('campaign_data') && Mage::registry('campaign_data')->getId()) {
$currentCampaign = Mage::registry('campaign_data');
} else {
return;
}
// get campaign type and show needed information
switch ($currentCampaign->getbanner_type()) {
case 1: // image
$myImgCollection = Mage::getModel('banners/bannersimg')->getCollection();
$myImgCollection->addfieldtofilter('bannerid',$currentCampaign->getID());
$currentImg = $myImgCollection->getFirstItem();
$currentImgPath = $currentImg->getimg_path();
//{{block type="catalog/product_new" product_id="16" template="catalog/product/view/your_new_page.phtml"}}
break;
case 2: // html
echo "html";
break;
case 3: // plain product url
echo "plain product url";
break;
}
}
}
As usual, couple of hours searching for an answer and when I post the question, found the answer. Just in case someone needs it: is as easy as creating an image html tag inside the code and return it to the template file. Sample code:
<?php
class Dts_Banners_Block_Front extends Mage_Core_Block_Template {
public function showCampaign() {
...
$currentImgPath = $currentImg->getimg_path();
//build html to output to the template
$html .= "<div class=\"visual\">";
$html .= "<img src=\"" . $currentImgPath . "\" alt=\"\" />";
$html .= "</div>";
....
return $html;
}
And the phtml file code:
<div class="visual">
<?php echo $this->showCampaign(); ?>
</div>

Resources