Making WordPress.org

Ticket #774: diff.diff

File diff.diff, 178.3 KB (added by BrashRebel, 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
     8get_header();
     9global $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&hellip;', '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
     30get_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
     9function 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
     176add_action( 'wp_head', 'anon_upload_css' );
     177
     178get_header();
     179
     180$message = '';
     181
     182if ( !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">
     345jQuery( 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
     8get_header();
     9global $wp_query, $post, $wptv;
     10?>
     11<div class="wptv-hero">
     12        <h2 class="page-title"><?php
     13                if ( is_category() ) :
     14                        printf( __( '&#8216;%s&#8217; Videos', 'wptv' ), single_cat_title( '', false ) );
     15
     16                elseif ( is_tag() ) :
     17                        printf( __( '&#8216;%s&#8217; 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 &#8216;%s&#8217;', '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 .= ' &#8212 ' . 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
     90get_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
     6global $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">&raquo;</span>' );
     12                $wptv->the_event( '<span class="arrow">&raquo;</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
     14get_header();
     15global $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
     74get_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
     9global $wp_query, $wptv;
     10get_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
     17if ( 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 */
     12if ( post_password_required() ) {
     13        return;
     14}
     15
     16global $wptv;
     17
     18if ( have_comments() ) :
     19?>
     20        <h3 id="comments">
     21                <?php
     22                        printf( _nx( 'One response on &ldquo;%2$s&rdquo;', '%1$s responses on &ldquo;%2$s&rdquo;', 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
     31endif;
     32
     33if ( ! 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
     38endif;
     39
     40comment_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">&#8226;</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);
     10if ( $sticky_posts = get_option( 'sticky_posts' ) ) {
     11        $featured_params['post__in'] = $sticky_posts;
     12}
     13$featured = new WP_Query( $featured_params );
     14
     15global $wptv;
     16get_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 &rarr;', '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
     128get_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 */
     6class 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' ), '&nbsp;&nbsp;', '' );
     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
     628global $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 */
     637class 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 &rarr;' ); ?></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
     704function 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}
     718add_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 */
     729function 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}
     752add_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
     8global $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
     3require_once WP_CONTENT_DIR . '/themes/vip/plugins/vip-init.php';
     4wpcom_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
     8get_header();
     9global $wp_query, $post, $wptv;
     10
     11if ( 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&hellip;' ); ?></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
     83endif;
     84
     85get_footer();
  • new file js/dropdowns.js

    diff --git a/js/dropdowns.js b/js/dropdowns.js
    new file mode 100755
    index 0000000..1ad1fe9
    - +  
     1jQuery(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 */
     5get_header();
     6the_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
     6if ( $wp_query->max_num_pages > 1 ) :
     7?>
     8<div class="pagination">
     9        <div class="nav-previous"><?php next_posts_link( __( '<span class="meta-nav">&larr;</span> Older videos', 'wptv' ) ); ?></div>
     10        <div class="nav-next"><?php previous_posts_link( __( 'Newer videos <span class="meta-nav">&rarr;</span>', 'wptv' ) ); ?></div>
     11</div>
     12<?php
     13endif;
  • 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 */
     8function 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}
     18add_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
     4class 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
     5Plugin Name:  WordPress.tv oEmbed Provider
     6Plugin URI:   http://wordpress.tv/oembed/
     7Description:  Creates an oEmbed provider for WordPress.tv.
     8Author:       Viper007Bond
     9
     10**************************************************************************/
     11
     12class 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
     159add_action( 'init', 'WordCampTV_oEmbed', 5 );
     160function 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 */
     7class 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.
     103add_action( 'init', 'wptv_rest_api_init', 5 );
     104function 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 */
     11class 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.
     203add_action( 'init', 'wptv_unisubs_init', 5 );
     204function 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 */
     9class 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( '&lt;br /&gt;', '&lt;br/&gt;' ), "<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                                     '&amp;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
     529new WordPressTV_Subtitles_Upload;
  • new file search.php

    diff --git a/search.php b/search.php
    new file mode 100755
    index 0000000..8b8fce4
    - +  
     1<?php
     2global $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
     11get_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 &rarr;</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 */
     5global $wptv, $originalcontent;
     6get_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/*
     2Theme Name: WordPress.tv v2
     3Theme URI: http://wordpress.tv
     4Description: WordPress.tv v2 Theme
     5Version: 2.0
     6Author: Automattic
     7Author URI: http://automattic.com/
     8*/
     9
     10/* meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/ */
     11html, body, div, span, applet, object, iframe,
     12h1, h2, h3, h4, h5, h6, p, blockquote, pre,
     13a, abbr, acronym, address, big, cite, code,
     14del, dfn, em, font, img, ins, kbd, q, s, samp,
     15small, strike, strong, sub, sup, tt, var,
     16dl, dt, dd, ol, ul, li,
     17fieldset, form, label, legend,
     18table, 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
     35body {
     36        line-height: 1;
     37        color: black;
     38        background: white;
     39}
     40
     41ol, ul {
     42        list-style: none;
     43}
     44
     45/* tables still need 'cellspacing="0"' in the markup */
     46table {
     47        border-collapse: separate;
     48        border-spacing: 0;
     49}
     50
     51caption, th, td {
     52        text-align: left;
     53        font-weight: normal;
     54}
     55
     56blockquote:before, blockquote:after,
     57q:before, q:after {
     58        content: "";
     59}
     60
     61blockquote, q {
     62        quotes: "" "";
     63}
     64
     65/* Tables still need 'cellspacing="0"' in the markup. */
     66table {
     67        border-collapse: separate;
     68        border-spacing: 0;
     69}
     70
     71caption, th, td {
     72        text-align: left;
     73        font-weight: 400;
     74}
     75
     76/* Remove possible quote marks (") from <q>,<blockquote>. */
     77blockquote:before, blockquote:after, q:before, q:after {
     78        content: "";
     79}
     80
     81blockquote, q {
     82        quotes: "" "";
     83}
     84
     85a 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 */
     106body {
     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
     126a, a:link, a:visited {
     127        color: #21759b;
     128        text-decoration: none;
     129}
     130
     131a:hover, a:active {
     132        color: #d54e21;
     133}
     134
     135em, cite {
     136        font-style: italic;
     137}
     138
     139strong {
     140        font-weight: bold;
     141}
     142
     143h1, h2, h3, h4, h5, h6 {
     144        font-weight: normal;
     145}
     146
     147p, pre, dl, ul, ol {
     148}
     149
     150table, td, th, tr, thead, tbody, tfoot {
     151}
     152
     153dd, dt, li {
     154}
     155
     156blockquote {
     157}
     158
     159form, 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
     285input[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
     310input[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
     326input[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 {
     517margin-right: 10px;
     518font-size: 18px !important;
     519font-family: Georgia,"Times New Roman",Times,serif !important;
     520margin-bottom: 10px !important;
     521padding-top: 18px !important;
     522padding-bottom: 3px !important;
     523border-bottom: 1px solid #ddd !important;
     524padding-left: 5px !important;
     525}
     526.blog h3 small {
     527font-size: 14px;
     528}
     529
     530.blog p, .blog object {
     531margin-bottom: 18px;
     532} */
     533
     534/* Captions */
     535.aligncenter,
     536div.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
     633div.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
     681h2.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
     751img.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
     978div.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