TinyMCE views API improvements

In WordPress 4.2 there will be changes to the experimental TinyMCE views APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways.. We don’t recommend this for use in production unless you closely follow the development.

If you’re using it we’d love to get some feedback: bugs, suggestions, things you wish you could do with it… You’re also welcome to leave a comment with a link to your project. I’d love to know what kind of content you’re using it for and how you’re using it.

Summary of the changes:

  • Simpler registration.
  • An easier way to update the view in the edit method.
  • You can choose to leave the text instead of replacing it with a loader. This is especially useful for our oEmbed views because we don’t know if the URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org can be embedded until we get a response from the server.
  • You can now update the view text with a text of a different type (e.g. audio to playlist).
  • No need to use the setIframes method directly, render and setContent will handle it for you.
  • Already rendered views will never refresh again while editing other content. They do refresh when undoing or redoing things though, because TinyMCE resets the whole content unfortunately.
  • Options set in the match method (previously toView) will be added automatically to the view instance.
  • A couple of memory leaks were fixed and there’s a better way to bind and unbind views.
  • We added documentation for all the methods.

How to use the API

Registration:

window.wp.mce.views.register( 'unique_name', {
	...
} );

If you’re converting shortcodes to views, make sure unique_name is the same. They’ll be matched automatically. If you’re interested in custom matching, take a look at the embedURL registration in core.

If the content of your view is static, you can set the content property directly, if it is dynamic, overwrite getContent. In most cases an ajax request is needed to generate the content, so use the initialize method and cache the content. Passing it through render will cache it automatically.

This example will display the most recent images.

initialize: function() {
	var self = this;

	wp.ajax.post( 'query-attachments', {
		query: {
			post_mime_type: 'image'
		}
	} )
	.done( function( response ) {
		self.render( _.map( response, function( data ) {
			return '<img src=' + data.sizes.thumbnail.url + ' alt=' + data.alt + '>';
		} ).join( '' ) );
	} );
}

To add UIUI User interface for editing a view, you need to add an edit method. This example is taken from the gallery view. Use the callback to update the view with the modified text (shortcodeShortcode A shortcode is a placeholder used within a WordPress post, page, or widget to insert a form or function generated by a plugin in a specific location on your site.).

edit: function( text, update ) {
	var frame = wp.media.gallery.edit( text );

	frame.state( 'gallery-edit' ).on( 'update', function( selection ) {
		update( wp.media.gallery.shortcode( selection ).string() );
	} );

	frame.on( 'close', function() {
		frame.detach();
	} );
}

It is not recommended to run JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. in the editor iframeiframe iFrame is an acronym for an inline frame. An iFrame is used inside a webpage to load another HTML document and render it. This HTML document may also contain JavaScript and/or CSS which is loaded at the time when iframe tag is parsed by the user’s browser.. If you need to run scripts it is best to use a sandbox iframe inside the view. The API will automatically do this for you if it detects scripts in your content. For example the Google Maps API might alter the editor’s iframe body. This is not acceptable because the body content is serialised by TinyMCE on saving.

In this example the content will be put in an iframe and you can do anything you want in that document.

content: [
	'<script src="//maps.googleapis.com/maps/api/js?sensor=false"></script>',
	'<style>img { max-width: none; }</style>',
	'<div id="map" style="width: 100%;height: 500px;"></div>',
	'<script>new google.maps.Map( document.getElementById( "map" ), { zoom: 0, center: new google.maps.LatLng( 0, 0 ) } )</script>'
].join( '' )

If you do want to run scripts, use the bind and unbind methods and make sure there are no memory leaks.

#4-2, #dev-notes