From bc2d1f044f3506d4b7d73bd2af17e363b66fdf43 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Fri, 28 Jul 2017 17:43:00 +0000 Subject: [PATCH] Permalinks: Add buttons for the available structure tags to the admin UI. Often times, it can be confusing to set a custom permalink structure. One has to double-check the documentation, make sure to correctly insert the structure tag, and hope not to break their site. With this addition, the available structure tags are being displayed as a list of easily clickable buttons that can be used to insert tags to the custom structure input field and to remove them again. Props kpdesign, swissspidy, joedolson, afercia. Fixes #29872. git-svn-id: https://develop.svn.wordpress.org/trunk@41182 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/forms.css | 5 ++ src/wp-admin/js/common.js | 95 ++++++++++++++++++++++++++++++ src/wp-admin/options-permalink.php | 63 ++++++++++++++++++++ 3 files changed, 163 insertions(+) diff --git a/src/wp-admin/css/forms.css b/src/wp-admin/css/forms.css index 50861ae4cb..6b36d20769 100644 --- a/src/wp-admin/css/forms.css +++ b/src/wp-admin/css/forms.css @@ -908,6 +908,11 @@ table.form-table td .updated p { vertical-align: middle; } +.form-table.permalink-structure .available-structure-tags li { + float: left; + margin-right: 5px; +} + /*------------------------------------------------------------------------------ 21.0 - Network Admin ------------------------------------------------------------------------------*/ diff --git a/src/wp-admin/js/common.js b/src/wp-admin/js/common.js index 930b659d62..5ea1d7cfbc 100644 --- a/src/wp-admin/js/common.js +++ b/src/wp-admin/js/common.js @@ -175,6 +175,101 @@ $('.contextual-help-tabs').delegate('a', 'click', function(e) { panel.addClass('active').show(); }); +/** + * Update custom permalink structure via buttons. + */ + +var permalinkStructureFocused = false, + $permalinkStructure = $( '#permalink_structure' ), + $availableStructureTags = $( '.form-table.permalink-structure .available-structure-tags button' ); + +// Check if the permalink structure input field has had focus at least once. +$permalinkStructure.on( 'focus', function( event ) { + permalinkStructureFocused = true; + $( this ).off( event ); +} ); + +/** + * Enables or disables a structure tag button depending on its usage. + * + * If the structure is already used in the custom permalink structure, + * it will be disabled. + * + * @param {object} button Button jQuery object. + */ +function changeStructureTagButtonState( button ) { + if ( -1 !== $permalinkStructure.val().indexOf( button.text().trim() ) ) { + button.attr( 'data-label', button.attr( 'aria-label' ) ); + button.attr( 'aria-label', button.attr( 'data-used' ) ); + button.attr( 'aria-pressed', true ); + button.addClass( 'active' ); + } else if ( button.attr( 'data-label' ) ) { + button.attr( 'aria-label', button.attr( 'data-label' ) ); + button.attr( 'aria-pressed', false ); + button.removeClass( 'active' ); + } +}; + +// Check initial button state. +$availableStructureTags.each( function() { + changeStructureTagButtonState( $( this ) ); +} ); + +// Observe permalink structure field and disable buttons of tags that are already present. +$permalinkStructure.on( 'change', function() { + $availableStructureTags.each( function() { + changeStructureTagButtonState( $( this ) ); + } ); +} ); + +$availableStructureTags.on( 'click', function() { + var permalinkStructureValue = $permalinkStructure.val(), + selectionStart = $permalinkStructure[ 0 ].selectionStart, + selectionEnd = $permalinkStructure[ 0 ].selectionEnd, + textToAppend = $( this ).text().trim(), + textToAnnounce = $( this ).attr( 'data-added' ); + + // Remove structure tag if already part of the structure. + if ( -1 !== permalinkStructureValue.indexOf( textToAppend ) ) { + permalinkStructureValue = permalinkStructureValue.replace( textToAppend + '/', '' ); + + $permalinkStructure.val( '/' === permalinkStructureValue ? '' : permalinkStructureValue ); + + // Announce change to screen readers. + $( '#custom_selection_updated' ).text( textToAnnounce ); + + // Disable button. + changeStructureTagButtonState( $( this ) ); + + return; + } + + // Input field never had focus, move selection to end of input. + if ( ! permalinkStructureFocused && 0 === selectionStart && 0 === selectionEnd ) { + selectionStart = selectionEnd = permalinkStructureValue.length; + } + + $( '#custom_selection' ).prop( 'checked', true ); + + // Prepend and append slashes if necessary. + if ( '/' !== permalinkStructureValue.substr( 0, selectionStart ).substr( -1 ) ) { + textToAppend = '/' + textToAppend; + } + + if ( '/' !== permalinkStructureValue.substr( selectionEnd, 1 ) ) { + textToAppend = textToAppend + '/'; + } + + // Insert structure tag at the specified position. + $permalinkStructure.val( permalinkStructureValue.substr( 0, selectionStart ) + textToAppend + permalinkStructureValue.substr( selectionEnd ) ); + + // Announce change to screen readers. + $( '#custom_selection_updated' ).text( textToAnnounce ); + + // Disable button. + changeStructureTagButtonState( $( this ) ); +} ); + $document.ready( function() { var checks, first, last, checked, sliced, mobileEvent, transitionTimeout, focusedRowActions, lastClicked = false, diff --git a/src/wp-admin/options-permalink.php b/src/wp-admin/options-permalink.php index 95c1a3e0ba..c7193f96a6 100644 --- a/src/wp-admin/options-permalink.php +++ b/src/wp-admin/options-permalink.php @@ -206,6 +206,69 @@ $structures = array( +
+
+ __( '%s (The year of the post, four digits, for example 2004.)' ), + /* translators: %s: permalink structure tag */ + 'monthnum' => __( '%s (Month of the year, for example 05.)' ), + /* translators: %s: permalink structure tag */ + 'day' => __( '%s (Day of the month, for example 28.)' ), + /* translators: %s: permalink structure tag */ + 'hour' => __( '%s (Hour of the day, for example 15.)' ), + /* translators: %s: permalink structure tag */ + 'minute' => __( '%s (Minute of the hour, for example 43.)' ), + /* translators: %s: permalink structure tag */ + 'second' => __( '%s (Second of the minute, for example 33.)' ), + /* translators: %s: permalink structure tag */ + 'post_id' => __( '%s (The unique ID of the post, for example 423.)' ), + /* translators: %s: permalink structure tag */ + 'postname' => __( '%s (The sanitized post title (slug).)' ), + /* translators: %s: permalink structure tag */ + 'category' => __( '%s (Category slug. Nested sub-categories appear as nested directories in the URI.)' ), + /* translators: %s: permalink structure tag */ + 'author' => __( '%s (A sanitized version of the author name.)' ), + ); + + /** + * Filters the list of available permalink structure tags on the Permalinks settings page. + * + * @since 4.8.0 + * + * @param array $available_tags A key => value pair of available permalink structure tags. + */ + $available_tags = apply_filters( 'available_permalink_structure_tags', $available_tags ); + + /* translators: %s: permalink structure tag */ + $structure_tag_added = __( '%s added to permalink structure' ); + + /* translators: %s: permalink structure tag */ + $structure_tag_already_used = __( '%s (already used in permalink structure)' ); + + if ( ! empty( $available_tags ) ) : + ?> +

+ + +