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
This commit is contained in:
Pascal Birchler 2017-07-28 17:43:00 +00:00
parent 1bdd506f4d
commit bc2d1f044f
3 changed files with 163 additions and 0 deletions

View File

@ -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
------------------------------------------------------------------------------*/

View File

@ -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,

View File

@ -206,6 +206,69 @@ $structures = array(
<td>
<code><?php echo get_option('home') . $blog_prefix; ?></code>
<input name="permalink_structure" id="permalink_structure" type="text" value="<?php echo esc_attr($permalink_structure); ?>" class="regular-text code" />
<div class="available-structure-tags hide-if-no-js">
<div id="custom_selection_updated" aria-live="assertive" class="screen-reader-text"></div>
<?php
$available_tags = array(
/* translators: %s: permalink structure tag */
'year' => __( '%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 ) ) :
?>
<p><?php _e( 'Available tags:' ); ?></p>
<ul role="list">
<?php
foreach ( $available_tags as $tag => $explanation ) {
?>
<li>
<button type="button"
class="button button-secondary"
aria-label="<?php echo esc_attr( sprintf( $explanation, $tag ) ); ?>"
data-added="<?php echo esc_attr( sprintf( $structure_tag_added, $tag ) ); ?>"
data-used="<?php echo esc_attr( sprintf( $structure_tag_already_used, $tag ) ); ?>">
<?php echo '%' . $tag . '%'; ?>
</button>
</li>
<?php
}
?>
</ul>
<?php endif; ?>
</div>
</td>
</tr>
</table>