Wordpress Media Uploader Frame Multiple Item Selection Clear/Edit Tool - wordpress

As part of a WP plugin I am creating, I am using Wordpress' Javascript/AJAX modal Uploader/gallery browser for multiple item selection. I am using this JS code;
file_frame = wp.media.frames.file_frame = wp.media({
multiple: true,
library: {
type: 'image'
},
});
This creates the frame as expected, but removes the left hand side bar, and the bottom edit/clear selection tool. Does anyone know how I can get these 2 things back?

Related

How do you add a custom button to the Elementor Text Editor widget toolbar?

I'm trying to add a custom button into the Elementor text widget toolbar next to other buttons like Bold, Italic, Underline etc. It seems that the ability to customize the instance using PHP may be disabled but that it is possible to do so using JavaScript instead.
I can get back the view by using the following code but I'm unable to get back the editor instance.
elementor.hooks.addAction( 'panel/open_editor/widget/text-editor', function( panel, model, view ) {}
I've tried the following suggestions but none seem to return anything after that.
// get active instances of the editor
let editor = tinymce.activeEditor;
var editor = elementor.editors.get(0).getEditModel().get('editor');
var activeEditor = view.getOption('editor');
The rest of the suggested code after getting the editor instance is as follows but I don't get this far.
// add a button to the editor buttons
editor.addButton('tooltip', {
text: 'tooltip',
icon: false,
onclick: (editor) => {
tooltipCallback(editor);
}
});
// the button now becomes
let button=editor.buttons['tooltip'];
// find the buttongroup in the toolbar found in the panel of the theme
let bg=editor.theme.panel.find('toolbar buttongroup')[0];
// without this, the buttons look weird after that
bg._lastRepaintRect=bg._layoutRect;
// append the button to the group
bg.append(button);

wp_enqueue_scripts in TinyMCE Modal

I'm creating a simple WordPress plugin that requires wp_enqueue_media() to be called from a TinyMCE pop up in order to upload and/or select an image.
The issue im having is wp_enqueue_media() and wp_enqueue_script() don't appear to work with the TinyMCE pop up modal.
I am including wp-load.php in my modal window.
Is there a way to utilize native WordPress script loading within a TinyMCE modal?
Here is an example of what I am doing.
http://return-true.com/adding-tinymce-button-to-wordpress-via-plugin-part-2/
Like I already said in my comment, I think the best approach is to use an inline modal (no iframe).
It is very simple: using the 1st part of the article (http://return-true.com/adding-tinymce-button-to-wordpress-via-a-plugin/) as a basis, just replace the JavaScript with the following (copied from TinyMCE guidelines):
(function() {
tinymce.PluginManager.add('example', function(editor) {
// Add a button that opens a window
editor.addButton('example', {
text: 'Example',
icon: false,
onclick: function() {
// Open window
editor.windowManager.open({
title: 'Example plugin',
body: [
{type: 'textbox', name: 'title', label: 'Title'}
],
onsubmit: function(e) {
// Insert content when the window form is submitted
editor.insertContent('Title: ' + e.data.title);
}
});
}
});
});
})();
After that, you have a simple modal, with no iframe, thus using the native Wordpress script loading.
If the content must be in an iframe (which I doubt), one option is to create a 'blank' page in Wordpress with a page template of its own and use that page as the modal content. I actually tested that it works, but it is clearly more complicated (requires something like a blog post to explain).
The issue was that I was not including wp_head() and wp_footer() in the modal window html.
Adding these functions solved the enqueue issues.

Dyanmically Adding Buttons to Toolbar in Addon SDK

In my script I am reading from a json file and building sdk menu buttons from the data there. This works just fine, but I am having trouble adding these buttons to my sdk toolbar.
So, in the loop where I load the data from the json file, I am creating a button from the data and I add the button to an array like this:
var alltheButtons = [];
...
alltheButtons.push(jsondata[key].button);
In the loop where I create the buttons, I am adding
var myToolbar = Toolbar({
title: "My toolbar",
items: [alltheButtons]
});
However, what happens is that the script errors out when trying to add alltheButtons to the toolbar (whence they end up on the regular navbar since they are not attached to any specific toolbar).
The error is this:
Message: TypeError: aId.startsWith is not a function
So, how do I specify an array of buttons to the toolbar's items attribute?
Try this:
var myToolbar = Toolbar({
title: "My toolbar",
items: alltheButtons
});
items is supposed to be an Array but you are giving it Array<Array>
Alternatively you could make use the ES2015 spread operator:
var myToolbar = Toolbar({
title: "My toolbar",
items: [...alltheButtons, oneMoreButton]
});

Open/Access WP Media library from tinymce plugin popup window

I'm building a tinymce button plugin for the Wordpress (4) editor. The popup window that my button opens displays a form with several fields. One of them is for selecting an image inside the WP media library. I can't figure how to achieve this.
If that's not possible, what would be the best way to allow the user to select an image stored in the WP media library from a tinymce plugin popup window ?
FYI, the tinymce plugin inserts a shortcode with an image src as an attribute.
thanks !
I had the same problem just now and found the solution so I'm sharing it here. I hope it's not too late.
First to be able to use WP Add Media button you would have to enqueue the needed script. This is easy, just call the wp_enqueue_media() function like so:
add_action('admin_enqueue_scripts', 'enqueue_scripts_styles_admin');
function enqueue_scripts_styles_admin(){
wp_enqueue_media();
}
This call ensures you have the needed libraries to use the WP Media button.
Of course you should also have the HTML elements to hold the uploaded/selected media file URL, something like this:
<input type="text" class="selected_image" />
<input type="button" class="upload_image_button" value="Upload Image">
The first text field will hold the URL of the media file while the second is a button to open the media popup window itself.
Then in your jscript, you'd have something like this:
var custom_uploader;
$('.upload_image_button').click(function(e) {
e.preventDefault();
var $upload_button = $(this);
//Extend the wp.media object
custom_uploader = wp.media.frames.file_frame = wp.media({
title: 'Choose Image',
button: {
text: 'Choose Image'
},
multiple: false
});
//When a file is selected, grab the URL and set it as the text field's value
custom_uploader.on('select', function() {
var attachment = custom_uploader.state().get('selection').first().toJSON();
$upload_button.siblings('input[type="text"]').val(attachment.url);
});
//Open the uploader dialog
custom_uploader.open();
});
Now I'm not going to explain every line because it's not that hard to understand. The most important part is the one that uses the wp object to make all these to work.
The tricky part is making all these work on a TinyMCE popup(which is the problem I faced). I've searched hi and lo for the solution and here's what worked for me. But before that, I'll talk about what problem I encountered first. When I first tried to implement this, I encountered the "WP is undefined" problem on the popup itself. To solve this, you just have to pass the WP object to the script like so:
(function() {
tinymce.create('tinymce.plugins.someplugin', {
init : function(ed, url) {
// Register commands
ed.addCommand('mcebutton', function() {
ed.windowManager.open(
{
file : url + '/editor_button.php', // file that contains HTML for our modal window
width : 800 + parseInt(ed.getLang('button.delta_width', 0)), // size of our window
height : 600 + parseInt(ed.getLang('button.delta_height', 0)), // size of our window
inline : 1
},
{
plugin_url : url,
wp: wp
}
);
});
// Register buttons
ed.addButton('someplugin_button', {title : 'Insert Seomthing', cmd : 'mcebutton', image: url + '/images/some_button.gif' });
}
});
// Register plugin
// first parameter is the button ID and must match ID elsewhere
// second parameter must match the first parameter of the tinymce.create() function above
tinymce.PluginManager.add('someplugin_button', tinymce.plugins.someplugin);
})();
What we're interested in is this line => "wp: wp" . This line ensures that we are passing the wp object to the popup window (an iframe really...) that is to be opened when we click the tinymce button. You can actually pass anything to the popup window via this object (the 2nd parameter of the ed.windowManager.open method)!
Last but not the least you'd have to reference that passed wp object on your javascript like so:
var args = top.tinymce.activeEditor.windowManager.getParams();
var wp = args.wp;
Make sure you do that before calling/using the WP object.
That's all you have to do to make this work. It worked for me, I hope it works for you :)
I took the code of Paolo and simplified it in order not to have many files to manage. Also, I didn't manage to make it work like this.
So this solution has less code and uses only one single file.
Just put this in your tinyMCE plugins js file:
(function(){
tinymce.PluginManager.add('myCustomButtons', function(editor, url){
editor.addButton('btnMedia', {
icon: 'image',
tooltip: 'Add an image',
onclick: function() {
editor.windowManager.open({
title: 'Add an image',
body: [{
type: 'textbox',
subtype: 'hidden',
name: 'id',
id: 'hiddenID'
},
{
type: 'textbox',
name: 'text',
label: 'Text',
id: 'imageText'
},
{
type: 'button',
text: 'Choose an image',
onclick: function(e){
e.preventDefault();
var hidden = jQuery('#hiddenID');
var texte = jQuery('#imageText');
var custom_uploader = wp.media.frames.file_frame = wp.media({
title: 'Choose an image',
button: {text: 'Add an image'},
multiple: false
});
custom_uploader.on('select', function() {
var attachment = custom_uploader.state().get('selection').first().toJSON();
hidden.val(attachment.id);
if(!texte.val()){
if(attachment.alt)
texte.val(attachment.alt);
else if(attachment.title)
texte.val(attachment.title);
else
texte.val('See the image');
}
});
custom_uploader.open();
}
}],
onsubmit: function(e){
var image = '<button data-id="'+e.data.id+'">'+e.data.text+'</button>';
editor.insertContent(image);
}
});
}
});
});
})();
The result in the frontend html is a button which has the ID of the image in a data-id attribute, and a text to display (the alt of the image, by default, or its title or a text the user can write).
Then, with my frontend js, I will get the corresponding image with its ID and show it in an ajax popup.
With this solution, you have all of your js functions in one single file, and you don't need to enqueue any script nor to create a php file.
I know it's old but in case anyone else facing the same situation, The Paolo's solution above is working fine but no need to enqueue wp_enqueue_media(); this will load a bunch of scripts, you can load only 2 scripts:
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'media-lib-uploader-js' );

Custom image size in new media uploader

I am developing a relatively simple Wordpress plugin for a client. It is used to upload/select images which are then saved (as image path) in the option variables and used as full-background images for the website's different categories/pages/etc..
Since images are of "wallpapery nature" (i.e. big) I added a custom image size with a maximum width of 1920 pixels (height is set to "auto", i.e. no image cropping). And that part also works, upon upload, images are being resized to my custom 1920 px width.
Now, the thing is, for uploading/choosing the background image I'm using the new media uploader and it works except that the chosen image (path) is always for the original uploaded image, for example "my-background-image.jpg".
My question is: is there a way to enable users (or make the uploader do it automatically) to select the 1920 px sized version of the original image, for example "my-background-image-1920x1080.jpg"?
Thanks!
I managed to sort out my problem, a bit differently than I first approached it - but it is a solution I'm even more pleased.
So, when you use the new media uploader, you have a jquery code that looks something like this:
jQuery(document).ready(function($){
var custom_uploader;
$('.upload_image_button').unbind('click').click(function(e) {
e.preventDefault();
formfieldID=jQuery(this).prev().attr("id");
//If the uploader object has already been created, reopen the dialog
if (custom_uploader) {
custom_uploader.open();
return;
}
//Extend the wp.media object
custom_uploader = wp.media.frames.file_frame = wp.media({
title: 'Choose Image',
button: {
text: 'Choose Image'
},
multiple: false
});
//When a file is selected, grab the URL and set it as the text field's value
custom_uploader.on('select', function() {
attachment = custom_uploader.state().get('selection').first().toJSON();
$('.' + formfieldID).val(attachment.url);
});
//Open the uploader dialog
custom_uploader.open();
});
});
Now, note the part of the code that gets the selected file's url:
$('.' + formfieldID).val(attachment.url);
This gets the ORIGINAL attachment's (image) url. So, to get some other image size, like thumbnail, large, etc. you use this:
$('.' + formfieldID).val(attachment.sizes.thumbnail.url);
AND in the end, you can even use your own custom image size like this:
$('.' + formfieldID).val(attachment.sizes.mysize.url);
BUT... I ran into one stupid but very time-consuming problem: DO NOT give your custom image size a name that is separated by a minus sign, like "background-image"; because while Wordpress part of it will work (the new image size will be visible and usable) the jquery for media uploader won't work with it.
If you need a separator, use underscore instead, e.g. "background_image" and it will work normally! This could be a beginner's error on my part, but I thought it could save someone some time! :)

Resources