Ticket #774: diff.diff
File diff.diff, 178.3 KB (added by , 10 years ago) |
---|
-
new file 404.php
From a130b3c19c3491eeb0b0259c2a3863b45c533c4e Mon Sep 17 00:00:00 2001 From: Kyle Maurer <kyle@realbigmarketing.com> Date: Thu, 11 Dec 2014 14:14:01 -0500 Subject: [PATCH] Getting started. --- 404.php | 30 + anon-upload-template.php | 402 +++ archive.php | 90 + breadcrumbs.php | 14 + category-wordcamptv.php | 74 + category.php | 95 + comments.php | 40 + footer.php | 20 + front-page.php | 128 + functions.php | 752 ++++++ header.php | 45 + ie6.css | 35 + inc/wpcom.php | 4 + index.php | 85 + js/dropdowns.js | 9 + page.php | 35 + pagination.php | 13 + plugins/rewrite.php | 18 + plugins/wordpresstv-anon-upload/anon-upload.php | 549 +++++ plugins/wordpresstv-oembed/wordpresstv-oembed.php | 163 ++ plugins/wordpresstv-rest/wordpresstv-rest.php | 106 + .../wordpresstv-unisubs/wordpresstv-unisubs.php | 207 ++ .../wordpresstv-upload-subtitles.php | 529 ++++ search.php | 11 + sidebar-event.php | 5 + sidebar-single.php | 85 + sidebar-wordcamptv.php | 5 + sidebar.php | 35 + single.php | 32 + style.css | 2598 ++++++++++++++++++++ taxonomy-event.php | 90 + upload-subtitles-template.php | 331 +++ 32 files changed, 6635 insertions(+) create mode 100755 404.php create mode 100755 anon-upload-template.php create mode 100755 archive.php create mode 100755 breadcrumbs.php create mode 100755 category-wordcamptv.php create mode 100755 category.php create mode 100755 comments.php create mode 100755 footer.php create mode 100755 front-page.php create mode 100755 functions.php create mode 100755 header.php create mode 100755 ie6.css create mode 100755 inc/wpcom.php create mode 100755 index.php create mode 100755 js/dropdowns.js create mode 100755 page.php create mode 100755 pagination.php create mode 100755 plugins/rewrite.php create mode 100755 plugins/wordpresstv-anon-upload/anon-upload.php create mode 100755 plugins/wordpresstv-oembed/wordpresstv-oembed.php create mode 100755 plugins/wordpresstv-rest/wordpresstv-rest.php create mode 100755 plugins/wordpresstv-unisubs/wordpresstv-unisubs.php create mode 100755 plugins/wordpresstv-upload-subtitles/wordpresstv-upload-subtitles.php create mode 100755 search.php create mode 100755 sidebar-event.php create mode 100755 sidebar-single.php create mode 100755 sidebar-wordcamptv.php create mode 100755 sidebar.php create mode 100755 single.php create mode 100755 style.css create mode 100755 taxonomy-event.php create mode 100755 upload-subtitles-template.php diff --git a/404.php b/404.php new file mode 100755 index 0000000..fff842f
- + 1 <?php 2 /* 3 * WordCamp.tv Index Fallback 4 * 5 * It will be weird if somebody sees this (but okay if 404) 6 */ 7 8 get_header(); 9 global $wp_query, $post, $wptv; 10 ?> 11 <div class="wptv-hero"> 12 <h2 class="page-title"><?php esc_html_e( 'Whoops!', 'wptv' ); ?></h2> 13 </div> 14 <div class="container"> 15 <div class="primary-content"> 16 <div class="baron-von-pick"> 17 <img src="<?php echo get_stylesheet_directory_uri(); ?>/i/michael-pick-stashes-a-guinness.gif" alt="" /><br /> 18 <?php printf( __( 'Photo animation credit: %s.', 'wptv' ), '<a href="http://markjaquith.com/">Mark Jaquith</a>' ); ?> 19 </div> 20 <div class="message-404"> 21 <h2><?php esc_html_e( 'Uh oh, someone made a mistake!', 'wptv' ); ?></h2> 22 <p><?php esc_html_e( 'These sorts of things happen…', 'wptv' ); ?></p> 23 <p><?php esc_html_e( 'Try searching for what you were looking for.', 'wptv' ); ?></p> 24 <p><?php echo get_search_form(); ?></p> 25 <p><?php printf( __( 'Or, <a href="%s">visit the homepage</a> to start a fresh journey.', 'wptv' ), '/' ); ?></p> 26 </div> 27 </div> 28 </div><!-- container --> 29 <?php 30 get_footer(); -
new file anon-upload-template.php
diff --git a/anon-upload-template.php b/anon-upload-template.php new file mode 100755 index 0000000..c1118ed
- + 1 <?php 2 /** 3 * Template Name: Anon video upload 4 * 5 * A custom page template containing the "submit video" form 6 */ 7 8 9 function anon_upload_css() { 10 ?> 11 <style type="text/css"> 12 <?php // theme structural css ?> 13 html, 14 body { 15 width: 100%; 16 height: 100%; 17 margin: 0; 18 } 19 20 .page-template-anon-upload-template-php #page { 21 height: auto; 22 min-height: 100%; 23 position: relative; 24 width: 100%; 25 } 26 27 .page-template-anon-upload-template-php #header { 28 margin: 0; 29 padding-top: 10px; 30 } 31 32 .page-template-anon-upload-template-php #footer { 33 position: absolute; 34 bottom: 0; 35 right: 0; 36 left: 0; 37 } 38 39 .video-upload { 40 padding-bottom: 70px; 41 } 42 43 .noscript-show p { 44 margin: 0 !important; 45 } 46 <?php // theme structural end ?> 47 48 .container { 49 overflow: hidden; 50 } 51 52 .video-upload-left { 53 max-width: 550px; 54 } 55 56 .video-upload-right { 57 float: right; 58 width: 390px; 59 margin: -25px 0 25px; 60 } 61 62 .video-upload p { 63 margin: 16px 0; 64 } 65 66 .video-upload h3 { 67 font-size: 22px; 68 } 69 70 .video-upload div.error { 71 border: 1px solid #c00; 72 border-radius: 3px; 73 background-color: #ffebe8; 74 padding: 0 10px; 75 margin: 10px 0; 76 } 77 78 .video-upload div.error p { 79 margin: 0.5em 0; 80 } 81 82 .video-upload-left p > label, 83 .video-upload-left div > label { 84 padding: 4px 0 0; 85 display: block; 86 width: 130px; 87 float: left; 88 font-weight: bold; 89 } 90 91 .video-upload-left p > label.wptv-video-wordcamp-cb { 92 display: inline; 93 float: none; 94 } 95 96 .video-upload-left p label .required { 97 line-height: 15px; 98 vertical-align: bottom; 99 margin: 0 3px; 100 } 101 102 .video-upload-left input[type="text"], 103 .video-upload-left textarea, 104 .video-upload-left ul.cats-checkboxes { 105 border-radius: 3px; 106 border: 1px solid #dfdfdf; 107 color: #333; 108 background-color: #fff; 109 padding: 4px; 110 width: 329px; 111 max-width: 329px; 112 } 113 114 .video-upload-left ul.cats-checkboxes { 115 margin-left: 130px; 116 height: 150px; 117 overflow: auto; 118 } 119 120 .video-upload-left ul.cats-checkboxes ul.children { 121 margin-left: 15px; 122 } 123 124 .video-upload-left input[type="text"]:focus, 125 .video-upload-left textarea:focus { 126 border-color: #bbb; 127 } 128 129 .video-upload-left #wptv_honey_container { 130 display: none; 131 } 132 133 #video-upload-form p.last { 134 margin: 5px 80px 25px; 135 text-align: right; 136 } 137 138 #video-upload-form p .invalid { 139 border: 1px solid red; 140 } 141 142 #video-upload-form input[type="submit"] { 143 font-size: 15px; 144 padding: 4px 12px; 145 } 146 147 .page-template-anon-upload-template-php .wptv-hero { 148 padding: 20px; 149 } 150 151 .page-template-anon-upload-template-php .wptv-hero h2 { 152 font-size: 24px; 153 } 154 155 .video-upload-right .accepted-formats { 156 margin-left: 16px; 157 } 158 159 .video-upload-right .accepted-formats li { 160 list-style: square; 161 } 162 163 .video-upload-right h3 { 164 padding-bottom: 4px; 165 } 166 167 .video-upload .pass-form label { 168 float: none; 169 display: inline; 170 width: auto; 171 } 172 </style> 173 <?php 174 } 175 176 add_action( 'wp_head', 'anon_upload_css' ); 177 178 get_header(); 179 180 $message = ''; 181 182 if ( !empty($_REQUEST['error']) ) { 183 $message = (int) $_REQUEST['error']; 184 185 switch ( $message ) { 186 case 1: 187 $message = 'Error: pleas select a video file.'; 188 break; 189 case 2: 190 $message = 'Error: invalid file type.'; 191 break; 192 case 3: 193 $message = 'Error: unknown file type.'; 194 break; 195 case 4: 196 $message = 'Upload error: the video cannot be saved.'; 197 break; 198 case 5: 199 $message = 'Unknown error. Please try again later.'; 200 break; 201 case 6: 202 $message = 'Error: invalid submission.'; 203 break; 204 // these shouldn't show, JS form validation should catch them 205 case 10: 206 $message = 'Error: pleas enter your name.'; 207 break; 208 case 11: 209 $message = 'Error: pleas enter your email address.'; 210 break; 211 case 12: 212 $message = 'Error: pleas enter a valid email address.'; 213 break; 214 case 13: 215 $message = "Error: please leave the first field empty. (It helps us know you're not a spammer.)"; 216 break; 217 } 218 $message = '<div class="error"><p>' . $message . '</p></div>'; 219 } elseif ( !empty($_REQUEST['success']) ) { 220 $message = '<h3>Thank you for submitting a video; it was uploaded successfully.</h3><p>Submit another?</p>'; 221 } 222 223 ?> 224 225 <div class="wptv-hero"> 226 <div class="single container"> 227 <h2><?php esc_html_e( 'Submit a video' ); ?></h2> 228 </div> 229 </div> 230 231 <div class="container"> 232 <div class="video-upload"> 233 <?php 234 235 // temp pwd? 236 if ( post_password_required() ) { 237 echo '<div class="pass-form">'; 238 echo get_the_password_form(); 239 echo '</div></div></div>'; 240 get_footer(); 241 return; 242 } else { 243 echo $message; 244 } 245 246 ?> 247 <noscript><div class="error"><p>This form requires JavaScript. Please enable it in your browser and reload the page.</p></div></noscript> 248 <div class="video-upload-right"> 249 <h3>Guidelines</h3> 250 <p>WordCamp videos: the audio is clear and easy to understand, the camera was on a tripod, the video shows the speaker and slides, divide the video by presentation if possible.</p> 251 <p>Screencasts: keep it concise, keep it clear, keep on track (no chock-full of personal promotion please), keep it current.</p> 252 <p>Vodcasts and other video-based content: if you have put together a video podcast or other WordPress focused, relevant video - let us <a href="http://wordpress.tv/contact/">know about it</a>. 253 <p>If this is the first time you're submitting a video, please check all <a href="http://blog.wordpress.tv/submission-guidelines/">Submission Guidelines</a>.</p> 254 <h3>Accepted formats</h3> 255 <p>Maximum upload file size: 1GB. You can upload the following video formats:</p> 256 <ul class="accepted-formats"> 257 <li>avi</li> 258 <li>mov/qt</li> 259 <li>mpeg/mpg</li> 260 <li>mp4</li> 261 <li>ogv</li> 262 <li>wmv</li> 263 <li>3gp/3g2</li> 264 </ul> 265 </div> 266 267 <div class="video-upload-left"> 268 <?php if ( !$message ) { ?> 269 <p>Please review the guidelines listed on the right, then submit your video below:</p> 270 <?php } ?> 271 272 <form method="post" action="<?php echo admin_url('admin-post.php'); ?>" id="video-upload-form" enctype="multipart/form-data"> 273 <?php wp_nonce_field('wptv-upload-video', 'wptvvideon'); ?> 274 <input type="hidden" name="action" value="wptv_video_upload" /> 275 276 <?php // This field only exists to trap spam bots that will automatically fill it in. It will be hidden from normal users. ?> 277 <p id="wptv_honey_container"> 278 <label for="wptv_honey"><?php esc_html_e( 'Leave this empty' ); ?></label> 279 <input type="text" id="wptv_honey" name="wptv_honey" value="" /> 280 </p> 281 <p> 282 <input type="checkbox" id="wptv_video_wordcamp" name="wptv_video_wordcamp" /> 283 <label for="wptv_video_wordcamp" class="wptv-video-wordcamp-cb"><?php esc_html_e( 'This is a WordCamp video' ); ?></label> 284 </p> 285 286 <?php if ( ! is_user_logged_in() ) : ?> 287 <p> 288 <label for="wptv_uploaded_by"><?php esc_html_e( 'Uploaded by' ); ?><span class="required"> * </span></label> 289 <input type="text" id="wptv_uploaded_by" name="wptv_uploaded_by" value="" /> 290 </p> 291 <p> 292 <label for="wptv_email"><?php esc_html_e( 'Email address' ); ?><span class="required"> * </span></label> 293 <input type="text" id="wptv_email" name="wptv_email" value="" /> 294 </p> 295 <?php endif; ?> 296 297 <p> 298 <label for="wptv_video_title"><?php esc_html_e( 'Video title' ); ?></label> 299 <input type="text" id="wptv_video_title" name="wptv_video_title" value="" /> 300 </p> 301 <p> 302 <label for="wptv_language"><?php esc_html_e( 'Language' ); ?></label> 303 <input type="text" id="wptv_language" name="wptv_language" value="" /> 304 </p> 305 306 <div class="cats"> 307 <label for="wptv_categories"><?php esc_html_e( 'Category' ); ?></label> 308 <ul class="cats-checkboxes"> 309 <?php 310 include_once( ABSPATH . '/wp-admin/includes/template.php' ); 311 wp_category_checklist(); 312 ?> 313 </ul> 314 </div> 315 316 <p> 317 <label for="wptv_video_producer"><?php esc_html_e( 'Video producer' ); ?></label> 318 <input type="text" id="wptv_video_producer" name="wptv_video_producer" value="" /> 319 </p> 320 <p> 321 <label for="wptv_speakers"><?php esc_html_e( 'Speakers' ); ?></label> 322 <input type="text" id="wptv_speakers" name="wptv_speakers" value="" /> 323 </p> 324 <p> 325 <label for="wptv_event"><?php esc_html_e( 'Event' ); ?></label> 326 <input type="text" id="wptv_event" name="wptv_event" value="" /> 327 </p> 328 <p> 329 <label for="wptv_video_description"><?php esc_html_e( 'Description' ); ?></label> 330 <textarea name="wptv_video_description" id="wptv_video_description" rows="8" cols="40"></textarea> 331 </p> 332 <p> 333 <label for="wptv_file"><?php esc_html_e( 'Video file' ); ?><span class="required"> * </span></label> 334 <input type="file" name="wptv_file" id="wptv_file" /> 335 </p> 336 <p class="last"> 337 <input type="submit" id="wptv_video_upload" style="display:none;" value="<?php esc_attr_e( 'Submit' ); ?>" /> 338 </p> 339 </form> 340 </div> 341 </div> 342 </div> 343 344 <script type="text/javascript"> 345 jQuery( function($) { 346 var invalid, 347 val, 348 uploaded_by = $( '#wptv_uploaded_by' ), 349 email = $( '#wptv_email' ), 350 file = $( '#wptv_file' ), 351 honey = $( '#wptv_honey' ); 352 353 invalid = function( el, e ) { 354 el.addClass( 'invalid' ); 355 el.one( 'click', function() { 356 $( this ).removeClass( 'invalid' ); 357 } ); 358 e.preventDefault(); 359 } 360 361 $( '#wptv_video_upload' ).show(); 362 $( '#video-upload-form input[type="text"]' ).each( function() { 363 $( this ).attr( 'maxlength', '100' ); 364 } ); 365 $( 'ul.cats-checkboxes input' ).prop( 'disabled', false ); 366 367 $( '#video-upload-form' ).submit( function( e ) { 368 var scroll = false; 369 370 if ( uploaded_by.length && ! uploaded_by.val() ) { 371 invalid( uploaded_by, e ); 372 scroll = true; 373 } 374 375 if ( email.length ) { 376 val = email.val(); 377 378 if ( !val || !/\S+@\S+\.\S+/.test( val ) ) { 379 invalid(email, e); 380 scroll = true; 381 } 382 } 383 384 if ( ! file.val() || !/\.(avi|mov|qt|mpeg|mpg|mpe|mp4|m4v|asf|asx|wax|wmv|wmx|ogv|3gp|3g2)$/.test( file.val() ) ) { 385 invalid(file, e); 386 } 387 388 // If there's any input in the honeypot field, it was probably put there by a bot, so reject the submission 389 if ( honey.val().length > 0 ) { 390 invalid( honey, e ); 391 scroll = true; 392 } 393 394 if ( scroll && uploaded_by.length ) { 395 uploaded_by.get( 0 ).scrollIntoView(); 396 } 397 } ); 398 } ); 399 </script> 400 401 <?php get_footer(); 402 -
new file archive.php
diff --git a/archive.php b/archive.php new file mode 100755 index 0000000..58074b4
- + 1 <?php 2 /* 3 * WordCamp.tv Archives 4 * 5 * Yearly, monthly, daily, author and whatever falls back to archive.php. 6 */ 7 8 get_header(); 9 global $wp_query, $post, $wptv; 10 ?> 11 <div class="wptv-hero"> 12 <h2 class="page-title"><?php 13 if ( is_category() ) : 14 printf( __( '‘%s’ Videos', 'wptv' ), single_cat_title( '', false ) ); 15 16 elseif ( is_tag() ) : 17 printf( __( '‘%s’ Videos', 'wptv' ), single_tag_title( '', false ) ); 18 19 elseif ( is_day() ) : 20 printf( _x( 'Archive for %s', 'Daily archive page', 'wptv' ), get_the_time( __( 'F jS, Y', 'wptv' ) ) ); 21 22 elseif ( is_month() ) : 23 printf( _x( 'Archive for %s', 'Monthly archive page', 'wptv' ), get_the_time( __( 'F, Y', 'wptv' ) ) ); 24 25 elseif ( is_year() ) : 26 printf( _x( 'Archive for %s', 'Yearly archive page', 'wptv' ), get_the_time( __( 'Y', 'wptv' ) ) ); 27 28 elseif ( is_author() ) : 29 esc_html_e( 'Author Archive', 'wptv' ); 30 31 elseif ( isset( $wp_query->query_vars['taxonomy'] ) ) : 32 $tax = get_taxonomy( $wp_query->query_vars['taxonomy'] ); 33 $terms = get_term_by( 'slug', $wp_query->query_vars['term'], $wp_query->query_vars['taxonomy'] ); 34 print( "$tax->label: $terms->name" ); 35 36 elseif ( is_search() ) : 37 printf( __( 'Search Results for ‘%s’', 'wptv' ), '<span>' . get_search_query() . '</span>' ); 38 39 else : 40 esc_html_e( 'Archives', 'wptv' ); 41 42 endif; 43 ?> 44 </h2> 45 </div> 46 <div class="container"> 47 <div class="primary-content"> 48 49 <?php if ( have_posts() ) : ?> 50 <ul class="archive video-list"> 51 52 <?php while ( have_posts() ) : the_post(); ?> 53 <li> 54 <a href="<?php the_permalink(); ?>" class="video-thumbnail"> 55 <?php $wptv->the_video_image( 50, null, false ); ?> 56 </a> 57 <div class="video-description"> 58 <h4 class="video-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h4> 59 <?php 60 $wptv->the_terms( 'event', '<span class="video-events">', ', ', '</span>', false ); 61 $label = _n( 'Speaker:', 'Speakers:', count( get_the_terms( $post->ID, 'speakers' ) ), 'wptv' ); 62 $wptv->the_terms( 'speakers', '<span class="video-speakers"><strong>' . $label . '</strong> ', ', ', '</span>', false ); 63 ?> 64 <span class="video-excerpt"> 65 <?php 66 $excerpt = get_the_time( get_option( 'date_format' ) ); 67 if ( has_excerpt() ) { 68 $excerpt .= ' — ' . get_the_excerpt(); 69 } 70 echo apply_filters( 'the_excerpt', $excerpt ); 71 ?> 72 </span> 73 </div> 74 </li> 75 <?php endwhile; // have_posts ?> 76 77 </ul><!-- .archive.video-list --> 78 <?php else: // have_posts ?> 79 80 <h3><?php esc_html_e( 'No videos found.', 'wptv' ); ?></h3> 81 82 <?php endif; // have_posts ?> 83 84 <?php get_template_part( 'pagination' ); ?> 85 86 </div><!-- primary-content --> 87 <?php get_sidebar(); ?> 88 </div><!-- .container --> 89 <?php 90 get_footer(); 91 No newline at end of file -
new file readcrumbs.php
diff --git a/breadcrumbs.php b/breadcrumbs.php new file mode 100755 index 0000000..93b3dfc
- + 1 <?php 2 /** 3 * Breadcrumbs template part, use with get_template_part() 4 */ 5 6 global $wptv; 7 ?> 8 <div class="breadcrumb"> 9 <a href="<?php echo esc_attr( home_url() );?>">Home</a> 10 <?php 11 $wptv->the_category( '<span class="arrow">»</span>' ); 12 $wptv->the_event( '<span class="arrow">»</span>' ); 13 ?> 14 </div> -
new file category-wordcamptv.php
diff --git a/category-wordcamptv.php b/category-wordcamptv.php new file mode 100755 index 0000000..6f74079
- + 1 <?php 2 /* 3 * WordCampTV Category Archives 4 * 5 * Requires a special display, hence the template. 6 */ 7 8 $featured = new WP_Query( array( 9 'posts_per_page' => 6, 10 'category_name' => 'wordcamptv', 11 'tag' => 'featured', 12 ) ); 13 14 get_header(); 15 global $wptv; 16 ?> 17 <div class="wptv-hero group"> 18 <div class="container"> 19 20 <h2 class="page-title"><?php single_term_title(); ?></h2> 21 <div class="desc"><?php echo category_description(); ?></div> 22 23 <?php if ( $featured->have_posts() ) : $featured->the_post(); ?> 24 <div class="main-video"> 25 <?php $wptv->the_video(); ?> 26 <h3> 27 <a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>" class="video-title"><?php the_title(); ?></a> 28 <?php $wptv->the_event( '<strong class="video-event">', '</strong>' ); ?> 29 </h3> 30 </div><!-- .main-video --> 31 <?php endif; // have_posts ?> 32 33 <div class="secondary-videos"> 34 <ul> 35 36 <?php while ( $featured->have_posts() ) : $featured->the_post(); ?> 37 <li class="group"> 38 <a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>" > 39 <span class="video-thumbnail"> 40 <img src="<?php $wptv->the_video( true, true ); ?>" /> 41 </span> 42 <span class="video-title"><?php the_title(); ?></span> 43 <?php $wptv->the_event( '<strong class="video-event">', '</strong>' ); ?> 44 </a> 45 </li> 46 <?php endwhile; // have_posts ?> 47 48 </ul> 49 </div><!-- .secondary-videos --> 50 </div><!-- .container --> 51 </div><!-- .wptv-hero --> 52 53 <div class="container"> 54 <div class="primary-content"> 55 56 <?php 57 /** 58 * The following is a very special navigation menu. It 59 * should contain Event taxonomy items only, and will list 60 * them with videos from the chosen event. 61 */ 62 wp_nav_menu( array( 63 'theme_location' => 'featured_wordcamps', 64 'depth' => 1, 65 'walker' => new WordCampTV_Walker_Nav_Menu, 66 ) ); 67 ?> 68 69 </div><!-- .primary-content --> 70 <?php get_sidebar( 'wordcamptv' ); ?> 71 </div><!-- container --> 72 73 <?php 74 get_footer(); -
new file category.php
diff --git a/category.php b/category.php new file mode 100755 index 0000000..3933df8
- + 1 <?php 2 /* 3 * Category Archives 4 * 5 * Used for categories display, especially the to-do category. 6 * Fallback to others as well. 7 */ 8 9 global $wp_query, $wptv; 10 get_header(); 11 12 /* The below if statement makes sure the hero is hidden on: 13 * - Second, third, etc pages. 14 * - If found posts is not more than 6 15 */ 16 17 if ( get_query_var( 'paged' ) < 2 && $wp_query->found_posts > 6 ) : ?> 18 <div class="wptv-hero group"> 19 <div class="container"> 20 21 <h2 class="page-title"><?php single_term_title(); ?></h2> 22 <div class="desc"><?php echo category_description(); ?></div> 23 24 <?php if ( have_posts() ) : the_post(); ?> 25 26 <div class="main-video"> 27 <?php $wptv->the_video(); ?> 28 <h3> 29 <a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php echo esc_attr( sprintf( __('Permanent Link to %s', 'wptv'), get_the_title() ) ); ?>" class="video-title"><?php the_title(); ?></a> 30 <?php $wptv->the_event( '<strong class="video-event">', '</strong>' ); ?> 31 </h3> 32 </div><!-- .main-video --> 33 34 <?php endif; // have_posts ?> 35 36 <div class="secondary-videos"> 37 <ul> 38 <?php while ( have_posts() && $wp_query->current_post < 5 ) : the_post(); ?> 39 <li class="group"> 40 <a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php echo esc_attr( sprintf(__('Permanent Link to %s', ''), get_the_title() ) ); ?>" > 41 <span class="video-thumbnail"> 42 <img src="<?php $wptv->the_video( true, true ); ?>" /> 43 </span> 44 <span class="video-title"><?php the_title(); ?></span> 45 <?php $wptv->the_event( '<strong class="video-event">', '</strong>' ); ?> 46 </a> 47 </li> 48 <?php endwhile; ?> 49 </ul> 50 </div><!-- .secondary-videos --> 51 52 </div> 53 </div><!-- .wptv-hero --> 54 55 <?php else : // get_query_var(paged) < 2 ?> 56 57 <div class="wptv-hero group"> 58 <div class="container"> 59 <h2 class="page-title"><?php single_cat_title(); ?></h2> 60 <div class="desc"><?php echo category_description(); ?></div> 61 </div> 62 </div> 63 64 <?php endif; // paged ?> 65 66 <div class="container"> 67 <div class="primary-content"> 68 69 <?php if ( have_posts() ) : ?> 70 71 <h3><?php esc_html_e( 'Latest Videos', 'wptv' ); ?></h3> 72 <ul class="video-list four-col"> 73 74 <?php while ( have_posts() ) : the_post() ; ?> 75 <li> 76 <a href="<?php the_permalink(); ?>"> 77 <span class="video-thumbnail"><?php $wptv->the_video_image( 50, null, false ); ?></span> 78 <span class="video-title"><?php the_title(); ?></span> 79 </a> 80 </li> 81 <?php endwhile; ?> 82 83 </ul> 84 85 <?php get_template_part( 'pagination' ); ?> 86 87 <?php else : // have_posts ?> 88 <p><?php esc_html_e( 'Sorry, no posts were found in this category.', 'wptv' ); ?></p> 89 <?php endif; ?> 90 91 </div><!-- .primary-content --> 92 <?php get_sidebar(); ?> 93 </div><!-- .container --> 94 95 <?php get_footer(); ?> 96 No newline at end of file -
new file comments.php
diff --git a/comments.php b/comments.php new file mode 100755 index 0000000..e7ea96b
- + 1 <?php 2 /** 3 * WordPress.tv Comments Template 4 * @uses global $wptv->list_comments 5 */ 6 7 /* 8 * If the current post is protected by a password and 9 * the visitor has not yet entered the password we will 10 * return early without loading the comments. 11 */ 12 if ( post_password_required() ) { 13 return; 14 } 15 16 global $wptv; 17 18 if ( have_comments() ) : 19 ?> 20 <h3 id="comments"> 21 <?php 22 printf( _nx( 'One response on “%2$s”', '%1$s responses on “%2$s”', get_comments_number(), 'comments title', 'wptv' ), 23 number_format_i18n( get_comments_number() ), '<span>' . get_the_title() . '</span>' ); 24 ?> 25 </h3> 26 27 <ol class="commentlist"> 28 <?php wp_list_comments( array( 'callback' => array( $wptv, 'list_comments' ) ) ); ?> 29 </ol> 30 <?php 31 endif; 32 33 if ( ! comments_open() && get_comments_number() && post_type_supports( get_post_type(), 'comments' ) ) : 34 ?> 35 <p class="nocomments"><?php esc_html_e( 'Comments are closed.', 'wptv' ); ?></p> 36 <?php 37 38 endif; 39 40 comment_form(); -
new file footer.php
diff --git a/footer.php b/footer.php new file mode 100755 index 0000000..4e712ef
- + 1 <?php 2 /** 3 * The Footer Template 4 * 5 * The header.php template opens the main container with a #page 6 * element, which is closed in the footer element. Everything else 7 * should go between the two. 8 */ 9 ?> 10 <div id="footer"> 11 <div class="container"> 12 <?php wp_nav_menu( array( 'theme_location' => 'footer', 'depth' => 1, 'link_after' => '<span class="dot">•</span>' ) ); ?> 13 <p class="automattic">An <a href="http://automattic.com/"><img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxvZ28iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgNDk0LjQgMzguMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNDk0LjQgMzguMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8cGF0aCBmaWxsPSIjODg4ODg4IiBkPSJNMTc5LjMsMzguMmMtMTIuNiwwLTIwLjctOS4xLTIwLjctMTguNXYtMS4yYzAtOS42LDguMi0xOC41LDIwLjctMTguNWMxMi42LDAsMjAuOCw4LjksMjAuOCwxOC41djEuMg0KCUMyMDAuMSwyOS4xLDE5MS45LDM4LjIsMTc5LjMsMzguMnogTTE5My4zLDE4LjZjMC02LjktNS0xMy0xNC4xLTEzYy05LjEsMC0xNCw2LjEtMTQsMTN2MC45YzAsNi45LDUsMTMuMSwxNCwxMy4xDQoJYzkuMSwwLDE0LjEtNi4yLDE0LjEtMTMuMVYxOC42eiIvPg0KPHBhdGggZmlsbD0iIzg4ODg4OCIgZD0iTTM3LjEsMzYuOEwzMi40LDI4SDExLjZMNywzNi44SDBMMTkuMiwxLjNoNS41bDE5LjUsMzUuNUgzNy4xeiBNMjEuOCw4LjJsLTcuNywxNC45aDE1LjdMMjEuOCw4LjJ6Ii8+DQo8cGF0aCBmaWxsPSIjODg4ODg4IiBkPSJNNzQuNiwzOC4yYy0xMi43LDAtMTguNy02LjktMTguNy0xNi4yVjEuM2g2LjZ2MjAuOWMwLDYuNiw0LjMsMTAuNSwxMi41LDEwLjVjOC40LDAsMTEuOS0zLjksMTEuOS0xMC41VjEuMw0KCWg2LjdWMjJDOTMuNiwzMC44LDg3LjksMzguMiw3NC42LDM4LjJ6Ii8+DQo8cGF0aCBmaWxsPSIjODg4ODg4IiBkPSJNMTMwLjcsNi44djMwaC02Ljd2LTMwaC0xNS41VjEuM2gzNy43djUuNUgxMzAuN3oiLz4NCjxwYXRoIGZpbGw9IiM4ODg4ODgiIGQ9Ik0yNTkuNSwzNi44VjguN2wtMS44LDMuMWwtMTQuOSwyNWgtMy4zbC0xNC43LTI1bC0xLjgtMy4xdjI4LjFoLTYuNVYxLjNoOS4ybDE0LDI0LjRsMS43LDNsMS43LTNMMjU3LDEuMw0KCWg5LjF2MzUuNUgyNTkuNXoiLz4NCjxwYXRoIGZpbGw9IiM4ODg4ODgiIGQ9Ik0zMTYuNSwzNi44bC00LjctOC44SDI5MWwtNC41LDguOGgtN2wxOS4yLTM1LjVoNS41bDE5LjUsMzUuNUgzMTYuNXogTTMwMS4yLDguMmwtNy43LDE0LjloMTUuN0wzMDEuMiw4LjJ6DQoJIi8+DQo8cGF0aCBmaWxsPSIjODg4ODg4IiBkPSJNMzUwLjYsNi44djMwaC02Ljd2LTMwaC0xNS41VjEuM2gzNy43djUuNUgzNTAuNnoiLz4NCjxwYXRoIGZpbGw9IiM4ODg4ODgiIGQ9Ik0zOTkuNSw2Ljh2MzBoLTYuN3YtMzBoLTE1LjVWMS4zSDQxNXY1LjVIMzk5LjV6Ii8+DQo8cGF0aCBmaWxsPSIjODg4ODg4IiBkPSJNNDMxLjQsMzYuOFY0LjZjMi43LDAsMy43LTEuNCwzLjctMy40aDIuOHYzNS41SDQzMS40eiIvPg0KPHBhdGggZmlsbD0iIzg4ODg4OCIgZD0iTTQ5MC4yLDExLjNjLTMuMi0yLjktNy45LTUuNy0xNC4yLTUuN2MtOS41LDAtMTQuOCw2LjUtMTQuOCwxMy4zdjAuN2MwLDYuNyw1LjQsMTMsMTUuMywxMw0KCWM1LjksMCwxMC44LTIuOCwxMy45LTUuN2w0LDQuMmMtMy45LDMuOC0xMC41LDcuMS0xOC4zLDcuMWMtMTMuNCwwLTIxLjYtOC43LTIxLjYtMTguM3YtMS4yYzAtOS42LDguOS0xOC43LDIxLjktMTguNw0KCWM3LjUsMCwxNC4zLDMuMSwxOCw3LjFMNDkwLjIsMTEuM3oiLz4NCjxwYXRoIGZpbGw9IiM4ODg4ODgiIGQ9Ik0xODMuNiwxMi40YzEuMiwwLjgsMS41LDIuNCwwLjgsMy42bC02LjEsOS40Yy0wLjgsMS4yLTIuNCwxLjYtMy42LDAuOGwwLDBjLTEuMi0wLjgtMS41LTIuNC0wLjgtMy42DQoJbDYuMS05LjRDMTgwLjgsMTEuOSwxODIuNCwxMS42LDE4My42LDEyLjRMMTgzLjYsMTIuNHoiLz4NCjwvc3ZnPg0K" alt="Automattic" width="165" height="14" /></a> <?php $words = array( 'Production', 'Joint', 'Medley', 'Experiment', 'Ruckus', 'Invention', 'Creation', 'Thingamajig', 'Opus', 'Brainchild', 'Contraption' ); echo $words[ mt_rand( 0, count( $words) -1 ) ]; ?></p> 14 </div> 15 </div><!-- #footer --> 16 </div><!-- #page --> 17 18 <?php wp_footer(); ?> 19 </body> 20 </html> -
new file front-page.php
diff --git a/front-page.php b/front-page.php new file mode 100755 index 0000000..81ea289
- + 1 <?php 2 /** 3 * WordPress.tv Front Page Template 4 */ 5 6 $featured_params = array( 7 'posts_per_page' => 1, 8 'tag' => 'featured', 9 ); 10 if ( $sticky_posts = get_option( 'sticky_posts' ) ) { 11 $featured_params['post__in'] = $sticky_posts; 12 } 13 $featured = new WP_Query( $featured_params ); 14 15 global $wptv; 16 get_header(); ?> 17 18 <div class="wptv-hero group"> 19 <div class="container"> 20 21 <?php while ( $featured->have_posts() ) : $featured->the_post(); ?> 22 <div class="main-video"> 23 <?php $wptv->the_video(); ?> 24 <h3> 25 <a href="<?php the_permalink() ?>" rel="bookmark" title="<?php the_title_attribute(); ?>" class="video-title"><?php the_title(); ?></a> 26 <?php $wptv->the_event( '<strong class="video-event">', '</strong>' ); ?> 27 </h3> 28 </div><!-- .main-video --> 29 <?php endwhile; // $featured->have_posts ?> 30 31 <div class="secondary-videos"> 32 <h3> 33 <?php esc_html_e( 'WordCampTV', 'wptv' ); ?> 34 <a href="<?php echo home_url( '/category/wordcamptv/' ); ?>" class="view-more"><?php _e( 'More →', 'wptv' ); ?></a> 35 </h3> 36 <ul> 37 <?php 38 $featured = new WP_Query( array( // WordCampTV Featured 39 'posts_per_page' => 4, 40 'post__not_in' => array( get_the_id() ), // In case the above video is the same 41 'category_name' => 'wordcamptv', 42 'tag' => 'featured', 43 ) ); 44 45 while ( $featured->have_posts() ) : 46 $featured->the_post(); 47 ?> 48 49 <li class="group"> 50 <a href="<?php the_permalink(); ?>" rel="bookmark" title="<?php the_title_attribute(); ?>" > 51 <span class="video-thumbnail"> 52 <img src="<?php $wptv->the_video( true, true ); ?>" /> 53 </span> 54 <span class="video-title"><?php the_title(); ?></span> 55 <?php $wptv->the_event( '<strong class="video-event">', '</strong>' ); ?> 56 </a> 57 </li> 58 59 <?php 60 endwhile; // $featured->have_posts 61 unset( $featured ); 62 ?> 63 </ul> 64 </div><!-- .secondary-videos --> 65 66 </div><!-- .container --> 67 </div><!-- .wptv-hero --> 68 69 <div class="container"> 70 <div class="primary-content"> 71 72 <!-- Latest Videos --> 73 <?php 74 if ( have_posts() ) : 75 ?> 76 <h3><?php esc_html_e( 'Latest Videos', 'wptv' ); ?></h3> 77 <ul class="video-list four-col"> 78 79 <?php while ( have_posts() ) : the_post(); ?> 80 <li> 81 <a href="<?php the_permalink(); ?>"> 82 <span class="video-thumbnail"><?php $wptv->the_video_image( 50, null, false ); ?></span> 83 <span class="video-title"><?php the_title(); ?></span> 84 </a> 85 </li> 86 <?php endwhile; ?> 87 88 </ul> 89 <?php 90 endif; // $latest->have_posts 91 92 // Popular Videos 93 $popular = new WP_Query( array( 94 'posts_per_page' => 8, 95 'meta_key' => 'wptv_post_views', 96 'orderby' => 'meta_value_num', 97 'order' => 'DESC', 98 'date_query' => array( 99 'after' => '-180 days', 100 ), 101 ) ); 102 103 if ( $popular->have_posts() ) : 104 ?> 105 <h3><?php esc_html_e( 'Popular Videos', 'wptv' ); ?></h3> 106 <ul class="video-list four-col"> 107 108 <?php while ( $popular->have_posts() ) : $popular->the_post(); ?> 109 <li> 110 <a href="<?php the_permalink(); ?>"> 111 <span class="video-thumbnail"><?php $wptv->the_video_image( 50, null, false ); ?></span> 112 <span class="video-title"><?php the_title(); ?></span> 113 </a> 114 </li> 115 <?php endwhile; ?> 116 117 </ul> 118 <?php 119 endif; // $popular->have_posts 120 unset( $popular ); 121 ?> 122 123 </div><!-- .primary-content --> 124 <?php get_sidebar(); ?> 125 </div><!-- .container--> 126 127 <?php 128 get_footer(); -
new file functions.php
diff --git a/functions.php b/functions.php new file mode 100755 index 0000000..87cb803
- + 1 <?php 2 3 /** 4 * WordPress.tv Functions 5 */ 6 class WordPressTV_Theme { 7 function __construct() { 8 if ( apply_filters( 'wptv_setup_theme', true ) ) { 9 // Load plugins and setup theme 10 require_once get_template_directory() . '/plugins/rewrite.php'; 11 require_once get_template_directory() . '/plugins/wordpresstv-oembed/wordpresstv-oembed.php'; 12 require_once get_template_directory() . '/plugins/wordpresstv-unisubs/wordpresstv-unisubs.php'; 13 require_once get_template_directory() . '/plugins/wordpresstv-rest/wordpresstv-rest.php'; 14 require_once get_template_directory() . '/plugins/wordpresstv-anon-upload/anon-upload.php'; 15 require_once get_template_directory() . '/plugins/wordpresstv-upload-subtitles/wordpresstv-upload-subtitles.php'; 16 17 add_action( 'after_setup_theme', array( $this, 'setup' ) ); 18 } 19 } 20 21 /** 22 * Runs during after_setup_theme. 23 */ 24 function setup() { 25 add_action( 'widgets_init', array( $this, 'widgets_init' ) ); 26 add_action( 'init', array( $this, 'register_taxonomies' ), 0 ); 27 add_action( 'pre_get_posts', array( $this, 'posts_per_page' ) ); 28 add_action( 'init', array( $this, 'improve_search' ) ); 29 add_action( 'publish_post', array( $this, 'publish_post' ), 10, 1 ); 30 add_action( 'wp_footer', array( $this, 'videopress_flash_params' ) ); 31 add_action( 'transition_post_status', array( $this, 'transition_post_status' ), 10, 2 ); 32 33 add_filter( 'pre_option_blog_upload_space', array( $this, 'blog_upload_space' ) ); 34 35 register_nav_menus( array( 36 'primary' => __( 'Primary Menu', 'wptv' ), 37 'footer' => __( 'Footer Menu', 'wptv' ), 38 'featured_wordcamps' => __( 'Featured WordCamps', 'wptv' ), 39 ) ); 40 } 41 42 /** 43 * Different posts_per_page settings for different views. Runs during pre_get_posts. 44 */ 45 function posts_per_page( $query ) { 46 $posts_per_page = $query->get( 'posts_per_page' ); 47 if ( ! $query->is_main_query() || ! empty( $posts_per_page ) ) { 48 return; 49 } 50 51 $queried_object = $query->get_queried_object(); 52 53 if ( $query->is_front_page() ) { // category archives 54 $query->set( 'posts_per_page', 8 ); 55 } elseif ( $query->is_category ) { // category archives 56 $query->set( 'posts_per_page', 22 ); 57 } elseif ( $query->is_tax && $queried_object->taxonomy == 'event' ) { // event taxonomy 58 $query->set( 'posts_per_page', 22 ); 59 } elseif ( $query->is_archive || $query->is_search ) { 60 $query->set( 'posts_per_page', 10 ); 61 } else { 62 $query->set( 'posts_per_page', 22 ); 63 } 64 } 65 66 /** 67 * Registers taxonomies, runs during init 68 */ 69 function register_taxonomies() { 70 register_taxonomy( 'producer', array( 'post' ), array( 71 'label' => __( 'Producer', 'wptv' ), 72 'template' => __( 'Producer: %l.', 'wptv' ), 73 'helps' => __( 'Separate producers with commas.', 'wptv' ), 74 'sort' => true, 75 'args' => array( 'orderby' => 'term_order' ), 76 'rewrite' => array( 'slug' => 'producer' ), 77 ) ); 78 79 register_taxonomy( 'speakers', array( 'post' ), array( 80 'label' => __( 'Speakers', 'wptv' ), 81 'template' => __( 'Speakers: %l.', 'wptv' ), 82 'helps' => __( 'Separate speakers with commas.', 'wptv' ), 83 'sort' => true, 84 'args' => array( 'orderby' => 'term_order' ), 85 'rewrite' => array( 'slug' => 'speakers' ), 86 ) ); 87 88 register_taxonomy( 'flavor', array( 'post' ), array( 89 'label' => __( 'Flavor', 'wptv' ), 90 'template' => __( 'Flavor: %l.', 'wptv' ), 91 'helps' => __( 'Separate flavors with commas.', 'wptv' ), 92 'sort' => true, 93 'args' => array( 'orderby' => 'term_order' ), 94 'rewrite' => array( 'slug' => 'flavor' ), 95 ) ); 96 97 register_taxonomy( 'language', array( 'post' ), array( 98 'label' => __( 'Language', 'wptv' ), 99 'template' => __( 'Language: %l.', 'wptv' ), 100 'helps' => __( 'Separate languages with commas.', 'wptv' ), 101 'sort' => true, 102 'args' => array( 'orderby' => 'term_order' ), 103 'rewrite' => array( 'slug' => 'language' ), 104 ) ); 105 106 register_taxonomy( 'event', array( 'post' ), array( 107 'label' => __( 'Event', 'wptv' ), 108 'template' => __( 'Event: %l.', 'wptv' ), 109 'helps' => __( 'Enter event', 'wptv' ), 110 'sort' => true, 111 'args' => array( 'orderby' => 'term_order' ), 112 'rewrite' => array( 'slug' => 'event' ), 113 ) ); 114 } 115 116 /** 117 * Runs during widgets_init, adds some sidebars. 118 */ 119 function widgets_init() { 120 register_sidebars( 1 ); 121 register_sidebar( array( 122 'name' => __( 'WordCampTV Sidebar', 'wptv' ), 123 'id' => 'wordcamptv-sidebar', 124 'description' => __( 'Widgets in this area will be shown on the WordCampTV landing page.', 'wptv' ), 125 'before_title' => '<h3>', 126 'after_title' => '</h3>', 127 ) ); 128 } 129 130 /** 131 * Filters the blog_upload_space option 132 */ 133 function blog_upload_space() { 134 return 1024 * 1024 * 10; // 10 terabytes 135 } 136 137 /** 138 * Runs during publish_post 139 * 140 * Since a lot of queries depend on the wptv_post_views meta 141 * key, make sure that every published post has one. 142 * 143 * @param int $post_id Post ID. 144 */ 145 function publish_post( $post_id ) { 146 if ( ! get_post_meta( $post_id, 'wptv_post_views', true ) ) { 147 update_post_meta( $post_id, 'wptv_post_views', 0 ); 148 } 149 } 150 151 /** 152 * Activates the improved search, but not in admin. 153 */ 154 function improve_search() { 155 if ( is_admin() ) { 156 return; 157 } 158 159 add_filter( 'posts_search', array( $this, 'search_posts_search' ), 10, 2 ); 160 add_action( 'pre_get_posts', array( $this, 'search_pre_get_posts' ) ); 161 } 162 163 /** 164 * @param WP_Query $query 165 */ 166 function search_pre_get_posts( $query ) { 167 if ( ! $query->is_main_query() || ! $query->is_search ) { 168 return; 169 } 170 171 // Set custom sorting 172 $query->set( 'meta_key', 'wptv_post_views' ); 173 $query->set( 'orderby', 'meta_value_num' ); 174 $query->set( 'order', 'DESC' ); 175 } 176 177 /** 178 * Improved Serach: posts_search filter 179 * 180 * Recreates the search SQL by including a taxonomy search. 181 * Relies on various other filters used once. 182 * @todo optimize the get_tax_query part. 183 * 184 * @param string $search 185 * @param WP_Query $query 186 * 187 * @return string 188 */ 189 function search_posts_search( $search, &$query ) { 190 global $wpdb; 191 if ( ! $query->is_main_query() || ! $query->is_search || is_admin() ) { 192 return $search; 193 } 194 195 // Get the tax query and replace the leading AND with an OR 196 $tax_query = get_tax_sql( $this->get_tax_query( get_query_var( 's' ) ), $wpdb->posts, 'ID' ); 197 if ( 'and' == substr( trim( strtolower( $tax_query['where'] ) ), 0, 3 ) ) { 198 $tax_query['where'] = ' OR ' . substr( trim( $tax_query['where'] ), 3 ); 199 } 200 201 // Mostly taken from query.php 202 if ( isset( $query->query_vars['search_terms'] ) ) { 203 $search = $searchand = ''; 204 $n = empty( $query->query_vars['exact'] ) ? '%' : ''; 205 206 foreach ( (array) $query->query_vars['search_terms'] as $term ) { 207 $term = esc_sql( like_escape( $term ) ); 208 $search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))"; 209 $searchand = ' AND '; 210 } 211 212 // Combine the search and tax queries. 213 if ( ! empty( $search ) ) { 214 // Add the tax search to the query 215 if ( ! empty( $tax_query['where'] ) ) { 216 $search .= $tax_query['where']; 217 } 218 219 $search = " AND ({$search}) "; 220 if ( ! is_user_logged_in() ) { 221 $search .= " AND ($wpdb->posts.post_password = '') "; 222 } 223 } 224 } 225 226 // These are single-use filters, they delete themselves right after they're used. 227 add_filter( 'posts_join', array( $this, 'search_posts_join' ), 10, 2 ); 228 add_filter( 'posts_groupby', array( $this, 'search_posts_groupby' ), 10, 2 ); 229 230 return $search; 231 } 232 233 /** 234 * Improved Search: posts_join filter 235 * 236 * This adds the JOIN clause resulting from the taxonomy 237 * search. Make sure this filter runs only once per WP_Query request. 238 * 239 * @param string $join 240 * @param WP_Query $query 241 * 242 * @return string 243 */ 244 function search_posts_join( $join, &$query ) { 245 // Make sure this filter doesn't run again. 246 remove_filter( 'posts_join', array( $this, 'search_posts_join' ), 10, 2 ); 247 248 if ( $query->is_main_query() ) { 249 global $wpdb; 250 $tax_query = get_tax_sql( $this->get_tax_query( get_query_var( 's' ) ), $wpdb->posts, 'ID' ); 251 $join .= $tax_query['join']; 252 } 253 254 return $join; 255 } 256 257 /** 258 * Improved Search: posts_groupby filter 259 * 260 * Searching with taxonomies may include duplicates when 261 * search query matches content and one or more taxonomies. 262 * This filter glues all duplicates. Use only once per WP_Query. 263 * 264 * @param string $group_by 265 * @param WP_Query $query 266 * 267 * @return string 268 */ 269 function search_posts_groupby( $group_by, &$query ) { 270 // Never run this again 271 remove_filter( 'posts_groupby', array( $this, 'search_posts_groupby' ), 10, 2 ); 272 273 global $wpdb; 274 $group_by = "$wpdb->posts.ID"; 275 276 return $group_by; 277 } 278 279 /** 280 * Returns a $tax_query array for an improved search. 281 * 282 * @param string $search 283 * 284 * @return array 285 */ 286 function get_tax_query( $search ) { 287 $taxonomies = array( 288 'producer', 289 'speakers', /*'flavor', 'language',*/ 290 'event' 291 ); 292 293 $terms = get_terms( $taxonomies, array( 294 'search' => $search, 295 ) ); 296 $term_ids = wp_list_pluck( $terms, 'term_id' ); 297 298 $tax_query = array(); 299 foreach ( $taxonomies as $taxonomy ) { 300 $tax_query[] = array( 301 'taxonomy' => $taxonomy, 302 'terms' => $term_ids, 303 ); 304 } 305 $tax_query['relation'] = 'OR'; 306 307 return $tax_query; 308 } 309 310 /** 311 * Change VideoPress Params, runs during wp_footer 312 */ 313 function videopress_flash_params() { 314 echo '<script type="text/javascript">if(jQuery.VideoPress){jQuery.VideoPress.video.flash.params.wmode="opaque";}</script>'; 315 } 316 317 /** 318 * List Comments Callback 319 * 320 * Used with wp_list_comments in the theme files, 321 * fired via the wptv_list_comments callback wrapper. 322 * 323 * @param object $comment 324 * @param array $args 325 * @param int $depth 326 */ 327 function list_comments( $comment, $args, $depth ) { 328 $GLOBALS['comment'] = $comment; 329 if ( $comment->comment_type == 'pingback' ) { 330 return; 331 } 332 ?> 333 <li <?php comment_class(); ?> id="comment-<?php comment_ID(); ?>"> 334 <cite class="authorinfo"> 335 <?php echo get_avatar( $comment, 24 ); ?> 336 <?php comment_author_link(); ?> 337 </cite> 338 339 <br/> 340 341 <?php if ( $comment->comment_type != 'pingback' ) : ?> 342 343 <small class="commentmetadata"> 344 <a href="#comment-<?php comment_ID() ?>" title=""><?php printf( __( '%1$s at %2$s', 'wptv' ), get_comment_date(), get_comment_time() ); ?></a> 345 <?php 346 edit_comment_link( __( 'edit', 'wptv' ), ' ', '' ); 347 echo comment_reply_link( array( 348 'depth' => $depth, 349 'max_depth' => $args['max_depth'], 350 'before' => ' | ', 351 ) ); 352 ?> 353 </small> 354 355 <?php endif; // comment_type != 'pingback' ?> 356 357 <div class="commenttext"> 358 <?php if ( $comment->comment_approved == '0' ) : ?> 359 <em><?php _e( 'Your comment is awaiting moderation.', 'wptv' ); ?></em> 360 <?php endif; // comment_approved == 0 ?> 361 362 <?php comment_text(); ?> 363 </div> 364 <div class="clear"></div> 365 </li> 366 <?php 367 } 368 369 /** 370 * Get VodPod Thumbnails, used by the_video_image 371 * 372 * @param string $code 373 * 374 * @return string 375 */ 376 function get_vodpod_thumbnails( $code ) { 377 preg_match( '/((Groupvideo|ExternalVideo).[0-9]+)/', $code, $matches ); 378 $id = $matches[1]; 379 380 if ( ! $id ) { 381 return get_template_directory_uri() . '/i/notfound.png'; 382 } 383 384 // Argh!! 385 $xml = file_get_contents( 'http://api.vodpod.com/api/video/details.xml?video_id=' . $id . '&api_key=03519ea5faf6a6ed' ); 386 387 if ( preg_match( '/<large>(.*)<\/large>/', $xml, $thevideoid ) ) { 388 return $thevideoid[1]; 389 } else { 390 return get_template_directory_uri() . '/i/notfound.png'; 391 } 392 } 393 394 /** 395 * Renders the video or a video thumbnail 396 * 397 * @param bool $thumb 398 * @param bool $no_html 399 */ 400 function the_video( $thumb = false, $no_html = false ) { 401 $image = $video = ''; 402 global $post, $originalcontent; 403 $originalcontent = $post->post_content; 404 405 remove_filter( 'the_content', array( $this, 'remove_shortcodes' ) ); 406 407 preg_match_all( '/\[wpvideo +([a-zA-Z0-9,\#,\&,\/,;,",=, ]*?)\]/i', $post->post_content, $matches ); 408 foreach ( $matches[1] as $key => $code ) { 409 410 preg_match( '/([0-9A-Za-z]+)/i', $code, $m ); 411 $guid = $m[1]; 412 413 $image = video_image_url_by_guid( $guid, 'fmt_dvd' ); //dvd image has width = 640 414 $video = apply_filters( 'the_content', '[wpvideo ' . $guid . ' w=605]' ); 415 416 /* 417 // Comment out the $video= line above and uncomment the following code to enable Unisubs 418 $permalink = get_permalink( $post->ID ); 419 $video = <<<HTML 420 <script type="text/javascript" src="http://unisubs.example.com:8000/site_media/embed.js"> 421 ({ 422 "video_url": "$permalink", 423 "video_config": { 424 "width": 648, 425 "height": 425 426 } 427 }) 428 </script> 429 HTML; 430 $video .= apply_filters( 'the_content', '' );*/ 431 } 432 433 preg_match_all( '|\[slideshare (.+?)]|ie', $post->post_content, $matches ); 434 foreach ( $matches[1] as $key => $code ) { 435 $code = '[slideshare ' . $code . ']'; 436 if ( $thumb ) { 437 preg_match( '/id=([0-9]+).*/', $code, $matches ); 438 $id = $matches[1]; 439 $ssxml = file_get_contents( 'http://www.slideshare.net/api/2/get_slideshow/?slideshow_id=' . $id . '&api_key=sM0rzJvp&ts=' . time() . '&hash=' . sha1( 'vHs2uii6' . time() ) ); 440 preg_match( '/<ThumbnailURL>(.+)<\/ThumbnailURL>/', $ssxml, $matches ); 441 $image = $matches[1]; 442 } else { 443 $slideshare = apply_filters( 'the_content', $code ); 444 $slideshare = preg_replace( '/height\=\'[0-9]+?\'/', "height='430'", $slideshare ); 445 $video = str_replace( "width='425'", "width='648'", $slideshare ); 446 } 447 } 448 449 preg_match_all( '|\[vodpod (.+?)]|ie', $post->post_content, $matches ); 450 foreach ( $matches[1] as $key => $code ) { 451 $code = '[vodpod ' . $code . ']'; 452 $vodpod = apply_filters( 'the_content', $code ); 453 $id = trim( str_replace( '</div>','', preg_replace( '/.*key\=([^&]+)&.*/', '$1', $vodpod ) ) ); 454 455 $image = $this->get_vodpod_thumbnails( $code ); 456 $video = $vodpod; 457 } 458 459 if ( $thumb ) { 460 if ( ! $no_html ) { 461 $image = '<img width="650" src="' . esc_url( $image ) . '" alt="' . esc_attr( $post->post_title ) . '" />'; 462 } 463 echo $image; 464 } else { 465 echo $video; 466 } 467 add_filter( 'the_content', array( $this, 'remove_shortcodes' ) ); 468 } 469 470 /** 471 * Outputs the video image 472 * 473 * @param int $h 474 * @param int $w 475 * @param bool $arrow 476 * @param bool $html_code 477 */ 478 function the_video_image( $h = 196, $w = 400, $arrow = true, $html_code = true ) { 479 $ret = ''; 480 global $post; 481 remove_filter( 'the_content', array( $this, 'remove_shortcodes' ) ); 482 483 preg_match_all( '/\[wpvideo +([a-zA-Z0-9,\#,\&,\/,;,",=, ]*?)\]/i', $post->post_content, $matches ); 484 foreach ( $matches[1] as $key => $code ) { 485 preg_match( '/([0-9A-Za-z]+)/i', $code, $m ); 486 $guid = $m[1]; 487 $ret = video_image_url_by_guid( $guid, 'fmt_dvd' ); 488 } 489 490 preg_match_all( '|\[wporg-screencast (.+?)]|ie', $post->post_content, $matches ); 491 foreach ( $matches[1] as $key => $code ) { 492 $wporg = apply_filters( 'the_content', '[wporg-screencast ' . $code . ']' ); 493 $ret = $wporg; 494 } 495 496 preg_match_all( '|\[slideshare (.+?)]|ie', $post->post_content, $matches ); 497 foreach ( $matches[1] as $key => $code ) { 498 $code = '[slideshare ' . $code . ']'; 499 500 preg_match( '/id=([0-9]+).*/', $code, $matches ); 501 $id = $matches[1]; 502 $url = 'http://www.slideshare.net/api/2/get_slideshow/?slideshow_id=' . $id . '&api_key=sM0rzJvp&ts=' . time() . '&hash=' . sha1( 'vHs2uii6' . time() ); 503 $ssxml = wp_remote_retrieve_body( wp_remote_get( esc_url_raw( $url ) ) ); 504 preg_match( '/<ThumbnailURL>(.+)<\/ThumbnailURL>/', $ssxml, $matches ); 505 $ret = $matches[1]; 506 } 507 508 preg_match_all( '|\[vodpod (.+?)]|ie', $post->post_content, $matches ); 509 foreach ( $matches[1] as $key => $code ) { 510 $code = '[vodpod ' . $code . ']'; 511 $ret = $this->get_vodpod_thumbnails( $code ); 512 } 513 514 if ( $arrow ) { 515 ?><a href="<?php the_permalink() ?>" class="showarrow arrow"><?php the_title(); ?></a><?php 516 } 517 if ( $html_code ) { 518 $ret = '<img src="' . $ret . '" alt="' . esc_attr( $post->post_title ) . '" />'; 519 } 520 echo $ret; 521 522 add_filter( 'the_content', array( $this, 'remove_shortcodes' ) ); 523 } 524 525 /** 526 * Removes shortcodes from $originalcontent global 527 * 528 * @param string $content 529 * 530 * @return mixed 531 */ 532 function remove_shortcodes( $content ) { 533 global $originalcontent; 534 535 return preg_replace( '/\[wpvideo +([a-zA-Z0-9,\#,\&,\/,;,",=, ]*?)\]/i', '', $originalcontent ); 536 } 537 538 /** 539 * Returns the home URL 540 * 541 * @param string $path 542 * 543 * @return mixed|void 544 */ 545 public function home_url( $path = '' ) { 546 return apply_filters( 'wptv_home_url', home_url( $path ), $path ); 547 } 548 549 /** 550 * Prints a single category with custom priorities. 551 * 552 * @param string $before 553 */ 554 public function the_category( $before = '' ) { 555 foreach ( array( 'wordcamptv', 'how-to' ) as $category_slug ) { 556 $category = get_category_by_slug( $category_slug ); 557 558 if ( in_category( $category ) ) { 559 $link = get_category_link( $category ); 560 echo $before . ' <a href="' . esc_url( $link ) . '">' . esc_html( $category->name ) . '</a>'; 561 break; // only one category is printed 562 } 563 } 564 } 565 566 /** 567 * Prints a single event. 568 * 569 * @param string $before 570 * @param string $after 571 */ 572 public function the_event( $before = '', $after = '' ) { 573 $terms = get_the_terms( get_post()->ID, 'event' ); 574 if ( ! $terms || is_wp_error( $terms ) ) { 575 return; 576 } 577 578 foreach ( $terms as $term ) { 579 $link = get_term_link( $term, 'event' ); 580 echo $before . '<a href="' . esc_url( $link ) . '">' . esc_html( $term->name ) . '</a>' . $after; 581 break; // only the first one event is printed 582 } 583 } 584 585 /** 586 * Display the Terms 587 * 588 * Give this a taxonomy 589 * 590 * @param string $taxonomy 591 * @param string $before 592 * @param string $sep 593 * @param string $after 594 * @param bool $display_count 595 */ 596 public function the_terms( $taxonomy = 'post_tag', $before = '', $sep = '', $after = '', $display_count = true ) { 597 $terms = get_the_terms( get_post()->ID, $taxonomy ); 598 if ( ! $terms || is_wp_error( $terms ) ) { 599 return false; 600 } 601 602 $links = array(); 603 foreach ( $terms as $term ) { 604 $count = $display_count ? ' <span class="tag-count">' . absint( $term->count ) . '</span>' : ''; 605 $links[] = '<a href="' . esc_url( get_term_link( $term, $taxonomy ) ) . '">' . esc_html( $term->name ) . $count . '</a>'; 606 } 607 echo $before . join( $sep, $links ) . $after; 608 } 609 610 /** 611 * Runs during transition_post_status, bumps some stats. 612 * 613 * @param string $new_status 614 * @param string $old_status 615 */ 616 function transition_post_status( $new_status, $old_status ) { 617 if ( 'publish' != $new_status || 'publish' == $old_status ) { 618 return; 619 } 620 621 // Make it easier to contribute to this theme by not assuming WP.com context. 622 if ( function_exists( 'bump_stats_extras' ) ) { 623 bump_stats_extras( 'wptv-activity', 'publish-video' ); 624 } 625 } 626 } 627 628 global $wptv; 629 $wptv = new WordPressTV_Theme; 630 631 /** 632 * WordCampTV wp_nav_menu Walker Class 633 * 634 * Use this class with wp_nav_menu to output an event 635 * together with some videos from the event. 636 */ 637 class WordCampTV_Walker_Nav_Menu extends Walker { 638 639 /** 640 * @see Walker 641 */ 642 var $tree_type = array( 'post_type', 'taxonomy', 'custom' ); 643 var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' ); 644 645 /** 646 * @see Walker::start_el() 647 * 648 * If an item is an event, print the event heading, 649 * followed by a WP_Query that loops through some of the 650 * videos in the event. start_el does all the work and does not need end_el. 651 * 652 * @param string $output 653 * @param object $item 654 * @param int $depth 655 * @param array $args 656 * @param int $id 657 */ 658 function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { 659 660 // Skip if it's not an event item. 661 if ( $item->object != 'event' || $item->type != 'taxonomy' ) { 662 return; 663 } 664 665 global $wptv; 666 667 // Use this query to fetch event videos. 668 $query = new WP_Query( array( 669 'posts_per_page' => 4, 670 'tax_query' => array( 671 array( 672 'taxonomy' => 'event', 673 'field' => 'id', 674 'terms' => $item->object_id, 675 ), 676 ), 677 ) ); 678 679 ob_start(); 680 ?> 681 <div> 682 <h3> 683 <?php echo apply_filters( 'the_title', $item->title ); ?> 684 <a href="<?php echo esc_url( $item->url ); ?>" class="view-more"><?php esc_html_e( 'More →' ); ?></a> 685 </h3> 686 <ul class="video-list four-col"> 687 <?php while ( $query->have_posts() ) : $query->the_post(); ?> 688 <li> 689 <a href="<?php the_permalink(); ?>"> 690 <span class="video-thumbnail"><?php $wptv->the_video_image( 50, null, false ); ?></span> 691 <span class="video-title"><?php the_title(); ?></span> 692 </a> 693 </li> 694 <?php endwhile; ?> 695 </ul> 696 </div> 697 <?php 698 $output .= ob_get_contents(); 699 ob_end_clean(); 700 } 701 } 702 703 704 function wptv_enqueue_scripts() { 705 wp_enqueue_style( 'wptv-style', get_stylesheet_uri() . '?s' ); 706 707 // Load the Internet Explorer specific stylesheet. 708 wp_enqueue_style( 'wptv-ie', get_template_directory_uri() . '/ie6.css', array( 'wptv-style' ) ); 709 wp_style_add_data( 'wptv-ie', 'conditional', 'IE 6' ); 710 711 wp_register_script( 'wptv-dropdowns', get_template_directory_uri() . '/js/dropdowns.js' ); 712 wp_enqueue_script( 'wptv-dropdowns', array( 'jquery' ) ); 713 714 if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) { 715 wp_enqueue_script( 'comment-reply' ); 716 } 717 } 718 add_action( 'wp_enqueue_scripts', 'wptv_enqueue_scripts' ); 719 720 /** 721 * Create a nicely formatted and more specific title element text for output 722 * in head of document, based on current view. 723 * 724 * @param string $title Default title text for current view. 725 * @param string $sep Optional separator. 726 * 727 * @return string The filtered title. 728 */ 729 function wptv_wp_title( $title, $sep ) { 730 if ( is_feed() ) { 731 return $title; 732 } 733 734 global $paged, $page; 735 736 // Add the site name. 737 $title .= get_bloginfo( 'name', 'display' ); 738 739 // Add the site description for the home/front page. 740 $site_description = get_bloginfo( 'description', 'display' ); 741 if ( $site_description && ( is_home() || is_front_page() ) ) { 742 $title = "$title $sep $site_description"; 743 } 744 745 // Add a page number if necessary. 746 if ( ( $paged >= 2 || $page >= 2 ) && ! is_404() ) { 747 $title = "$title $sep " . sprintf( __( 'Page %s', 'wptv' ), max( $paged, $page ) ); 748 } 749 750 return $title; 751 } 752 add_filter( 'wp_title', 'wptv_wp_title', 10, 2 ); -
new file header.php
diff --git a/header.php b/header.php new file mode 100755 index 0000000..7cbab9d
- + 1 <?php 2 /** 3 * WordPress.tv Header Template 4 * 5 * @global $wptv 6 */ 7 8 global $wptv; 9 ?><!DOCTYPE html> 10 <!--[if IE 6]> <html class="ie6" <?php language_attributes(); ?>> <![endif]--> 11 <!--[if IE 7]> <html class="ie7" <?php language_attributes(); ?>> <![endif]--> 12 <!--[if IE 8]> <html class="ie8" <?php language_attributes(); ?>> <![endif]--> 13 <!--[if gt IE 8]><!--> <html <?php language_attributes(); ?>> <!--<![endif]--> 14 15 <head> 16 <meta charset="<?php bloginfo( 'charset' ); ?>"> 17 <title><?php wp_title( '|', true, 'right' ); ?></title> 18 19 <link rel="alternate" type="application/rss+xml" title="<?php esc_attr_e( 'WordPress.tv RSS Feed', 'wptv' ); ?>" href="http://wordpress.tv/feed/" /> 20 <link rel="alternate" type="application/rss+xml" title="<?php esc_attr_e( 'WordPress.tv Blog RSS Feed', 'wptv' ); ?>" href="http://blog.wordpress.tv/feed/" /> 21 <link rel="profile" href="http://gmpg.org/xfn/11"> 22 <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" /> 23 24 <script type="text/javascript" src="http://use.typekit.com/mgi6udv.js"></script> 25 <script type="text/javascript">try{Typekit.load();}catch(e){}</script> 26 <?php wp_head(); ?> 27 </head> 28 29 <body <?php body_class(); ?>> 30 <div id="page"> 31 <div id="header"> 32 <div class="sleeve"> 33 34 <h1><a rel="home" href="<?php echo $wptv->home_url( '/' ); ?>"><img src="<?php echo get_template_directory_uri(); ?>/i/wptv-2x.png" alt="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>" height="40" width="210" /></a></h1> 35 36 <form id="searchform" name="searchform" method="get" action="<?php echo $wptv->home_url( '/' ); ?>"> 37 <input type="search" placeholder="<?php esc_attr_e( 'Search WordPress.tv', 'wptv' ); ?>" id="searchbox" name="s" value="<?php the_search_query(); ?>" /> 38 </form> 39 40 <div id="menu"> 41 <?php wp_nav_menu( array( 'theme_location' => 'primary' ) ); ?> 42 </div> 43 44 </div><!-- .sleeve --> 45 </div><!-- #header --> -
new file ie6.css
diff --git a/ie6.css b/ie6.css new file mode 100755 index 0000000..0e46208
- + 1 .videofeatured h3 { 2 position: absolute; 3 top: 0; 4 left: 0; 5 } 6 7 .videofeatured { 8 height: 175px; 9 } 10 11 .arrow { 12 background-position: -100px -100px; 13 top: 0; 14 left: 0; 15 } 16 17 .pagetitle { 18 height: 50px; 19 } 20 21 .videowrapper .sleeve { 22 padding-bottom: 14px; 23 } 24 25 .thirds { 26 width: 970px !important; 27 } 28 29 .blog .videowrapper { 30 display: none; 31 } 32 33 .blog .title { 34 border-bottom: 1px solid #333; 35 } 36 No newline at end of file -
new file inc/wpcom.php
diff --git a/inc/wpcom.php b/inc/wpcom.php new file mode 100755 index 0000000..fe67da7
- + 1 <?php 2 3 require_once WP_CONTENT_DIR . '/themes/vip/plugins/vip-init.php'; 4 wpcom_vip_load_plugin( 'taxonomy-list-widget' ); -
new file index.php
diff --git a/index.php b/index.php new file mode 100755 index 0000000..cf6a863
- + 1 <?php 2 /* 3 * WordCamp.tv Index Fallback 4 * 5 * It will be weird if somebody sees this (but okay if 404) 6 */ 7 8 get_header(); 9 global $wp_query, $post, $wptv; 10 11 if ( have_posts() ) : 12 ?> 13 14 <div class="wptv-hero"> 15 <h2 class="page-title"><?php esc_html_e( 'Archives', 'wptv' ); ?></h2> 16 </div> 17 <div class="container"> 18 <div class="primary-content"> 19 20 <ul class="archive video-list"> 21 22 <?php while ( have_posts() ) : the_post(); ?> 23 <li> 24 <a href="<?php the_permalink(); ?>" class="video-thumbnail"> 25 <?php $wptv->the_video_image( 50, null, false ); ?> 26 </a> 27 28 <div class="video-description"> 29 <div class="video-info"> 30 31 <h5><?php esc_html_e( 'Published', 'wptv' ); ?></h5> 32 <p class="video-date"><?php the_date(); ?></p> 33 34 <?php if ( $post->post_excerpt ) : ?> 35 <div class="video-description"><?php the_excerpt(); ?></div> 36 <?php 37 endif; 38 39 $wptv->the_terms( 'event', '<h5>Event</h5><p class="video-event">', '<br /> ', '</p>' ); 40 $wptv->the_terms( 'speakers', '<h5>Speakers</h5><p class="video-speakers">', '<br /> ', '</p>' ); 41 $wptv->the_terms( 'post_tag', '<h5>Tags</h5><p class="video-tags">', '<br /> ', '</p>' ); 42 $wptv->the_terms( 'language', '<h5>Language</h5><p class="video-lang">', '<br /> ', '</p>' ); 43 ?> 44 </div><!-- .video-info --> 45 </div> 46 </li> 47 <?php endwhile; // have_posts ?> 48 49 </ul><!-- .archive.video-list --> 50 51 <?php get_template_part( 'pagination' ); ?> 52 53 </div> 54 55 <div class="secondary-content"> 56 <?php get_sidebar(); ?> 57 </div><!-- .secondary-content --> 58 </div><!-- .container --> 59 60 <?php else : // have_posts ?> 61 62 <div class="wptv-hero"> 63 <h2 class="page-title"><?php esc_html_e( 'Whoops!', 'wptv' ); ?></h2> 64 </div> 65 <div class="container"> 66 <div class="primary-content"> 67 68 <div class="fourOHfour"> 69 <h2 class="center"><?php esc_html_e( 'Uh oh, someone made a mistake!' ); ?></h2> 70 <p><?php esc_html_e( 'These sorts of things happen…' ); ?></p> 71 <p class="center"><?php esc_html_e( 'Try searching for what you were looking for.' ); ?></p> 72 <p><?php echo get_search_form(); ?></p> 73 <p><?php printf ( __( 'Or, <a href="%s">visit the homepage</a> to start a fresh journey.', 'wptv' ), '/' ); ?></p> 74 <p> 75 <img src="<?php echo get_stylesheet_directory_uri(); ?>/i/michael-pick-stashes-a-guinness.gif" alt="" /><br /> 76 Photo animation credit: <a href="http://markjaquith.com/">Mark Jaquith</a>. 77 </p> 78 </div> 79 </div> 80 </div><!-- container --> 81 82 <?php 83 endif; 84 85 get_footer(); -
new file js/dropdowns.js
diff --git a/js/dropdowns.js b/js/dropdowns.js new file mode 100755 index 0000000..1ad1fe9
- + 1 jQuery(document).ready( function( $ ) { 2 $('#menu li').hover( 3 function() { 4 $(this).children('.sub-menu').slideDown('fast'); 5 }, function () { 6 $(this).children('.sub-menu').fadeOut('fast'); 7 } 8 ); 9 }); -
new file page.php
diff --git a/page.php b/page.php new file mode 100755 index 0000000..8784463
- + 1 <?php 2 /** 3 * Page Template 4 */ 5 get_header(); 6 the_post(); 7 ?> 8 <div class="wptv-hero"> 9 <h2 class="page-title"> 10 <?php the_title(); ?> 11 </h2> 12 </div> 13 14 <div class="container"> 15 <div class="primary-content"> 16 17 <div <?php post_class(); ?>> 18 19 <div class="entry"> 20 <div class="sleeve"> 21 <?php the_content(); ?><br /> 22 <div id="comments"> 23 <?php wp_link_pages(); ?> 24 <?php comments_template(); ?> 25 </div> 26 </div> 27 </div><!-- .entry --> 28 29 </div><!-- post_class() --> 30 31 </div><!-- .primary-content --> 32 <?php /*get_sidebar('page');*/ ?> 33 </div><!-- .container --> 34 35 <?php get_footer(); ?> 36 No newline at end of file -
new file pagination.php
diff --git a/pagination.php b/pagination.php new file mode 100755 index 0000000..9ddd43c
- + 1 <?php 2 /** 3 * Pagination template part, use with get_template_part() 4 */ 5 6 if ( $wp_query->max_num_pages > 1 ) : 7 ?> 8 <div class="pagination"> 9 <div class="nav-previous"><?php next_posts_link( __( '<span class="meta-nav">←</span> Older videos', 'wptv' ) ); ?></div> 10 <div class="nav-next"><?php previous_posts_link( __( 'Newer videos <span class="meta-nav">→</span>', 'wptv' ) ); ?></div> 11 </div> 12 <?php 13 endif; -
new file plugins/rewrite.php
diff --git a/plugins/rewrite.php b/plugins/rewrite.php new file mode 100755 index 0000000..6267cab
- + 1 <?php 2 /** 3 * WordPress.tv Rewrites 4 * 5 * Some WordPress.tv plugins will add new rewrite rules during init, this plugin 6 * will allow a $_GET request to flush rules. 7 */ 8 function wptv_maybe_flush_rewrite_rules() { 9 global $wp_rewrite; 10 11 // Visit http://wordpress.tv/?flush_rules=1 as a super admin or kovshenin (4637740) 12 // to flush the rules for /unisubs/ endpoint to work. 13 if ( ( is_super_admin() || get_current_user_id() == 4637740 ) && !empty( $_GET['flush_rules'] ) ) { 14 $wp_rewrite->flush_rules(); 15 exit( 'Rewrite rules flushed.' ); 16 } 17 } 18 add_action( 'init', 'wptv_maybe_flush_rewrite_rules', 99 ); -
new file plugins/wordpresstv-anon-upload/anon-upload.php
diff --git a/plugins/wordpresstv-anon-upload/anon-upload.php b/plugins/wordpresstv-anon-upload/anon-upload.php new file mode 100755 index 0000000..5c1930b
- + 1 <?php 2 3 // Anonnymous uploads of videos for WPTV 4 class WPTV_Anon_Upload { 5 // hardcoded user_id for the fake contributor that owns the drafts (username: anonvideoupload, currently uses andrew.ozz@automattic email) 6 private $drafts_author = 34340661; 7 var $errors = false; 8 var $success = false; 9 10 function __construct() { 11 $this->drafts_author = apply_filters( 'wptv_drafts_author_id', $this->drafts_author ); // this is filterable in order to support local development 12 13 add_action( 'admin_post_wptv_video_upload', array( &$this, 'init' ) ); 14 add_action( 'admin_post_nopriv_wptv_video_upload', array( &$this, 'init' ) ); 15 add_action( 'dbx_post_sidebar', array( &$this, 'display' ) ); 16 } 17 18 function init() { 19 if ( ! empty( $_POST['wptvvideon'] ) && wp_verify_nonce( $_POST['wptvvideon'], 'wptv-upload-video' ) ) { 20 $this->validate(); 21 22 if ( ! $this->errors ) { 23 $this->success = $this->save(); 24 } 25 26 $redir = home_url( 'submit-video' ); 27 28 if ( $this->success ) { 29 $redir = add_query_arg( array( 'success' => 1 ), $redir ); 30 } elseif ( $this->errors ) { 31 $redir = add_query_arg( array( 'error' => $this->errors ), $redir ); 32 } else { 33 $redir = add_query_arg( array( 'error' => 5 ), $redir ); 34 } 35 36 wp_redirect( $redir ); 37 } else { 38 // no nonce, send them "home"? 39 wp_redirect( home_url() ); 40 } 41 42 exit; 43 } 44 45 // This should never trigger in "proper" use as there's JS validation on the form and JS is required. 46 // If it triggers, consider it as a bot/improper use and exit? 47 function validate() { 48 $text_fields = array( 49 'wptv_video_title', 50 'wptv_video_producer', 51 'wptv_speakers', 52 'wptv_event', 53 ); 54 55 // Normal users won't see the honeypot field, so if there's a value in it, then we can assume the submission is spam from a bot 56 if ( ! isset( $_POST['wptv_honey'] ) || ! empty( $_POST['wptv_honey'] ) ) { 57 if ( function_exists( 'bump_stats_extras' ) ) { 58 bump_stats_extras( 'wptv-spam', 'honeypot_trapped_anon_upload' ); 59 } 60 61 return $this->error( 13 ); 62 } 63 64 if ( ! is_user_logged_in() ) { 65 if ( empty( $_POST['wptv_uploaded_by'] ) ) { 66 return $this->error( 10 ); 67 } 68 69 if ( empty( $_POST['wptv_email'] ) ) { 70 return $this->error( 11 ); 71 } elseif ( ! is_email( $_POST['wptv_email'] ) ) { 72 return $this->error( 12 ); 73 } 74 75 $text_fields[] = 'wptv_uploaded_by'; 76 $text_fields[] = 'wptv_email'; 77 } 78 79 foreach ( $text_fields as $field ) { 80 if ( strlen( (string) $field ) > 150 ) { 81 return $this->error( 6 ); 82 } 83 } 84 } 85 86 function handle_upload( $parent_id ) { 87 // allow only video mimes 88 $overrides = array( 89 'test_form' => false, 90 'mimes' => array( 91 'avi' => 'video/avi', 92 'mov|qt' => 'video/quicktime', 93 'mpeg|mpg|mpe' => 'video/mpeg', 94 'mp4|m4v' => 'video/mp4', 95 'asf|asx|wax|wmv|wmx' => 'video/asf', 96 'ogv' => 'video/ogg', 97 '3gp' => 'video/3gpp', 98 '3g2' => 'video/3gpp2', 99 ), 100 ); 101 102 unset( $_FILES['async-upload'] ); 103 104 if ( empty( $_FILES['wptv_file']['name'] ) ) { 105 return new WP_Error( 'upload_error', 'Invalid file name.' ); 106 } 107 108 $name = $_FILES['wptv_file']['name']; 109 add_filter( 'wp_handle_upload_prefilter', array( &$this, 'video_filename' ), 5 ); 110 111 $file = wp_handle_upload( $_FILES['wptv_file'], $overrides ); 112 113 if ( isset( $file['error'] ) ) { 114 return new WP_Error( 'upload_error', $file['error'] ); 115 } 116 117 $filepath = $file['file']; 118 119 $attachment = array( 120 'post_title' => $this->sanitize_text( $name ), 121 'guid' => $file['url'], 122 'post_mime_type' => $file['type'], 123 'post_content' => '', 124 'post_author' => $this->drafts_author, 125 ); 126 127 // expects slashed 128 $attachment_id = wp_insert_attachment( add_magic_quotes( $attachment ), $filepath, $parent_id ); 129 130 if ( ! is_wp_error( $attachment_id ) ) { 131 wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $filepath ) ); 132 } 133 134 return $attachment_id; 135 } 136 137 // expects slashed, returns unslashed 138 function sanitize_text( $str, $remove_line_breaks = true ) { 139 $str = str_replace( '\\', '', $str ); 140 141 if ( $remove_line_breaks ) { 142 $str = sanitize_text_field( $str ); 143 } else { 144 $str = wp_check_invalid_utf8( $str ); 145 $str = wp_strip_all_tags( $str ); 146 147 $match = array(); 148 while ( preg_match( '/%[a-f0-9]{2}/i', $str, $match ) ) { 149 $str = str_replace( $match[0], '', $str ); 150 } 151 } 152 153 return htmlspecialchars( $str, ENT_QUOTES, 'UTF-8' ); 154 } 155 156 function error( $msg ) { 157 $this->errors = $msg; 158 159 return false; 160 } 161 162 function video_filename( $file ) { 163 $name_parts = pathinfo( $file['name'] ); 164 165 // this should never happen 166 if ( empty( $name_parts['extension'] ) ) { 167 die; 168 } 169 170 // random file name 171 $str = md5( time() . rand( 1, 1000000 ) ); 172 $file['name'] = 'video-' . substr( $str, rand( 5, 20 ), 10 ) . '.' . $name_parts['extension']; 173 174 return $file; 175 } 176 177 function save() { 178 // check 179 if ( empty( $_FILES['wptv_file']['name'] ) ) { 180 return $this->error( 1 ); 181 } 182 183 // quick file extension check 184 $name_parts = pathinfo( $_FILES['wptv_file']['name'] ); 185 186 if ( ! empty( $name_parts['extension'] ) ) { 187 if ( ! in_array( strtolower( $name_parts['extension'] ), array( 188 'avi', 189 'mov', 190 'qt', 191 'mpeg', 192 'mpg', 193 'mpe', 194 'mp4', 195 'm4v', 196 'asf', 197 'asx', 198 'wax', 199 'wmv', 200 'wmx', 201 'ogv', 202 '3gp', 203 '3g2', 204 ), true ) 205 ) { 206 return $this->error( 2 ); 207 } 208 } else { 209 return $this->error( 3 ); 210 } 211 212 // empty the globals just in case 213 $_posted = $_POST; 214 $_requested = $_REQUEST; 215 $_got = $_GET; 216 $_POST = $_REQUEST = $_GET = array(); 217 218 $blog_id = get_current_blog_id(); 219 220 $anon_post = get_default_post_to_edit( 'post' ); // without saving auto-draft 221 $anon_post = get_object_vars( $anon_post ); 222 223 $anon_post['post_title'] = 'Uploaded video'; 224 $anon_post['post_excerpt'] = ''; 225 $anon_post['post_author'] = $this->drafts_author; 226 $anon_post['post_status'] = 'pending'; 227 228 // Add default cat according to the "This is a WC video" checkbox 229 if ( ! empty( $_posted['wptv_video_wordcamp'] ) ) { 230 $anon_post['post_category'] = array( '12784353' ); // add the "WordCampTV" category 231 } 232 else { 233 $anon_post['post_category'] = array( '1' ); // Uncategorized 234 } 235 236 // Insert the post and attachment 237 $post_id = wp_insert_post( add_magic_quotes( $anon_post ) ); 238 239 if ( is_wp_error( $post_id ) ) { 240 return $this->error( 5 ); 241 } 242 243 $attachment_id = $this->handle_upload( $post_id ); 244 245 if ( is_wp_error( $attachment_id ) ) { 246 return $this->error( 5 ); 247 } 248 249 // Put the video shortcode in post_content (makes a standard post for wptv). 250 $video_data = function_exists( 'video_get_info_by_blogpostid' ) ? video_get_info_by_blogpostid( $blog_id, $attachment_id ) : false; 251 252 if ( ! $video_data || empty( $video_data->guid ) ) { 253 return $this->error( 4 ); 254 } 255 256 wp_update_post( array( 'ID' => $post_id, 'post_content' => '[wpvideo ' . $video_data->guid . ']' ) ); 257 258 // we have post_id, add post meta 259 $current_user = wp_get_current_user(); 260 261 if ( ! empty( $current_user->ID ) ) { 262 // use the logged in user name and email 263 $anon_author = $current_user->display_name; 264 $anon_author_email = $current_user->user_email; 265 } else { 266 // validate these in the back-end? 267 $anon_author = $this->sanitize_text( $_posted['wptv_uploaded_by'] ); 268 $anon_author_email = $this->sanitize_text( $_posted['wptv_email'] ); 269 } 270 271 $video_title = $this->sanitize_text( $_posted['wptv_video_title'] ); 272 $video_producer = $this->sanitize_text( $_posted['wptv_video_producer'] ); 273 $speakers = $this->sanitize_text( $_posted['wptv_speakers'] ); 274 $event = $this->sanitize_text( $_posted['wptv_event'] ); 275 $description = $this->sanitize_text( $_posted['wptv_video_description'], false ); 276 $language = $this->sanitize_text( $_posted['wptv_language'] ); 277 $ip = $_SERVER['REMOTE_ADDR']; 278 279 $categories = ''; 280 if ( ! empty( $_posted['post_category'] ) && is_array( $_posted['post_category'] ) ) { 281 foreach ( $_posted['post_category'] as $cat ) { 282 $cat = (int) $cat; 283 if ( $cat ) { 284 $categories .= "$cat,"; 285 } 286 } 287 } 288 289 $post_meta = array( 290 'attachment_id' => $attachment_id, 291 'submitted_by' => $anon_author, 292 'submitted_email' => $anon_author_email, 293 'title' => $video_title, 294 'producer' => $video_producer, 295 'speakers' => $speakers, 296 'event' => $event, 297 'language' => $language, 298 'categories' => $categories, 299 'description' => $description, 300 'ip' => $ip, 301 ); 302 303 $post_meta['video_guid'] = $video_data->guid; 304 update_post_meta( $post_id, '_wptv_submitted_video', $post_meta ); 305 306 // put back the globals 307 $_POST = $_posted; 308 $_REQUEST = $_requested; 309 $_GET = $_got; 310 311 return true; 312 } 313 314 function display() { 315 $post = get_post(); 316 317 if ( $post->post_author == $this->drafts_author ) { 318 $meta = get_post_meta( $post->ID, '_wptv_submitted_video', true ); 319 } 320 321 if ( empty( $meta ) ) { 322 return; 323 } 324 325 $attachment_post = get_post( $meta['attachment_id'] ); 326 327 $embed_args = array( 328 'format' => 'fmt_std', 329 'width' => 600, 330 'context' => 'admin', 331 ); 332 $embed_args['blog_id'] = get_current_blog_id(); 333 $embed_args['post_id'] = $meta['attachment_id']; 334 335 ?> 336 <div class="stuffbox" id="review-video"> 337 <style type="text/css" scoped="scoped"> 338 #poststuff #anon-data-wrap { 339 padding: 5px 15px; 340 } 341 342 #review-video h3.hndle { 343 cursor: pointer; 344 } 345 346 .anon-data { 347 padding: 15px 0 0; 348 } 349 350 .anon-data p { 351 margin: 8px 0; 352 } 353 354 .anon-data .label { 355 display: inline-block; 356 width: 23%; 357 } 358 359 .anon-data .data { 360 display: inline-block; 361 width: 75%; 362 } 363 364 .anon-data input[type="text"], .anon-data textarea { 365 width: 80%; 366 } 367 368 .anon-data a.anon-approve { 369 max-width: 19%; 370 margin-left: 1%; 371 } 372 373 .anon-data .txtarea .data a.anon-approve { 374 bottom: 6px; 375 position: relative; 376 } 377 378 .anon-data .txtarea .label { 379 padding: 10px 0; 380 vertical-align: top; 381 } 382 383 .anon-data a.disabled { 384 color: #888; 385 } 386 </style> 387 <h3 class="hndle"><span>Submitted video</span></h3> 388 389 <div id="anon-data-wrap" class="inside"> 390 391 <p>To change the default thumbnail image, play the video and click "Capture Thumbnail" button.</p> 392 <table> 393 <tr> 394 <td> 395 <?php 396 if ( function_exists( 'video_embed' ) ) { 397 echo video_embed( $embed_args ); 398 } 399 ?> 400 </td> 401 </tr> 402 </table> 403 404 <div class="anon-data"> 405 <div class="row"> 406 <p class="label">Submitted by:<br></p> 407 <p class="data"> 408 <input type="text" readonly="readonly" value="<?php echo esc_attr( $meta['submitted_by'] ); ?>"/> 409 </p> 410 </div> 411 412 <div class="row"> 413 <p class="label">Email:</p> 414 <p class="data"> 415 <a href="mailto:<?php echo esc_attr( $meta['submitted_email'] ); ?>?Subject=Your%20WordPress.tv%20submission"><?php echo esc_html( $meta['submitted_email'] ); ?></a> 416 </p> 417 </div> 418 419 <div class="row"> 420 <p class="label">IP Address:</p> 421 <p class="data"> 422 <a href="<?php echo esc_url( add_query_arg( array( 'query' => $meta['ip'] ), 'http://en.utrace.de' ) ); ?>" target="_blank"><?php echo esc_html( $meta['ip'] ); ?></a> (opens in new tab, shows location of the IP) 423 </p> 424 </div> 425 426 <div class="row"> 427 <p class="label">Title:</p> 428 <p class="data"> 429 <input type="text" value="<?php echo esc_attr( $meta['title'] ); ?>"/> 430 <a class="button-secondary anon-approve" href="#title">Approve</a> 431 </p> 432 </div> 433 434 <div class="row"> 435 <p class="label">Language:</p> 436 <p class="data"> 437 <input type="text" value="<?php echo esc_attr( $meta['language'] ); ?>"/> 438 <a class="button-secondary anon-approve" href="#new-tag-language">Approve</a> 439 </p> 440 </div> 441 442 <div class="row"> 443 <p class="label">Categories:</p> 444 <p class="data" id="anon-approve-cats"> 445 <?php 446 $cats = preg_replace( '/[^0-9,]+/', '', trim( $meta['categories'], ' ,' ) ); 447 $cats = explode( ',', $cats ); 448 foreach ( $cats as $cat ) { 449 if ( intval( $cat ) ) { 450 echo '<a href="#in-category-' . $cat . '" class="anon-cat-link" title="Click to approve">Unknown?</a>, '; 451 } 452 } 453 ?> 454 </p> 455 </div> 456 457 <div class="row"> 458 <p class="label">Event:</p> 459 <p class="data"> 460 <input type="text" value="<?php echo esc_attr( $meta['event'] ); ?>"/> 461 <a class="button-secondary anon-approve" href="#new-tag-event">Approve</a> 462 </p> 463 </div> 464 465 <div class="row"> 466 <p class="label">Producer:</p> 467 <p class="data"> 468 <input type="text" value="<?php echo esc_attr( $meta['producer'] ); ?>"/> 469 <a class="button-secondary anon-approve" href="#new-tag-producer">Approve</a> 470 </p> 471 </div> 472 473 <div class="row"> 474 <p class="label">Speakers:</p> 475 <p class="data"> 476 <input type="text" value="<?php echo esc_attr( $meta['speakers'] ); ?>"/> 477 <a class="button-secondary anon-approve" href="#new-tag-speakers">Approve</a> 478 </p> 479 </div> 480 481 <div class="row txtarea"> 482 <p class="label">Description:</p> 483 <p class="data"> 484 <textarea rows="10"><?php echo esc_html( $meta['description'] ); ?></textarea> 485 <a class="button-secondary anon-approve" href="#excerpt">Approve</a> 486 </p> 487 </div> 488 489 <div class="row"> 490 <p class="label">Edit attachment:</p> 491 <p class="data"> 492 <a href="<?php echo esc_url( get_edit_post_link( $meta['attachment_id'] ) ); ?>" target="_blank"><?php echo esc_html( $attachment_post->post_title ); ?></a> 493 </p> 494 </div> 495 </div> 496 </div> 497 </div> 498 <script type="text/javascript"> 499 (function ($) { 500 $('#post-body-content').prepend($('#review-video')); 501 502 $(document).ready(function ($) { 503 var default_cat = true; 504 505 $('#review-video h3.hndle').bind('click.fold-anon-video', function (e) { 506 $('#anon-data-wrap').slideToggle(); 507 }); 508 509 $('#anon-approve-cats a.anon-cat-link').each(function (i, el) { 510 var id = el.href.replace(/.*?#/, '#'); 511 if (id) 512 $(el).html($(id).parent().text()); 513 }); 514 515 $('div.anon-data a.anon-approve, #anon-approve-cats a.anon-cat-link').bind('click.anon-approve', function (e) { 516 var target = $(e.target), id = target.attr('href'), el = $(id); 517 518 if (target.hasClass('disabled')) 519 return; 520 521 target.addClass('disabled'); 522 523 if (id.indexOf('#new-tag-') != -1) { 524 el.val(target.siblings('input[type="text"]').val()); 525 el.siblings('.tagadd').click(); 526 } else if (id == '#title') { 527 el.val(target.siblings('input[type="text"]').val()); 528 } else if (id == '#excerpt') { 529 el.val(target.siblings('textarea').val()); 530 } else if (target.is('a.anon-cat-link')) { 531 if (default_cat) { 532 // remove the default category only once 533 $('#in-category-12784353').prop('checked', false); 534 default_cat = false; 535 } 536 537 el.prop('checked', true); 538 } 539 540 e.preventDefault(); 541 }); 542 }); 543 })(jQuery); 544 </script> 545 <?php 546 } 547 } 548 549 $_wptv_anon = new WPTV_Anon_Upload; -
new file plugins/wordpresstv-oembed/wordpresstv-oembed.php
diff --git a/plugins/wordpresstv-oembed/wordpresstv-oembed.php b/plugins/wordpresstv-oembed/wordpresstv-oembed.php new file mode 100755 index 0000000..f51a909
- + 1 <?php /* 2 3 ************************************************************************** 4 5 Plugin Name: WordPress.tv oEmbed Provider 6 Plugin URI: http://wordpress.tv/oembed/ 7 Description: Creates an oEmbed provider for WordPress.tv. 8 Author: Viper007Bond 9 10 **************************************************************************/ 11 12 class WordCampTV_oEmbed { 13 14 /** 15 * Class construct, duh. 16 * 17 * @global WP $wp 18 */ 19 function __construct() { 20 global $wp; 21 22 add_action( 'template_redirect', array( $this, 'oembed_provider' ), 2 ); 23 add_action( 'wp_head', array( $this, 'maybe_add_discovery_tags' ) ); 24 25 // Set up WordPress to accept /oembed/ 26 add_rewrite_rule( 'oembed/?(.*)', 'index.php?$matches[1]&oembed=1', 'top' ); 27 // @see rewrite.php in plugins to flush rules 28 29 // Tell WordPress to not ignore the "oembed" query variable 30 $wp->add_query_var( 'oembed' ); 31 } 32 33 34 // Invalid (404) 35 function fourohfour() { 36 status_header( 404 ); 37 exit( 'Missing or invalid URL parameter.' ); 38 } 39 40 41 // oEmbed output 42 function oembed_provider() { 43 if ( ! get_query_var( 'oembed' ) ) { 44 return false; 45 } 46 47 if ( empty( $_GET['url'] ) ) { 48 $this->fourohfour(); 49 } 50 51 if ( is_ssl() ) { 52 $_lookup_url = str_replace( 'http:', 'https:', $_GET['url'] ); 53 } else { 54 $_lookup_url = str_replace( 'https:', 'http:', $_GET['url'] ); 55 } 56 57 // Do a quick check to see if the URL starts with the blog's URL 58 if ( get_bloginfo( 'url' ) != substr( $_lookup_url, 0, strlen( get_bloginfo( 'url' ) ) ) ) { 59 $this->fourohfour(); 60 } 61 62 // Attempt to turn the URL into a post object 63 $post_ID = url_to_postid( $_lookup_url ); 64 $post = get_post( $post_ID ); 65 if ( empty( $post_ID ) || ! $post ) { 66 $this->fourohfour(); 67 } 68 69 $defaults = array( 70 'maxwidth' => '400', 71 'maxheight' => '300', 72 ); 73 74 if ( ! empty( $_GET['maxwidth'] ) ) { 75 $maxwidth = (int) $_GET['maxwidth']; 76 } 77 if ( empty( $maxwidth ) ) { 78 $maxwidth = $defaults['maxwidth']; 79 } 80 81 if ( ! empty( $_GET['maxheight'] ) ) { 82 $maxheight = (int) $_GET['maxheight']; 83 } 84 if ( empty( $maxheight ) ) { 85 $maxheight = $defaults['maxheight']; 86 } 87 88 $data = array( 89 'type' => 'video', 90 'version' => '1.0', 91 ); 92 93 // Alright, let's see what kind of video is used 94 // VideoPress 95 if ( false !== stristr( $post->post_content, '[wpvideo' ) ) { 96 preg_match( '#\[wpvideo ([a-zA-Z0-9]+)#i', $post->post_content, $guid ); 97 $guid = $guid[1]; 98 $info = function_exists( 'video_get_info_by_guid' ) ? video_get_info_by_guid( $guid ) : new StdClass; 99 if ( empty( $guid ) || ! $info ) { 100 status_header( 500 ); 101 exit( 'An error has occurred on our end. Please contact WordPress.com support.' ); 102 } 103 104 list( $width, $height ) = wp_expand_dimensions( $info->width, $info->height, $maxwidth, $maxheight ); 105 106 $data['title'] = $info->title; 107 $data['width'] = $width; 108 $data['height'] = $height; 109 $data['html'] = '<embed src="//v.wordpress.com/' . $info->guid . '" type="application/x-shockwave-flash" width="' . $width . '" height="' . $height . '" allowscriptaccess="always" allowfullscreen="true" wmode="transparent"></embed>'; 110 } // Other video types aren't supported quite yet 111 else { 112 status_header( 501 ); 113 exit( 'Support has not been added for this non-VideoPress type video yet.' ); 114 } 115 116 // Figure out the format 117 $format = 'json'; 118 if ( ! empty( $_GET['format'] ) ) { 119 $format = $_GET['format']; 120 } 121 122 // Output the response 123 switch ( $format ) { 124 case 'json': 125 header( 'Content-Type: application/json' ); 126 echo json_encode( $data ); 127 exit(); 128 case 'xml': 129 header( 'Content-Type: text/xml' ); 130 echo '<' . '?xml version="1.0" encoding="utf-8" standalone="yes"?>' . "\n"; 131 echo "<oembed>\n"; 132 foreach ( $data as $tag => $value ) { 133 echo " <{$tag}>" . htmlspecialchars( $value ) . "</{$tag}>\n"; 134 } 135 echo '</oembed>'; 136 exit(); 137 default; 138 header( 'HTTP/1.0 501 Not Implemented' ); 139 exit(); 140 } 141 } 142 143 144 // If it's a single post that uses VideoPress, add discovery tags 145 function maybe_add_discovery_tags() { 146 if ( is_single() && stristr( get_post()->post_content, '[wpvideo' ) ) { 147 printf( '<link rel="alternate" type="application/json+oembed" href="%1$s" title="%2$s" />' . "\n", 148 esc_url( add_query_arg( array( 'url' => urlencode( get_permalink() ), 'format' => 'json' ), home_url( '/oembed/' ) ) ), 149 the_title_attribute( array( 'echo' => false ) ) 150 ); 151 printf( '<link rel="alternate" type="text/xml+oembed" href="%1$s" title="%2$s" />' . "\n", 152 esc_url( add_query_arg( array( 'url' => urlencode( get_permalink() ), 'format' => 'xml' ), home_url( '/oembed/' ) ) ), 153 the_title_attribute( array( 'echo' => false ) ) 154 ); 155 } 156 } 157 } 158 159 add_action( 'init', 'WordCampTV_oEmbed', 5 ); 160 function WordCampTV_oEmbed() { 161 global $WordCampTV_oEmbed; 162 $WordCampTV_oEmbed = new WordCampTV_oEmbed(); 163 } -
new file plugins/wordpresstv-rest/wordpresstv-rest.php
diff --git a/plugins/wordpresstv-rest/wordpresstv-rest.php b/plugins/wordpresstv-rest/wordpresstv-rest.php new file mode 100755 index 0000000..fc37846
- + 1 <?php 2 3 /** 4 * WordPress.tv REST APi 5 * 6 */ 7 class WordPressTV_REST_API { 8 9 /** 10 * Constructor fired during init. 11 * 12 * @global WP $wp 13 */ 14 function __construct() { 15 global $wp; 16 17 add_action( 'template_redirect', array( $this, 'template_redirect' ), 2 ); 18 add_rewrite_rule( 'api/(.*)', 'index.php?wptvapi=$matches[1]', 'top' ); 19 // @see rewrite.php in plugins to flush rules 20 21 // ?unisubs and ?guid query variables. 22 $wp->add_query_var( 'wptvapi' ); 23 } 24 25 /** 26 * Returns a 404 status header and exits. 27 */ 28 function fourohfour() { 29 status_header( 404 ); 30 exit( 'Invalid request.' ); 31 } 32 33 function template_redirect() { 34 global $wp_query, $post, $wptv; 35 36 if ( ! get_query_var( 'wptvapi' ) ) { 37 return; 38 } 39 40 $matches = array(); 41 if ( ! preg_match( '/^(.+)\.(json|array)$/i', get_query_var( 'wptvapi' ), $matches ) ) { 42 $this->error( 'Invalid request.' ); 43 } 44 45 $method = $matches[1]; 46 $format = $matches[2]; 47 $response = array(); 48 49 switch ( $method ) { 50 case 'videos': 51 if ( isset( $_REQUEST['posts_per_page'] ) ) { 52 query_posts( array_merge( $wp_query->query, array( 'posts_per_page' => intval( $_REQUEST['posts_per_page'] ) ) ) ); 53 } 54 55 $response['videos'] = array(); 56 while ( have_posts() ) { 57 the_post(); 58 59 // Super lame hack to get a thumbnail from VideoPress :) 60 ob_start(); 61 $wptv->the_video_image( 50, null, false, false ); 62 $thumbnail = esc_url_raw( trim( ob_get_contents() ) ); 63 ob_end_clean(); 64 65 $response['videos'][] = array( 66 'title' => $post->post_title, 67 'permalink' => get_permalink( get_the_ID() ), 68 'thumbnail' => $thumbnail, 69 ); 70 } 71 72 break; 73 default: 74 $this->error( 'Unknown method.' ); 75 break; 76 } 77 78 if ( ! empty( $response ) ) { 79 switch ( $format ) { 80 case 'json': 81 echo json_encode( $response ); 82 break; 83 case 'array': 84 if ( defined( 'WPCOM_SANDBOXED' ) && WPCOM_SANDBOXED ) { 85 print_r( $response ); 86 } 87 break; 88 } 89 die(); 90 } 91 92 $this->error( 'Empty response.' ); 93 die(); 94 } 95 96 function error( $message, $http_code = 404 ) { 97 status_header( $http_code ); 98 exit( $message ); 99 } 100 } 101 102 // Initialize the object. 103 add_action( 'init', 'wptv_rest_api_init', 5 ); 104 function wptv_rest_api_init() { 105 $wptv_rest_api = new WordPressTV_REST_API(); 106 } -
new file plugins/wordpresstv-unisubs/wordpresstv-unisubs.php
diff --git a/plugins/wordpresstv-unisubs/wordpresstv-unisubs.php b/plugins/wordpresstv-unisubs/wordpresstv-unisubs.php new file mode 100755 index 0000000..b3b5d7f
- + 1 <?php 2 3 /** 4 * Universal Subtitles for WordPress.tv 5 * 6 * This class is included from the WordPress.tv VIP theme's function.php file. 7 * Provides a /unisubs/ end-point for Universal Subtitles to access stuff via HTTP. 8 * 9 * @global WP $wp 10 */ 11 class WordCampTV_Unisubs { 12 13 /** 14 * Constructor fired during init. 15 */ 16 function __construct() { 17 global $wp; 18 19 add_action( 'template_redirect', array( &$this, 'template_redirect' ), 2 ); 20 add_rewrite_rule( 'unisubs/?(.*)', 'index.php?$matches[1]&unisubs=1', 'top' ); 21 // @see rewrite.php in plugins to flush rules 22 23 // ?unisubs and ?guid query variables. 24 $wp->add_query_var( 'unisubs' ); 25 $wp->add_query_var( 'guid' ); 26 27 // Let's change the videopress.js file. @todo: Uncomment this before going live with Unisubs. OR dequeue it. 28 // add_filter( 'script_loader_src', array( &$this, 'script_loader_src' ), 10, 2 ); 29 } 30 31 /** 32 * Returns a 404 status header and exits. 33 */ 34 function fourohfour() { 35 status_header( 404 ); 36 exit( 'Invalid request.' ); 37 } 38 39 /** 40 * Returns a $post object by searching for the wpvideo guid or false. 41 * 42 * @param int $guid ID. 43 * 44 * @return bool 45 */ 46 function get_post_by_guid( $guid ) { 47 $posts = get_posts( array( 's' => "[wpvideo $guid]", 'post_status' => 'publish' ) ); 48 if ( $posts ) { 49 return $posts[0]; 50 } 51 52 return false; 53 } 54 55 /** 56 * Unisubs API output and ?guid= redirect hook, fired during 57 * template_redirect, output in ?format=(json|xml) 58 */ 59 function template_redirect() { 60 61 // If a ?guid has been specified, but not a /unisubs/ endpoint, redirect 62 // to the post permalink. Allows requests like http://wordpress.tv/?guid=nWoZmCPz 63 if ( get_query_var( 'guid' ) && ! get_query_var( 'unisubs' ) ) { 64 $post = $this->get_post_by_guid( get_query_var( 'guid' ) ); 65 if ( $post ) { 66 wp_redirect( get_permalink( $post ) ); 67 exit(); 68 } 69 } 70 71 // Is this a /unisubs/ endpoint? 72 if ( ! get_query_var( 'unisubs' ) ) { 73 return false; 74 } 75 76 // Either ?guid or ?url must be present for /unisubs/ 77 if ( ! isset( $_GET['guid'] ) && ! isset( $_GET['url'] ) ) { 78 $this->fourohfour(); 79 } 80 81 $post = false; 82 $post_id = 0; 83 84 if ( isset( $_GET['guid'] ) ) { 85 $post = $this->get_post_by_guid( $_GET['guid'] ); 86 if ( ! $post ) { 87 $this->fourohfour(); 88 } 89 } 90 91 if ( isset( $_GET['url'] ) ) { 92 // Do a quick check to see if the URL starts with the blog's URL 93 if ( home_url() != substr( $_GET['url'], 0, strlen( home_url() ) ) ) { 94 $this->fourohfour(); 95 } 96 97 $post_id = url_to_postid( $_GET['url'] ); 98 if ( empty( $post_id ) || ! $post = get_post( $post_id ) ) { 99 $this->fourohfour(); 100 } 101 } 102 103 // Works with VideoPress videos only. 104 if ( false == stristr( $post->post_content, '[wpvideo' ) ) { 105 status_header( 501 ); 106 exit( 'Support has not been added for this non-VideoPress type video yet.' ); 107 } 108 109 $data = array( 110 'type' => 'video', 111 'version' => '1.0', 112 'permalink' => esc_url_raw( get_permalink( $post_id ) ), 113 ); 114 115 // Search for VideoPress. 116 preg_match( '#\[wpvideo ([a-zA-Z0-9]+)#i', $post->post_content, $guid ); 117 $guid = $guid[1]; 118 $info = function_exists( 'video_get_info_by_guid' ) ? video_get_info_by_guid( $guid ) : new StdClass; 119 if ( empty( $guid ) || ! $info ) { 120 status_header( 500 ); 121 exit( 'An error has occurred on our end. Please contact WordPress.com support.' ); 122 } 123 124 list( $width, $height ) = array( $info->width, $info->height ); 125 126 // Let's try and get the best thumbnail available. 127 $thumb = false; 128 foreach ( array( 'hd_files', 'dvd_files', 'std_files' ) as $key ) { 129 if ( isset( $info->{$key} ) && ! $thumb ) { 130 $files = maybe_unserialize( $info->{$key} ); 131 $thumb = isset( $files['original_img'] ) ? $files['original_img'] : false; 132 } 133 } 134 135 $data['guid'] = $info->guid; 136 $data['post_id'] = $post->ID; 137 $data['title'] = ! empty( $post->post_title ) ? $post->post_title : 'Untitled'; 138 $data['description'] = ! empty( $info->description ) ? $info->description : 'No description given.'; 139 $data['thumbnail'] = esc_url_raw( sprintf( 'http://videos.videopress.com/%s/%s', $info->guid, $thumb ) ); 140 141 $data['width'] = absint( $width ); 142 $data['height'] = absint( $height ); 143 $data['duration'] = absint( $info->duration ); 144 $data['swf'] = esc_url_raw( sprintf( 'http://v.wordpress.com/wp-content/plugins/video/assets/player.wptv.swf?guid=%s', $info->guid ) ); 145 146 // Redirect to the SWF file if we need to. 147 if ( isset( $_GET['redirect_to_swf'] ) ) { 148 wp_redirect( $data['swf'] ); 149 exit(); 150 } 151 152 $format = 'json'; 153 if ( ! empty( $_GET['format'] ) ) { 154 $format = strtolower( $_GET['format'] ); 155 } 156 157 // Output the response based on $format. 158 switch ( $format ) { 159 case 'json': 160 header( 'Content-Type: application/json' ); 161 echo json_encode( $data ); 162 exit(); 163 case 'xml': 164 header( 'Content-Type: text/xml' ); 165 echo '<' . '?xml version="1.0" encoding="utf-8" standalone="yes"?>' . "\n"; 166 echo "<item>\n"; 167 foreach ( $data as $tag => $value ) { 168 echo " <{$tag}>" . htmlspecialchars( $value ) . "</{$tag}>\n"; 169 } 170 echo '</item>'; 171 exit(); 172 case 'array': // useful for debugging 173 if ( defined( 'WPCOM_SANDBOXED' ) && WPCOM_SANDBOXED ) { 174 print_r( $data ); 175 exit(); 176 } 177 break; 178 default: 179 header( 'HTTP/1.0 501 Not Implemented' ); 180 exit(); 181 } 182 } 183 184 /** 185 * Replaces the src= for VideoPress into a special videopress.wptv.js, 186 * filters script_loader_src. Note: not used yet. 187 * 188 * @param string $src 189 * @param string $handle 190 * 191 * @return string 192 */ 193 function script_loader_src( $src, $handle ) { 194 if ( $handle == 'videopress' ) { 195 $src = plugins_url( '/video/assets/js/videopress.wptv.js' ); 196 } 197 198 return $src; 199 } 200 } 201 202 // Initialize the object. 203 add_action( 'init', 'wptv_unisubs_init', 5 ); 204 function wptv_unisubs_init() { 205 global $wptv_unisubs; 206 $wptv_unisubs = new WordCampTV_Unisubs(); 207 } -
new file plugins/wordpresstv-upload-subtitles/wordpresstv-upload-subtitles.php
diff --git a/plugins/wordpresstv-upload-subtitles/wordpresstv-upload-subtitles.php b/plugins/wordpresstv-upload-subtitles/wordpresstv-upload-subtitles.php new file mode 100755 index 0000000..f1b11e7
- + 1 <?php 2 3 /** 4 * Subtitles Upload Handling 5 * 6 * Works with the form in the upload-subtitles-template.php page template. 7 * Based on (copy pasted from) the anonymous video upload form by Androw Ozz. 8 */ 9 class WordPressTV_Subtitles_Upload { 10 // hardcoded user_id for the fake contributor that owns the drafts (username: anonvideoupload) 11 private $drafts_author = 34340661; 12 13 private $video_id; 14 15 function __construct() { 16 add_action( 'admin_post_wptv_video_upload_subtitles', array( $this, 'post' ) ); 17 add_action( 'admin_post_nopriv_wptv_video_upload_subtitles', array( $this, 'post' ) ); 18 add_action( 'edit_form_after_title', array( $this, 'in_post_edit_form' ) ); 19 add_action( 'all_admin_notices', array( $this, 'pending_notice' ) ); 20 21 add_filter( 'attachment_fields_to_save', array( $this, 'moderate' ) ); 22 add_filter( 'views_upload', array( $this, 'views_links' ) ); 23 add_filter( 'post_mime_types', array( $this, 'post_mime_types' ) ); 24 } 25 26 /** 27 * Creates the attachment if it's a valid file 28 * 29 * @uses wp_handle_upload 30 */ 31 function handle_upload() { 32 // allow only video mimes 33 $overrides = array( 34 'test_form' => false, 35 'mimes' => array( 36 'ttml' => 'application/ttml+xml', 37 'dfxp' => 'application/ttml+xml', // .dfxp is changed to .ttml in $this->generate_filename() 38 ), 39 ); 40 41 unset( $_FILES['async-upload'] ); 42 43 if ( empty( $_FILES['wptv_subtitles_file']['name'] ) ) { 44 return new WP_Error( 'upload_error', 'Invalid file name.' ); 45 } 46 47 $name = $_FILES['wptv_subtitles_file']['name']; 48 add_filter( 'wp_handle_upload_prefilter', array( $this, 'generate_filename' ), 5 ); 49 50 $file = wp_handle_upload( $_FILES['wptv_subtitles_file'], $overrides ); 51 52 if ( isset( $file['error'] ) ) { 53 return new WP_Error( 'upload_error', $file['error'] ); 54 } 55 56 $filepath = $file['file']; 57 58 $attachment = array(); 59 $attachment['post_title'] = $this->sanitize_text( $name ); 60 $attachment['guid'] = $file['url']; 61 $attachment['post_mime_type'] = $file['type']; 62 $attachment['post_content'] = ''; 63 $attachment['post_author'] = $this->drafts_author; 64 65 // expects slashed 66 $attachment_id = wp_insert_attachment( add_magic_quotes( $attachment ), $filepath ); 67 68 if ( ! is_wp_error( $attachment_id ) ) { 69 wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $filepath ) ); 70 } 71 72 return $attachment_id; 73 } 74 75 /** 76 * Generate a non-guessable filename for uploaded files. 77 * 78 * @param string $file 79 * 80 * @return string 81 */ 82 function generate_filename( $file ) { 83 $name_parts = pathinfo( $file['name'] ); 84 85 // this should never happen 86 if ( empty( $name_parts['extension'] ) ) { 87 die; 88 } 89 90 // Change .dfxp to .ttml 91 if ( 'dfxp' == strtolower( $name_parts['extension'] ) ) { 92 $name_parts['extension'] = 'ttml'; 93 } 94 95 // random file name 96 $str = md5( time() . rand( 1, 1000000 ) ); 97 $file['name'] = 'subtitles-' . substr( $str, rand( 5, 20 ), 10 ) . '.' . $name_parts['extension']; 98 99 return $file; 100 } 101 102 /** 103 * When the POST request is fired with the subtitles form and action. 104 */ 105 function post() { 106 if ( empty( $_POST['wptv-upload-subtitles-nonce'] ) || ! wp_verify_nonce( $_POST['wptv-upload-subtitles-nonce'], 'wptv-upload-subtitles' ) ) { 107 wp_die( 'Invalid form data. Please go back and try again.' ); 108 } 109 110 if ( empty( $_POST['wptv_video_id'] ) ) { 111 wp_die( 'Requires a video context.' ); 112 } 113 114 $video_id = absint( $_POST['wptv_video_id'] ); 115 $this->video_id = $video_id; 116 117 if ( function_exists( 'wp_attachment_is_video' ) && ! wp_attachment_is_video( $video_id ) ) { 118 wp_die( 'You can only subtitle videos.' ); 119 } 120 121 if ( empty( $_POST['wptv_wporg_username'] ) || empty( $_POST['wptv_author_email'] ) || ! is_email( $_POST['wptv_author_email'] ) ) { 122 $this->error( 4 ); 123 } 124 125 $wporg_username = $this->sanitize_text( $_POST['wptv_wporg_username'] ); 126 $author_email = $this->sanitize_text( $_POST['wptv_author_email'] ); 127 128 if ( empty( $_POST['wptv_language'] ) ) { 129 $this->error( 8 ); 130 } 131 132 $language = $_POST['wptv_language']; 133 $available_languages = class_exists( 'VideoPress_Subtitles' ) ? VideoPress_Subtitles::get_languages() : array(); 134 135 if ( ! array_key_exists( $language, $available_languages ) ) { 136 $this->error( 7 ); 137 } 138 139 $language = $available_languages[ $language ]; 140 141 $video_data = function_exists( 'video_get_info_by_blogpostid' ) ? video_get_info_by_blogpostid( get_current_blog_id(), $video_id ) : new StdClass; 142 $video_attachment = get_post( $video_id ); 143 if ( empty( $video_data ) || empty( $video_attachment ) ) { 144 wp_die( 'Invalid form data.' ); 145 } 146 147 $parent = get_post( $video_attachment->post_parent ); 148 149 if ( ! $parent || 'publish' != $parent->post_status ) { 150 wp_die( 'You can not subtitle this video.' ); 151 } 152 153 $tracks = class_exists( 'VideoPress_Subtitles' ) ? VideoPress_Subtitles::get_tracks( $video_data->guid ) : array(); 154 if ( ! empty( $tracks[ $language['key'] ] ) ) { 155 $this->error( 8 ); 156 } 157 158 if ( empty( $_FILES['wptv_subtitles_file']['name'] ) ) { 159 $this->error( 1 ); 160 } 161 162 // quick file extension check 163 $name_parts = pathinfo( $_FILES['wptv_subtitles_file']['name'] ); 164 165 if ( ! empty( $name_parts['extension'] ) ) { 166 if ( ! in_array( strtolower( $name_parts['extension'] ), array( 'ttml', 'dfxp' ), true ) ) { 167 $this->error( 2 ); 168 } 169 } else { 170 $this->error( 3 ); 171 } 172 173 // empty the globals just in case 174 $_POST = $_REQUEST = $_GET = array(); 175 176 $subs_attachment_id = $this->handle_upload(); 177 178 if ( is_wp_error( $subs_attachment_id ) ) { 179 $this->error( 5 ); 180 } 181 182 // TODO: needed?? Better to test in $this->handle_upload() and return WP_Error 183 // Link the uploaded attachment 184 /* if ( get_post_mime_type( $subs_attachment_id ) != 'application/ttml+xml' ) { 185 wp_delete_attachment( $subs_attachment_id ); 186 $this->error( 2 ); 187 } 188 */ 189 // TODO: needed?? 190 // Not visible on wordpress.tv but is in the HTML source. However 'post_content' is public data. 191 // Used for <meta name="description" and "og:description". 192 $post_content = sprintf( "Uploaded by: %s\nLanguage: %s", 193 $wporg_username, 194 $language['label'] 195 ); 196 197 wp_update_post( array( 198 'ID' => $subs_attachment_id, 199 'post_content' => $post_content, 200 'post_title' => sprintf( 'Subtitles: %s (%s)', $parent->post_title, $language['label'] ), 201 // 'post_parent' => $parent->ID, // easier to look for unapproved subtitles attachment if they are "unattached"? 202 ) ); 203 204 $subs_attachment_meta = array( 205 'video_attachment_id' => $video_attachment->ID, 206 'video_post_id' => $parent->ID, 207 'video_guid' => $video_data->guid, 208 'submitted_by' => $wporg_username, 209 'submitted_email' => $author_email, 210 'language_key' => $language['key'], 211 // 'ip' => $_SERVER['REMOTE_ADDR'], // keep this for ref? 212 ); 213 214 update_post_meta( $subs_attachment_id, '_wptv_submitted_subtitles', $subs_attachment_meta ); 215 216 /* // TODO: can add this on upload to indicate that there is a file being moderated. 217 // This will block uploads of other files for the same language, 218 // but needs change in VideoPress_Subtitles::get_tracks() in /videopress/subtitles.php 219 // to bypass the trac when 'subtitles_post_id' == 0. 220 // Alternatively can add some meta on the video attachment post. 221 $subtitles = get_post_meta( $video_attachment->ID, '_videopress_subtitles', true ); 222 if ( empty( $subtitles ) ) 223 $subtitles = array(); 224 225 $subtitles[ $language['key'] ] = array( 226 'language' => $language['key'], 227 'subtitles_post_id' => 0, 228 'pending_subtitles_post_id' => $subs_attachment_id, 229 ); 230 231 if ( ! update_post_meta( $video_attachment->ID, '_videopress_subtitles', $subtitles ) ) { 232 wp_delete_attachment( $subs_attachment_id ); 233 $this->error( 5 ); 234 } 235 */ 236 // success() redirects to the 'subtitle' page with "Thank you for uploading" message and exits. 237 $this->success(); 238 } 239 240 // Runs on 'attachment_fields_to_save' (an attachment post is being saved) 241 function moderate( $post_data ) { 242 if ( empty( $post_data['wptv-subtitles'] ) ) { 243 return $post_data; 244 } 245 246 $approve = ! empty( $post_data['wptv-approve-subtitles'] ); 247 $attachment_id = $post_data['ID']; 248 249 $attachment_meta = get_post_meta( $attachment_id, '_wptv_submitted_subtitles', true ); 250 if ( empty( $attachment_meta ) ) { 251 wp_die( 'Missing attachment metadata.' ); // Cannot show errors other than die(...) 252 } 253 254 $parent_id = (int) $attachment_meta['video_post_id']; 255 $video_attachment_id = (int) $attachment_meta['video_attachment_id']; 256 $language_key = $attachment_meta['language_key']; 257 $subtitles = $_subtitles = get_post_meta( $video_attachment_id, '_videopress_subtitles', true ); 258 259 if ( empty( $subtitles ) ) { 260 $subtitles = array(); 261 } 262 263 if ( $approve ) { 264 $subtitles[ $language_key ] = array( 265 'language' => $language_key, 266 'subtitles_post_id' => $attachment_id, 267 ); 268 // Attach the attachment 269 $post_data['post_parent'] = $parent_id; 270 } else { 271 unset( $subtitles[ $language_key ] ); 272 /* 273 $subtitles[ $language_key ] = array( 274 'language' => $language_key, 275 'subtitles_post_id' => 0, 276 'pending_subtitles_post_id' => $attachment_id, 277 ); 278 */ 279 // Detach the attachment 280 $post_data['post_parent'] = 0; 281 } 282 283 if ( $subtitles != $_subtitles ) { 284 if ( empty( $subtitles ) ) { 285 delete_post_meta( $video_attachment_id, '_videopress_subtitles' ); 286 } else { 287 update_post_meta( $video_attachment_id, '_videopress_subtitles', $subtitles ); 288 } 289 } 290 291 return $post_data; 292 } 293 294 // Output the HTML for moderation 295 function in_post_edit_form( $attachment_post ) { 296 if ( $attachment_post->post_type != 'attachment' || $attachment_post->post_mime_type != 'application/ttml+xml' ) { 297 return; 298 } 299 300 // Added meta to these existing subtitles posts: 301 // done: 17732,21488,21578,21987,22063,22064,22065,22066,22144, 302 // remain: 17295,17297,22459 // all are tests 303 304 $file_content = file_get_contents( wp_get_attachment_url( $attachment_post->ID ) ); 305 if ( ! $file_content ) { 306 echo '<div class="error"><p>ERROR: the attached file doesn\'t exist or is empty.</p></div>'; 307 308 return; 309 } 310 311 $attachment_meta = get_post_meta( $attachment_post->ID, '_wptv_submitted_subtitles', true ); 312 if ( empty( $attachment_meta ) ) { 313 echo '<div class="error"><p>ERROR: the attachment post metadata is missing.</p></div>'; 314 315 return; 316 } 317 318 $is_approved = $another_approved = false; 319 $video_attachment_id = (int) $attachment_meta['video_attachment_id']; 320 $parent_id = (int) $attachment_meta['video_post_id']; 321 $language_key = $attachment_meta['language_key']; 322 $subtitles = get_post_meta( $video_attachment_id, '_videopress_subtitles', true ); 323 324 if ( is_array( $subtitles ) && ! empty( $subtitles[ $language_key ]['subtitles_post_id'] ) ) { 325 if ( $subtitles[ $language_key ]['subtitles_post_id'] == $attachment_post->ID ) { 326 $is_approved = true; 327 } else { 328 // Has another approved subtitles file 329 $another_approved = (int) $subtitles[ $language_key ]['subtitles_post_id']; 330 } 331 } 332 333 // Add some line breaks to make it easier to read 334 $file_content = str_replace( array( "\r", '>', '<' ), array( '', ">\n", "\n<" ), $file_content ); 335 $file_content = preg_replace( '/\n\n+/', "\n\n", trim( $file_content ) ); 336 337 // Replace any urlencoded bits with '?'. Maybe flag this too, there shouldn't be any? 338 $match = array(); 339 while ( preg_match( '/%[a-f0-9]{2}/i', $file_content, $match ) ) { 340 $file_content = str_replace( $match[0], '?', $file_content ); 341 } 342 343 // Replace any escaped <br/> inside the subtitles strings. Makes it easier to read. 344 $file_content = str_replace( array( '<br />', '<br/>' ), "<br />\n", $file_content ); 345 346 $file_content = htmlspecialchars( $file_content, ENT_QUOTES, 'UTF-8' ); 347 $file_content = str_replace( "\n", '<br>', $file_content ); 348 349 ?> 350 <div id="subs-wrapper"> 351 <style type="text/css" scoped=""> 352 #subs-wrapper { 353 margin: 20px 0; 354 } 355 356 #subs-content { 357 padding: 10px; 358 border: 1px solid #ccc; 359 margin-top: 0; 360 overflow: auto; 361 max-height: 400px; 362 background-color: #fff; 363 font-family: Consolas, Monaco, monospace; 364 } 365 366 #subs-wrapper .subs-approved { 367 background-color: #f9f9f9; 368 border: 1px solid #dfdfdf; 369 border-radius: 3px; 370 padding: 10px; 371 } 372 373 #subs-wrapper .subs-approved label { 374 font-size: 120%; 375 } 376 377 #subs-wrapper .subs-approved input[type="checkbox"] { 378 margin: 1px 5px; 379 } 380 381 #subs-wrapper .warning { 382 color: #dd0000; 383 } 384 </style> 385 <strong>Content of the subtitles file</strong><br> 386 387 <div id="subs-content"><?php echo $file_content; ?></div> 388 389 <div class="subs-info"> 390 <input type="hidden" name="wptv-subtitles" value="1"/> 391 392 <p><a href="<?php echo esc_url( get_permalink( $parent_id ) ); ?>" target="_blank">Preview</a> the video (opens in 393 new tab).</p> 394 395 <p>Submitted by: <a 396 href="http://profiles.wordpress.org/<?php echo esc_attr( $attachment_meta['submitted_by'] ); ?>/"><?php echo esc_html( $attachment_meta['submitted_by'] ); ?></a>, 397 email: <a 398 href="mailto:<?php echo esc_attr( $attachment_meta['submitted_email'] ); ?>"><?php echo esc_html( $attachment_meta['submitted_email'] ); ?></a> 399 </p> 400 401 <p><a href="<?php echo esc_url( get_edit_post_link( $video_attachment_id ) ); ?>">Edit</a> the video attachment 402 post.</p> 403 <?php 404 405 if ( $another_approved ) { 406 ?> 407 <p class="subs-approved"> 408 <span class="warning">WARNING:</span> There is <a href="<?php echo esc_url( get_edit_post_link( $another_approved ) ); ?>">another approved subtitles 409 file</a> 410 for this video and language. If you approve the current file, the other will be automatically 411 unapproved.</p> 412 <?php 413 } 414 415 ?> 416 <p class="subs-approved"><label><input type="checkbox" 417 name="wptv-approve-subtitles"<?php echo $is_approved ? ' checked="checked"' : ''; ?> /> 418 Approved</label></p> 419 </div> 420 </div> 421 <?php 422 } 423 424 /** 425 * Add "Subtitles (..)" link to the view links on the Media Library screen. 426 * 427 * If post_mime_types in wp_match_mime_types() and 428 * class-wp-media-list-table.php were working well, this would not 429 * be needed. 430 * 431 * @param array $links 432 * 433 * @return array 434 */ 435 function views_links( $links ) { 436 $mime_type = 'application/ttml+xml'; 437 438 $all_subs = wp_count_attachments( $mime_type ); 439 $class = ''; 440 441 if ( ! empty( $_GET['post_mime_type'] ) && $mime_type == $_GET['post_mime_type'] ) { 442 $class = ' class="current"'; 443 } 444 445 $links['wptv_subs'] = '<a href="upload.php?post_mime_type=' . urlencode( $mime_type ) . '"' . $class . '>Subtitles <span class="count">(' . $all_subs->$mime_type . ')</span></a>'; 446 447 return $links; 448 } 449 450 /** 451 * Output "Need moderation" message 452 */ 453 function pending_notice() { 454 global $wpdb, $pagenow; 455 456 $where_to_show = array( 'index.php', 'edit.php', 'upload.php' ); 457 458 if ( in_array( $pagenow, $where_to_show, true ) ) { 459 $pending_subs = $wpdb->get_var( "SELECT COUNT( 1 ) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' AND post_parent = 0 AND post_mime_type = 'application/ttml+xml'" ); 460 461 if ( $pending_subs ) { 462 echo '<div class="updated"><p><a href="upload.php?post_mime_type=' . urlencode( 'application/ttml+xml' ) . 463 '&detached=1">Subtitles awaiting moderation (' . $pending_subs . ')</a></p></div>'; 464 } 465 } 466 } 467 468 /** 469 * Add support fot the subtitles mime type. This should work better in core... 470 * 471 * @param $mime_types 472 * 473 * @return mixed 474 */ 475 function post_mime_types( $mime_types ) { 476 $mime_types['application/ttml+xml'] = array( 477 __( 'Subtitles' ), 478 __( 'Manage Subtitles' ), 479 _n_noop( 'Subtitles <span class="count">(%s)</span>', 'Subtitles <span class="count">(%s)</span>' ) 480 ); 481 482 return $mime_types; 483 } 484 485 /** 486 * Create an error and redirect. 487 * 488 * @param string $message 489 */ 490 function error( $message ) { 491 wp_safe_redirect( add_query_arg( array( 492 'video' => $this->video_id, 493 'error' => $message, 494 ), home_url( 'subtitle' ) ) ); 495 die(); 496 } 497 498 /** 499 * Redirect to a success page. 500 */ 501 function success() { 502 wp_safe_redirect( add_query_arg( array( 503 'video' => $this->video_id, 504 'success' => 1, 505 ), home_url( 'subtitle' ) ) ); 506 exit; 507 } 508 509 // expects slashed, returns unslashed 510 function sanitize_text( $str, $remove_line_breaks = true ) { 511 $str = str_replace( '\\', '', $str ); 512 513 if ( $remove_line_breaks ) { 514 $str = sanitize_text_field( $str ); 515 } else { 516 $str = wp_check_invalid_utf8( $str ); 517 $str = wp_strip_all_tags( $str ); 518 519 $match = array(); 520 while ( preg_match( '/%[a-f0-9]{2}/i', $str, $match ) ) { 521 $str = str_replace( $match[0], '', $str ); 522 } 523 } 524 525 return htmlspecialchars( $str, ENT_QUOTES, 'UTF-8' ); 526 } 527 } 528 529 new WordPressTV_Subtitles_Upload; -
new file search.php
diff --git a/search.php b/search.php new file mode 100755 index 0000000..8b8fce4
- + 1 <?php 2 global $wp_query; 3 4 // See improved improved (yes, improved twice) search. 5 /*if ( $wp_query->is_search() ) { 6 $query = wptv_search_taxonomies( $wp_query->query_vars['s'] ); 7 $wp_query->posts = array_merge( $wp_query->posts, $query->posts ); 8 $wp_query->post_count = count( $wp_query->posts ); 9 }*/ 10 11 get_template_part( 'archive' ); -
new file sidebar-event.php
diff --git a/sidebar-event.php b/sidebar-event.php new file mode 100755 index 0000000..d69808b
- + 1 <div class="secondary-content"> 2 <ul> 3 <?php dynamic_sidebar(); ?> 4 </ul> 5 </div> 6 No newline at end of file -
new file sidebar-single.php
diff --git a/sidebar-single.php b/sidebar-single.php new file mode 100755 index 0000000..27974a7
- + 1 <?php global $wptv, $originalcontent; ?> 2 3 <div class="secondary-content video-info"> 4 <h5>Published</h5> 5 <p class="video-date"><?php echo get_the_date(); ?></p> 6 7 <?php if ( $post->post_excerpt ) : ?> 8 <div class="video-description"><?php the_excerpt(); ?></div> 9 <?php 10 endif; 11 12 $wptv->the_terms( 'event', '<h5>Event</h5><p class="video-event">', '<br /> ', '</p>' ); 13 $wptv->the_terms( 'speakers', '<h5>Speakers</h5><p class="video-speakers">', '<br /> ', '</p>' ); 14 $wptv->the_terms( 'post_tag', '<h5>Tags</h5><p class="video-tags">', '<br /> ', '</p>' ); 15 $wptv->the_terms( 'language', '<h5>Language</h5><p class="video-lang">', '<br /> ', '</p>' ); 16 17 if ( function_exists( 'find_all_videopress_shortcodes' ) ) { 18 $videos = array_keys( find_all_videopress_shortcodes( $originalcontent ) ); 19 if ( ! empty( $videos ) ) { 20 $video = video_get_info_by_guid( $videos[0] ); 21 $formats = array( 'fmt_std' => 'Low', 'fmt_dvd' => 'Med', 'fmt_hd' => 'High', 'fmt1_ogg' => 'Low' ); 22 $mp4_links = array(); 23 $ogg_link = NULL; 24 foreach ( $formats as $format => $name ) { 25 if ( 'fmt1_ogg' == $format ) { 26 $link = video_highest_resolution_ogg( $video ); 27 } else { 28 $link = video_url_by_format( $video, $format ); 29 } 30 31 if ( empty( $link ) ) { 32 continue; 33 } 34 35 if ( 'fmt1_ogg' == $format ) { 36 $ogg_link = "<a href='$link'>$name</a>"; 37 } else { 38 $mp4_links[] = "<a href='$link'>$name</a>"; 39 } 40 } 41 42 if ( ! empty( $mp4_links ) || ! empty( $ogg_link ) ) { 43 ?> 44 <h5>Download</h5> 45 <div class="video-downloads"> 46 <?php 47 if ( ! empty( $mp4_links ) ) { 48 echo 'MP4: ' . join( ', ', $mp4_links ) . '<br/>'; 49 } 50 if ( ! empty( $ogg_link ) ) { 51 echo "OGG: $ogg_link"; 52 } 53 ?> 54 </div> 55 <?php 56 } 57 58 echo '<h5>Subtitles</h5>'; 59 $ttml_links = array(); 60 $languages = VideoPress_Subtitles::get_languages(); 61 $subtitles = (array) get_post_meta( $video->post_id, '_videopress_subtitles', true ); 62 63 foreach ( $subtitles as $track ) { 64 if ( empty( $track['subtitles_post_id'] ) ) { 65 continue; 66 } 67 68 $tracks[ $track['language'] ] = new VideoPress_Subtitles_Track( array( 69 'guid' => $video->guid, 70 'language' => $track['language'], 71 'subtitles_post_id' => $track['subtitles_post_id'], 72 ) ); 73 74 $ttml_links[] = '<a href="'. $tracks[ $track['language'] ]->url() .'">'. $languages[ $track['language'] ]['localized_label'] .'</a>'; 75 } 76 77 if ( ! empty( $ttml_links ) ) { 78 echo 'TTML: ' . join( ', ', $ttml_links ) . '<br />'; 79 } 80 81 printf( '<a href="%s">Subtitle this video →</a>', esc_url( add_query_arg( 'video', $video->post_id, home_url( 'subtitle/' ) ) ) ); 82 } 83 } 84 ?> 85 </div><!-- .secondary-content --> -
new file sidebar-wordcamptv.php
diff --git a/sidebar-wordcamptv.php b/sidebar-wordcamptv.php new file mode 100755 index 0000000..08d9d59
- + 1 <div class="secondary-content"> 2 <ul> 3 <?php dynamic_sidebar( 'WordCampTV Sidebar' ); ?> 4 </ul> 5 </div> 6 No newline at end of file -
new file sidebar.php
diff --git a/sidebar.php b/sidebar.php new file mode 100755 index 0000000..2b81bb6
- + 1 <div class="secondary-content"> 2 <ul> 3 <li> 4 <h3><a href="http://blog.wordpress.tv"><?php esc_html_e( 'From the Blog', 'wptv' ); ?></a></h3> 5 <ul> 6 <?php 7 // Make it easier to contribute to this theme by not assuming multisite context. 8 if ( function_exists( 'switch_to_blog' ) ) { 9 switch_to_blog( 5310177 ); // blog.wordpress.tv 10 } 11 12 query_posts( 'posts_per_page=5' ); 13 14 while ( have_posts() ) : 15 the_post(); 16 ?> 17 <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li> 18 <?php 19 endwhile; 20 21 if ( function_exists( 'restore_current_blog' ) ) { 22 restore_current_blog(); 23 } 24 ?> 25 </ul> 26 </li> 27 <li> 28 <h3><?php esc_html_e( 'Resources', 'wptv' ); ?></h3> 29 30 <ul> 31 <?php wp_list_bookmarks( 'title_li=&categorize=0' ); ?> 32 </ul> 33 </li> 34 <ul/> 35 </div><!-- .secondary_content --> 36 No newline at end of file -
new file single.php
diff --git a/single.php b/single.php new file mode 100755 index 0000000..021416d
- + 1 <?php 2 /** 3 * Single Video Template 4 */ 5 global $wptv, $originalcontent; 6 get_header(); the_post(); 7 ?> 8 <div class="wptv-hero group"> 9 <div class="container"> 10 11 <?php get_template_part( 'breadcrumbs' ); ?> 12 <h2 class="video-title"><?php the_title(); ?></h2> 13 14 <div class="the-video"> 15 <?php $wptv->the_video(); ?> 16 </div> 17 18 </div><!-- .container --> 19 </div><!-- .wptv-hero --> 20 21 <div class="container"> 22 <div class="primary-content"> 23 <div id="content"> 24 <div id="comments"> 25 <?php comments_template(); ?> 26 </div> 27 </div><!-- #content --> 28 </div><!-- .primary-content --> 29 <?php get_sidebar( 'single' ); ?> 30 </div><!-- .container --> 31 32 <?php get_footer(); ?> -
new file style.css
diff --git a/style.css b/style.css new file mode 100755 index 0000000..7865023
- + 1 /* 2 Theme Name: WordPress.tv v2 3 Theme URI: http://wordpress.tv 4 Description: WordPress.tv v2 Theme 5 Version: 2.0 6 Author: Automattic 7 Author URI: http://automattic.com/ 8 */ 9 10 /* meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/ */ 11 html, body, div, span, applet, object, iframe, 12 h1, h2, h3, h4, h5, h6, p, blockquote, pre, 13 a, abbr, acronym, address, big, cite, code, 14 del, dfn, em, font, img, ins, kbd, q, s, samp, 15 small, strike, strong, sub, sup, tt, var, 16 dl, dt, dd, ol, ul, li, 17 fieldset, form, label, legend, 18 table, caption, tbody, tfoot, thead, tr, th, td { 19 margin: 0; 20 padding: 0; 21 border: 0; 22 outline: 0; 23 font-weight: inherit; 24 font-style: inherit; 25 font-size: 100%; 26 font-family: inherit; 27 vertical-align: baseline; 28 } 29 30 /* remember to define focus styles! */ 31 :focus { 32 outline: 0; 33 } 34 35 body { 36 line-height: 1; 37 color: black; 38 background: white; 39 } 40 41 ol, ul { 42 list-style: none; 43 } 44 45 /* tables still need 'cellspacing="0"' in the markup */ 46 table { 47 border-collapse: separate; 48 border-spacing: 0; 49 } 50 51 caption, th, td { 52 text-align: left; 53 font-weight: normal; 54 } 55 56 blockquote:before, blockquote:after, 57 q:before, q:after { 58 content: ""; 59 } 60 61 blockquote, q { 62 quotes: "" ""; 63 } 64 65 /* Tables still need 'cellspacing="0"' in the markup. */ 66 table { 67 border-collapse: separate; 68 border-spacing: 0; 69 } 70 71 caption, th, td { 72 text-align: left; 73 font-weight: 400; 74 } 75 76 /* Remove possible quote marks (") from <q>,<blockquote>. */ 77 blockquote:before, blockquote:after, q:before, q:after { 78 content: ""; 79 } 80 81 blockquote, q { 82 quotes: "" ""; 83 } 84 85 a img { 86 border: none; 87 } 88 89 /* Contain floats */ 90 .group:before, .group:after { 91 content: ""; 92 display: table; 93 } 94 95 .group:after { 96 clear: both; 97 } 98 99 .group { 100 *zoom: 1; 101 } 102 103 /*************************************/ 104 105 /* Defaults */ 106 body { 107 font-size: 75%; /* 16px * 0.75 = 12px */ 108 line-height: 1.5em; /* 12x1.5 = 16 */ 109 font-family: "Lucida Grande", "Lucida Sans Unicode", sans-serif; 110 background: #fff; 111 color: #444; 112 } 113 114 .group:after { 115 content: "."; 116 display: block; 117 height: 0; 118 clear: both; 119 visibility: hidden; 120 } 121 122 .clear { 123 clear: both; 124 } 125 126 a, a:link, a:visited { 127 color: #21759b; 128 text-decoration: none; 129 } 130 131 a:hover, a:active { 132 color: #d54e21; 133 } 134 135 em, cite { 136 font-style: italic; 137 } 138 139 strong { 140 font-weight: bold; 141 } 142 143 h1, h2, h3, h4, h5, h6 { 144 font-weight: normal; 145 } 146 147 p, pre, dl, ul, ol { 148 } 149 150 table, td, th, tr, thead, tbody, tfoot { 151 } 152 153 dd, dt, li { 154 } 155 156 blockquote { 157 } 158 159 form, fieldset, address { 160 } 161 162 /* Utility */ 163 .highlite, blockquote em { 164 background-color: #FFFCCE; 165 } 166 167 .none { 168 text-indent: -1000em; 169 } 170 171 /* Alignment */ 172 .alignleft, .alignright, .align-left, .align-right { 173 } 174 175 .alignright, .align-right, .inset { 176 float: right; 177 } 178 179 .alignleft, .align-left, .alternate { 180 float: left; 181 } 182 183 .aligncenter, .align-center { 184 margin: 0 auto; 185 text-align: center; 186 } 187 188 .text-left { 189 text-align: left; 190 } 191 192 .text-right { 193 text-align: right; 194 } 195 196 /* Figures & images */ 197 .image { 198 } 199 200 .figure { 201 } 202 203 .figure .caption { 204 } 205 206 /* Structure */ 207 #page { 208 } 209 210 #header { 211 margin-top: 10px; 212 height: 57px; 213 } 214 215 #header h1 { 216 padding-top: 8px; 217 float: left; 218 } 219 220 #header .sleeve { 221 width: 942px; 222 margin: 0 auto; 223 } 224 225 #menu ul { 226 float: right; 227 height: 57px;; 228 } 229 230 #menu li { 231 float: left; 232 display: block; 233 margin-left: 10px; 234 line-height: 57px; 235 } 236 237 #menu li a, #menu li a:link, #menu li a:visited { 238 padding: 5px; 239 color: #555; 240 text-decoration: none; 241 border: 0; 242 } 243 244 #menu li a:hover, #menu li a:active { 245 color: #21759b !important; 246 } 247 248 #menu .current-menu-item > a, 249 #menu .current-menu-ancestor > a, 250 #menu .current_page_item > a, 251 #menu .current_page_ancestor > a { 252 font-weight: bold; 253 color: #000 !important; 254 } 255 256 #searchform { 257 float: right; 258 margin-left: 15px; 259 } 260 261 #searchform #searchbox, 262 #searchform input#s { 263 box-sizing: content-box; 264 color: #AAAAAA; 265 float: left; 266 margin-right: 6px; 267 background: white; 268 border: 1px solid #ccc; 269 padding: 5px 6px; 270 margin-right: 3px; 271 -webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.1); 272 -moz-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.1); 273 box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.1); 274 border-radius: 2px; 275 vertical-align: middle; 276 height: 15px; 277 line-height: 1; 278 width: 130px; 279 } 280 281 #searchform #searchbox { 282 margin-top: 15px; 283 } 284 285 input[type=submit], button, .button { 286 text-decoration: none; 287 -moz-border-radius: 5px; 288 -webkit-border-radius: 5px; 289 border-radius: 5px; 290 border: 1px solid #ccc; 291 border-bottom-color: #aaa; 292 border-right-color: #aaa; 293 background: #f5f5f5; 294 background: -webkit-gradient(linear, left top, left bottom, from(#f7f7f7), to(#e1e1e1)); 295 background: -moz-linear-gradient(top, #f7f7f7, #e1e1e1); 296 padding: 4px 8px; 297 font-size: 12px; 298 font-weight: 400; 299 color: #555 !important; 300 text-shadow: 0 1px 0 #fff; 301 -webkit-transition: all 0.25s ease-in-out; 302 -moz-transition: all 0.25s ease-in-out; 303 -o-transition: all 0.25s ease-in-out; 304 transition: all 0.25s ease-in-out; 305 -webkit-box-shadow: inset 1px 1px 1px rgba(255, 255, 255, 0.7), 1px 1px 1px rgba(0, 0, 0, 0.1); 306 -moz-box-shadow: inset 1px 1px 1px rgba(255, 255, 255, 0.7), 1px 1px 1px rgba(0, 0, 0, 0.1); 307 box-shadow: inset 1px 1px 1px rgba(255, 255, 255, 0.7), 1px 1px 1px rgba(0, 0, 0, 0.1); 308 } 309 310 input[type=submit]:hover, button:hover, .button:hover, input[type=submit]:focus, button:focus, .button:focus { 311 cursor: pointer; 312 color: #000 !important; 313 text-decoration: none; 314 border: 1px solid #bbb; 315 border-bottom-color: #888; 316 border-right-color: #888; 317 -webkit-box-shadow: inset 1px 1px 2px rgba(255, 255, 255, 1), 1px 1px 1px rgba(0, 0, 0, 0.2); 318 -moz-box-shadow: inset 1px 1px 2px rgba(255, 255, 255, 1), 1px 1px 1px rgba(0, 0, 0, 0.2); 319 box-shadow: inset 1px 1px 2px rgba(255, 255, 255, 1), 1px 1px 1px rgba(0, 0, 0, 0.2); 320 -webkit-transition: all 0.25s ease-in-out; 321 -moz-transition: all 0.25s ease-in-out; 322 -o-transition: all 0.25s ease-in-out; 323 transition: all 0.25s ease-in-out; 324 } 325 326 input[type=submit]:active, button:active, .button:active { 327 background: #ccc; 328 background: -webkit-gradient(linear, left top, left bottom, from(#bbb), to(#ddd)); 329 background: -moz-linear-gradient(top, #bbb, #ddd); 330 -webkit-box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.7), 0 0 0 rgba(0, 0, 0, 0); 331 -moz-box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.7), 0 0 0 rgba(0, 0, 0, 0); 332 box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.7), 0 0 0 rgba(0, 0, 0, 0); 333 } 334 335 .disabled:hover { 336 -moz-box-shadow: none; 337 -webkit-box-shadow: none; 338 box-shadow: none; 339 border-color: #ccc; 340 cursor: default; 341 } 342 343 .disabled:active { 344 background: #e3e3e3 url(/images/button-light.png) top left repeat-x; 345 background: -webkit-gradient( 346 linear, 347 left top, 348 left bottom, 349 color-stop(0.0, #fff), 350 color-stop(1, #eee) 351 ); 352 background: -moz-linear-gradient( 353 center top, 354 #fff 0%, 355 #eee 100% 356 ); 357 } 358 359 .intro { 360 font-size: 30px; 361 height: 64px; 362 line-height: 64px; 363 margin-bottom: 12px; 364 margin-left: 5px; 365 font-family: Georgia, "Times New Roman", Times, serif; 366 text-align: center; 367 color: #666; 368 text-shadow: #fff 0px 1px 0px; 369 } 370 371 .intro em { 372 font-style: italic; 373 font-variant: normal; 374 text-shadow: #eee 0px 0px 1px; 375 letter-spacing: normal; 376 } 377 378 /* News */ 379 380 .blog #content { 381 width: 704px; 382 float: left; 383 margin-bottom: 30px; 384 padding-top: 20px; 385 } 386 387 .blog .post h3 .post-author { 388 display: block; 389 390 font-size: 12px; 391 font-weight: normal; 392 393 color: #888; 394 margin: 5px 0; 395 } 396 397 .blog .post .entry { 398 float: left; 399 width: 558px; 400 padding-left: 0; 401 margin: 0 0 30px 0; 402 } 403 404 .entry p { 405 margin: 0 0 20px 0 406 } 407 408 .blog .post .excerpt { 409 width: 600px; 410 } 411 412 .blog .post .entry .sleeve { 413 padding-left: 10px; 414 border-left: 1px solid #ddd; 415 padding-right: 10px; 416 border-right: 1px solid #ddd; 417 } 418 419 .blog .post .wpcom-author { 420 float: left; 421 text-align: center; 422 width: 56px; 423 padding-right: 30px; 424 margin-right: -1px; 425 } 426 427 .blog .post #wpcom-author { 428 float: left; 429 text-align: center; 430 width: 136px; 431 } 432 433 .blog .post #wpcom-author, .blog .wpcom-author { 434 padding-right: 30px; 435 margin-right: -1px; 436 } 437 438 .single .postmetadata { 439 border-top: 1px solid #F1F1F1; 440 clear: both; 441 color: #999999; 442 font-size: 9px; 443 margin: 20px 0 0 0; 444 padding: 15px 0 5px 0; 445 text-align: left; 446 } 447 448 .blog .post #wpcom-author .postmetadata p { 449 text-align: left; 450 margin-bottom: 10px; 451 } 452 453 .blog .post #wpcom-author .avatar, .blog .post .wpcom-author .avatar { 454 float: none; 455 margin: 0 auto; 456 padding: 0; 457 } 458 459 .blog .post #wpcom-author .avatar img, .blog .post .wpcom-author .avatar img { 460 padding: 3px; 461 border: 1px solid #ddd; 462 } 463 464 .blog .primary-content { 465 margin: -20px 0 0 0; 466 } 467 468 .blog #sidebar { 469 width: 227px; 470 float: left; 471 margin-left: -1px; 472 } 473 474 #sidebar #search { 475 clear: both; 476 height: 30px; 477 } 478 479 #sidebar #s { 480 width: 130px; 481 margin-right: 5px; 482 float: left; 483 } 484 485 #sidebar #searchsubmit { 486 margin-top: 0; 487 } 488 489 #sidebar .sleeve { 490 padding-left: 10px; 491 border-left: 1px solid #ddd; 492 margin-top: 40px; 493 margin-bottom: 20px; 494 text-align: left; 495 } 496 497 .excerpt .sleeve { 498 padding-bottom: 20px; 499 } 500 501 .excerpt .postmetadata { 502 font-style: italic; 503 font-size: 9px; 504 margin-bottom: 10px; 505 } 506 507 .page p, .blog p { 508 margin-bottom: 1em; 509 line-height: 1.5em; 510 } 511 512 .blog #comments textarea { 513 width: 90%; 514 } 515 516 /* .blog h3 { 517 margin-right: 10px; 518 font-size: 18px !important; 519 font-family: Georgia,"Times New Roman",Times,serif !important; 520 margin-bottom: 10px !important; 521 padding-top: 18px !important; 522 padding-bottom: 3px !important; 523 border-bottom: 1px solid #ddd !important; 524 padding-left: 5px !important; 525 } 526 .blog h3 small { 527 font-size: 14px; 528 } 529 530 .blog p, .blog object { 531 margin-bottom: 18px; 532 } */ 533 534 /* Captions */ 535 .aligncenter, 536 div.aligncenter { 537 display: block; 538 margin-left: auto; 539 margin-right: auto; 540 } 541 542 .wp-caption { 543 border: 1px solid #ddd; 544 text-align: center; 545 background-color: #f3f3f3; 546 padding-top: 4px; 547 margin: 10px; 548 -moz-border-radius: 3px; 549 -khtml-border-radius: 3px; 550 -webkit-border-radius: 3px; 551 border-radius: 3px; 552 } 553 554 .wp-caption img { 555 margin: 0; 556 padding: 0; 557 border: 0 none; 558 } 559 560 .wp-caption p.wp-caption-text { 561 font-size: 11px; 562 line-height: 17px; 563 padding: 0 4px 5px; 564 margin: 0; 565 } 566 567 .tools h3 { 568 569 } 570 571 .tools p { 572 margin-bottom: 18px; 573 padding-left: 5px; 574 } 575 576 /* Title */ 577 578 .title h2 { 579 color: #000; 580 text-align: left; 581 margin-bottom: 10px; 582 font-size: 32px; 583 line-height: 1.1em; 584 font-family: Georgia, serif; 585 } 586 587 .title h2 a { 588 font-size: 18px; 589 line-height: 18px; 590 font-size: 16px; 591 font-family: "Lucida Grande", "Lucida Sans Unicode", sans-serif; 592 } 593 594 .title h2 a, .title h2 a:link, .title h2 a:visited { 595 color: #21759b; 596 } 597 598 .title h2 a:hover, .title h2 a:active { 599 } 600 601 .title h2.pagetitle { 602 margin-top: 20px; 603 text-align: left; 604 } 605 606 .title .sleeve { 607 width: 937px; 608 margin: 0 auto; 609 } 610 611 .title .desc, 612 .title.group h2.pagetitle { 613 color: #000; 614 font-family: Georgia, serif; 615 font-size: 32px; 616 line-height: 1.1; 617 margin-bottom: 10px; 618 } 619 620 .home .title { 621 padding: 5px 0; 622 height: 50px; 623 } 624 625 .home .desc { 626 float: none; 627 margin-left: 10px; 628 line-height: 50px; 629 color: #31ade5; 630 clear: both; 631 } 632 633 div.desc p { 634 font-size: 16px; 635 color: #666; 636 } 637 638 /* Video Wrapper */ 639 640 .videowrapper { 641 clear: both; 642 643 margin: 10px auto 14px auto; 644 padding-bottom: 4px; 645 646 background: #F0F0F0; 647 border: 1px #E2E2E2 solid; 648 649 box-shadow: inset 0 0 0 1px #fcfcfc; 650 -webkit-box-shadow: inset 0 0 0 1px #fcfcfc; 651 -moz-box-shadow: inset 0 0 0 1px #fcfcfc; 652 } 653 654 .blog .videowrapper { 655 height: 1px; 656 padding: 0; 657 margin: 0; 658 } 659 660 .videowrapper a, .videowrapper a:link, .videowrapper a:visited { 661 color: #f7f7f7; 662 } 663 664 .videowrapper a:hover, .videowrapper a:active { 665 color: #d54e21; 666 } 667 668 .videowrapper .sleeve { 669 width: 937px; 670 margin: 0 auto; 671 text-align: left; 672 } 673 674 .videowrapper .meta { 675 color: #333; 676 margin-top: -10px; 677 padding-bottom: 22px; 678 font-size: 10px; 679 } 680 681 h2.featured { 682 text-transform: uppercase; 683 letter-spacing: 0.2em; 684 font-size: 9px; 685 width: 100%; 686 color: #444; 687 padding-left: 5px; 688 margin-bottom: 5px; 689 } 690 691 .secondcolumn h2.featured { 692 font-size: 18px; 693 line-height: 1.2em; 694 text-transform: none; 695 font-family: Georgia; 696 letter-spacing: 0; 697 font-style: italic; 698 } 699 700 .sharedaddy * { 701 color: #666; 702 font-family: "Lucida Grande", "Lucida Sans Unicode", sans-serif !important; 703 } 704 705 .video-player { 706 padding: 0 !important; 707 margin-top: 19px !important; 708 margin-bottom: 10px !important; 709 } 710 711 .videopress-placeholder { 712 margin-top: 65px; 713 margin-bottom: 0; 714 } 715 716 .videopress-placeholder div img { 717 display: none; 718 } 719 720 .thevideo { 721 float: left; 722 width: 648px; 723 text-align: center; 724 margin: 10px 0 6px 0; 725 position: relative; 726 overflow: hidden; 727 -webkit-border-radius: 6px; 728 -moz-border-radius: 6px; 729 -khtml-border-radius: 6px; 730 border-radius: 6px; 731 } 732 733 .thevideo .avideo { 734 -webkit-border-radius: 6px; 735 -moz-border-radius: 6px; 736 -khtml-border-radius: 6px; 737 border-radius: 6px; 738 position: relative; 739 bottom: 0; 740 background-position: top center; 741 background-repeat: no-repeat; 742 743 } 744 745 .thevideo img { 746 position: absolute; 747 bottom: 6px; 748 left: 0; 749 } 750 751 img.videothumb { 752 width: 100%; 753 } 754 755 .home .thevideo, .category .thevideo, .category .thevideo .avideo { 756 height: 350px; 757 } 758 759 .home .thevideo { 760 margin-bottom: 0; 761 } 762 763 .home .title { 764 margin-bottom: 0px; 765 } 766 767 #rotate { 768 width: 648px; 769 float: left; 770 } 771 772 #rotate.ui-tabs { 773 padding: 0; 774 } 775 776 #rotate .ui-tabs-panel { 777 margin: 0; 778 padding: 0; 779 } 780 781 #rotate .ui-tabs-nav { 782 text-align: center; 783 margin: 0 auto; 784 width: 150px; 785 padding: 0; 786 } 787 788 #rotate .ui-tabs-nav li { 789 display: inline; 790 float: none; 791 margin: 0; 792 padding: 0; 793 width: 30px; 794 text-align: center; 795 } 796 797 #rotate .ui-tabs-nav a { 798 display: block; 799 float: left; 800 width: 30px; 801 text-align: center; 802 padding: 10px 0; 803 } 804 805 #rotate .ui-tabs-nav a span { 806 display: block; 807 width: 30px; 808 text-align: center; 809 background: 0; 810 font-size: 30px; 811 padding: 0; 812 margin: 0; 813 } 814 815 #rotate .ui-tabs-selected, 816 #rotate .ui-tabs-selected a { 817 color: #d54e21; 818 cursor: pointer; 819 } 820 821 .thevideo h3 { 822 position: absolute; 823 bottom: 0px; 824 left: 0px; 825 padding: 20px 0; 826 font-size: 20px; 827 line-height: 1.3em; 828 width: 100%; 829 text-align: center; 830 background: #000; 831 -webkit-border-bottom-left-radius: 6px; 832 -webkit-border-bottom-right-radius: 6px; 833 -moz-border-radius-bottomleft: 6px; 834 -moz-border-radius-bottomright: 6px; 835 -khtml-border-bottom-left-radius: 6px; 836 -khtml-border-bottom-right-radius: 6px; 837 border-bottom-left-radius: 6px; 838 border-bottom-right-radius: 6px; 839 } 840 841 .ui-tabs h3 a { 842 text-align: center; 843 color: white; 844 padding: 0 3px; 845 display: block; 846 width: 100%; 847 } 848 849 .ui-tabs h3 a, .ui-tabs h3 a:link, .ui-tabs h3 a:visited { 850 color: white; 851 } 852 853 .ui-tabs h3 a:hover, .ui-tabs h3 a:active { 854 } 855 856 .thevideo .ui-tabs-panel { 857 height: 350px; 858 overflow: hidden; 859 position: relative; 860 } 861 862 .thevideo a.hiddenpanel { 863 position: absolute; 864 z-index: 1000; 865 text-indent: -1000em; 866 height: 350px; 867 width: auto; 868 display: block; 869 width: 100%; 870 } 871 872 .supplementvideos { 873 float: left; 874 width: 279px; 875 margin-left: 10px; 876 text-align: center; 877 position: relative; 878 padding: 10px 0 0 0; 879 margin-bottom: -4px; 880 } 881 882 .supplementvideos img { 883 width: 279px; 884 } 885 886 .videofeatured { 887 margin-bottom: 14px; 888 position: relative; 889 } 890 891 .thirds .videofeatured { 892 width: 305px; 893 float: left; 894 margin-left: 10px; 895 } 896 897 .videofeatured h3 { 898 text-align: left 899 } 900 901 .supplementvideos .videofeatured h3 a { 902 padding: 0 5px; 903 color: #21759b; 904 } 905 906 .supplementvideos .videofeatured img, 907 .supplementvideos .videofeatured embed { 908 width: 135px; 909 height: auto; 910 float: left; 911 } 912 913 .thirds .videofeatured img { 914 width: 305px; 915 bottom: 5px; 916 top: auto; 917 } 918 919 /* this holds the video and allows it to hide parts of the video that overflow */ 920 .videofeaturedcontainer { 921 position: relative; 922 height: 165px; 923 overflow: hidden; 924 border-radius: 6px; 925 -webkit-border-radius: 6px; 926 -khtml-border-radius: 6px; 927 -moz-border-radius: 6px; 928 } 929 930 /* fake link overlay */ 931 .videofeaturedcontainer .arrow { 932 display: block; 933 z-index: 1000; 934 position: absolute; 935 height: 169px; 936 width: 284px; 937 text-indent: -1000em; 938 } 939 940 .thirds .videofeaturedcontainer .arrow { 941 width: 305px; 942 } 943 944 /* add this css class if you want to show the arrow */ 945 .showarrow { 946 background: url(./i/arrow.png) no-repeat center center; 947 } 948 949 .thevideo .ui-tabs a:hover span { 950 background-color: none !important; 951 } 952 953 .thevideo .showarrow { 954 display: block; 955 z-index: 1000; 956 position: absolute; 957 height: 50px; 958 width: 100%; 959 top: 50%; 960 margin-top: -50px; 961 text-indent: -1000em; 962 } 963 964 .thevideotabs { 965 float: left; 966 width: 279px; 967 margin-left: 10px; 968 color: #ccc; 969 margin-top: 10px; 970 height: 100%; 971 overflow: auto; 972 } 973 974 .thevideotabs .sd-rating { 975 display: none; 976 } 977 978 div.sharedaddy.sd-rating-enabled .sd-like .post-likes-widget, div.sharedaddy.sd-sharing-enabled .sd-like .post-likes-widget { 979 width: 100% !important; 980 } 981 982 .thevideotabs h4 { 983 text-transform: uppercase; 984 letter-spacing: 0.2em; 985 font-size: 9px; 986 color: #ccc; 987 } 988 989 .thevideotabs p { 990 margin-bottom: 10px; 991 color: #bbb; 992 } 993 994 #related { 995 width: 284px; 996 float: right; 997 margin-top: 10px; 998 } 999 1000 #related ul a { 1001 width: 274px; 1002 } 1003 1004 .listedthumbs ul { 1005 margin-bottom: 15px; 1006 } 1007 1008 .listedthumbs ul span { 1009 float: right; 1010 height: 40px; 1011 width: 40px; 1012 overflow: hidden; 1013 margin-left: 4px; 1014 border: 1px solid #ccc; 1015 } 1016 1017 .listedthumbs ul li { 1018 font-size: 13px; 1019 letter-spacing: -0.04em; 1020 clear: both; 1021 min-height: 40px; 1022 padding-bottom: 10px; 1023 padding-top: 5px; 1024 border-bottom: 1px solid #dfdfdf; 1025 border-top: 1px solid #fff; 1026 padding-left: 5px; 1027 } 1028 1029 .listedthumbs ul li:last-child { 1030 border-bottom: none; 1031 } 1032 1033 .listedthumbs ul a, .listedthumbs ul a:link, .listedthumbs ul a:visited { 1034 position: relative; 1035 z-index: 1000; 1036 display: block; 1037 width: 228px; 1038 } 1039 1040 .home .listedthumbs ul a { 1041 width: 289px; 1042 } 1043 1044 .listedthumbs ul span { 1045 position: relative; 1046 } 1047 1048 .listedthumbs ul span img { 1049 height: 50px; 1050 } 1051 1052 .listedthumbs ul span embed { 1053 z-index: 999; 1054 position: absolute; 1055 top: -100px; 1056 left: -100px; 1057 } 1058 1059 .listedthumbs .list { 1060 padding-top: 0; 1061 } 1062 1063 .listedthumbs .list li:last-child { 1064 border-bottom: none; 1065 } 1066 1067 /* Tabs for related stuffs */ 1068 /* Caution! Ensure accessibility in print and other media types... */ 1069 @media projection, screen { 1070 /* Use class for showing/hiding tab content, so that visibility can be better controlled in different media types... */ 1071 .ui-tabs-hide { 1072 display: none !important; 1073 } 1074 } 1075 1076 /* Hide useless elements in print layouts... */ 1077 @media print { 1078 .ui-tabs { 1079 display: none; 1080 } 1081 } 1082 1083 /* Skin */ 1084 .ui-tabs, .ui-tabs-panel { 1085 font-size: 12px; 1086 } 1087 1088 .ui-tabs { 1089 list-style: none; 1090 margin: 0; 1091 padding: 0 0 0 3px; 1092 } 1093 1094 .ui-tabs:after { 1095 /* clearing without presentational markup, IE gets extra treatment */ 1096 display: block; 1097 clear: both; 1098 content: " "; 1099 } 1100 1101 .ui-tabs li { 1102 float: left; 1103 margin: 0 0 0 2px; 1104 } 1105 1106 .ui-tabs a, .ui-tabs a span { 1107 float: left; /* fixes dir=ltr problem and other quirks IE */ 1108 padding: 0; 1109 } 1110 1111 .ui-tabs a { 1112 text-decoration: none; 1113 white-space: nowrap; /* @ IE 6 */ 1114 outline: 0; /* @ Firefox, prevent dotted border after click */ 1115 } 1116 1117 .ui-tabs a:link, .ui-tabs a:visited { 1118 color: #555; 1119 } 1120 1121 .ui-tabs .ui-tabs-selected a { 1122 position: relative; 1123 top: 0px; 1124 z-index: 2; 1125 margin-top: 0; 1126 color: #31ade5; 1127 } 1128 1129 .ui-tabs a span { 1130 /*border-radius-topright: .4em; 1131 -webkit-border-radius-topright: .4em; 1132 -moz-border-radius-topright: .4em; 1133 border-radius-topleft: .4em; 1134 -webkit-border-radius-topleft: .4em; 1135 -moz-border-radius-topleft: .4em; 1136 background: #444;*/ 1137 padding: 2px 5px; 1138 1139 text-transform: uppercase; 1140 letter-spacing: 0.2em; 1141 font-size: 9px; 1142 } 1143 1144 .ui-tabs a:hover span { 1145 1146 } 1147 1148 .ui-tabs .ui-tabs-selected a span { 1149 /*background: #333; */ 1150 cursor: pointer; 1151 } 1152 1153 .ui-tabs .ui-tabs-selected a:link, .ui-tabs .ui-tabs-selected a:visited, 1154 .ui-tabs .ui-tabs-disabled a:link, .ui-tabs .ui-tabs-disabled a:visited { 1155 /* @ Opera, use pseudo classes otherwise it confuses cursor... */ 1156 cursor: text; 1157 } 1158 1159 .ui-tabs a:hover, .ui-tabs a:focus, .ui-tabs a:active, 1160 .ui-tabs .ui-tabs-unselect a:hover, .ui-tabs .ui-tabs-unselect a:focus, .ui-tabs .ui-tabs-unselect a:active { 1161 /* @ Opera, we need to be explicit again here now... */ 1162 cursor: pointer; 1163 } 1164 1165 .ui-tabs a:hover { 1166 color: #d54e21; 1167 cursor: pointer; 1168 } 1169 1170 .ui-tabs-disabled { 1171 opacity: .4; 1172 } 1173 1174 .ui-tabs .ui-tabs-disabled a:link, .ui-tabs .ui-tabs-disabled a:visited { 1175 color: #000; 1176 } 1177 1178 .ui-tabs-panel { 1179 padding: 10px; 1180 } 1181 1182 /*.ui-tabs-loading em { 1183 padding: 0 0 0 20px; 1184 background: url(loading.gif) no-repeat 0 50%; 1185 }*/ 1186 1187 /* Additional IE specific bug fixes... */ 1188 * html .ui-tabs { 1189 /* auto clear @ IE 6 & IE 7 Quirks Mode */ 1190 display: inline-block; 1191 } 1192 1193 *:first-child + html .ui-tabs { 1194 /* auto clear @ IE 7 Standards Mode - do not group selectors, otherwise IE 6 will ignore complete rule (because of the unknown + combinator)... */ 1195 display: inline-block; 1196 } 1197 1198 /* Wrap for main content */ 1199 #wrap { 1200 width: 937px; 1201 margin: 0 auto 30px auto; 1202 } 1203 1204 .searchwrap, 1205 .searchwordcamptv { 1206 margin-bottom: 0em; 1207 } 1208 1209 .languagewrap { 1210 padding: 5px 10px; 1211 margin-bottom: 2em; 1212 border-radius: .4em; 1213 -webkit-border-radius: .4em; 1214 -moz-border-radius: .4em; 1215 border: 1px solid #DFDFDF; 1216 height: 2em; 1217 position: relative; 1218 background: #e8e8e8; 1219 } 1220 1221 .searchwrap { 1222 margin-top: 10px; 1223 height: 2em; 1224 margin-bottom: -2em; 1225 position: relative; 1226 } 1227 1228 .searchwrap form { 1229 margin-bottom: -2em; 1230 } 1231 1232 .searchwordcamptv form #wordcampsubmit, 1233 #setlanguage input { 1234 background: #ccc; 1235 border: 1px solid #888; 1236 color: #666; 1237 -moz-border-radius-bottomleft: 3px; 1238 -moz-border-radius-bottomright: 3px; 1239 -moz-border-radius-topleft: 3px; 1240 -moz-border-radius-topright: 3px; 1241 -webkit-border-radius: 3px; 1242 cursor: pointer; 1243 font-size: 10px; 1244 height: 20px; 1245 padding: 0 4px; 1246 } 1247 1248 .searchwordcamptv form #wordcampsubmit:hover { 1249 background: #B3B3B3; 1250 color: #f7f7f7; 1251 } 1252 1253 .searchwordcamptv #setlanguage { 1254 margin-top: -20px; 1255 } 1256 1257 #setlanguage select, 1258 .searchwordcamptv form select { 1259 margin-right: 15px; 1260 } 1261 1262 .image a { 1263 background: url(./i/arrow.png) no-repeat 50% 50%; 1264 } 1265 1266 #setlanguage { 1267 float: right; 1268 height: 2em; 1269 } 1270 1271 .searchwordcamptv #setlanguage { 1272 bottom: 10px; 1273 top: auto; 1274 } 1275 1276 #setlanguage input, #setlanguage select, #setlanguage p { 1277 display: block; 1278 float: left; 1279 } 1280 1281 /* list for below content */ 1282 1283 /* this holds .linklist divs that have uls */ 1284 .linklists { 1285 width: 769px; 1286 margin-left: -20px; 1287 } 1288 1289 .secondcolumn { 1290 margin-left: 20px; 1291 float: left; 1292 width: 739px; 1293 } 1294 1295 .submenu { 1296 width: 177px; 1297 float: left; 1298 } 1299 1300 .submenu .selected { 1301 background: #f7f7f7; 1302 } 1303 1304 .submenu ul { 1305 margin-bottom: 20px; 1306 border-top: 1px solid #ddd; 1307 border-bottom: 1px solid #f5f5f5; 1308 } 1309 1310 .submenu ul li a { 1311 display: block; 1312 height: 25px; 1313 padding: 0 5px; 1314 line-height: 25px; 1315 border-bottom: 1px solid #ddd; 1316 border-top: 1px solid #f5f5f5; 1317 1318 } 1319 1320 .home .linklists, .full { 1321 float: none; 1322 width: 967px; 1323 margin-left: -20px; 1324 } 1325 1326 /* to wrap around each list */ 1327 .linklist { 1328 width: 33%; 1329 float: left; 1330 } 1331 1332 .linklist ul { 1333 border-top: 1px solid #ddd; 1334 padding-top: 5px; 1335 } 1336 1337 .linklist li { 1338 font-size: 14px; 1339 padding-bottom: 15px; 1340 padding-left: 5px; 1341 letter-spacing: -0.04em; 1342 } 1343 1344 .linklist h3, .linklists h3 { 1345 font-family: Georgia, Times, "Times New Roman", serif; 1346 font-size: 20px; 1347 line-height: 36px; 1348 height: 36px; 1349 padding-left: 5px; 1350 } 1351 1352 .linklists h3 { 1353 clear: both; 1354 margin-left: 20px; 1355 } 1356 1357 .linklist h3 { 1358 margin-left: 0; 1359 } 1360 1361 .linklist h3 a, .linklist h3 a:link, .linklist h3 a:visited { 1362 color: #444; 1363 } 1364 1365 .linklist h3 a:hover, .linklist h3 a:active { 1366 color: #d54e21; 1367 } 1368 1369 .linklist .more { 1370 float: right; 1371 line-height: 22px; 1372 height: 22px; 1373 font-size: 9px; 1374 } 1375 1376 .linklist .more, .linklist .more:link, .linklist .more:visited { 1377 color: #333; 1378 } 1379 1380 .linklist .more:hover, .linklist .more:active { 1381 color: #d54e21; 1382 } 1383 1384 .linklist .sleeve { 1385 margin-left: 20px; 1386 } 1387 1388 .secondary_content { 1389 width: 971px; 1390 margin-bottom: 30px; 1391 margin-left: -7px; 1392 } 1393 1394 .secondary_content ul { 1395 list-style: none; 1396 border-top: 1px solid #ddd; 1397 } 1398 1399 .secondary_content li { 1400 padding: 5px; 1401 list-style: none; 1402 border-bottom: 1px solid #dfdfdf; 1403 border-top: 1px solid #fff; 1404 } 1405 1406 .secondary_content li:last-child { 1407 border-bottom: none; 1408 } 1409 1410 .secondary_content div.half { 1411 width: 460px; 1412 float: left; 1413 padding: 15px 7px; 1414 } 1415 1416 .miro { 1417 text-align: right; 1418 margin-bottom: -46px; 1419 } 1420 1421 .secondary_content h3 { 1422 font-family: Georgia, Times, "Times New Roman", serif; 1423 font-size: 20px; 1424 line-height: 36px; 1425 padding-left: 5px; 1426 } 1427 1428 #wpstats { 1429 display: none; 1430 } 1431 1432 #content { 1433 width: 630px; 1434 float: left; 1435 } 1436 1437 #content .post { 1438 margin-bottom: 20px; 1439 clear: both; 1440 } 1441 1442 #comments { 1443 margin-top: 10px; 1444 } 1445 1446 #comments .depth-2 { 1447 margin-left: 20px; 1448 } 1449 1450 #comments .depth-3 { 1451 margin-left: 40px; 1452 } 1453 1454 #comments a, #comments a:link, #comments a:visited { 1455 color: #222; 1456 } 1457 1458 #comments a:hover, #comments a:active { 1459 color: #d54e21; 1460 } 1461 1462 #comments .commenttext a, #comments .commenttext a:link, #comments .commenttext a:visited { 1463 color: #21759b;; 1464 } 1465 1466 #comments a:hover, #comments a:active { 1467 color: #d54e21; 1468 } 1469 1470 #respond { 1471 border-top: 1px solid #dfdfdf !important; 1472 margin-top: 0 !important; 1473 } 1474 1475 #respond:first-child { 1476 border-top: none !important; 1477 padding-top: 0 !important; 1478 } 1479 1480 #respond h3 { 1481 border: none; 1482 margin-top: 0 !important; 1483 } 1484 1485 .children { 1486 margin-left: 10px; 1487 } 1488 1489 .children #respond { 1490 margin-top: 10px; 1491 } 1492 1493 .children #respond textarea { 1494 width: 90%; 1495 } 1496 1497 #commentform { 1498 color: #222; 1499 margin-bottom: 15px; 1500 background: transparent !important; 1501 } 1502 1503 #commentform, #commentform input, #commentform textarea { 1504 font-family: "Lucida Grande", "Lucida Sans Unicode", sans-serif; 1505 } 1506 1507 #commentform textarea, #commentform input[type="text"] { 1508 background: white; 1509 border: 1px solid #ccc; 1510 padding: 4px 6px; 1511 margin-right: 3px; 1512 -webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.1); 1513 -moz-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.1); 1514 box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.1); 1515 border-radius: 2px; 1516 } 1517 1518 #commentform textarea { 1519 width: 600px; 1520 height: 100px; 1521 margin-bottom: 5px; 1522 } 1523 1524 #commentform #submit { 1525 margin-bottom: 10px; 1526 } 1527 1528 #commentform p { 1529 font-size: 10px; 1530 margin-bottom: 5px; 1531 } 1532 1533 .commentlist li { 1534 list-style: none; 1535 padding: 10px 2px; 1536 border-top: 1px solid #dfdfdf; 1537 } 1538 1539 .commentlist li small { 1540 float: right; 1541 font-size: 11px; 1542 margin-top: -23px; 1543 } 1544 1545 .commentlist li { 1546 clear: both; 1547 } 1548 1549 .commentlist li .authorinfo { 1550 font-weight: bold; 1551 font-style: normal; 1552 line-height: 1.8em; 1553 } 1554 1555 .commentmetadata { 1556 line-height: 1.8em; 1557 } 1558 1559 .avatar { 1560 float: left; 1561 margin: 0 10px 5px 0; 1562 border-radius: 2px; 1563 -webkit-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1); 1564 -moz-box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1); 1565 box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1); 1566 } 1567 1568 .commenttext { 1569 float: left; 1570 padding-top: 5px; 1571 clear: both; 1572 width: 100%; 1573 } 1574 1575 .commenttext p { 1576 margin-bottom: 1em; 1577 } 1578 1579 .comment .pd-rating { 1580 float: right; 1581 font-size: 10px; 1582 } 1583 1584 #footer { 1585 clear: both; 1586 height: 3.5em; 1587 margin-bottom: 15px; 1588 color: #888; 1589 } 1590 1591 #footer .automattic { 1592 width: 400px; 1593 float: right; 1594 text-align: right; 1595 font-size: 11px; 1596 letter-spacing: 0.2em; 1597 line-height: 3em; 1598 padding-top: 13px; 1599 padding-right: 2px; 1600 text-transform: uppercase; 1601 line-height: 28px; 1602 } 1603 1604 .menu-footer-container { 1605 float: left; 1606 line-height: 4em; 1607 margin-left: 2px; 1608 font-size: 13px; 1609 margin-bottom: 0; 1610 } 1611 1612 .menu-footer-container li { 1613 display: inline-block; 1614 } 1615 1616 .menu-footer-container li:last-of-type .dot { 1617 display: none; 1618 } 1619 1620 .menu-footer-container a { 1621 color: #888; 1622 } 1623 1624 .menu-footer-container a:hover { 1625