Skip to content

Commit

Permalink
Use the new media modal to insert galleries into TinyMCE and the text…
Browse files Browse the repository at this point in the history
… editor.

'''Galleries'''

* Gallery insertion from the new media modal (into TinyMCE, the text editor, etc).
* Gallery previews in TinyMCE now use the `wp.mce.views` API.
* Disables the TinyMCE `wpgallery` plugin.
* Gallery previews consist of the first image of the gallery and the appearance of a stack. This will later be fleshed out to include more images/functionality (including editing the gallery, gallery properties, and showing the number of images in the gallery).
* Multiple galleries can be added to a single post.
* The gallery MCE view provides a bridge between the `wp.shortcode` and `Attachments` representation of a gallery, which allows the existing collection to persist when a gallery is initially created (preventing a request to the server for the query).


'''Shortcodes'''

* Renames `wp.shortcode.Match` to `wp.shortcode` to better expose the shortcode constructor.
* The `wp.shortcode` constructor now accepts an object of options instead of a `wp.shortcode.regexp()` match.
* A `wp.shortcode` instance can be created from a `wp.shortcode.regexp()` match by calling `wp.shortcode.fromMatch( match )`.
* Adds `wp.shortcode.string()`, which takes a set of shortcode parameters and converts them into a string.* Renames `wp.shortcode.prototype.text()` to `wp.shortcode.prototype.string()`.
* Adds an additional capture group to `wp.shortcode.regexp()` that records whether or not the shortcode has a closing tag. This allows us to improve the accuracy of the syntax used when transforming a shortcode object back into a string.

'''Media Models'''

* Prevents media `Query` models from observing the central `Attachments.all` object when query args without corresponding filters are set (otherwise, queries quickly amass false positives).
* Adds `post__in`, `post__not_in`, and `post_parent` as acceptable JS attachment `Query` args.
* `Attachments.more()` always returns a `$.promise` object.

see #21390, #21809, #21812, #21815, #21817.


git-svn-id: http://core.svn.wordpress.org/trunk@22120 1a063a9b-81f0-0310-95a4-ce76da25c4cd
  • Loading branch information
koop committed Oct 5, 2012
1 parent 4d4d747 commit 1deab58
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 72 deletions.
5 changes: 4 additions & 1 deletion wp-admin/includes/ajax-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -1802,7 +1802,10 @@ function wp_ajax_get_attachment() {
*/
function wp_ajax_query_attachments() {
$query = isset( $_REQUEST['query'] ) ? (array) $_REQUEST['query'] : array();
$query = array_intersect_key( $query, array_flip( array( 's', 'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type' ) ) );
$query = array_intersect_key( $query, array_flip( array(
's', 'order', 'orderby', 'posts_per_page', 'paged', 'post_mime_type',
'post_parent', 'post__in', 'post__not_in',
) ) );

$query['post_type'] = 'attachment';
$query['post_status'] = 'inherit';
Expand Down
13 changes: 12 additions & 1 deletion wp-admin/js/media-upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,23 @@ var tb_position;
multiple: true
} ) );

workflow.on( 'update', function( selection ) {
workflow.on( 'update:insert', function( selection ) {
this.insert( '\n' + selection.map( function( attachment ) {
return wp.media.string.image( attachment );
}).join('\n\n') + '\n' );
}, this );

workflow.on( 'update:gallery', function( selection ) {
var view = wp.mce.view.get('gallery'),
shortcode;

if ( ! view )
return;

shortcode = view.gallery.shortcode( selection );
this.insert( shortcode.string() );
}, this );

return workflow;
},

Expand Down
2 changes: 1 addition & 1 deletion wp-includes/class-wp-editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public static function editor_settings($editor_id, $set) {
self::$baseurl = includes_url('js/tinymce');
self::$mce_locale = $mce_locale = ( '' == get_locale() ) ? 'en' : strtolower( substr(get_locale(), 0, 2) ); // only ISO 639-1
$no_captions = (bool) apply_filters( 'disable_captions', '' );
$plugins = array( 'inlinepopups', 'spellchecker', 'tabfocus', 'paste', 'media', 'fullscreen', 'wordpress', 'wpgallery', 'wplink', 'wpdialogs', 'wpview' );
$plugins = array( 'inlinepopups', 'spellchecker', 'tabfocus', 'paste', 'media', 'fullscreen', 'wordpress', 'wplink', 'wpdialogs', 'wpview' );
$first_run = true;
$ext_plugins = '';

Expand Down
102 changes: 101 additions & 1 deletion wp-includes/js/mce-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ if ( typeof wp === 'undefined' )
shortcode: {
view: Backbone.View,
text: function( instance ) {
return instance.options.shortcode.text();
return instance.options.shortcode.string();
},

toView: function( content ) {
Expand Down Expand Up @@ -503,4 +503,104 @@ if ( typeof wp === 'undefined' )
}
}
});

mceview.add( 'gallery', {
shortcode: 'gallery',

gallery: (function() {
var galleries = {};

return {
attachments: function( shortcode, parent ) {
var shortcodeString = shortcode.string(),
result = galleries[ shortcodeString ],
attrs, args;

delete galleries[ shortcodeString ];

if ( result )
return result;

attrs = shortcode.attrs.named;
args = _.pick( attrs, 'orderby', 'order' );

args.type = 'image';
args.perPage = -1;

// Map the `ids` param to the correct query args.
if ( attrs.ids ) {
args.post__in = attrs.ids.split(',');
args.orderby = 'post__in';
} else if ( attrs.include ) {
args.post__in = attrs.include.split(',');
}

if ( attrs.exclude )
args.post__not_in = attrs.exclude.split(',');

if ( ! args.post__in )
args.parent = attrs.id || parent;

return media.query( args );
},

shortcode: function( attachments ) {
var attrs = _.pick( attachments.props.toJSON(), 'include', 'exclude', 'orderby', 'order' ),
shortcode;

attrs.ids = attachments.pluck('id');

shortcode = new wp.shortcode({
tag: 'gallery',
attrs: attrs,
type: 'single'
});

galleries[ shortcode.string() ] = attachments;
return shortcode;
}
};
}()),

view: {
className: 'editor-gallery',
template: media.template('editor-gallery'),

// The fallback post ID to use as a parent for galleries that don't
// specify the `ids` or `include` parameters.
//
// Uses the hidden input on the edit posts page by default.
parent: $('#post_ID').val(),

events: {
'click .close': 'remove'
},

initialize: function() {
var view = mceview.get('gallery'),
shortcode = this.options.shortcode;

this.attachments = view.gallery.attachments( shortcode, this.parent );
this.attachments.more().done( _.bind( this.render, this ) );
},

render: function() {
var options, thumbnail, size;

if ( ! this.attachments.length )
return;

thumbnail = this.attachments.first().toJSON();
size = thumbnail.sizes && thumbnail.sizes.thumbnail ? thumbnail.sizes.thumbnail : thumbnail;

options = {
url: size.url,
orientation: size.orientation,
count: this.attachments.length
};

this.$el.html( this.template( options ) );
}
}
});
}(jQuery));
36 changes: 24 additions & 12 deletions wp-includes/js/media-models.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,7 @@ if ( typeof wp === 'undefined' )
this.props.on( 'change:type', this._changeType, this );

// Set the `props` model and fill the default property values.
this.props.set( _.defaults( options.props || {}, {
order: 'DESC'
}) );
this.props.set( _.defaults( options.props || {} ) );

// Observe another `Attachments` collection if one is provided.
if ( options.observe )
Expand All @@ -248,7 +246,7 @@ if ( typeof wp === 'undefined' )
if ( this.comparator && this.comparator !== Attachments.comparator )
return;

if ( orderby )
if ( orderby && 'post__in' !== orderby )
this.comparator = Attachments.comparator;
else
delete this.comparator;
Expand Down Expand Up @@ -347,6 +345,7 @@ if ( typeof wp === 'undefined' )
more: function( options ) {
if ( this.mirroring && this.mirroring.more )
return this.mirroring.more( options );
return $.Deferred().resolve().promise();
},

parse: function( resp, xhr ) {
Expand All @@ -363,7 +362,7 @@ if ( typeof wp === 'undefined' )
}, {
comparator: function( a, b ) {
var key = this.props.get('orderby'),
order = this.props.get('order'),
order = this.props.get('order') || 'DESC',
ac = a.cid,
bc = b.cid;

Expand Down Expand Up @@ -423,6 +422,8 @@ if ( typeof wp === 'undefined' )
*/
Query = media.model.Query = Attachments.extend({
initialize: function( models, options ) {
var allowed;

options = options || {};
Attachments.prototype.initialize.apply( this, arguments );

Expand Down Expand Up @@ -451,20 +452,28 @@ if ( typeof wp === 'undefined' )
return false;
};

this.observe( Attachments.all );
// Observe the central `Attachments.all` model to watch for new
// matches for the query.
//
// Only observe when a limited number of query args are set. There
// are no filters for other properties, so observing will result in
// false positives in those queries.
allowed = [ 's', 'order', 'orderby', 'posts_per_page', 'post_mime_type' ];
if ( _( this.args ).chain().keys().difference().isEmpty().value() )
this.observe( Attachments.all );
},

more: function( options ) {
var query = this;

if ( ! this.hasMore )
return;
return $.Deferred().resolve().promise();

options = options || {};
options.add = true;

return this.fetch( options ).done( function( resp ) {
if ( _.isEmpty( resp ) || resp.length < this.args.posts_per_page )
if ( _.isEmpty( resp ) || -1 === this.args.posts_per_page || resp.length < this.args.posts_per_page )
query.hasMore = false;
});
},
Expand All @@ -484,7 +493,8 @@ if ( typeof wp === 'undefined' )
args = _.clone( this.args );

// Determine which page to query.
args.paged = Math.floor( this.length / args.posts_per_page ) + 1;
if ( -1 !== args.posts_per_page )
args.paged = Math.floor( this.length / args.posts_per_page ) + 1;

options.data.query = args;
return media.ajax( options );
Expand All @@ -506,16 +516,18 @@ if ( typeof wp === 'undefined' )
},

orderby: {
allowed: [ 'name', 'author', 'date', 'title', 'modified', 'uploadedTo', 'id' ],
allowed: [ 'name', 'author', 'date', 'title', 'modified', 'uploadedTo', 'id', 'post__in' ],
valuemap: {
'id': 'ID',
'uploadedTo': 'parent'
}
},

propmap: {
'search': 's',
'type': 'post_mime_type'
'search': 's',
'type': 'post_mime_type',
'parent': 'post_parent',
'perPage': 'posts_per_page'
},

// Caches query objects so queries can be easily reused.
Expand Down
7 changes: 4 additions & 3 deletions wp-includes/js/media-views.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,10 @@
return this;
},

update: function() {
update: function( event ) {
this.close();
this.trigger( 'update', this.selection );
this.trigger( 'update:' + event, this.selection );
this.selection.clear();
},

Expand Down Expand Up @@ -630,7 +631,7 @@
'insert-into-post': {
text: l10n.insertIntoPost,
priority: 30,
click: _.bind( controller.update, controller )
click: _.bind( controller.update, controller, 'insert' )
},

'add-to-gallery': {
Expand Down Expand Up @@ -698,7 +699,7 @@
style: 'primary',
text: l10n.insertGalleryIntoPost,
priority: 40,
click: _.bind( controller.update, controller )
click: _.bind( controller.update, controller, 'gallery' )
},

'add-images-from-library': {
Expand Down
Loading

0 comments on commit 1deab58

Please sign in to comment.