WordPress.org

Making WordPress.org

Ticket #3117: 3117.3.diff

File 3117.3.diff, 13.4 KB (added by iandunn, 2 years ago)

Create rows for every 5 minutes; remove duplicate sessions

  • new file wc-post-types/inc/schedule.php

    diff --git wc-post-types/inc/schedule.php wc-post-types/inc/schedule.php
    new file mode 100644
    index 0000000..1b219fb
    - +  
     1<?php
     2
     3namespace WordCamp\Post_Types\Schedule;
     4
     5defined( 'WPINC' ) || die();
     6
     7
     8/*
     9 * todo
     10 * make sure preserve all the functionality of the existing
     11 * implement all the functionality of the new
     12 * add length to session ui/save
     13 * test and make compatible w/ personalized schedule builder
     14 * give people working on https://meta.trac.wordpress.org/ticket/3306 and https://trello.com/c/kLVDRj5s/56-wordcamp-design-templates a heads up about this, since it might be best if they design default styles for it rather than old schedule
     15 * test all the scenarios listed at https://meta.trac.wordpress.org/ticket/3117#comment:2. lightning talks too, if not already covered there.
     16 * once ready for testing, deploy behind a filter
     17 * once ready for all sites, enable feature flag
     18 */
     19
     20
     21/**
     22 * Render the `[schedule]` shortcode using markup and styles for a CSS Grid-based approach.
     23 *
     24 * @param array $attributes
     25 * // todo add extra params
     26 *
     27 *
     28 * @return string
     29 */
     30function render_grid_schedule( $attributes, $tracks, $sessions ) {
     31        $time_format = get_option( 'time_format', 'g:i a' );
     32
     33        /*
     34         * Remove duplicate session IDs.
     35         *
     36         * This can't be done in `get_schedule_sessions()` because the table schedule relies on them being there.
     37         */
     38        foreach ( $sessions as $time_slot => $session_ids ) {
     39                $sessions[ $time_slot ] = array_unique( $session_ids );
     40        }
     41
     42        ob_start();
     43        require_once( dirname( __DIR__ ) . '/views/grid-schedule.php' );
     44        return ob_get_clean();
     45}
  • new file wc-post-types/views/grid-schedule.php

    diff --git wc-post-types/views/grid-schedule.php wc-post-types/views/grid-schedule.php
    new file mode 100644
    index 0000000..453bfe4
    - +  
     1<?php
     2
     3namespace WordCamp\Post_Types\Schedule;
     4
     5defined( 'WPINC' ) || die();
     6
     7/**
     8 * todo
     9 *
     10 * @var array  $attributes
     11 * @var array  $tracks
     12 * @var array  $sessions
     13 * @var array  $columns
     14 * @var string $time_format
     15 */
     16
     17/*
     18 * todo
     19 *
     20 * move styles out of inline properties
     21 * move most css to external file, only put what needs to be generated inside <style>?
     22 * rename classes to match v1 schedule, have wordcamp prefix
     23 * want sensible default styles that will make schedule look good out of the box, but that each camp can override as they see fit
     24 * outputting <style> outside <head> is technically invalid, but pretty sure all browsers support it and always will
     25 * test with 0 tracks, 1 track, tracks with no sessions assigned to them, etc
     26 * people will want to set the track sorting order. can do that in css probably, but should provide easier way? like ui in wp-admin to drag/drop order?
     27 * what about short sessions (~5 minutes)? the amount of space required to display all the text is greater than the amount that would naturally be taken up by the sessions fractional units
     28 *
     29 * post prototype on make/community to get feedback. particularly interested in devex of customizing this. will people have to manually override a lot of the grid-* properties in order to do the things they want? if so, is that still less painful than the table schedule?
     30 */
     31
     32$time_slots = array_keys( $sessions );
     33
     34?>
     35
     36<style>
     37        /*************************
     38         * LAYOUT
     39         *************************/
     40        body {
     41                padding: 50px;
     42                counter-reset: session;
     43                max-width: 1100px;
     44                margin: 0 auto;
     45                line-height: 1.5;
     46        }
     47
     48        .track-slot {
     49                display: none;
     50        }
     51        .session {
     52                margin-bottom:  1em;
     53        }
     54
     55        @supports( display:grid ) {
     56                @media screen and (min-width:700px) {
     57                        .schedule {
     58                                display: grid;
     59                        }
     60
     61                        /* a background for the sticky tracks */
     62                        .schedule::after {
     63                                display: block;
     64                                content: '';
     65                                position: sticky;
     66                                top: 0;
     67                                grid-column: track-1 / -1;
     68                                grid-row: tracks;
     69                                z-index: 999;
     70                                background-color: rgba(255,255,255,.9);
     71                        }
     72
     73                        .track-slot {
     74                                display: block;
     75                                padding: 10px 5px 5px;
     76                                position: sticky;
     77                                top: 0; /* otherwise seeing a gap above in at least Firefox. */
     78                                z-index: 1000;
     79                        }
     80                        .session {
     81                                margin: 0;
     82                        }
     83                }
     84        }
     85
     86        .schedule {
     87                grid-gap: 1em;
     88                grid-template-rows:
     89                        [tracks] auto
     90                        <?php
     91                        for ( $i = $time_slots[0]; $i < $time_slots[ count( $time_slots ) - 1 ]; $i += ( 5 * 60 ) ) : ?>
     92                                [time-<?php echo esc_attr( date( 'Hi', $i ) ); ?>] 2px
     93                        <?php endfor; ?>
     94
     95                 /* Note 1:
     96                        In this format, gridlines will need to be "named" in 24hr time
     97
     98                        Note 2: Use "auto" instead of "1fr" for a more compact schedule where height of a slot is not proportional to the session length. Implementing a "compact" shortcode attribute might make sense for this!
     99                */
     100                ;
     101                grid-template-columns:
     102                        [times] 4em
     103                        [track-<?php echo esc_html( $tracks[0]->slug ); ?>-start] 1fr
     104                        <?php for ( $i = 0; $i < count( $tracks ) - 1; $i++ ) : ?>
     105                                [track-<?php echo esc_html( $tracks[ $i ]->slug ); ?>-end track-<?php echo esc_html( $tracks[ $i + 1 ]->slug ); ?>-start] 1fr
     106                        <?php endfor; ?>
     107                        [track-<?php echo esc_html( $tracks[ $i ]->slug ); ?>-end]
     108                ;
     109        }
     110
     111        /*************************
     112         * VISUAL STYLES
     113         *************************/
     114        .text {
     115                max-width: 750px;
     116                font-size: 18px;
     117                margin: 0 auto 50px;
     118        }
     119
     120        .meta {
     121                color: #555;
     122                font-style: italic;
     123        }
     124        .meta a {
     125                color: #555;
     126        }
     127
     128        hr {
     129                margin: 40px 0;
     130        }
     131
     132        .session {
     133                padding: .5em;
     134                border-radius: 2px;
     135                font-size: 14px;
     136        }
     137
     138        .title,
     139        .time-slot {
     140                margin: 0;
     141                font-size: 1em;
     142        }
     143
     144        body {
     145                counter-reset: session-count;
     146        }
     147        .title::before {
     148                counter-increment: session-count;
     149                content: 'Session #' counter(session-count) ': ';
     150        }
     151
     152        .track-slot,
     153        .time-slot {
     154                font-weight: bold;
     155                font-size:.75em;
     156        }
     157
     158        span {
     159                display: block;
     160        }
     161
     162        .track-many {
     163                display: flex;
     164                justify-content: center;
     165                align-items: center;
     166                background: #ccc;
     167                color: #000;
     168        }
     169
     170        ins {
     171                text-decoration: none;
     172                background-color: #ddffdd;
     173        }
     174
     175
     176
     177        /* these styles won't be in the patch, they'd be custom css for a site */
     178        .track-robertson-auditorium-upstairs {
     179                background-color: #1259B2;
     180                color: #fff;
     181        }
     182
     183        .track-fisher-banquet-room-downstairs {
     184                background-color: #687f00;
     185                color: #fff;
     186        }
     187
     188        .track-3 {
     189                background-color: #544D69;
     190                color: #fff;
     191        }
     192
     193        .track-4 {
     194                background-color: #c35500;
     195                color: #fff;
     196        }
     197</style>
     198
     199<div class="schedule">
     200        <?php foreach ( $tracks as $track ) : ?>
     201                <span class="track-slot" aria-hidden="true" style="grid-column: track-<?php echo esc_attr( $track->slug ); ?>; grid-row: tracks;">
     202                        <?php echo esc_html( $track->name ); ?>
     203                </span>
     204        <?php endforeach; ?>
     205
     206        <?php foreach ( $sessions as $time_slot => $session_ids ) : ?>
     207                <h2 class="time-slot" style="grid-column: times; grid-row: time-<?php echo esc_attr( date( 'Hi', $time_slot ) ); ?>;">
     208                        <?php echo esc_html( date_i18n( $time_format, $time_slot ) ); ?>
     209                </h2>
     210
     211                <?php foreach ( $session_ids as $session_id ) : ?>
     212                        <?php
     213
     214                        $session        = get_post( $session_id );
     215                        $speakers       = get_posts( array( 'post__in' => get_post_meta( $session_id, '_wcpt_speaker_id' ) ) );
     216                        $end_time       = $time_slot + ( absint( $session->_wcpt_session_length ) * 60 );
     217                        $session_tracks = get_the_terms( $session->ID, 'wcb_track' );
     218                        $track_classes  = preg_filter( '/^/', 'track-', wp_list_pluck( $session_tracks, 'slug' ) );
     219
     220                        ?>
     221
     222                        <div
     223                                class="session session-<?php echo esc_attr( $session->post_name ); ?> <?php echo esc_attr( implode( ' ', $track_classes ) ); ?>"
     224                                style="
     225                                        grid-column-start: track-<?php echo esc_attr( $session_tracks[ 0 ]->slug ); ?>-start;
     226                                        grid-column-end: track-<?php echo esc_attr( $session_tracks[ count( $session_tracks ) - 1 ]->slug ); ?>-end;
     227                                        grid-row-start: time-<?php echo esc_attr( date( 'Hi', $time_slot ) ); ?>;
     228                                        grid-row-end: time-<?php echo esc_attr( date( 'Hi', $end_time ) ); ?>;
     229                                "
     230                        >
     231                                <h3 class="title">
     232                                        <?php echo esc_html( $session->post_title ); ?>
     233                                </h3>
     234
     235                                <span class="time">
     236                                        <?php echo esc_html( date_i18n( $time_format, $time_slot ) ); ?>
     237                                        -
     238                                        <?php echo esc_html( date_i18n( $time_format, $end_time ) ); ?>
     239                                </span>
     240
     241                                <span class="track">
     242                                        <?php echo esc_attr( implode( ', ', wp_list_pluck( $session_tracks, 'name' ) ) ); ?>
     243                                </span>
     244
     245                                <?php if ( $speakers ) : ?>
     246                                        <ul class="author">
     247                                                <?php foreach ( $speakers as $speaker ) : ?>
     248                                                        <li>
     249                                                                <?php echo esc_html( $speaker->post_title ); ?>
     250                                                        </li>
     251                                                <?php endforeach; ?>
     252                                        </ul>
     253                                <?php endif; ?>
     254                        </div>
     255                <?php endforeach; ?>
     256        <?php endforeach; ?>
     257</div>
  • wc-post-types/wc-post-types.php

    diff --git wc-post-types/wc-post-types.php wc-post-types/wc-post-types.php
    index cc9e84c..fbb88ac 100644
     
    44 * Plugin Description: Sessions, Speakers, Sponsors and much more.
    55 */
    66
     7use WordCamp\Post_Types\Schedule;
     8
    79require( 'inc/back-compat.php' );
    810require_once( 'inc/favorite-schedule-shortcode.php' );
    911
    class WordCamp_Post_Types_Plugin { 
    518520        }
    519521
    520522        /**
    521          * The [schedule] shortcode callback (experimental)
     523         * Render the appropriate version of the `[schedule]` shortcode.
    522524         *
    523          * @todo implement date arg
    524          * @todo implement anchor for session_link
    525          * @todo maybe simplify $attr['custom']
    526          * @todo cleanup
     525         * @param array  $attr
     526         * @param string $content
     527         *
     528         * @return string
    527529         */
    528530        function shortcode_schedule( $attr, $content ) {
    529531                $this->enqueue_schedule_shortcode_dependencies();
    class WordCamp_Post_Types_Plugin { 
    532534                $tracks                      = get_schedule_tracks( $attr['tracks'] );
    533535                $tracks_explicitly_specified = 'all' !== $attr['tracks'];
    534536                $sessions                    = get_schedule_sessions( $attr['date'], $tracks_explicitly_specified, $tracks );
    535                 $columns                     = get_schedule_columns( $tracks, $sessions, $tracks_explicitly_specified );
    536537
     538                if ( wcorg_skip_feature( 'css-grid-schedule' ) ) {
     539                        $columns = get_schedule_columns( $tracks, $sessions, $tracks_explicitly_specified );
     540                        $output  = $this->render_table_schedule( $attr, $content, $tracks, $sessions, $columns );
     541                } else {
     542                        require_once( __DIR__ . '/inc/schedule.php' );
     543                        $output = Schedule\render_grid_schedule( $attr, $tracks, $sessions );
     544                }
     545
     546                $output .= $this->fav_session_email_form();
     547
     548                return $output;
     549        }
     550
     551        /**
     552         * The [schedule] shortcode callback (experimental)
     553         *
     554         * @todo implement date arg
     555         * @todo implement anchor for session_link
     556         * @todo maybe simplify $attr['custom']
     557         * @todo cleanup
     558         */
     559        function render_table_schedule( $attr, $content, $tracks, $sessions, $columns ) {
    537560                $html  = '<table class="wcpt-schedule" border="0">';
    538561                $html .= '<thead>';
    539562                $html .= '<tr>';
    class WordCamp_Post_Types_Plugin { 
    704727
    705728                $html .= '</tbody>';
    706729                $html .= '</table>';
    707                 $html .= $this->fav_session_email_form();
     730
    708731                return $html;
    709732        }
    710733
    class WordCamp_Post_Types_Plugin { 
    17341757                $session_hours    = ( $session_time ) ? date( 'g', $session_time )     : date( 'g' );
    17351758                $session_minutes  = ( $session_time ) ? date( 'i', $session_time )     : '00';
    17361759                $session_meridiem = ( $session_time ) ? date( 'a', $session_time )     : 'am';
     1760                $session_length   = absint( get_post_meta( $post->ID, '_wcpt_session_length', true ) ); // todo default to 30 minutes or 45 ?
    17371761                $session_type     = get_post_meta( $post->ID, '_wcpt_session_type', true );
    17381762                $session_slides   = get_post_meta( $post->ID, '_wcpt_session_slides', true );
    17391763                $session_video    = get_post_meta( $post->ID, '_wcpt_session_video',  true );
    class WordCamp_Post_Types_Plugin { 
    17441768                <p>
    17451769                        <label for="wcpt-session-date"><?php _e( 'Date:', 'wordcamporg' ); ?></label>
    17461770                        <input type="text" id="wcpt-session-date" data-date="<?php echo esc_attr( $session_date ); ?>" name="wcpt-session-date" value="<?php echo esc_attr( $session_date ); ?>" /><br />
     1771
    17471772                        <label><?php _e( 'Time:', 'wordcamporg' ); ?></label>
    17481773
    17491774                        <select name="wcpt-session-hour" aria-label="<?php _e( 'Session Start Hour', 'wordcamporg' ); ?>">
    class WordCamp_Post_Types_Plugin { 
    17651790                        <select name="wcpt-session-meridiem" aria-label="<?php _e( 'Session Meridiem', 'wordcamporg' ); ?>">
    17661791                                <option value="am" <?php selected( 'am', $session_meridiem ); ?>>am</option>
    17671792                                <option value="pm" <?php selected( 'pm', $session_meridiem ); ?>>pm</option>
    1768                         </select>
     1793                        </select><br />
     1794
     1795                        <label for="wcpt-session-length">
     1796                                <?php
     1797                                // translators: todo
     1798                                esc_html_e( 'Length:', 'wordcamporg' );
     1799                                ?>
     1800
     1801                                <!-- todo dropdown for every 5 minutes instead of text input? what about a full-day workshop that's ~7 hours? what if it has a break in the middle for lunch? -->
     1802                                <input type="number" name="wcpt-session-length" value="<?php echo esc_attr( $session_length ); ?>" />
     1803                                <?php
     1804                                // translators: todo
     1805                                esc_html_e( 'minutes', 'wordcamporg' );
     1806                                ?>
     1807                        </label>
     1808                        <br />
    17691809                </p>
    17701810
    17711811                <p>
    class WordCamp_Post_Types_Plugin { 
    19642004                        ) );
    19652005                        update_post_meta( $post_id, '_wcpt_session_time', $session_time );
    19662006
     2007                        $session_length = absint( $_POST['wcpt-session-length'] );
     2008                        update_post_meta( $post_id, '_wcpt_session_length', $session_length );
     2009
    19672010                        // Update session type
    19682011                        $session_type = sanitize_text_field( $_POST['wcpt-session-type'] );
    19692012                        if ( ! in_array( $session_type, array( 'session', 'custom' ) ) ) {