PrestaShop, use tinymce directly from Smarty template - php

I'm doing a PrestaShop module. This module will be anchored to the hook called "hookDisplayAdminProductsExtra".
I need to use the TEXTAREA field tinymce using the library, you can do so by creating the textarea directly from Smarty and not as a controller? Maybe using jQuery function or adding a class to the field?
My code in tpl file is:
{foreach $row_list as $row}
<textarea id="description_1" name="description_1" class="autoload_rte" aria-hidden="true">
{$row['desc']}
</textarea>
{/foreach}
My module function is:
$this->context->smarty->assign(
array(
'row_list' => $this->getField($id)
)
);
return $this->display(__FILE__, 'admin-view.tpl');

The autoload_rte is "used" when tab Informations is loaded by Prestashop using:
$(document).ready(function(){
// Execute when tab Informations has finished loading
tabs_manager.onLoad('Informations', function(){
tinySetup({
editor_selector :"autoload_rte",
setup : function(ed) {
ed.on('init', function(ed)
{
if (typeof ProductMultishop.load_tinymce[ed.target.id] != 'undefined')
{
if (typeof ProductMultishop.load_tinymce[ed.target.id])
tinyMCE.get(ed.target.id).hide();
else
tinyMCE.get(ed.target.id).show();
}
});
ed.on('keydown', function(ed, e) {
tinyMCE.triggerSave();
textarea = $('#'+tinymce.activeEditor.id);
var max = textarea.parent('div').find('span.counter').data('max');
if (max != 'none')
{
count = tinyMCE.activeEditor.getBody().textContent.length;
rest = max - count;
if (rest < 0)
textarea.parent('div').find('span.counter').html('<span style="color:red;">Maximum '+ max +' characters : '+rest+'</span>');
else
textarea.parent('div').find('span.counter').html(' ');
}
});
}
});
});
});
In addition to this, the other tabs are also loaded later than the Informations tab. To solve this, you need to initialized the tinymce for the field you want. Choose another selector (not sure it's needed but at least there is 100% no chance to mess with the current ones), for example the class mytextarea, then use:
<script>$(document).ready(function(){tinymce.init({mode : "textareas", editor_selector : "mytextarea", plugins: "textcolor paste code"});})</script>
This can be in your tpl.
In my tests, if there is no plugins setup there would be an error in console log. But you can adjust the tinymce settings as you wish.

Related

Exclude a dynamic value from cache with Wordpress Super Cache

I'm using the Super Cache plugin.
For some time I was looking for a solution, but without success. I need to disable the cache for one function in the file functions.php.
add_shortcode('custom_counter', 'example_shortcode');
function example_shortcode() {
// Get custom counter option value
$counter = get_option( 'wc-custom-counter' );
return '<span class="custom-counter">' . $counter . ' rub.</span>';
}
This is shortcode is used on the created custom page. It is necessary that the data output by this shortcode does not fall into the page cache.
Adapted from this old WSE thread, you will find below the complete way to make it working.
Here we display a spinner loading icon that will be replaced by the counter real non cached value through ajax. Javascript stays always active even in a cached page, so it can change anything needed on the page via Ajax or via any detected event. So there is no need to exclude anything in the plugin settings.
The replacement code:
// The shortcode
add_shortcode('custom_counter', 'customer_counter_shortcode');
function customer_counter_shortcode() {
// Start buffering
ob_start();
// Using woocommerce existing animated spinner gif icon
$loading_url = home_url( '/wp-content/plugins/woocommerce/assets/images/select2-spinner.gif' );
// Displaying a "Loading spinner icon + text to be replaced by Ajax value
echo '<span class="custom-counter">
<img id="loading-img" src="'.$loading_url.'" alt="Loading..." style="opacity:0.5; display:inline-block; vertical-align: middle;" />
<span style="opacity:0.5;"> ' . _("loading…") . '</span>
</span>';
?>
<script type="text/javascript">
jQuery( function($){
if (typeof woocommerce_params === 'undefined')
return false;
$.ajax({
type: 'POST',
url: woocommerce_params.ajax_url,
data: {
'action': 'custom_counter',
'custom-counter': true,
},
success: function (result) {
$('.custom-counter').text(result);
console.log('response: '+result); // just for testing | TO BE REMOVED
},
error: function(error){
console.log(error); // just for testing | TO BE REMOVED
}
});
});
</script>
<?php
return ob_get_clean(); // Return the buffered code
}
// The wordpress ajax hooked function (for logged in and non logged users)
add_action('wp_ajax_custom_counter', 'ajax_custom_counter');
add_action('wp_ajax_nopriv_custom_counter', 'ajax_custom_counter');
function ajax_custom_counter() {
if( isset($_POST['custom-counter']) && $_POST['custom-counter'] )
echo get_option( 'wc-custom-counter' ); // Get option value
exit();
}
Code goes in function.php file of your active child theme (or active theme). tested and works.
You cannot exclude a function from cache plugins. Instead you can exclude an URL (in WP Super Cache, go to 'Settings > WP Super Cache > Advanced' - 'Accepted Filenames & Rejected URIs' section).
So, call this function using AJAX instead calling directly and you can exclude the AJAX URL.
Here is the full code.
Add these in theme's functions.php:
add_action('wp_ajax_customer_counter', 'customer_counter_ajax_handler'); // wp_ajax_{action}
add_action('wp_ajax_nopriv_customer_counter', 'customer_counter_ajax_handler'); // wp_ajax_nopriv_{action}
function customer_counter_ajax_handler() {
// Get custom counter option value
$counter = get_option( 'wc-custom-counter' );
echo $counter . ' rub.';
}
Replace all your shortcodes [custom_counter] instances with <span class="customer_counter_shortcode"> </span>.
Add this script to theme's footer.php:
jQuery(function($){
$.ajax({
url : '<?php echo site_url(); ?>/wp-admin/admin-ajax.php', // AJAX handler
data : { action : 'customer_counter' },
type : 'POST',
success : function( $result ){
if( $result ) {
$('.customer_counter_shortcode').html($result);
}
}
});
});
You can then exclude the AJAX URL - /wp-admin/admin-ajax.php?action=customer_counter.

CKEditor Inline Editing on jQuery UI

I'm stuck on making CKEditor inline editing work on jQuery UI, especially on Tabs. Does anyone know how to make it work? Are there any plugins that will make CKEditor work on jQuery UI?
I had a similar issue and it turned out to be due to how the browsers were handling the "hidden" or "disabled" components which had yet to be rendered.
http://ckeditor.com/ticket/9814 gave a example of adding a listener to change the readOnly status when the instance becomes ready.
var ck = CKEDITOR.inline(element);
ck.on( 'instanceReady', function( ev ) {
var editor = ev.editor;
editor.setReadOnly( false );
});
I've been struggling with the same problem since this morning, but I found a fix.
var objCKeditor = new Object({
config: base_url + "library/applications/ckeditor/config.simple.js"
});
var objTab = new Object({
active: false
});
CKEDITOR.disableAutoInline = true;
// Activate your editors when the tabs themselves are activated.
$( ".navigation-tabs" ).on( "tabsactivate", function( event, ui ) {
// Find which tab has been chosen by the user.
objTab.chosen = $(this).tabs('option', 'active');
// Only initialize the editors once...
if ( (objTab.chosen == 3) && (objTab.active == false) ) {
// Loop through the editors.
$( 'div.link-bookmark-comment').each( function() {
// Find the ID for the editor.
objCKeditor.editor = $(this).attr('id');
// ... which is facilitated by this boolean.
objTab.active = true;
CKEDITOR.inline( objCKeditor.editor, { customConfig: objCKeditor.config } );
});
}
} );
So, it would appear that CKEditor does not like to be placed within tabs, or any object which is initially hidden.

Jquery replaceWith:replace one php file with another php file based on screen resolution

I need to be able to replace a php file with another php file based on screen resolution. This is what I have so far:
<script type="text/javascript">
function adjustStyle(width) {
width = parseInt(width);
if (width = 1920) {
$('book.php').replaceWith('book2.php');
}
}
$(function() {
adjustStyle($(this).width());
$(window).resize(function() {
adjustStyle($(this).width());
});
});
</script>
which obviously isn't working-- any ideas? Thank you in advance for any help received.
UPDATE
Is this at all close (to replace the book.php line)?
{ $("a[href*='book.php']").replaceWith('href', 'book2.php'); };
Second Update to reflect input gathered here
function adjustStyle(width) {
width = parseInt(width);
if (width == 1920) {
$('#bookinfo').replaceWith(['book2.php']);
$.ajax({
url: "book2.php",
}).success(function ( data ) {
$('#bookinfo').replaceWith(data);
});
$(function() {
adjustStyle($(this).width());
$(window).resize(function() {
adjustStyle($(this).width());
});
});
}
}
I have not seen the use of replaceWith in the context you put it in. Interpreting that you want to exchange the content, you may want to do so my using the load() function of jQuery.
if(width == 1920){
$("#myDiv").load("book1.php");
} else {
$("#myDiv").load("book2.php");
}
Clicking on the button replaces the content of the div to book2.php.
The first problem is I don't think that you are using the correct selectors. If you have the following container:
<div id="bookContainer">Contents of book1.php</div>
The code to replace the contents of that container should be
$('#bookContainer').replaceWith([contents of book2.php]);
In order to get [contents of book2.php] you will need to pull it in by ajax using the following code I have also included the line above so that the data from book2.php will be placed into the container:
$.ajax({
url: "http://yoururl.com/book2.php",
}).success(function ( data ) {
$('#bookContainer').replaceWith(data);
});.
I haven't tested this so there might be an issue but this is the concept you need to accomplish this.
First off... using a conditional with a single = (equal sign) will cause the condition to always be true while setting the value of variable your checking to the value your checking against.
Your condition should look like the following...
if (width == 1920) { // do something }
Second, please refer to the jQuery documentation for how to replace the entire tag with a jquery object using replaceWith()... http://api.jquery.com/replaceWith/
I would use a shorthand POST with http://api.jquery.com/jQuery.post/ since you don't have the object loaded yet...
In short, my code would look like the following using $.post instead of $.ajax assuming I had a tag with the id of "book" that originally has the contents of book.php and I wanted to replace it with the contents of book2.php...
HTML
<div id="book">*Contents of book.php*</div>
jQuery
function onResize(width) {
if (parseInt(width) >= 1920) {
$.post('book2.php',function(html){
$('#book').html(html).width(width);
});
}
else {
$.post('book.php',function(html){
$('#book').html(html).width(width);
});
}
}
Hope this helps.

jquery script of wordpress plugin dont work in content loaded via ajax

I am using Jquery Hover Footnotes plugin that allows adding footnotes and dynamically displays them on hover-over.
An example of its usage is here: http://restoredisrael.org/blog/961/footnote-plugin-test-page/
In addition, in my single.php, I am showing metadata from custom fields using tabbed content. In other words, when clicking on a tab, a custom field is loaded via ajax on the div, and this content is containing footnotes.
The jquery function managing tabs is:
function tab(var)
{
$(document).ready(function(){
var Tabs = {
'1' : 'page1.php?p='+var,
'2' : 'page2.php?p='+var,
'3' : 'page3.php?p='+var,
'4' : 'page4.php?p='+var,
'5' : 'page5.php?p='+var
}
$.each(Tabs,function(i,j){
var tmp = $('<li>'+i+'</li>');
tmp.find('a').data('page',j);
$('ul.tabContainer').append(tmp);
})
var the_tabs = $('.tab');
the_tabs.click(function(e){
var element = $(this);
var bg = element.attr('class').replace('tab','');
if(!element.data('cache'))
{
$.get(element.data('page'),function(msg){
$('#contentHolder').html(msg);
element.data('cache',msg);
});
}
e.preventDefault();
})
the_tabs.eq(0).click();
});
return false;
}
where Ajax is calling pagex.php which is returning custom field using:
get_post_meta($post->ID, 'key', true);
the html code in single.php is:
<ul class="tabContainer" style="display: none;">
</ul>
<div class="clear"></div>
<div id="tabContent" style="display:none;">
<div id="contentHolder">
</div>
</div>
with:
<body onLoad="tab(<?php echo $thePostID?>);>
the problem is that footnotes appear correcly but the hover dont work. The hover is managed by a js script inside the plugin folder which is loaded correctly in the final source code, but the hover effect dont work for the footnotes in the div loaded by ajax.
I hope I was clear.
Your help is highly appreciated.
So as you said, the problem is related to triggering the plugin JS action after the DOM is updated. I found on the js source of the plugin that the action is triggered by : Footnotes.Setup(), so I added it in the ajax load function.
The code now is:
function tab(var)
{
$(document).ready(function(){
var Tabs = {
'1' : 'page1.php?p='+var,
'2' : 'page2.php?p='+var,
'3' : 'page3.php?p='+var,
'4' : 'page4.php?p='+var,
'5' : 'page5.php?p='+var
}
$.each(Tabs,function(i,j){
var tmp = $('<li>'+i+'</li>');
tmp.find('a').data('page',j);
$('ul.tabContainer').append(tmp);
})
var the_tabs = $('.tab');
the_tabs.click(function(e){
var element = $(this);
var bg = element.attr('class').replace('tab','');
if(!element.data('cache'))
{
$.get(element.data('page'),function(msg){
$('#contentHolder').html(msg);
**Footnotes.setup();**
element.data('cache',msg);
});
}
e.preventDefault();
})
the_tabs.eq(0).click();
});
return false;
}

Codeigniter: TinyMCE image manager dynamic image paths

I have installed TinyMCE into my codeigniter build, and I have included the image manager.
In the image manager plugin (which is saved in the public/assets folder) there is a php config file which defines the image & file path constants.
define('DIR_IMAGES', 'images/path/here'); etc
The problem I have is I need the path to be dynamic depending on some data in the database, such as template_name, but I dont know how to include the right files into the config file so I can view the dynamic info.
So if the user has a template_name saved then I need the path to be
define('DIR_IMAGES', $template_name.'images/path/here');
I have also defined the template_name in a constant in core/MY_Controller.php so if I could access that variable that would be easier than doing a query to the DB but either way will work.
Can someone give me a hand with this, thanks a lot!
I've just custom tinymce image but not using TinyMCE image manager.
but I use the tutorial from the link below.
How-to implement a custom file browser
<!-- Start tinymce custom -->
<script type="text/javascript">
tinyMCE.init({
<!--
your tiny mce init here
--->
<!-- custom file browser callback -->
file_browser_callback : 'myFileBrowser',
});
function myFileBrowser (field_name, url, type, win) {
// this is your dynamic image path
var cmsURL = "<?php echo base_url() ?>admin/media/select_image"; <== you can set as you wish
if (cmsURL.indexOf("?") < 0) {
//add the type as the only query parameter
cmsURL = cmsURL + "?type=" + type;
}
else {
//add the type as an additional query parameter
// (PHP session ID is now included if there is one at all)
cmsURL = cmsURL + "&type=" + type;
}
tinyMCE.activeEditor.windowManager.open({
file : cmsURL
,width : 600
,height : 600
,resizable : "yes"
,inline : "yes"
,close_previous : "yes"
,popup_css : true // Disable TinyMCE's default popup CSS
}, {
window : win,
input : field_name
});
return false;
}
</script>
Add a "data-" attribute to your tinymce element and echo your desired url from there. Then in tinymce activeEditor, access that data- attribute value.
Textarea
<textarea name="description" class="tinymceDescription" data-uploadLink="<?php echo DIR_IMAGES; ?>" ></textarea>
TinyMce
tinymce.init({
// other settings here
//either use this if you are uploading automatically.
images_upload_url: $(tinymce.activeEditor.targetElm).attr("data-uploadLink"),
//or use this if you want to override tinymce auto upload.
images_upload_handler: function (blobInfo, success, failure) {
var xhr, formData;
var uploadLink = $(tinymce.activeEditor.targetElm).attr("data-uploadLink");
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', uploadLink);
xhr.onload = function () {
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
failure(xhr.responseText);
return;
}
success(json.location);
};
formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
}
});
The point here is to show you how i got a dynamic upload url into tinymce from the currently selected tinymce instance. The way you upload is your choice which i hope you know how to handle. But ether way, i have provide both the automatic and custom examples.

Categories