wp/wp-admin/options-permalink.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    55 			'<p>' . __( 'You must click the Save Changes button at the bottom of the screen for new settings to take effect.' ) . '</p>',
    55 			'<p>' . __( 'You must click the Save Changes button at the bottom of the screen for new settings to take effect.' ) . '</p>',
    56 	)
    56 	)
    57 );
    57 );
    58 
    58 
    59 $help_sidebar_content = '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
    59 $help_sidebar_content = '<p><strong>' . __( 'For more information:' ) . '</strong></p>' .
    60 						'<p>' . __( '<a href="https://wordpress.org/support/article/settings-permalinks-screen/">Documentation on Permalinks Settings</a>' ) . '</p>' .
    60 	'<p>' . __( '<a href="https://wordpress.org/documentation/article/settings-permalinks-screen/">Documentation on Permalinks Settings</a>' ) . '</p>' .
    61 						'<p>' . __( '<a href="https://wordpress.org/support/article/using-permalinks/">Documentation on Using Permalinks</a>' ) . '</p>';
    61 	'<p>' . __( '<a href="https://wordpress.org/documentation/article/customize-permalinks/">Documentation on Using Permalinks</a>' ) . '</p>';
    62 
    62 
    63 if ( $is_nginx ) {
    63 if ( $is_nginx ) {
    64 	$help_sidebar_content .= '<p>' . __( '<a href="https://wordpress.org/support/article/nginx/">Documentation on Nginx configuration</a>.' ) . '</p>';
    64 	$help_sidebar_content .= '<p>' . __( '<a href="https://developer.wordpress.org/advanced-administration/server/web-server/nginx/">Documentation on Nginx configuration</a>.' ) . '</p>';
    65 }
    65 }
    66 
    66 
    67 $help_sidebar_content .= '<p>' . __( '<a href="https://wordpress.org/support/">Support</a>' ) . '</p>';
    67 $help_sidebar_content .= '<p>' . __( '<a href="https://wordpress.org/support/forums/">Support forums</a>' ) . '</p>';
    68 
    68 
    69 get_current_screen()->set_help_sidebar( $help_sidebar_content );
    69 get_current_screen()->set_help_sidebar( $help_sidebar_content );
    70 unset( $help_sidebar_content );
    70 unset( $help_sidebar_content );
    71 
    71 
    72 $home_path           = get_home_path();
    72 $home_path           = get_home_path();
    73 $iis7_permalinks     = iis7_supports_permalinks();
    73 $iis7_permalinks     = iis7_supports_permalinks();
    74 $permalink_structure = get_option( 'permalink_structure' );
    74 $permalink_structure = get_option( 'permalink_structure' );
    75 
    75 
    76 $prefix      = '';
    76 $index_php_prefix = '';
    77 $blog_prefix = '';
    77 $blog_prefix      = '';
       
    78 
    78 if ( ! got_url_rewrite() ) {
    79 if ( ! got_url_rewrite() ) {
    79 	$prefix = '/index.php';
    80 	$index_php_prefix = '/index.php';
    80 }
    81 }
    81 
    82 
    82 /*
    83 /*
    83  * In a subdirectory configuration of multisite, the `/blog` prefix is used by
    84  * In a subdirectory configuration of multisite, the `/blog` prefix is used by
    84  * default on the main site to avoid collisions with other sites created on that
    85  * default on the main site to avoid collisions with other sites created on that
    85  * network. If the `permalink_structure` option has been changed to remove this
    86  * network. If the `permalink_structure` option has been changed to remove this
    86  * base prefix, WordPress core can no longer account for the possible collision.
    87  * base prefix, WordPress core can no longer account for the possible collision.
    87  */
    88  */
    88 if ( is_multisite() && ! is_subdomain_install() && is_main_site() && 0 === strpos( $permalink_structure, '/blog/' ) ) {
    89 if ( is_multisite() && ! is_subdomain_install() && is_main_site()
       
    90 	&& str_starts_with( $permalink_structure, '/blog/' )
       
    91 ) {
    89 	$blog_prefix = '/blog';
    92 	$blog_prefix = '/blog';
    90 }
    93 }
    91 
    94 
    92 $category_base = get_option( 'category_base' );
    95 $category_base = get_option( 'category_base' );
    93 $tag_base      = get_option( 'tag_base' );
    96 $tag_base      = get_option( 'tag_base' );
   105 			$permalink_structure = $_POST['permalink_structure'];
   108 			$permalink_structure = $_POST['permalink_structure'];
   106 		}
   109 		}
   107 
   110 
   108 		if ( ! empty( $permalink_structure ) ) {
   111 		if ( ! empty( $permalink_structure ) ) {
   109 			$permalink_structure = preg_replace( '#/+#', '/', '/' . str_replace( '#', '', $permalink_structure ) );
   112 			$permalink_structure = preg_replace( '#/+#', '/', '/' . str_replace( '#', '', $permalink_structure ) );
   110 			if ( $prefix && $blog_prefix ) {
   113 
   111 				$permalink_structure = $prefix . preg_replace( '#^/?index\.php#', '', $permalink_structure );
   114 			if ( $index_php_prefix && $blog_prefix ) {
       
   115 				$permalink_structure = $index_php_prefix . preg_replace( '#^/?index\.php#', '', $permalink_structure );
   112 			} else {
   116 			} else {
   113 				$permalink_structure = $blog_prefix . $permalink_structure;
   117 				$permalink_structure = $blog_prefix . $permalink_structure;
   114 			}
   118 			}
   115 		}
   119 		}
   116 
   120 
   141 		$wp_rewrite->set_tag_base( $tag_base );
   145 		$wp_rewrite->set_tag_base( $tag_base );
   142 	}
   146 	}
   143 }
   147 }
   144 
   148 
   145 if ( $iis7_permalinks ) {
   149 if ( $iis7_permalinks ) {
   146 	if ( ( ! file_exists( $home_path . 'web.config' ) && win_is_writable( $home_path ) ) || win_is_writable( $home_path . 'web.config' ) ) {
   150 	if ( ( ! file_exists( $home_path . 'web.config' )
       
   151 		&& win_is_writable( $home_path ) ) || win_is_writable( $home_path . 'web.config' )
       
   152 	) {
   147 		$writable = true;
   153 		$writable = true;
   148 	} else {
   154 	} else {
   149 		$writable = false;
   155 		$writable = false;
   150 	}
   156 	}
   151 } elseif ( $is_nginx ) {
   157 } elseif ( $is_nginx || $is_caddy ) {
   152 	$writable = false;
   158 	$writable = false;
   153 } else {
   159 } else {
   154 	if ( ( ! file_exists( $home_path . '.htaccess' ) && is_writable( $home_path ) ) || is_writable( $home_path . '.htaccess' ) ) {
   160 	if ( ( ! file_exists( $home_path . '.htaccess' )
       
   161 		&& is_writable( $home_path ) ) || is_writable( $home_path . '.htaccess' )
       
   162 	) {
   155 		$writable = true;
   163 		$writable = true;
   156 	} else {
   164 	} else {
   157 		$writable       = false;
   165 		$writable       = false;
   158 		$existing_rules = array_filter( extract_from_markers( $home_path . '.htaccess', 'WordPress' ) );
   166 		$existing_rules = array_filter( extract_from_markers( $home_path . '.htaccess', 'WordPress' ) );
   159 		$new_rules      = array_filter( explode( "\n", $wp_rewrite->mod_rewrite_rules() ) );
   167 		$new_rules      = array_filter( explode( "\n", $wp_rewrite->mod_rewrite_rules() ) );
   180 					/* translators: %s: web.config */
   188 					/* translators: %s: web.config */
   181 					__( 'Permalink structure updated. Remove write access on %s file now!' ),
   189 					__( 'Permalink structure updated. Remove write access on %s file now!' ),
   182 					'<code>web.config</code>'
   190 					'<code>web.config</code>'
   183 				);
   191 				);
   184 			}
   192 			}
   185 		} elseif ( ! $is_nginx && $htaccess_update_required && ! $writable ) {
   193 		} elseif ( ! $is_nginx && ! $is_caddy && $htaccess_update_required && ! $writable ) {
   186 			$message = sprintf(
   194 			$message = sprintf(
   187 				/* translators: %s: .htaccess */
   195 				/* translators: %s: .htaccess */
   188 				__( 'You should update your %s file now.' ),
   196 				__( 'You should update your %s file now.' ),
   189 				'<code>.htaccess</code>'
   197 				'<code>.htaccess</code>'
   190 			);
   198 			);
   193 
   201 
   194 	if ( ! get_settings_errors() ) {
   202 	if ( ! get_settings_errors() ) {
   195 		add_settings_error( 'general', 'settings_updated', $message, 'success' );
   203 		add_settings_error( 'general', 'settings_updated', $message, 'success' );
   196 	}
   204 	}
   197 
   205 
   198 	set_transient( 'settings_errors', get_settings_errors(), 30 );
   206 	set_transient( 'settings_errors', get_settings_errors(), 30 ); // 30 seconds.
   199 
   207 
   200 	wp_redirect( admin_url( 'options-permalink.php?settings-updated=true' ) );
   208 	wp_redirect( admin_url( 'options-permalink.php?settings-updated=true' ) );
   201 	exit;
   209 	exit;
   202 }
   210 }
   203 
   211 
   209 <h1><?php echo esc_html( $title ); ?></h1>
   217 <h1><?php echo esc_html( $title ); ?></h1>
   210 
   218 
   211 <form name="form" action="options-permalink.php" method="post">
   219 <form name="form" action="options-permalink.php" method="post">
   212 <?php wp_nonce_field( 'update-permalink' ); ?>
   220 <?php wp_nonce_field( 'update-permalink' ); ?>
   213 
   221 
   214 	<p>
   222 <p>
   215 	<?php
       
   216 		printf(
       
   217 			/* translators: %s: Documentation URL. */
       
   218 			__( 'WordPress offers you the ability to create a custom URL structure for your permalinks and archives. Custom URL structures can improve the aesthetics, usability, and forward-compatibility of your links. A <a href="%s">number of tags are available</a>, and here are some examples to get you started.' ),
       
   219 			__( 'https://wordpress.org/support/article/using-permalinks/' )
       
   220 		);
       
   221 		?>
       
   222 	</p>
       
   223 
       
   224 <?php
   223 <?php
   225 if ( is_multisite() && ! is_subdomain_install() && is_main_site() && 0 === strpos( $permalink_structure, '/blog/' ) ) {
   224 printf(
       
   225 	/* translators: %s: Documentation URL. */
       
   226 	__( 'WordPress offers you the ability to create a custom URL structure for your permalinks and archives. Custom URL structures can improve the aesthetics, usability, and forward-compatibility of your links. A <a href="%s">number of tags are available</a>, and here are some examples to get you started.' ),
       
   227 	__( 'https://wordpress.org/documentation/article/customize-permalinks/' )
       
   228 );
       
   229 ?>
       
   230 </p>
       
   231 
       
   232 <?php
       
   233 if ( is_multisite() && ! is_subdomain_install() && is_main_site()
       
   234 	&& str_starts_with( $permalink_structure, '/blog/' )
       
   235 ) {
   226 	$permalink_structure = preg_replace( '|^/?blog|', '', $permalink_structure );
   236 	$permalink_structure = preg_replace( '|^/?blog|', '', $permalink_structure );
   227 	$category_base       = preg_replace( '|^/?blog|', '', $category_base );
   237 	$category_base       = preg_replace( '|^/?blog|', '', $category_base );
   228 	$tag_base            = preg_replace( '|^/?blog|', '', $tag_base );
   238 	$tag_base            = preg_replace( '|^/?blog|', '', $tag_base );
   229 }
   239 }
   230 
   240 
   231 $structures = array(
   241 $url_base = home_url( $blog_prefix . $index_php_prefix );
   232 	0 => '',
   242 
   233 	1 => $prefix . '/%year%/%monthnum%/%day%/%postname%/',
   243 $default_structures = array(
   234 	2 => $prefix . '/%year%/%monthnum%/%postname%/',
   244 	array(
   235 	3 => $prefix . '/' . _x( 'archives', 'sample permalink base' ) . '/%post_id%',
   245 		'id'      => 'plain',
   236 	4 => $prefix . '/%postname%/',
   246 		'label'   => __( 'Plain' ),
   237 );
   247 		'value'   => '',
       
   248 		'example' => home_url( '/?p=123' ),
       
   249 	),
       
   250 	array(
       
   251 		'id'      => 'day-name',
       
   252 		'label'   => __( 'Day and name' ),
       
   253 		'value'   => $index_php_prefix . '/%year%/%monthnum%/%day%/%postname%/',
       
   254 		'example' => $url_base . '/' . gmdate( 'Y/m/d' ) . '/' . _x( 'sample-post', 'sample permalink structure' ) . '/',
       
   255 	),
       
   256 	array(
       
   257 		'id'      => 'month-name',
       
   258 		'label'   => __( 'Month and name' ),
       
   259 		'value'   => $index_php_prefix . '/%year%/%monthnum%/%postname%/',
       
   260 		'example' => $url_base . '/' . gmdate( 'Y/m' ) . '/' . _x( 'sample-post', 'sample permalink structure' ) . '/',
       
   261 	),
       
   262 	array(
       
   263 		'id'      => 'numeric',
       
   264 		'label'   => __( 'Numeric' ),
       
   265 		'value'   => $index_php_prefix . '/' . _x( 'archives', 'sample permalink base' ) . '/%post_id%',
       
   266 		'example' => $url_base . '/' . _x( 'archives', 'sample permalink base' ) . '/123',
       
   267 	),
       
   268 	array(
       
   269 		'id'      => 'post-name',
       
   270 		'label'   => __( 'Post name' ),
       
   271 		'value'   => $index_php_prefix . '/%postname%/',
       
   272 		'example' => $url_base . '/' . _x( 'sample-post', 'sample permalink structure' ) . '/',
       
   273 	),
       
   274 );
       
   275 
       
   276 $default_structure_values = wp_list_pluck( $default_structures, 'value' );
       
   277 
       
   278 $available_tags = array(
       
   279 	/* translators: %s: Permalink structure tag. */
       
   280 	'year'     => __( '%s (The year of the post, four digits, for example 2004.)' ),
       
   281 	/* translators: %s: Permalink structure tag. */
       
   282 	'monthnum' => __( '%s (Month of the year, for example 05.)' ),
       
   283 	/* translators: %s: Permalink structure tag. */
       
   284 	'day'      => __( '%s (Day of the month, for example 28.)' ),
       
   285 	/* translators: %s: Permalink structure tag. */
       
   286 	'hour'     => __( '%s (Hour of the day, for example 15.)' ),
       
   287 	/* translators: %s: Permalink structure tag. */
       
   288 	'minute'   => __( '%s (Minute of the hour, for example 43.)' ),
       
   289 	/* translators: %s: Permalink structure tag. */
       
   290 	'second'   => __( '%s (Second of the minute, for example 33.)' ),
       
   291 	/* translators: %s: Permalink structure tag. */
       
   292 	'post_id'  => __( '%s (The unique ID of the post, for example 423.)' ),
       
   293 	/* translators: %s: Permalink structure tag. */
       
   294 	'postname' => __( '%s (The sanitized post title (slug).)' ),
       
   295 	/* translators: %s: Permalink structure tag. */
       
   296 	'category' => __( '%s (Category slug. Nested sub-categories appear as nested directories in the URL.)' ),
       
   297 	/* translators: %s: Permalink structure tag. */
       
   298 	'author'   => __( '%s (A sanitized version of the author name.)' ),
       
   299 );
       
   300 
       
   301 /**
       
   302  * Filters the list of available permalink structure tags on the Permalinks settings page.
       
   303  *
       
   304  * @since 4.9.0
       
   305  *
       
   306  * @param string[] $available_tags An array of key => value pairs of available permalink structure tags.
       
   307  */
       
   308 $available_tags = apply_filters( 'available_permalink_structure_tags', $available_tags );
       
   309 
       
   310 /* translators: %s: Permalink structure tag. */
       
   311 $tag_added = __( '%s added to permalink structure' );
       
   312 /* translators: %s: Permalink structure tag. */
       
   313 $tag_removed = __( '%s removed from permalink structure' );
       
   314 /* translators: %s: Permalink structure tag. */
       
   315 $tag_already_used = __( '%s (already used in permalink structure)' );
   238 ?>
   316 ?>
   239 <h2 class="title"><?php _e( 'Common Settings' ); ?></h2>
   317 <h2 class="title"><?php _e( 'Common Settings' ); ?></h2>
   240 <table class="form-table permalink-structure">
   318 <p>
       
   319 <?php
       
   320 printf(
       
   321 	/* translators: %s: %postname% */
       
   322 	__( 'Select the permalink structure for your website. Including the %s tag makes links easy to understand, and can help your posts rank higher in search engines.' ),
       
   323 	'<code>%postname%</code>'
       
   324 );
       
   325 ?>
       
   326 </p>
       
   327 <table class="form-table permalink-structure" role="presentation">
       
   328 <tbody>
       
   329 <tr>
       
   330 	<th scope="row"><?php _e( 'Permalink structure' ); ?></th>
       
   331 	<td>
       
   332 		<fieldset class="structure-selection">
       
   333 			<legend class="screen-reader-text">
       
   334 				<?php
       
   335 				/* translators: Hidden accessibility text. */
       
   336 				_e( 'Permalink structure' );
       
   337 				?>
       
   338 			</legend>
       
   339 			<?php foreach ( $default_structures as $input ) : ?>
       
   340 			<div class="row">
       
   341 				<input id="permalink-input-<?php echo esc_attr( $input['id'] ); ?>"
       
   342 					name="selection" aria-describedby="permalink-<?php echo esc_attr( $input['id'] ); ?>"
       
   343 					type="radio" value="<?php echo esc_attr( $input['value'] ); ?>"
       
   344 					<?php checked( $input['value'], $permalink_structure ); ?>
       
   345 				/>
       
   346 				<div>
       
   347 					<label for="permalink-input-<?php echo esc_attr( $input['id'] ); ?>">
       
   348 						<?php echo esc_html( $input['label'] ); ?>
       
   349 					</label>
       
   350 					<p>
       
   351 						<code id="permalink-<?php echo esc_attr( $input['id'] ); ?>">
       
   352 							<?php echo esc_html( $input['example'] ); ?>
       
   353 						</code>
       
   354 					</p>
       
   355 				</div>
       
   356 			</div><!-- .row -->
       
   357 			<?php endforeach; ?>
       
   358 
       
   359 			<div class="row">
       
   360 				<input id="custom_selection"
       
   361 					name="selection" type="radio" value="custom"
       
   362 					<?php checked( ! in_array( $permalink_structure, $default_structure_values, true ) ); ?>
       
   363 				/>
       
   364 				<div>
       
   365 					<label for="custom_selection"><?php _e( 'Custom Structure' ); ?></label>
       
   366 					<p>
       
   367 						<label for="permalink_structure" class="screen-reader-text">
       
   368 							<?php
       
   369 							/* translators: Hidden accessibility text. */
       
   370 							_e( 'Customize permalink structure by selecting available tags' );
       
   371 							?>
       
   372 						</label>
       
   373 						<span class="code">
       
   374 							<code id="permalink-custom"><?php echo esc_url( $url_base ); ?></code>
       
   375 							<input name="permalink_structure" id="permalink_structure"
       
   376 								type="text" value="<?php echo esc_attr( $permalink_structure ); ?>"
       
   377 								aria-describedby="permalink-custom" class="regular-text code"
       
   378 							/>
       
   379 						</span>
       
   380 					</p>
       
   381 
       
   382 					<div class="available-structure-tags hide-if-no-js">
       
   383 						<div id="custom_selection_updated" aria-live="assertive" class="screen-reader-text"></div>
       
   384 						<?php if ( ! empty( $available_tags ) ) : ?>
       
   385 						<fieldset>
       
   386 							<legend><?php _e( 'Available tags:' ); ?></legend>
       
   387 							<ul role="list">
       
   388 							<?php foreach ( $available_tags as $tag => $explanation ) : ?>
       
   389 								<li>
       
   390 									<button type="button"
       
   391 										class="button button-secondary"
       
   392 										aria-label="<?php echo esc_attr( sprintf( $explanation, $tag ) ); ?>"
       
   393 										data-added="<?php echo esc_attr( sprintf( $tag_added, $tag ) ); ?>"
       
   394 										data-removed="<?php echo esc_attr( sprintf( $tag_removed, $tag ) ); ?>"
       
   395 										data-used="<?php echo esc_attr( sprintf( $tag_already_used, $tag ) ); ?>">
       
   396 										<?php echo '%' . esc_html( $tag ) . '%'; ?>
       
   397 									</button>
       
   398 								</li>
       
   399 							<?php endforeach; ?>
       
   400 							</ul>
       
   401 						</fieldset>
       
   402 						<?php endif; ?>
       
   403 					</div><!-- .available-structure-tags -->
       
   404 				</div>
       
   405 			</div><!-- .row -->
       
   406 		</fieldset><!-- .structure-selection -->
       
   407 	</td>
       
   408 </tr>
       
   409 </tbody>
       
   410 </table>
       
   411 
       
   412 <h2 class="title"><?php _e( 'Optional' ); ?></h2>
       
   413 <p>
       
   414 <?php
       
   415 printf(
       
   416 	/* translators: %s: Placeholder that must come at the start of the URL. */
       
   417 	__( 'If you like, you may enter custom structures for your category and tag URLs here. For example, using <code>topics</code> as your category base would make your category links like <code>%s/topics/uncategorized/</code>. If you leave these blank the defaults will be used.' ),
       
   418 	$url_base
       
   419 );
       
   420 ?>
       
   421 </p>
       
   422 
       
   423 <table class="form-table" role="presentation">
   241 	<tr>
   424 	<tr>
   242 		<th scope="row"><label><input name="selection" type="radio" value="" <?php checked( '', $permalink_structure ); ?> /> <?php _e( 'Plain' ); ?></label></th>
   425 		<th>
   243 		<td><code><?php echo get_option( 'home' ); ?>/?p=123</code></td>
   426 			<label for="category_base">
   244 	</tr>
   427 				<?php /* translators: Prefix for category permalinks. */ _e( 'Category base' ); ?>
   245 	<tr>
       
   246 		<th scope="row"><label><input name="selection" type="radio" value="<?php echo esc_attr( $structures[1] ); ?>" <?php checked( $structures[1], $permalink_structure ); ?> /> <?php _e( 'Day and name' ); ?></label></th>
       
   247 		<td><code><?php echo get_option( 'home' ) . $blog_prefix . $prefix . '/' . gmdate( 'Y' ) . '/' . gmdate( 'm' ) . '/' . gmdate( 'd' ) . '/' . _x( 'sample-post', 'sample permalink structure' ) . '/'; ?></code></td>
       
   248 	</tr>
       
   249 	<tr>
       
   250 		<th scope="row"><label><input name="selection" type="radio" value="<?php echo esc_attr( $structures[2] ); ?>" <?php checked( $structures[2], $permalink_structure ); ?> /> <?php _e( 'Month and name' ); ?></label></th>
       
   251 		<td><code><?php echo get_option( 'home' ) . $blog_prefix . $prefix . '/' . gmdate( 'Y' ) . '/' . gmdate( 'm' ) . '/' . _x( 'sample-post', 'sample permalink structure' ) . '/'; ?></code></td>
       
   252 	</tr>
       
   253 	<tr>
       
   254 		<th scope="row"><label><input name="selection" type="radio" value="<?php echo esc_attr( $structures[3] ); ?>" <?php checked( $structures[3], $permalink_structure ); ?> /> <?php _e( 'Numeric' ); ?></label></th>
       
   255 		<td><code><?php echo get_option( 'home' ) . $blog_prefix . $prefix . '/' . _x( 'archives', 'sample permalink base' ) . '/123'; ?></code></td>
       
   256 	</tr>
       
   257 	<tr>
       
   258 		<th scope="row"><label><input name="selection" type="radio" value="<?php echo esc_attr( $structures[4] ); ?>" <?php checked( $structures[4], $permalink_structure ); ?> /> <?php _e( 'Post name' ); ?></label></th>
       
   259 		<td><code><?php echo get_option( 'home' ) . $blog_prefix . $prefix . '/' . _x( 'sample-post', 'sample permalink structure' ) . '/'; ?></code></td>
       
   260 	</tr>
       
   261 	<tr>
       
   262 		<th scope="row">
       
   263 			<label><input name="selection" id="custom_selection" type="radio" value="custom" <?php checked( ! in_array( $permalink_structure, $structures, true ) ); ?> />
       
   264 			<?php _e( 'Custom Structure' ); ?>
       
   265 			</label>
   428 			</label>
   266 		</th>
   429 		</th>
   267 		<td>
   430 		<td>
   268 			<code><?php echo get_option( 'home' ) . $blog_prefix; ?></code>
   431 			<?php echo $blog_prefix; ?>
   269 			<input name="permalink_structure" id="permalink_structure" type="text" value="<?php echo esc_attr( $permalink_structure ); ?>" class="regular-text code" />
   432 			<input name="category_base" id="category_base" type="text"
   270 			<div class="available-structure-tags hide-if-no-js">
   433 				value="<?php echo esc_attr( $category_base ); ?>" class="regular-text code"
   271 				<div id="custom_selection_updated" aria-live="assertive" class="screen-reader-text"></div>
   434 			/>
   272 				<?php
       
   273 				$available_tags = array(
       
   274 					/* translators: %s: Permalink structure tag. */
       
   275 					'year'     => __( '%s (The year of the post, four digits, for example 2004.)' ),
       
   276 					/* translators: %s: Permalink structure tag. */
       
   277 					'monthnum' => __( '%s (Month of the year, for example 05.)' ),
       
   278 					/* translators: %s: Permalink structure tag. */
       
   279 					'day'      => __( '%s (Day of the month, for example 28.)' ),
       
   280 					/* translators: %s: Permalink structure tag. */
       
   281 					'hour'     => __( '%s (Hour of the day, for example 15.)' ),
       
   282 					/* translators: %s: Permalink structure tag. */
       
   283 					'minute'   => __( '%s (Minute of the hour, for example 43.)' ),
       
   284 					/* translators: %s: Permalink structure tag. */
       
   285 					'second'   => __( '%s (Second of the minute, for example 33.)' ),
       
   286 					/* translators: %s: Permalink structure tag. */
       
   287 					'post_id'  => __( '%s (The unique ID of the post, for example 423.)' ),
       
   288 					/* translators: %s: Permalink structure tag. */
       
   289 					'postname' => __( '%s (The sanitized post title (slug).)' ),
       
   290 					/* translators: %s: Permalink structure tag. */
       
   291 					'category' => __( '%s (Category slug. Nested sub-categories appear as nested directories in the URL.)' ),
       
   292 					/* translators: %s: Permalink structure tag. */
       
   293 					'author'   => __( '%s (A sanitized version of the author name.)' ),
       
   294 				);
       
   295 
       
   296 				/**
       
   297 				 * Filters the list of available permalink structure tags on the Permalinks settings page.
       
   298 				 *
       
   299 				 * @since 4.9.0
       
   300 				 *
       
   301 				 * @param string[] $available_tags An array of key => value pairs of available permalink structure tags.
       
   302 				 */
       
   303 				$available_tags = apply_filters( 'available_permalink_structure_tags', $available_tags );
       
   304 
       
   305 				/* translators: %s: Permalink structure tag. */
       
   306 				$structure_tag_added = __( '%s added to permalink structure' );
       
   307 
       
   308 				/* translators: %s: Permalink structure tag. */
       
   309 				$structure_tag_already_used = __( '%s (already used in permalink structure)' );
       
   310 
       
   311 				if ( ! empty( $available_tags ) ) :
       
   312 					?>
       
   313 					<p><?php _e( 'Available tags:' ); ?></p>
       
   314 					<ul role="list">
       
   315 						<?php
       
   316 						foreach ( $available_tags as $tag => $explanation ) {
       
   317 							?>
       
   318 							<li>
       
   319 								<button type="button"
       
   320 										class="button button-secondary"
       
   321 										aria-label="<?php echo esc_attr( sprintf( $explanation, $tag ) ); ?>"
       
   322 										data-added="<?php echo esc_attr( sprintf( $structure_tag_added, $tag ) ); ?>"
       
   323 										data-used="<?php echo esc_attr( sprintf( $structure_tag_already_used, $tag ) ); ?>">
       
   324 									<?php echo '%' . $tag . '%'; ?>
       
   325 								</button>
       
   326 							</li>
       
   327 							<?php
       
   328 						}
       
   329 						?>
       
   330 					</ul>
       
   331 				<?php endif; ?>
       
   332 			</div>
       
   333 		</td>
   435 		</td>
   334 	</tr>
   436 	</tr>
   335 </table>
       
   336 
       
   337 <h2 class="title"><?php _e( 'Optional' ); ?></h2>
       
   338 <p>
       
   339 <?php
       
   340 /* translators: %s: Placeholder that must come at the start of the URL. */
       
   341 printf( __( 'If you like, you may enter custom structures for your category and tag URLs here. For example, using <code>topics</code> as your category base would make your category links like <code>%s/topics/uncategorized/</code>. If you leave these blank the defaults will be used.' ), get_option( 'home' ) . $blog_prefix . $prefix );
       
   342 ?>
       
   343 </p>
       
   344 
       
   345 <table class="form-table" role="presentation">
       
   346 	<tr>
   437 	<tr>
   347 		<th><label for="category_base"><?php /* translators: Prefix for category permalinks. */ _e( 'Category base' ); ?></label></th>
   438 		<th>
   348 		<td><?php echo $blog_prefix; ?> <input name="category_base" id="category_base" type="text" value="<?php echo esc_attr( $category_base ); ?>" class="regular-text code" /></td>
   439 			<label for="tag_base"><?php _e( 'Tag base' ); ?></label>
   349 	</tr>
   440 		</th>
   350 	<tr>
   441 		<td>
   351 		<th><label for="tag_base"><?php _e( 'Tag base' ); ?></label></th>
   442 			<?php echo $blog_prefix; ?>
   352 		<td><?php echo $blog_prefix; ?> <input name="tag_base" id="tag_base" type="text" value="<?php echo esc_attr( $tag_base ); ?>" class="regular-text code" /></td>
   443 			<input name="tag_base" id="tag_base" type="text"
       
   444 				value="<?php echo esc_attr( $tag_base ); ?>" class="regular-text code"
       
   445 			/>
       
   446 		</td>
   353 	</tr>
   447 	</tr>
   354 	<?php do_settings_fields( 'permalink', 'optional' ); ?>
   448 	<?php do_settings_fields( 'permalink', 'optional' ); ?>
   355 </table>
   449 </table>
   356 
   450 
   357 <?php do_settings_sections( 'permalink' ); ?>
   451 <?php do_settings_sections( 'permalink' ); ?>
   358 
   452 
   359 <?php submit_button(); ?>
   453 <?php submit_button(); ?>
   360 </form>
   454 </form>
   361 <?php if ( ! is_multisite() ) { ?>
   455 
       
   456 <?php if ( ! is_multisite() ) : ?>
   362 	<?php
   457 	<?php
   363 	if ( $iis7_permalinks ) :
   458 	if ( $iis7_permalinks ) :
   364 		if ( isset( $_POST['submit'] ) && $permalink_structure && ! $using_index_permalinks && ! $writable ) :
   459 		if ( isset( $_POST['submit'] ) && $permalink_structure && ! $using_index_permalinks && ! $writable ) :
   365 			if ( file_exists( $home_path . 'web.config' ) ) :
   460 			if ( file_exists( $home_path . 'web.config' ) ) :
   366 				?>
   461 				?>
   367 <p id="iis-description-a">
   462 				<p id="iis-description-a">
   368 				<?php
   463 				<?php
   369 				printf(
   464 				printf(
   370 					/* translators: 1: web.config, 2: Documentation URL, 3: Ctrl + A, 4: ⌘ + A, 5: Element code. */
   465 					/* translators: 1: web.config, 2: Documentation URL, 3: Ctrl + A, 4: ⌘ + A, 5: Element code. */
   371 					__( '<strong>Error:</strong> Your %1$s file is not <a href="%2$s">writable</a>, so updating it automatically was not possible. This is the URL rewrite rule you should have in your %1$s file. Click in the field and press %3$s (or %4$s on Mac) to select all. Then insert this rule inside of the %5$s element in %1$s file.' ),
   466 					__( '<strong>Error:</strong> Your %1$s file is not <a href="%2$s">writable</a>, so updating it automatically was not possible. This is the URL rewrite rule you should have in your %1$s file. Click in the field and press %3$s (or %4$s on Mac) to select all. Then insert this rule inside of the %5$s element in %1$s file.' ),
   372 					'<code>web.config</code>',
   467 					'<code>web.config</code>',
   373 					__( 'https://wordpress.org/support/article/changing-file-permissions/' ),
   468 					__( 'https://developer.wordpress.org/advanced-administration/server/file-permissions/' ),
   374 					'<kbd>Ctrl + A</kbd>',
   469 					'<kbd>Ctrl + A</kbd>',
   375 					'<kbd>⌘ + A</kbd>',
   470 					'<kbd>⌘ + A</kbd>',
   376 					'<code>/&lt;configuration&gt;/&lt;system.webServer&gt;/&lt;rewrite&gt;/&lt;rules&gt;</code>'
   471 					'<code>/&lt;configuration&gt;/&lt;system.webServer&gt;/&lt;rewrite&gt;/&lt;rules&gt;</code>'
   377 				);
   472 				);
   378 				?>
   473 				?>
   379 </p>
   474 				</p>
   380 <form action="options-permalink.php" method="post">
   475 				<form action="options-permalink.php" method="post">
   381 				<?php wp_nonce_field( 'update-permalink' ); ?>
   476 					<?php wp_nonce_field( 'update-permalink' ); ?>
   382 	<p><label for="rules"><?php _e( 'Rewrite rules:' ); ?></label><br /><textarea rows="9" class="large-text readonly" name="rules" id="rules" readonly="readonly" aria-describedby="iis-description-a"><?php echo esc_textarea( $wp_rewrite->iis7_url_rewrite_rules() ); ?></textarea></p>
   477 					<p>
   383 </form>
   478 						<label for="rules"><?php _e( 'Rewrite rules:' ); ?></label><br />
   384 <p>
   479 						<textarea rows="9" class="large-text readonly"
       
   480 							name="rules" id="rules" readonly="readonly"
       
   481 							aria-describedby="iis-description-a"
       
   482 						><?php echo esc_textarea( $wp_rewrite->iis7_url_rewrite_rules() ); ?></textarea>
       
   483 					</p>
       
   484 				</form>
       
   485 				<p>
   385 				<?php
   486 				<?php
   386 				printf(
   487 				printf(
   387 					/* translators: %s: web.config */
   488 					/* translators: %s: web.config */
   388 					__( 'If you temporarily make your %s file writable to generate rewrite rules automatically, do not forget to revert the permissions after the rule has been saved.' ),
   489 					__( 'If you temporarily make your %s file writable to generate rewrite rules automatically, do not forget to revert the permissions after the rule has been saved.' ),
   389 					'<code>web.config</code>'
   490 					'<code>web.config</code>'
   390 				);
   491 				);
   391 				?>
   492 				?>
   392 </p>
   493 				</p>
   393 		<?php else : ?>
   494 			<?php else : ?>
   394 <p id="iis-description-b">
   495 				<p id="iis-description-b">
       
   496 				<?php
       
   497 				printf(
       
   498 					/* translators: 1: Documentation URL, 2: web.config, 3: Ctrl + A, 4: ⌘ + A */
       
   499 					__( '<strong>Error:</strong> The root directory of your site is not <a href="%1$s">writable</a>, so creating a file automatically was not possible. This is the URL rewrite rule you should have in your %2$s file. Create a new file called %2$s in the root directory of your site. Click in the field and press %3$s (or %4$s on Mac) to select all. Then insert this code into the %2$s file.' ),
       
   500 					__( 'https://developer.wordpress.org/advanced-administration/server/file-permissions/' ),
       
   501 					'<code>web.config</code>',
       
   502 					'<kbd>Ctrl + A</kbd>',
       
   503 					'<kbd>⌘ + A</kbd>'
       
   504 				);
       
   505 				?>
       
   506 				</p>
       
   507 				<form action="options-permalink.php" method="post">
       
   508 					<?php wp_nonce_field( 'update-permalink' ); ?>
       
   509 					<p>
       
   510 						<label for="rules"><?php _e( 'Rewrite rules:' ); ?></label><br />
       
   511 						<textarea rows="18" class="large-text readonly"
       
   512 							name="rules" id="rules" readonly="readonly"
       
   513 							aria-describedby="iis-description-b"
       
   514 						><?php echo esc_textarea( $wp_rewrite->iis7_url_rewrite_rules( true ) ); ?></textarea>
       
   515 					</p>
       
   516 				</form>
       
   517 				<p>
       
   518 				<?php
       
   519 				printf(
       
   520 					/* translators: %s: web.config */
       
   521 					__( 'If you temporarily make your site&#8217;s root directory writable to generate the %s file automatically, do not forget to revert the permissions after the file has been created.' ),
       
   522 					'<code>web.config</code>'
       
   523 				);
       
   524 				?>
       
   525 				</p>
       
   526 			<?php endif; // End if 'web.config' exists. ?>
       
   527 		<?php endif; // End if $_POST['submit'] && ! $writable. ?>
       
   528 	<?php else : ?>
       
   529 		<?php if ( $permalink_structure && ! $using_index_permalinks && ! $writable && $htaccess_update_required ) : ?>
       
   530 			<p id="htaccess-description">
   395 			<?php
   531 			<?php
   396 			printf(
   532 			printf(
   397 				/* translators: 1: Documentation URL, 2: web.config, 3: Ctrl + A, 4: ⌘ + A */
   533 				/* translators: 1: .htaccess, 2: Documentation URL, 3: Ctrl + A, 4: ⌘ + A */
   398 				__( '<strong>Error:</strong> The root directory of your site is not <a href="%1$s">writable</a>, so creating a file automatically was not possible. This is the URL rewrite rule you should have in your %2$s file. Create a new file called %2$s in the root directory of your site. Click in the field and press %3$s (or %4$s on Mac) to select all. Then insert this code into the %2$s file.' ),
   534 				__( '<strong>Error:</strong> Your %1$s file is not <a href="%2$s">writable</a>, so updating it automatically was not possible. These are the mod_rewrite rules you should have in your %1$s file. Click in the field and press %3$s (or %4$s on Mac) to select all.' ),
   399 				__( 'https://wordpress.org/support/article/changing-file-permissions/' ),
   535 				'<code>.htaccess</code>',
   400 				'<code>web.config</code>',
   536 				__( 'https://developer.wordpress.org/advanced-administration/server/file-permissions/' ),
   401 				'<kbd>Ctrl + A</kbd>',
   537 				'<kbd>Ctrl + A</kbd>',
   402 				'<kbd>⌘ + A</kbd>'
   538 				'<kbd>⌘ + A</kbd>'
   403 			);
   539 			);
   404 			?>
   540 			?>
   405 </p>
   541 			</p>
   406 <form action="options-permalink.php" method="post">
   542 			<form action="options-permalink.php" method="post">
   407 			<?php wp_nonce_field( 'update-permalink' ); ?>
   543 				<?php wp_nonce_field( 'update-permalink' ); ?>
   408 	<p><label for="rules"><?php _e( 'Rewrite rules:' ); ?></label><br /><textarea rows="18" class="large-text readonly" name="rules" id="rules" readonly="readonly" aria-describedby="iis-description-b"><?php echo esc_textarea( $wp_rewrite->iis7_url_rewrite_rules( true ) ); ?></textarea></p>
   544 				<p>
   409 </form>
   545 					<label for="rules"><?php _e( 'Rewrite rules:' ); ?></label><br />
   410 <p>
   546 					<textarea rows="8" class="large-text readonly"
   411 			<?php
   547 						name="rules" id="rules" readonly="readonly"
   412 			printf(
   548 						aria-describedby="htaccess-description"
   413 				/* translators: %s: web.config */
   549 					><?php echo esc_textarea( $wp_rewrite->mod_rewrite_rules() ); ?></textarea>
   414 				__( 'If you temporarily make your site&#8217;s root directory writable to generate the %s file automatically, do not forget to revert the permissions after the file has been created.' ),
   550 				</p>
   415 				'<code>web.config</code>'
   551 			</form>
   416 			);
   552 		<?php endif; // End if ! $writable && $htaccess_update_required. ?>
   417 			?>
   553 	<?php endif; // End if $iis7_permalinks. ?>
   418 </p>
   554 <?php endif; // End if ! is_multisite(). ?>
   419 		<?php endif; ?>
   555 
   420 	<?php endif; ?>
   556 </div><!-- .wrap -->
   421 		<?php
       
   422 else :
       
   423 	if ( $permalink_structure && ! $using_index_permalinks && ! $writable && $htaccess_update_required ) :
       
   424 		?>
       
   425 <p id="htaccess-description">
       
   426 		<?php
       
   427 		printf(
       
   428 			/* translators: 1: .htaccess, 2: Documentation URL, 3: Ctrl + A, 4: ⌘ + A */
       
   429 			__( '<strong>Error:</strong> Your %1$s file is not <a href="%2$s">writable</a>, so updating it automatically was not possible. These are the mod_rewrite rules you should have in your %1$s file. Click in the field and press %3$s (or %4$s on Mac) to select all.' ),
       
   430 			'<code>.htaccess</code>',
       
   431 			__( 'https://wordpress.org/support/article/changing-file-permissions/' ),
       
   432 			'<kbd>Ctrl + A</kbd>',
       
   433 			'<kbd>⌘ + A</kbd>'
       
   434 		);
       
   435 		?>
       
   436 </p>
       
   437 <form action="options-permalink.php" method="post">
       
   438 		<?php wp_nonce_field( 'update-permalink' ); ?>
       
   439 	<p><label for="rules"><?php _e( 'Rewrite rules:' ); ?></label><br /><textarea rows="8" class="large-text readonly" name="rules" id="rules" readonly="readonly" aria-describedby="htaccess-description"><?php echo esc_textarea( $wp_rewrite->mod_rewrite_rules() ); ?></textarea></p>
       
   440 </form>
       
   441 	<?php endif; ?>
       
   442 <?php endif; ?>
       
   443 <?php } // End if ! is_multisite(). ?>
       
   444 
       
   445 </div>
       
   446 
   557 
   447 <?php require_once ABSPATH . 'wp-admin/admin-footer.php'; ?>
   558 <?php require_once ABSPATH . 'wp-admin/admin-footer.php'; ?>