Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build a better time zone selector (and engineer out continents-cities.php) #50

Open
stuwest opened this issue Feb 11, 2016 · 2 comments

Comments

@stuwest
Copy link
Contributor

stuwest commented Feb 11, 2016

WordPress core currently includes a hack around time zones, a php file called continents-cities.php. This isn't used by any code but includes a list of ~500 geographic names in English wrapped in __() so they get into GlotPress. Language packs include localized versions of this file. Core's time zone selector then gets a list of time zone IDs from PHP's timezone_identifiers_list(), does some parsing, generates a drop down list, and uses those localized strings for display names.

A couple issues here:

  • continents-cities.php creates ~500 strings of unnecessary busy work for our translators. These country/region names have all been translated widely before and we don't get to take advantage of all that work (and as a result have inconsistencies and gaps across our locales).
  • The IANA's list of cities isn't a great centerpiece for a UI. Those choices were driven by geography and time zone boundaries, an approach which makes sense in a standards-body kind of way but isn't how most users think (11 examples for Antarctica? Eight for the U.S. state of Indiana?). Also, that list can be brittle due to variations in PHP versions of the time zone db.
  • The design approach -- a drop-down menu of 500 items (😱) -- could use some love.

CLDR data could offer a better way.

@stuwest stuwest changed the title Engineer out the continents-cities.php hack in wordpress core Get CLDR data in shape as potential alternative to the continents-cities.php hack in wordpress core Feb 12, 2016
@stuwest
Copy link
Contributor Author

stuwest commented Feb 29, 2016

We should be able to do something here once we add some more data files and functions see #15 and #24.

@stuwest stuwest changed the title Get CLDR data in shape as potential alternative to the continents-cities.php hack in wordpress core See if we can replace core's continents-cities.php hack with CLDR data Mar 2, 2016
@stuwest stuwest changed the title See if we can replace core's continents-cities.php hack with CLDR data Build a better time zone selector (and engineer out continents-cities.php) Mar 11, 2016
@stuwest
Copy link
Contributor Author

stuwest commented Mar 11, 2016

With the time zone names committed in #80, we can start playing around here. For example, if we replaced continents-cities.php in language packs with the relevant CLDR timeZoneNames.json file, this function -- written here as a part of the WP_CLDR class -- could with some tweaking replace core's wp_timezone_choice:

/**
 * Gets  nicely-formatted list of timezone strings from CLDR. Drop-in replacement for wp_timezone_choice().
 *
 * @link http://www.iana.org/time-zones IANA time zone
 * @link http://unicode.org/reports/tr35/tr35-dates.html#Time_Zone_Names CLDR info on time zone names
 *
 * @param string $selected_zone The currently selected timezone.
 * @return string The list of timezones.
 */
function wp_cldr_timezone_choice( $selected_zone ) {

    // Load locale display names for time zones.
    $time_zone_names_json = $this->get_locale_bucket( $locale, 'timeZoneNames' );
    $zonen = $time_zone_names_json['zone'];

    $structure = array();

    if ( empty( $selected_zone ) ) {
        $structure[] = '<option selected="selected" value="">' . __( 'Select a city' ) . '</option>';
    }

    foreach ( $zonen as $continent_id => $continent_array ) {

        $structure[] = '<optgroup label="'. esc_attr( $continent_id ) .'">';
        foreach ( $continent_array as $level_1_id => $level_1_array ) {
            if ( isset( $level_1_array['exemplarCity'] ) ) {
                $id = esc_attr( $continent_id ) . '/' . esc_attr( $level_1_id );
                $structure[] = '<option ' . $selected . 'value="' . $id . '">' . esc_html( $level_1_array['exemplarCity'] ) . '</option>';
            } else {
                foreach ( $level_1_array as $level_2_id => $level_2_array ) {
                    $structure[] = '<option ' . $selected . 'value="' . esc_attr( $continent_id ) . '/' . esc_attr( $level_1_id ) . '/' . esc_attr( $level_2_id ) . '">' . esc_html( $level_1_id . ' - ' . $level_2_array['exemplarCity'] ) . '</option>';
                }
            }
        }
        $structure[] = '</optgroup>';
    }
    return join( "\n", $structure );
}

While we're at it though, seems like we should be able to use some combination of country, browser time zone offset, and the user's locale to give users a simpler and more targeted set of time zone choices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant