Make WordPress Core

Changeset 28682


Ignore:
Timestamp:
06/05/2014 10:00:24 PM (12 years ago)
Author:
helen
Message:

Grid view for the media library, first pass. This is alpha; expect imperfection. We will be iterating further.

props ericlewis, shaunandrews, wonderboymusic.
see #24716.

Location:
trunk/src
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/list-tables.css

    r27956 r28682  
    635635.view-switch > a:before {
    636636        color: #bbb;
    637         content: '\f163';
    638637        display: inline-block;
    639638        float: left;
     
    646645}
    647646
     647.view-switch > .view-list:before {
     648        content: '\f163';
     649}
     650
    648651.view-switch a:hover:before {
    649652        color: #727272;
     
    654657}
    655658
    656 .view-switch > a + a:before {
     659.view-switch > a + a {
    657660        margin-left: 5px;
     661}
     662
     663.view-switch > .view-excerpt:before {
    658664        content: '\f164';
     665}
     666
     667.view-switch > .view-grid:before {
     668        content: '\f180';
    659669}
    660670
  • trunk/src/wp-admin/includes/class-wp-list-table.php

    r28524 r28682  
    494494<?php
    495495                        foreach ( $modes as $mode => $title ) {
    496                                 $class = ( $current_mode == $mode ) ? 'class="current"' : '';
    497                                 echo "<a href='" . esc_url( add_query_arg( 'mode', $mode, $_SERVER['REQUEST_URI'] ) ) . "' $class><img id='view-switch-$mode' src='" . esc_url( includes_url( 'images/blank.gif' ) ) . "' width='20' height='20' title='$title' alt='$title' /></a>\n";
     496                                $classes = array( 'view-' . $mode );
     497                                if ( $current_mode == $mode )
     498                                        $classes[] = 'current';
     499                                printf(
     500                                        "<a href='%s' class='%s'><img id='view-switch-$mode' src='%s' width='20' height='20' title='%s' alt='%s' /></a>\n",
     501                                        esc_url( add_query_arg( 'mode', $mode ) ),
     502                                        implode( ' ', $classes ),
     503                                        esc_url( includes_url( 'images/blank.gif' ) ),
     504                                        $title,
     505                                        $title
     506                                );
    498507                        }
    499508                ?>
  • trunk/src/wp-admin/includes/class-wp-media-list-table.php

    r28553 r28682  
    2424
    2525        public function prepare_items() {
    26                 global $lost, $wp_query, $post_mime_types, $avail_post_mime_types;
     26                global $lost, $wp_query, $post_mime_types, $avail_post_mime_types, $mode;
    2727
    2828                $q = $_REQUEST;
     
    3434
    3535                $this->is_trash = isset( $_REQUEST['status'] ) && 'trash' == $_REQUEST['status'];
     36
     37                $mode = empty( $_REQUEST['mode'] ) ? 'list' : $_REQUEST['mode'];
    3638
    3739                $this->set_pagination_args( array(
     
    124126        public function no_items() {
    125127                _e( 'No media attachments found.' );
     128        }
     129
     130        protected function pagination( $which ) {
     131                global $mode;
     132
     133                parent::pagination( $which );
     134
     135                $this->view_switcher( $mode );
     136        }
     137
     138        /**
     139         * Display a view switcher
     140         *
     141         * @since 3.1.0
     142         * @access protected
     143         */
     144        protected function view_switcher( $current_mode ) {
     145                $modes = array(
     146                        'list'    => __( 'List View' ),
     147                        'grid' => __( 'Grid View' )
     148                );
     149
     150?>
     151                <input type="hidden" name="mode" value="<?php echo esc_attr( $current_mode ); ?>" />
     152                <div class="view-switch">
     153<?php
     154                        foreach ( $modes as $mode => $title ) {
     155                                $classes = array( 'view-' . $mode );
     156                                if ( $current_mode == $mode )
     157                                        $classes[] = 'current';
     158                                printf(
     159                                        "<a href='%s' class='%s'><img id='view-switch-$mode' src='%s' width='20' height='20' title='%s' alt='%s' /></a>\n",
     160                                        esc_url( add_query_arg( 'mode', $mode ) ),
     161                                        implode( ' ', $classes ),
     162                                        esc_url( includes_url( 'images/blank.gif' ) ),
     163                                        $title,
     164                                        $title
     165
     166                                );
     167                        }
     168                ?>
     169                </div>
     170<?php
    126171        }
    127172
  • trunk/src/wp-admin/js/media.js

    r27403 r28682  
    7373
    7474        $( document ).ready( function() {
     75                // Open up a manage media frame into the grid.
     76                wp.media && wp.media({
     77                        frame: 'manage',
     78                        container: $('#wpbody-content')
     79                }).open();
     80
    7581                $( '#find-posts-submit' ).click( function( event ) {
    7682                        if ( ! $( '#find-posts-response input[type="radio"]:checked' ).length )
  • trunk/src/wp-admin/upload.php

    r27469 r28682  
    1212if ( !current_user_can('upload_files') )
    1313        wp_die( __( 'You do not have permission to upload files.' ) );
     14
     15$mode = get_user_option( 'media_library_mode', get_current_user_id() ) ? get_user_option( 'media_library_mode', get_current_user_id() ) : 'grid';
     16$modes = array( 'grid', 'list' );
     17
     18if ( isset( $_GET['mode'] ) && in_array( $_GET['mode'], $modes ) ) {
     19        $mode = $_GET['mode'];
     20        update_user_option( get_current_user_id(), 'media_library_mode', $mode );
     21}
     22
     23if ( 'grid' === $mode ) {
     24        wp_enqueue_media();
     25        wp_enqueue_script( 'media' );
     26        require_once( ABSPATH . 'wp-admin/admin-header.php' );
     27        ?><div class="view-switch media-grid-view-switch">
     28                <a href="<?php echo esc_url( add_query_arg( 'mode', 'list', $_SERVER['REQUEST_URI'] ) ) ?>" class="view-list">
     29                        <img id="view-switch-list" src="<?php echo includes_url( 'images/blank.gif' ) ?>" width="20" height="20" title="List View" alt="List View"/>
     30                </a>
     31                <a href="<?php echo esc_url( add_query_arg( 'mode', 'grid', $_SERVER['REQUEST_URI'] ) ) ?>" class="view-grid current">
     32                        <img id="view-switch-excerpt" src="<?php echo includes_url( 'images/blank.gif' ) ?>" width="20" height="20" title="Grid View" alt="Grid View"/>
     33                </a>
     34        </div><?php
     35        include( ABSPATH . 'wp-admin/admin-footer.php' );
     36        exit;
     37}
    1438
    1539$wp_list_table = _get_list_table('WP_Media_List_Table');
     
    238262
    239263<div id="ajax-response"></div>
    240 <?php find_posts_div(); ?> 
     264<?php find_posts_div(); ?>
    241265</form>
    242266</div>
  • trunk/src/wp-includes/css/media-views.css

    r28607 r28682  
    296296}
    297297
    298 .media-sidebar .setting span {
     298.media-sidebar .setting .name {
    299299        min-width: 30%;
    300300        margin-right: 4%;
    301301        font-size: 12px;
     302        text-align: right;
    302303}
    303304
     
    320321        padding-top: 8px;
    321322        line-height: 16px;
    322         text-align: right;
    323323        font-weight: normal;
    324324        color: #666;
    325325}
    326326
     327.compat-item label span  {
     328        text-align: right;
     329}
     330
    327331.media-sidebar .setting input,
    328 .media-sidebar .setting textarea {
     332.media-sidebar .setting textarea,
     333.media-sidebar .setting .value {
    329334        margin: 1px;
    330335        width: 65%;
     
    18131818}
    18141819
    1815 .image-details .embed-media-settings .setting span {
     1820.image-details .embed-media-settings .setting .name {
    18161821        float: left;
    18171822        width: 25%;
     
    23692374        }
    23702375}
     2376
     2377
     2378/**
     2379 * Media Grid
     2380 */
     2381
     2382.media-grid-view h1 {
     2383        color: #222;
     2384        font-size: 23px;
     2385        font-weight: 400;
     2386        margin: 10px 0 0;
     2387        padding: 9px 15px 4px 22px;
     2388        line-height: 29px;
     2389}
     2390
     2391.media-grid-view-switch {
     2392        position: fixed;
     2393        right: 10px;
     2394        top: 44px;
     2395        z-index: 300;
     2396}
     2397
     2398/**
     2399 * Position both the frame and the uploader window into the content
     2400 * area of the screen.
     2401 */
     2402.media-grid-view {
     2403        position: fixed;
     2404        bottom: 0;
     2405        left: 160px;
     2406        right: 0;
     2407        top: 32px;
     2408}
     2409@media screen and (max-width: 900px) {
     2410        .auto-fold .media-grid-view {
     2411                left: 36px;
     2412        }
     2413}
     2414@media screen and (max-width: 782px) {
     2415        .media-grid-view {
     2416                top: 46px;
     2417        }
     2418        .auto-fold .media-grid-view {
     2419                left: 0px;
     2420                bottom: 0px;
     2421        }
     2422}
     2423
     2424/* Regions we don't use at all */
     2425.media-grid-view .media-frame-toolbar,
     2426.media-grid-view .media-frame-menu {
     2427        display: none;
     2428}
     2429
     2430.media-grid-view .media-frame-content {
     2431        bottom: 40px;
     2432}
     2433@media screen and (max-width: 782px) {
     2434        .media-grid-view .media-frame-content {
     2435                border-bottom: none;
     2436                bottom: 0;
     2437        }
     2438}
     2439
     2440@media only screen and (max-width: 640px), screen and (max-height: 400px) {
     2441        .media-grid-view .media-frame-title {
     2442                display: block;
     2443                width: auto;
     2444                bottom: auto;
     2445                right: 0;
     2446                top: 0;
     2447                height: 60px;
     2448        }
     2449}
  • trunk/src/wp-includes/js/media-models.js

    r28095 r28682  
    3131                } else if ( 'post' === attributes.frame && MediaFrame.Post ) {
    3232                        frame = new MediaFrame.Post( attributes );
     33                } else if ( 'manage' === attributes.frame && MediaFrame.Manage ) {
     34                        frame = new MediaFrame.Manage( attributes );
    3335                } else if ( 'image' === attributes.frame && MediaFrame.ImageDetails ) {
    3436                        frame = new MediaFrame.ImageDetails( attributes );
  • trunk/src/wp-includes/js/media-views.js

    r28675 r28682  
    616616                        this.get('selection').on( 'add remove reset', this.refreshContent, this );
    617617
    618                         if ( this.get('contentUserSetting') ) {
     618                        if ( this.get( 'router' ) && this.get('contentUserSetting') ) {
    619619                                this.frame.on( 'content:activate', this.saveContentMode, this );
    620620                                this.set( 'content', getUserSetting( 'libraryContent', this.get('content') ) );
     
    19191919                        return this;
    19201920                };
     1921        });
     1922
     1923        /**
     1924         * wp.media.view.MediaFrame.Manage
     1925         *
     1926         * A generic management frame workflow.
     1927         *
     1928         * Used in the media grid view.
     1929         *
     1930         * @constructor
     1931         * @augments wp.media.view.MediaFrame
     1932         * @augments wp.media.view.Frame
     1933         * @augments wp.media.View
     1934         * @augments wp.Backbone.View
     1935         * @augments Backbone.View
     1936         * @mixes wp.media.controller.StateMachine
     1937         */
     1938        media.view.MediaFrame.Manage = media.view.MediaFrame.extend({
     1939                /**
     1940                 * @global wp.Uploader
     1941                 */
     1942                initialize: function() {
     1943                        _.defaults( this.options, {
     1944                                title:     l10n.mediaLibraryTitle,
     1945                                modal:     false,
     1946                                selection: [],
     1947                                library:   {},
     1948                                multiple:  false,
     1949                                state:     'library',
     1950                                uploader:  true
     1951                        });
     1952
     1953                        // Ensure core and media grid view UI is enabled.
     1954                        this.$el.addClass('wp-core-ui media-grid-view');
     1955
     1956                        // Force the uploader off if the upload limit has been exceeded or
     1957                        // if the browser isn't supported.
     1958                        if ( wp.Uploader.limitExceeded || ! wp.Uploader.browser.supported ) {
     1959                                this.options.uploader = false;
     1960                        }
     1961
     1962                        // Initialize a window-wide uploader.
     1963                        if ( this.options.uploader ) {
     1964                                this.uploader = new media.view.UploaderWindow({
     1965                                        controller: this,
     1966                                        uploader: {
     1967                                                dropzone:  $('body'),
     1968                                                container: $('body')
     1969                                        }
     1970                                }).render();
     1971                                this.uploader.ready();
     1972                                $('body').append( this.uploader.el );
     1973
     1974                                this.options.uploader = false;
     1975                        }
     1976
     1977                        /**
     1978                         * call 'initialize' directly on the parent class
     1979                         */
     1980                        media.view.MediaFrame.prototype.initialize.apply( this, arguments );
     1981
     1982                        // Since we're not using the default modal built into
     1983                        // a media frame, append our $element to the supplied container.
     1984                        this.$el.appendTo( this.options.container );
     1985
     1986                        this.createSelection();
     1987                        this.createStates();
     1988                        this.bindHandlers();
     1989                        this.render();
     1990                },
     1991
     1992                createSelection: function() {
     1993                        var selection = this.options.selection;
     1994
     1995                        if ( ! (selection instanceof media.model.Selection) ) {
     1996                                this.options.selection = new media.model.Selection( selection, {
     1997                                        multiple: this.options.multiple
     1998                                });
     1999                        }
     2000
     2001                        this._selection = {
     2002                                attachments: new media.model.Attachments(),
     2003                                difference: []
     2004                        };
     2005                },
     2006
     2007                createStates: function() {
     2008                        var options = this.options;
     2009
     2010                        if ( this.options.states ) {
     2011                                return;
     2012                        }
     2013
     2014                        // Add the default states.
     2015                        this.states.add([
     2016                                new media.controller.Library({
     2017                                        library:    media.query( options.library ),
     2018                                        multiple:   options.multiple,
     2019                                        title:      options.title,
     2020                                        priority:   20,
     2021                                        toolbar:    false,
     2022                                        router:     false,
     2023                                        content:    'browse',
     2024                                        filterable: 'mime-types'
     2025                                }),
     2026
     2027                                new media.controller.EditImage( { model: options.editImage } )
     2028                        ]);
     2029                },
     2030
     2031                bindHandlers: function() {
     2032                        this.on( 'content:create:browse', this.browseContent, this );
     2033                        this.on( 'content:render:edit-image', this.editImageContent, this );
     2034                },
     2035
     2036                /**
     2037                 * Content
     2038                 *
     2039                 * @param {Object} content
     2040                 * @this wp.media.controller.Region
     2041                 */
     2042                browseContent: function( content ) {
     2043                        var state = this.state();
     2044
     2045                        // Browse our library of attachments.
     2046                        content.view = new media.view.AttachmentsBrowser({
     2047                                controller: this,
     2048                                collection: state.get('library'),
     2049                                selection:  state.get('selection'),
     2050                                model:      state,
     2051                                sortable:   state.get('sortable'),
     2052                                search:     state.get('searchable'),
     2053                                filters:    state.get('filterable'),
     2054                                display:    state.get('displaySettings'),
     2055                                dragInfo:   state.get('dragInfo'),
     2056                                bulkEdit:   true,
     2057
     2058                                suggestedWidth:  state.get('suggestedWidth'),
     2059                                suggestedHeight: state.get('suggestedHeight'),
     2060
     2061                                AttachmentView: state.get('AttachmentView')
     2062                        });
     2063                },
     2064
     2065                editImageContent: function() {
     2066                        var image = this.state().get('image'),
     2067                                view = new media.view.EditImage( { model: image, controller: this } ).render();
     2068
     2069                        this.content.set( view );
     2070
     2071                        // after creating the wrapper view, load the actual editor via an ajax call
     2072                        view.loadEditor();
     2073
     2074                },
    19212075        });
    19222076
     
    53645518        });
    53655519
     5520        /**
     5521         * wp.media.view.AttachmentFilters.FileTypes
     5522         *
     5523         * @constructor
     5524         * @augments wp.media.view.AttachmentFilters
     5525         * @augments wp.media.View
     5526         * @augments wp.Backbone.View
     5527         * @augments Backbone.View
     5528         */
     5529        media.view.AttachmentFilters.mimeTypes = media.view.AttachmentFilters.extend({
     5530                createFilters: function() {
     5531                        var filters = {};
     5532
     5533                        _.each( media.view.settings.mimeTypes || {}, function( text, key ) {
     5534                                filters[ key ] = {
     5535                                        text: text,
     5536                                        props: {
     5537                                                type:    key,
     5538                                                uploadedTo: null,
     5539                                                orderby: 'date',
     5540                                                order:   'DESC'
     5541                                        }
     5542                                };
     5543                        });
     5544                        filters.all = {
     5545                                text:  l10n.allMediaTypes,
     5546                                props: {
     5547                                        type:    null,
     5548                                        uploadedTo: null,
     5549                                        orderby: 'date',
     5550                                        order:   'DESC'
     5551                                },
     5552                                priority: 10
     5553                        };
     5554
     5555                        this.filters = filters;
     5556                }
     5557        });
     5558
    53665559
    53675560        /**
     
    54185611                        } else if ( 'all' === filters ) {
    54195612                                FiltersConstructor = media.view.AttachmentFilters.All;
     5613                        } else if ( 'mime-types' === filters ) {
     5614                                FiltersConstructor = media.view.AttachmentFilters.mimeTypes;
    54205615                        }
    54215616
  • trunk/src/wp-includes/media-template.php

    r28607 r28682  
    309309                                <div class="uploaded">{{ data.dateFormatted }}</div>
    310310
     311                                <div class="file-size">{{ data.filesizeHumanReadable }}</div>
    311312                                <# if ( 'image' === data.type && ! data.uploading ) { #>
    312313                                        <# if ( data.width && data.height ) { #>
     
    340341                </div>
    341342
     343                <label class="setting" data-setting="url">
     344                        <span class="name"><?php _e('URL'); ?></span>
     345                        <input type="text" value="{{ data.url }}" readonly />
     346                </label>
    342347                <# var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly'; #>
    343                         <label class="setting" data-setting="title">
    344                                 <span><?php _e('Title'); ?></span>
    345                                 <input type="text" value="{{ data.title }}" {{ maybeReadOnly }} />
    346                         </label>
    347                         <label class="setting" data-setting="caption">
    348                                 <span><?php _e('Caption'); ?></span>
    349                                 <textarea {{ maybeReadOnly }}>{{ data.caption }}</textarea>
    350                         </label>
     348                <label class="setting" data-setting="title">
     349                        <span class="name"><?php _e('Title'); ?></span>
     350                        <input type="text" value="{{ data.title }}" {{ maybeReadOnly }} />
     351                </label>
     352                <label class="setting" data-setting="caption">
     353                        <span class="name"><?php _e('Caption'); ?></span>
     354                        <textarea {{ maybeReadOnly }}>{{ data.caption }}</textarea>
     355                </label>
    351356                <# if ( 'image' === data.type ) { #>
    352357                        <label class="setting" data-setting="alt">
    353                                 <span><?php _e('Alt Text'); ?></span>
     358                                <span class="name"><?php _e('Alt Text'); ?></span>
    354359                                <input type="text" value="{{ data.alt }}" {{ maybeReadOnly }} />
    355360                        </label>
    356361                <# } #>
    357                         <label class="setting" data-setting="description">
    358                                 <span><?php _e('Description'); ?></span>
    359                                 <textarea {{ maybeReadOnly }}>{{ data.description }}</textarea>
     362                <label class="setting" data-setting="description">
     363                        <span class="name"><?php _e('Description'); ?></span>
     364                        <textarea {{ maybeReadOnly }}>{{ data.description }}</textarea>
     365                </label>
     366                <label class="setting">
     367                                <span class="name"><?php _e( 'Uploaded By' ); ?></span>
     368                                <span class="value">{{ data.authorName }}</span>
    360369                        </label>
     370                <# if ( data.uploadedTo ) { #>
     371                        <label class="setting">
     372                                <span class="name"><?php _e('Uploaded To'); ?></span>
     373                                <span class="value"><a href="{{ data.uploadedToLink }}">{{ data.uploadedToTitle }}</a></span>
     374                        </label>
     375                <# } #>
    361376        </script>
    362377
  • trunk/src/wp-includes/media.php

    r28653 r28682  
    25932593        );
    25942594
     2595        $author = new WP_User( $attachment->post_author );
     2596        $response['authorName'] = $author->display_name;
     2597
     2598        if ( $attachment->post_parent ) {
     2599                $post_parent = get_post( $attachment->post_parent );
     2600                $response['uploadedToLink'] = get_edit_post_link( $attachment->post_parent, 'raw' );
     2601                $response['uploadedToTitle'] = $post_parent->post_title ? $post_parent->post_title : __( '(No title)' );
     2602        }
     2603
     2604        $bytes = filesize( get_attached_file( $attachment->ID ) );
     2605        $response['filesizeInBytes'] = $bytes;
     2606        $response['filesizeHumanReadable'] = size_format( $bytes );
     2607
    25952608        if ( current_user_can( 'edit_post', $attachment->ID ) ) {
    25962609                $response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID );
     
    28502863                'returnToLibrary'    => __( '&#8592; Return to library' ),
    28512864                'allMediaItems'      => __( 'All media items' ),
     2865                'allMediaTypes'      => __( 'All media types' ),
    28522866                'noItemsFound'       => __( 'No items found.' ),
    28532867                'insertIntoPost'     => $hier ? __( 'Insert into page' ) : __( 'Insert into post' ),
Note: See TracChangeset for help on using the changeset viewer.