WC_Admin_Attributes::slug_byte_counter_scriptprivate staticWC 1.0

Output an inline script that shows a live UTF-8 byte count next to the slug input and visually warns when the value approaches or exceeds the server-side byte limit.

The HTML maxlength attribute counts characters, not bytes, so a multibyte slug (e.g. Cyrillic, Chinese) can pass the browser's guard and still be rejected by register_taxonomy()s 32-byte name limit. This counter closes that feedback gap before submission.

Method of the class: WC_Admin_Attributes{}

No Hooks.

Returns

null. Nothing (null).

Usage

$result = WC_Admin_Attributes::slug_byte_counter_script(): void;

WC_Admin_Attributes::slug_byte_counter_script() code WC 11.0.1

<?php
private static function slug_byte_counter_script(): void {
	$max_bytes = wc_get_attribute_slug_max_byte_length();
	/* translators: 1: current byte count, 2: maximum allowed bytes. */
	$template = wp_json_encode( __( '%1$d / %2$d bytes', 'woocommerce' ), JSON_HEX_TAG | JSON_HEX_AMP );
	if ( false === $template ) {
		// Encoding the counter template failed (e.g. invalid UTF-8 in the translated
		// string); skip the counter rather than emit broken inline JavaScript.
		return;
	}
	?>
	<script type="text/javascript">
		( function() {
			var input = document.getElementById( 'attribute_name' );
			if ( ! input || ! ( 'TextEncoder' in window ) ) {
				return;
			}
			var wrapper = input.closest( 'td, .form-field' );
			var description = wrapper ? wrapper.querySelector( 'p.description' ) : null;
			if ( ! description ) {
				return;
			}
			var maxBytes = <?php echo (int) $max_bytes; ?>;
			var template = <?php echo $template; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wp_json_encode with JSON_HEX_TAG produces JS-safe output. ?>;
			var encoder = new TextEncoder();
			var counter = document.createElement( 'span' );
			counter.style.display = 'block';
			counter.style.marginTop = '4px';
			description.appendChild( counter );
			function update() {
				var bytes = encoder.encode( input.value ).length;
				if ( 0 === bytes ) {
					counter.textContent = '';
					counter.style.color = '';
					return;
				}
				counter.textContent = template
					.replace( '%1$d', bytes )
					.replace( '%2$d', maxBytes );
				if ( bytes > maxBytes ) {
					counter.style.color = '#d63638';
				} else if ( bytes >= maxBytes - 3 ) {
					// Within one multibyte character (up to 3 bytes) of the limit.
					counter.style.color = '#996800';
				} else {
					counter.style.color = '';
				}
			}
			input.addEventListener( 'input', update );
			update();
		} )();
	</script>
	<?php
}