Changeset 27499
- Timestamp:
- 03/11/2014 07:46:27 AM (11 years ago)
- Location:
- trunk/src
- Files:
-
- 2 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/css/themes.css
r27289 r27499 26 26 } 27 27 28 .themes-php .wrap .theme-count { 28 .themes-php .wrap .theme-count, 29 .theme-navigation .theme-count { 29 30 color: #fff; 30 31 -webkit-border-radius: 30px; … … 1065 1066 ------------------------------------------------------------------------------*/ 1066 1067 1067 .theme-install-php h4 { 1068 margin: 2.5em 0 8px; 1069 } 1070 1071 .theme-install-php .tablenav { 1072 height: auto; 1073 } 1074 1075 .theme-install-php .spinner { 1076 margin-top: 9px; 1077 } 1078 1079 .available-theme { 1068 .theme-install-php h2 .upload { 1069 margin-left: 10px; 1070 } 1071 .theme-navigation { 1072 background: #fff; 1073 box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); 1074 -moz-box-sizing: border-box; 1075 box-sizing: border-box; 1076 color: #555; 1080 1077 display: inline-block; 1081 margin-right: 10px; 1078 font-size: 13px; 1079 margin: 20px 0 30px; 1080 padding: 0 20px; 1081 position: relative; 1082 width: 100%; 1083 } 1084 .upload-theme { 1085 -moz-box-sizing: border-box; 1086 box-sizing: border-box; 1087 display: none; 1088 margin: 0px 0 0; 1089 padding: 0; 1090 width: 100%; 1082 1091 overflow: hidden; 1083 padding: 20px 20px 20px 0; 1092 position: relative; 1093 top: 10px; 1094 } 1095 .upload-theme.opened { 1096 display: block; 1097 } 1098 .upload-theme .wp-upload-form { 1099 background: #fafafa; 1100 border: 1px solid #e5e5e5; 1101 padding: 30px; 1102 margin: 30px auto; 1103 max-width: 380px; 1104 } 1105 .upload-theme .install-help { 1106 color: #999; 1107 font-size: 18px; 1108 font-style: normal; 1109 margin: 0; 1110 padding: 40px 0 0; 1111 text-align: center; 1112 } 1113 .upload-theme.opened + .theme-navigation, 1114 .upload-theme.opened + .theme-navigation + .theme-browser { 1115 display: none; 1116 } 1117 .theme-navigation .theme-count { 1118 top: 3px; 1119 margin-left: 0; 1120 } 1121 .theme-section, 1122 .theme-filter { 1123 border-bottom: 4px solid #fff; 1124 color: #666; 1125 cursor: pointer; 1126 display: inline-block; 1127 margin: 0 10px; 1128 padding: 15px 0; 1129 -moz-transition: border-color .1s ease-in; 1130 -webkit-transition: border-color .1s ease-in; 1131 } 1132 .theme-section.current, 1133 .theme-filter.current { 1134 border-bottom: 4px solid #666; 1135 color: #222; 1136 } 1137 .theme-top-filters { 1138 display: inline-block; 1139 } 1140 .theme-navigation .more-filters { 1141 color: #666; 1142 cursor: pointer; 1143 display: inline-block; 1144 margin: 0 10px; 1145 padding: 4px 5px; 1146 -moz-transition: color .1s ease-in, background .1s ease-in; 1147 -webkit-transition: color .1s ease-in, background .1s ease-in; 1148 transition: color .1s ease-in, background .1s ease-in; 1149 } 1150 body.more-filters-opened .more-filters, 1151 .theme-navigation .more-filters.current { 1152 background: rgb(46, 162, 204); 1153 border-radius: 2px; 1154 border: none; 1155 color: #fff; 1156 } 1157 .theme-install-php .theme-search { 1158 position: absolute; 1159 right: 10px; 1160 top: 9px; 1161 font-size: 16px; 1162 font-weight: 300; 1163 line-height: 1.5; 1164 width: 280px; 1165 } 1166 .more-filters:before { 1167 color: #777; 1168 text-align: center; 1169 margin: 0 5px 0 0; 1170 content: "\f111"; 1171 display: inline-block; 1172 width: 16px; 1173 height: 16px; 1174 -webkit-font-smoothing: antialiased; 1175 font-size: 16px; 1176 line-height: 1; 1177 font-family: "dashicons"; 1178 text-decoration: inherit; 1179 font-weight: normal; 1180 font-style: normal; 1084 1181 vertical-align: top; 1085 width: 300px; 1086 } 1087 1088 .available-theme .screenshot { 1089 width: 300px; 1090 height: 225px; 1091 display: block; 1092 border: 1px solid #ccc; 1093 margin-bottom: 10px; 1094 overflow: hidden; 1095 background-color: #fff; 1096 } 1097 1098 .available-theme img { 1099 width: 300px; 1100 } 1101 1102 .available-theme h3 { 1103 margin: 15px 0 0; 1104 } 1105 1106 .available-theme .theme-author { 1107 line-height: 18px; 1108 } 1109 1110 .available-theme .action-links { 1111 margin-top: 10px; 1112 overflow: hidden; 1113 } 1114 1115 .available-theme a.screenshot:focus { 1116 border-color: #777; 1117 } 1118 1119 .available-theme .action-links li { 1120 float: left; 1121 padding-right: 10px; 1122 margin-right: 10px; 1123 border-right: 1px solid #dfdfdf; 1124 } 1125 1126 .available-theme .action-links li { 1127 padding-right: 8px; 1128 margin-right: 8px; 1129 } 1130 1131 .ie8 .available-theme .action-links li { 1132 padding-right: 7px; 1133 margin-right: 7px; 1134 } 1135 1136 .available-theme .action-links li:last-child { 1137 padding-right: 0; 1138 margin-right: 0; 1139 border-right: 0; 1140 } 1141 1142 .available-theme .action-links .delete-theme { 1143 float: right; 1144 margin-left: 8px; 1145 margin-right: 0; 1146 } 1147 1148 .available-theme .action-links .delete-theme a { 1149 color: red; 1150 padding: 2px; 1151 } 1152 1153 .available-theme .action-links .delete-theme a:hover { 1154 background: red; 1182 -moz-transition: color .1s ease-in 0; 1183 -webkit-transition: color .1s ease-in 0; 1184 transition: color .1s ease-in 0; 1185 text-align: center; 1186 } 1187 .more-filters.current:before { 1155 1188 color: #fff; 1156 text-decoration: none; 1157 } 1158 1159 .available-theme .action-links p { 1160 float: left; 1161 } 1162 1163 /* Allow for three-up in small windows when sidebar is collapsed */ 1164 @media only screen and (max-width: 1200px) { 1165 .folded .available-theme, 1166 .folded .available-theme .screenshot { 1167 width: 300px; 1168 } 1169 1170 .folded .available-theme .screenshot { 1171 height: 225px; 1172 } 1173 } 1174 1175 /* Adjust three-up display in smaller windows when sidebar is collapsed */ 1176 @media only screen and (max-width: 1079px) { 1177 .folded .available-theme, 1178 .folded .available-theme .screenshot { 1179 width: 270px; 1180 } 1181 1182 .folded .available-theme .screenshot { 1183 height: 203px; 1184 } 1185 } 1186 1187 /* Allow for three-up on 1024px wide screens, e.g. tablets */ 1188 @media only screen and (max-width: 1200px) { 1189 .available-theme, 1190 .available-theme .screenshot { 1191 width: 240px; 1192 } 1193 1194 .available-theme .screenshot { 1195 height: 180px; 1196 } 1197 1198 .available-theme img { 1199 width: 100%; 1200 } 1201 } 1202 1203 .feature-filter { 1204 padding: 8px 12px 0; 1205 } 1206 1207 .feature-filter .feature-group { 1208 float: left; 1209 margin: 5px 10px 10px; 1210 } 1211 1212 .feature-filter .feature-group li { 1189 } 1190 .more-filters-container { 1191 display: none; 1192 padding: 30px; 1193 border-top: 1px solid #eee; 1194 margin: 0 -20px; 1195 background: #fafafa; 1196 } 1197 body.more-filters-opened .more-filters-container { 1198 display: block; 1199 } 1200 .theme-install-php .add-new-theme { 1201 display: none !important; 1202 } 1203 1204 .rating { 1205 margin: 30px 0; 1206 } 1207 .rating span:before { 1208 color: #e6b800; 1209 content: "\f154"; 1213 1210 display: inline-block; 1211 -webkit-font-smoothing: antialiased; 1212 font: normal 20px/1 'dashicons'; 1214 1213 vertical-align: top; 1215 list-style-type: none; 1216 padding-right: 25px; 1217 width: 150px; 1214 } 1215 /* Half stars */ 1216 .rating-10 span.one:before, 1217 .rating-30 span.two:before, 1218 .rating-50 span.three:before, 1219 .rating-70 span.four:before, 1220 .rating-90 span.five:before { 1221 content: "\f459"; 1222 } 1223 /* Full stars */ 1224 .rating-20 span.one:before { 1225 content: "\f155"; 1226 } 1227 .rating-30 span.one:before, 1228 .rating-40 span.one:before, 1229 .rating-40 span.two:before { 1230 content: "\f155"; 1231 } 1232 .rating-50 span.one:before, 1233 .rating-50 span.two:before, 1234 .rating-60 span.one:before, 1235 .rating-60 span.two:before, 1236 .rating-60 span.three:before { 1237 content: "\f155"; 1238 } 1239 .rating-70 span.one:before, 1240 .rating-70 span.two:before, 1241 .rating-70 span.three:before, 1242 .rating-80 span.one:before, 1243 .rating-80 span.two:before, 1244 .rating-80 span.three:before, 1245 .rating-80 span.four:before { 1246 content: "\f155"; 1247 } 1248 .rating-90 span.one:before, 1249 .rating-90 span.two:before, 1250 .rating-90 span.three:before, 1251 .rating-90 span.four:before, 1252 .rating-100 span.one:before, 1253 .rating-100 span.two:before, 1254 .rating-100 span.three:before, 1255 .rating-100 span.four:before, 1256 .rating-100 span.five:before { 1257 content: "\f155"; 1258 } 1259 .rating .votes { 1260 display: inline; 1261 margin-left: 10px; 1262 line-height: 20px; 1263 } 1264 .loading-themes .theme-browser, 1265 .error .theme-browser { 1266 display: none; 1267 } 1268 .loading-themes .spinner { 1269 display: block; 1270 margin: 40px auto 0; 1271 float: none; 1218 1272 } 1219 1273 -
trunk/src/wp-admin/includes/theme-install.php
r24189 r27499 133 133 <?php 134 134 } 135 add_action('install_themes_dashboard', 'install_themes_dashboard');136 137 function install_themes_upload( $page = 1) {135 // add_action('install_themes_dashboard', 'install_themes_dashboard'); 136 137 function install_themes_upload() { 138 138 ?> 139 <h4><?php _e('Install a theme in .zip format'); ?></h4>140 139 <p class="install-help"><?php _e('If you have a theme in a .zip format, you may install it by uploading it here.'); ?></p> 141 140 <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url('update.php?action=upload-theme'); ?>"> … … 146 145 <?php 147 146 } 148 add_action('install_themes_upload', 'install_themes_upload', 10, 1);147 // add_action('install_themes_upload', 'install_themes_upload', 10, 0); 149 148 150 149 /** … … 156 155 _deprecated_function( __FUNCTION__, '3.4' ); 157 156 global $wp_list_table; 157 if ( ! isset( $wp_list_table ) ) { 158 $wp_list_table = _get_list_table('WP_Theme_Install_List_Table'); 159 } 160 $wp_list_table->prepare_items(); 158 161 $wp_list_table->single_row( $theme ); 159 162 } … … 167 170 global $wp_list_table; 168 171 172 if ( ! isset( $wp_list_table ) ) { 173 $wp_list_table = _get_list_table('WP_Theme_Install_List_Table'); 174 } 175 $wp_list_table->prepare_items(); 169 176 $wp_list_table->display(); 170 } 171 add_action('install_themes_search', 'display_themes'); 172 add_action('install_themes_featured', 'display_themes'); 173 add_action('install_themes_new', 'display_themes'); 174 add_action('install_themes_updated', 'display_themes'); 177 178 } 179 // add_action('install_themes_search', 'display_themes'); 180 // add_action('install_themes_featured', 'display_themes'); 181 // add_action('install_themes_new', 'display_themes'); 182 // add_action('install_themes_updated', 'display_themes'); 175 183 176 184 /** … … 180 188 */ 181 189 function install_theme_information() { 182 global $ tab, $themes_allowedtags, $wp_list_table;190 global $wp_list_table; 183 191 184 192 $theme = themes_api( 'theme_information', array( 'slug' => wp_unslash( $_REQUEST['theme'] ) ) ); … … 188 196 189 197 iframe_header( __('Theme Install') ); 198 if ( ! isset( $wp_list_table ) ) { 199 $wp_list_table = _get_list_table('WP_Theme_Install_List_Table'); 200 } 190 201 $wp_list_table->theme_installer_single( $theme ); 191 202 iframe_footer(); -
trunk/src/wp-admin/js/theme.js
r27306 r27499 13 13 l10n = themes.data.l10n; 14 14 15 // Shortcut for isInstall check 16 themes.isInstall = !! themes.data.settings.isInstall; 17 15 18 // Setup app structure 16 19 _.extend( themes, { model: {}, view: {}, routes: {}, router: {}, template: wp.template }); 17 20 18 themes.model = Backbone.Model.extend({}); 21 themes.Model = Backbone.Model.extend({ 22 // Adds attributes to the default data coming through the .org themes api 23 // Map `id` to `slug` for shared code 24 initialize: function() { 25 var install, preview; 26 27 // Install url for the theme 28 // using the install nonce 29 install = { 30 action: 'install-theme', 31 theme: this.get( 'slug' ), 32 _wpnonce: themes.data.settings._nonceInstall 33 }; 34 35 // Build the url query 36 install = themes.data.settings.updateURI + '?' + $.param( install ); 37 38 // Preview url for the theme 39 preview = { 40 tab: 'theme-information', 41 theme: this.get( 'slug' ) 42 }; 43 44 preview = themes.data.settings.installURI + '?' + $.param( preview ); 45 46 // Set the attributes 47 this.set({ 48 installURI: install, 49 previewURI: preview, 50 id: this.get( 'slug' ) 51 }); 52 } 53 }); 19 54 20 55 // Main view controller for themes.php … … 29 64 30 65 // Sets up a throttler for binding to 'scroll' 31 initialize: function( ) {66 initialize: function( options ) { 32 67 // Scroller checks how far the scroll position is 33 68 _.bindAll( this, 'scroller' ); 34 69 70 this.SearchView = options.SearchView ? options.SearchView : themes.view.Search; 35 71 // Bind to the scroll event and throttle 36 72 // the results from this.scroller … … 56 92 }, 57 93 94 // Defines search element container 95 searchContainer: $( '#wpbody h2:first' ), 96 58 97 // Search input and view 59 98 // for current theme collection … … 67 106 } 68 107 69 view = new themes.view.Search({ collection: self.collection, parent: this }); 108 view = new this.SearchView({ 109 collection: self.collection, 110 parent: this 111 }); 70 112 71 113 // Render and append after screen title 72 114 view.render(); 73 $('#wpbody h2:first')115 this.searchContainer 74 116 .append( $.parseHTML( '<label class="screen-reader-text" for="theme-search-input">' + l10n.search + '</label>' ) ) 75 117 .append( view.el ); … … 96 138 themes.Collection = Backbone.Collection.extend({ 97 139 98 model: themes. model,140 model: themes.Model, 99 141 100 142 // Search terms … … 188 230 189 231 events: { 190 'click': 'expand', 191 'keydown': 'expand', 192 'touchend': 'expand', 232 'click': themes.isInstall ? 'preview': 'expand', 233 'click .preview': 'preview', 234 'keydown': themes.isInstall ? 'preview': 'expand', 235 'touchend': themes.isInstall ? 'preview': 'expand', 193 236 'touchmove': 'preventExpand' 194 237 }, … … 251 294 preventExpand: function() { 252 295 this.touchDrag = true; 296 }, 297 298 preview: function( event ) { 299 // Bail if the user scrolled on a touch device 300 if ( this.touchDrag === true ) { 301 return this.touchDrag = false; 302 } 303 304 event.preventDefault(); 305 306 event = event || window.event; 307 308 var preview = new themes.view.Preview({ 309 model: this.model 310 }); 311 312 preview.render(); 313 $( 'div.wrap' ).append( preview.el ); 253 314 } 254 315 }); … … 416 477 }); 417 478 479 // Theme Preview view 480 // Set ups a modal overlay with the expanded theme data 481 themes.view.Preview = wp.Backbone.View.extend({ 482 483 className: 'wp-full-overlay expanded', 484 el: '#theme-installer', 485 486 events: { 487 'click .close-full-overlay': 'close', 488 'click .collapse-sidebar': 'collapse' 489 }, 490 491 // The HTML template for the theme preview 492 html: themes.template( 'theme-preview' ), 493 494 render: function() { 495 var data = this.model.toJSON(); 496 this.$el.html( this.html( data ) ); 497 498 themes.router.navigate( themes.router.baseUrl( '?theme=' + this.model.get( 'id' ) ), { replace: true } ); 499 500 this.$el.fadeIn( 200, function() { 501 $( 'body' ).addClass( 'theme-installer-active full-overlay-active' ); 502 }); 503 }, 504 505 close: function() { 506 this.$el.fadeOut( 200, function() { 507 $( 'body' ).removeClass( 'theme-installer-active full-overlay-active' ); 508 }); 509 510 themes.router.navigate( themes.router.baseUrl( '' ) ); 511 return false; 512 }, 513 514 collapse: function() { 515 this.$el.toggleClass( 'collapsed' ).toggleClass( 'expanded' ); 516 return false; 517 } 518 }); 519 418 520 // Controls the rendering of div.themes, 419 521 // a wrapper that will hold all the theme elements … … 733 835 // Sets up the routes events for relevant url queries 734 836 // Listens to [theme] and [search] params 735 themes. routes= Backbone.Router.extend({837 themes.Router = Backbone.Router.extend({ 736 838 737 839 routes: { … … 789 891 // Bind to our global thx object 790 892 // so that the object is available to sub-views 791 themes.router = new themes. routes();893 themes.router = new themes.Router(); 792 894 793 895 // Handles theme details route event … … 806 908 self.themes.doSearch( query ); 807 909 }); 910 911 this.extraRoutes(); 912 }, 913 914 extraRoutes: function() { 915 return false; 808 916 } 809 917 }; 810 918 919 // Extend the main Search view 920 themes.view.InstallerSearch = themes.view.Search.extend({ 921 922 events: { 923 'keyup': 'search' 924 }, 925 926 // Handles Ajax request for searching through themes in public repo 927 search: function( event ) { 928 this.collection = this.options.parent.view.collection; 929 930 // Clear on escape. 931 if ( event.type === 'keyup' && event.which === 27 ) { 932 event.target.value = ''; 933 } 934 935 _.debounce( _.bind( this.doSearch, this ), 300 )( event.target.value ); 936 }, 937 938 doSearch: function( value ) { 939 var request = {}, 940 self = this; 941 942 request.search = value; 943 944 // Intercept an [author] search. 945 // 946 // If input value starts with `author:` send a request 947 // for `author` instead of a regular `search` 948 if ( value.substring( 0, 7 ) === 'author:' ) { 949 request.search = ''; 950 request.author = value.slice( 7 ); 951 } 952 953 // Intercept a [tag] search. 954 // 955 // If input value starts with `tag:` send a request 956 // for `tag` instead of a regular `search` 957 if ( value.substring( 0, 4 ) === 'tag:' ) { 958 request.search = ''; 959 request.tag = [ value.slice( 4 ) ]; 960 } 961 962 // Send Ajax POST request to api.wordpress.org/themes 963 themes.view.Installer.prototype.apiCall( request ).done( function( data ) { 964 // Update the collection with the queried data 965 self.collection.reset( data.themes ); 966 // Trigger a collection refresh event to render the views 967 self.collection.trigger( 'update' ); 968 969 // Un-spin it 970 $( 'body' ).removeClass( 'loading-themes' ); 971 $( '.theme-browser' ).find( 'div.error' ).remove(); 972 }).fail( function() { 973 $( '.theme-browser' ).find( 'div.error' ).remove(); 974 $( '.theme-browser' ).append( '<div class="error"><p>' + l10n.error + '</p></div>' ); 975 }); 976 977 return false; 978 } 979 }); 980 981 themes.view.Installer = themes.view.Appearance.extend({ 982 983 el: '#wpbody-content .wrap', 984 985 // Register events for sorting and filters in theme-navigation 986 events: { 987 'click .theme-section': 'onSort', 988 'click .theme-filter': 'onFilter', 989 'click .more-filters': 'moreFilters' 990 }, 991 992 // Send Ajax POST request to api.wordpress.org/themes 993 apiCall: function( request ) { 994 return $.ajax({ 995 url: 'https://api.wordpress.org/themes/info/1.1/?action=query_themes', 996 997 // We want JSON data 998 dataType: 'json', 999 type: 'POST', 1000 crossDomain: true, 1001 1002 // Request data 1003 data: { 1004 action: 'query_themes', 1005 request: _.extend({ 1006 per_page: 36, 1007 fields: { 1008 description: true, 1009 tested: true, 1010 requires: true, 1011 rating: true, 1012 downloaded: true, 1013 downloadLink: true, 1014 last_updated: true, 1015 homepage: true, 1016 num_ratings: true 1017 } 1018 }, request) 1019 }, 1020 1021 beforeSend: function() { 1022 // Spin it 1023 $( 'body' ).addClass( 'loading-themes' ); 1024 } 1025 }); 1026 }, 1027 1028 // Handles all the rendering of the public theme directory 1029 browse: function( section ) { 1030 var self = this; 1031 1032 // @todo Cache the collection after fetching based on the section 1033 this.collection = new themes.Collection(); 1034 1035 // Create a new collection with the proper theme data 1036 // for each section 1037 this.apiCall({ browse: section }).done( function( data ) { 1038 // Update the collection with the queried data 1039 self.collection.reset( data.themes ); 1040 // Trigger a collection refresh event to render the views 1041 self.collection.trigger( 'update' ); 1042 1043 // Un-spin it 1044 $( 'body' ).removeClass( 'loading-themes' ); 1045 $( '.theme-browser' ).find( 'div.error' ).remove(); 1046 }); 1047 1048 if ( this.view ) { 1049 this.view.remove(); 1050 } 1051 1052 // Set ups the view and passes the section argument 1053 this.view = new themes.view.Themes({ 1054 collection: this.collection, 1055 section: section, 1056 parent: this 1057 }); 1058 1059 // Reset pagination every time the install view handler is run 1060 this.page = 0; 1061 1062 // Render and append 1063 this.$el.find( '.themes' ).remove(); 1064 this.view.render(); 1065 this.$el.find( '.theme-browser' ).append( this.view.el ).addClass( 'rendered' ); 1066 }, 1067 1068 // Initial render method 1069 render: function() { 1070 this.search(); 1071 this.uploader(); 1072 return this.browse( this.options.section ); 1073 }, 1074 1075 // Sorting navigation 1076 onSort: function( event ) { 1077 var $el = $( event.target ), 1078 sort = $el.data( 'sort' ); 1079 1080 // Bail if this is already active 1081 if ( $el.hasClass( this.activeClass ) ) { 1082 return; 1083 } 1084 1085 this.sort( sort ); 1086 1087 // Trigger a router.naviagte update 1088 themes.router.navigate( themes.router.baseUrl( '?sort=' + sort ) ); 1089 }, 1090 1091 sort: function( sort ) { 1092 $( '#theme-search-input' ).val( '' ); 1093 1094 $( '.theme-section, .theme-filter' ).removeClass( this.activeClass ); 1095 $( '[data-sort="' + sort + '"]' ).addClass( this.activeClass ); 1096 1097 this.browse( sort ); 1098 }, 1099 1100 // Filters and Tags 1101 onFilter: function( event ) { 1102 var request, 1103 $el = $( event.target ), 1104 filter = $el.data( 'filter' ), 1105 self = this; 1106 1107 // Bail if this is already active 1108 if ( $el.hasClass( this.activeClass ) ) { 1109 return; 1110 } 1111 1112 $( '.theme-filter, .theme-section' ).removeClass( this.activeClass ); 1113 $el.addClass( this.activeClass ); 1114 1115 if ( ! filter ) { 1116 return; 1117 } 1118 1119 // Construct the filter request 1120 // using the default values 1121 1122 // @todo Cache the collection after fetching based on the filter 1123 request = { tag: [ filter ] }; 1124 1125 // Send Ajax POST request to api.wordpress.org/themes 1126 this.apiCall( request ).done( function( data ) { 1127 // Update the collection with the queried data 1128 self.collection.reset( data.themes ); 1129 // Trigger a collection refresh event to render the views 1130 self.collection.trigger( 'update' ); 1131 1132 // Un-spin it 1133 $( 'body' ).removeClass( 'loading-themes' ); 1134 $( '.theme-browser' ).find( 'div.error' ).remove(); 1135 }).fail( function() { 1136 $( '.theme-browser' ).find( 'div.error' ).remove(); 1137 $( '.theme-browser' ).append( '<div class="error"><p>' + l10n.error + '</p></div>' ); 1138 }); 1139 1140 return false; 1141 }, 1142 1143 activeClass: 'current', 1144 1145 // Overwrite search container class to append search 1146 // in new location 1147 searchContainer: $( '.theme-navigation' ), 1148 1149 uploader: function() { 1150 $( 'a.upload.button' ).on( 'click', function() { 1151 $( '.upload-theme' ) 1152 .toggleClass( 'opened' ) 1153 .hasClass( 'opened' ) ? $( this ).text( l10n.back ) : $( this ).text( l10n.upload ); 1154 }); 1155 }, 1156 1157 moreFilters: function() { 1158 $( 'body' ).toggleClass( 'more-filters-opened' ); 1159 } 1160 }); 1161 1162 themes.InstallerRouter = Backbone.Router.extend({ 1163 routes: { 1164 'theme-install.php?theme=:slug': 'preview', 1165 'theme-install.php(?sort=:sort)': 'sort', 1166 '': 'sort' 1167 }, 1168 1169 baseUrl: function( url ) { 1170 return 'theme-install.php' + url; 1171 } 1172 }); 1173 1174 1175 themes.RunInstaller = { 1176 1177 init: function() { 1178 // Set up the view 1179 // Passes the default 'section' as an option 1180 this.view = new themes.view.Installer({ 1181 section: 'featured', 1182 SearchView: themes.view.InstallerSearch 1183 }); 1184 1185 // Render results 1186 this.render(); 1187 1188 }, 1189 1190 render: function() { 1191 1192 // Render results 1193 this.view.render(); 1194 this.routes(); 1195 1196 Backbone.history.start({ 1197 root: themes.data.settings.adminUrl, 1198 pushState: true, 1199 hashChange: false 1200 }); 1201 }, 1202 1203 routes: function() { 1204 var self = this; 1205 // Bind to our global thx object 1206 // so that the object is available to sub-views 1207 themes.router = new themes.InstallerRouter(); 1208 1209 // Handles theme details route event 1210 themes.router.on( 'route:theme', function( slug ) { 1211 self.view.view.expand( slug ); 1212 }); 1213 1214 themes.router.on( 'route:sort', function( sort ) { 1215 if ( ! sort ) { 1216 sort = 'featured'; 1217 } 1218 self.view.sort( sort ); 1219 self.view.trigger( 'theme:close' ); 1220 }); 1221 1222 this.extraRoutes(); 1223 }, 1224 1225 extraRoutes: function() { 1226 return false; 1227 } 1228 }; 1229 811 1230 // Ready... 812 jQuery( document ).ready( 813 814 // Bring on the themes 815 _.bind( themes.Run.init, themes.Run ) 816 817 ); 1231 $( document ).ready(function() { 1232 if ( themes.isInstall ) { 1233 themes.RunInstaller.init(); 1234 } else { 1235 themes.Run.init(); 1236 } 1237 }); 818 1238 819 1239 })( jQuery ); -
trunk/src/wp-admin/theme-install.php
r27469 r27499 7 7 */ 8 8 9 if ( !defined( 'IFRAME_REQUEST' ) && isset( $_GET['tab'] ) && ( 'theme-information' == $_GET['tab'] ) )10 define( 'IFRAME_REQUEST', true );11 12 9 /** WordPress Administration Bootstrap */ 13 10 require_once( dirname( __FILE__ ) . '/admin.php' ); 11 require( ABSPATH . 'wp-admin/includes/theme-install.php' ); 12 13 wp_reset_vars( array( 'tab' ) ); 14 14 15 15 if ( ! current_user_can('install_themes') ) … … 21 21 } 22 22 23 $wp_list_table = _get_list_table('WP_Theme_Install_List_Table'); 24 $pagenum = $wp_list_table->get_pagenum(); 25 $wp_list_table->prepare_items(); 26 27 $title = __('Install Themes'); 23 $title = __( 'Add Themes' ); 28 24 $parent_file = 'themes.php'; 29 if ( !is_network_admin() ) 25 26 if ( ! is_network_admin() ) { 30 27 $submenu_file = 'themes.php'; 31 32 wp_enqueue_script( 'theme-install' ); 33 wp_enqueue_script( 'theme-preview' ); 34 35 $body_id = $tab; 28 } 29 30 $sections = array( 31 'featured' => __( 'Featured Themes' ), 32 'popular' => __( 'Popular Themes' ), 33 'new' => __( 'Newest Themes' ), 34 ); 35 36 wp_localize_script( 'theme', '_wpThemeSettings', array( 37 'themes' => false, 38 'settings' => array( 39 'isInstall' => true, 40 'canInstall' => current_user_can( 'install_themes' ), 41 'installURI' => current_user_can( 'install_themes' ) ? self_admin_url( 'theme-install.php' ) : null, 42 'adminUrl' => parse_url( self_admin_url(), PHP_URL_PATH ), 43 'updateURI' => self_admin_url( 'update.php' ), 44 '_nonceInstall' => wp_create_nonce( 'install-theme' ) 45 ), 46 'l10n' => array( 47 'addNew' => __( 'Add New Theme' ), 48 'search' => __( 'Search Themes' ), 49 'searchPlaceholder' => __( 'Search themes...' ), 50 'upload' => __( 'Upload Theme' ), 51 'back' => __( 'Back' ), 52 'error' => __( 'There was a problem trying to load the themes. Please, try again.' ), 53 ), 54 'browse' => array( 55 'sections' => $sections, 56 ), 57 ) ); 58 59 wp_enqueue_script( 'theme' ); 36 60 37 61 /** … … 44 68 * @since 2.8.0 45 69 */ 46 do_action( "install_themes_pre_{$tab}" ); 70 if ( $tab ) { 71 do_action( "install_themes_pre_{$tab}" ); 72 } 47 73 48 74 $help_overview = … … 74 100 75 101 include(ABSPATH . 'wp-admin/admin-header.php'); 102 76 103 ?> 77 104 <div class="wrap"> 78 <h2><?php echo esc_html( $title ); ?></h2> 79 <?php 80 81 $wp_list_table->views(); ?> 82 83 <br class="clear" /> 105 <h2> 106 <?php echo esc_html( $title ); ?> 107 <a class="upload button button-secondary"><?php esc_html_e( 'Upload Theme' ); ?></a> 108 </h2> 109 110 <div class="upload-theme"> 111 <?php install_themes_upload(); ?> 112 </div> 113 114 <div class="theme-navigation"> 115 <span class="theme-count"></span> 116 <span class="theme-section current" data-sort="featured"><?php esc_html_e( 'Featured' ); ?></span> 117 <span class="theme-section" data-sort="popular"><?php esc_html_e( 'Popular' ); ?></span> 118 <span class="theme-section" data-sort="new"><?php esc_html_e( 'Latest' ); ?></span> 119 <div class="theme-top-filters"> 120 <span class="theme-filter" data-filter="photoblogging">Photography</span> 121 <span class="theme-filter" data-filter="responsive-layout">Responsive</span> 122 <span class="theme-filter more-filters">More</span> 123 </div> 124 <div class="more-filters-container"> 125 Display more filters. 126 </div> 127 </div> 128 <div class="theme-browser"></div> 129 <div class="theme-overlay"></div> 130 <div id="theme-installer" class="wp-full-overlay expanded"></div> 131 132 <span class="spinner"></span> 133 134 <br class="clear" /> 84 135 <?php 85 136 /** … … 94 145 * @param int $paged Number of the current page of results being viewed. 95 146 */ 96 do_action( "install_themes_{$tab}", $paged ); 147 if ( $tab ) { 148 do_action( "install_themes_{$tab}", $paged ); 149 } 97 150 ?> 98 151 </div> 152 153 <script id="tmpl-theme" type="text/template"> 154 <# if ( data.screenshot_url ) { #> 155 <div class="theme-screenshot"> 156 <img src="{{ data.screenshot_url }}" alt="" /> 157 </div> 158 <# } else { #> 159 <div class="theme-screenshot blank"></div> 160 <# } #> 161 <span class="more-details"><?php _ex( 'Details & Preview', 'theme' ); ?></span> 162 <div class="theme-author"><?php printf( __( 'By %s' ), '{{ data.author }}' ); ?></div> 163 <h3 class="theme-name">{{ data.name }}</h3> 164 165 <div class="theme-actions"> 166 <a class="button button-primary" href="{{ data.installURI }}"><?php esc_html_e( 'Install' ); ?></a> 167 <a class="button button-secondary preview install-theme-preview" href="#"><?php esc_html_e( 'Preview' ); ?></a> 168 </div> 169 </script> 170 171 <script id="tmpl-theme-preview" type="text/template"> 172 <div class="wp-full-overlay-sidebar"> 173 <div class="wp-full-overlay-header"> 174 <a href="" class="close-full-overlay button-secondary"><?php _e( 'Close' ); ?></a> 175 <a href="{{ data.installURI }}" class="button button-primary theme-install"><?php _e( 'Install' ); ?></a> 176 </div> 177 <div class="wp-full-overlay-sidebar-content"> 178 <div class="install-theme-info"> 179 <h3 class="theme-name">{{ data.name }}</h3> 180 <span class="theme-by"><?php printf( __( 'By %s' ), '{{ data.author }}' ); ?></span> 181 182 <img class="theme-screenshot" src="{{ data.screenshot_url }}" alt="" /> 183 184 <div class="theme-details"> 185 <div class="rating rating-{{ Math.round( data.rating / 10 ) * 10 }}"> 186 <span class="one"></span> 187 <span class="two"></span> 188 <span class="three"></span> 189 <span class="four"></span> 190 <span class="five"></span> 191 <p class="votes"><?php printf( __( 'Based on %s ratings.' ), '{{ data.num_ratings }}' ); ?></p> 192 </div> 193 <div class="theme-version"><?php printf( __( 'Version: %s' ), '{{ data.version }}' ); ?></div> 194 <div class="theme-description">{{ data.description }}</div> 195 </div> 196 </div> 197 </div> 198 <div class="wp-full-overlay-footer"> 199 <a href="" class="collapse-sidebar" title="<?php esc_attr_e( 'Collapse Sidebar' ); ?>"> 200 <span class="collapse-sidebar-label"><?php _e( 'Collapse' ); ?></span> 201 <span class="collapse-sidebar-arrow"></span> 202 </a> 203 </div> 204 </div> 205 <div class="wp-full-overlay-main"> 206 <iframe src="{{ data.preview_url }}" /> 207 </div> 208 </script> 209 99 210 <?php 100 211 include(ABSPATH . 'wp-admin/admin-footer.php'); -
trunk/src/wp-admin/update.php
r27280 r27499 203 203 include_once ABSPATH . 'wp-admin/includes/theme-install.php'; //for themes_api.. 204 204 205 check_admin_referer( 'install-theme_' . $theme);205 check_admin_referer( 'install-theme' ); 206 206 $api = themes_api('theme_information', array('slug' => $theme, 'fields' => array('sections' => false, 'tags' => false) ) ); //Save on a bit of bandwidth. 207 207 -
trunk/src/wp-includes/script-loader.php
r27497 r27499 455 455 456 456 $scripts->add( 'theme', "/wp-admin/js/theme$suffix.js", array( 'wp-backbone' ), false, 1 ); 457 $scripts->add( 'theme-install', "/wp-admin/js/theme-install$suffix.js", array( 'jquery' ), false, 1 );458 459 // @todo: Core no longer uses theme-preview.js. Remove?460 $scripts->add( 'theme-preview', "/wp-admin/js/theme-preview$suffix.js", array( 'thickbox', 'jquery' ), false, 1 );461 457 462 458 $scripts->add( 'inline-edit-post', "/wp-admin/js/inline-edit-post$suffix.js", array( 'jquery', 'suggest', 'heartbeat' ), false, 1 );
Note: See TracChangeset
for help on using the changeset viewer.