From 1144256540046c8fef7c9bda5714e4fba00cfe9d Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Tue, 6 Jan 2026 15:04:35 -0700 Subject: [PATCH 1/7] feat: add support for displaying tags as labels --- includes/class-newspack.php | 3 + includes/tag-labels/class-tag-labels.php | 202 +++++++++++++++++++++++ src/other-scripts/tag-labels/index.js | 11 ++ 3 files changed, 216 insertions(+) create mode 100644 includes/tag-labels/class-tag-labels.php create mode 100644 src/other-scripts/tag-labels/index.js diff --git a/includes/class-newspack.php b/includes/class-newspack.php index 26aab9a957..47d50e65af 100644 --- a/includes/class-newspack.php +++ b/includes/class-newspack.php @@ -235,6 +235,9 @@ private function includes() { // Filter by authors in the Posts page. include_once NEWSPACK_ABSPATH . 'includes/author-filter/class-author-filter.php'; + // Display tags as labels. + include_once NEWSPACK_ABSPATH . 'includes/tag-labels/class-tag-labels.php'; + // Load the general Newspack UI front-end styles. include_once NEWSPACK_ABSPATH . 'includes/class-newspack-ui.php'; include_once NEWSPACK_ABSPATH . 'includes/class-newspack-ui-icons.php'; diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php new file mode 100644 index 0000000000..99350125ce --- /dev/null +++ b/includes/tag-labels/class-tag-labels.php @@ -0,0 +1,202 @@ +term_id ) { + return false; + } + return (bool) ( true == get_term_meta( $term->term_id, self::TAG_LABEL_META_KEY, true ) ); + } + + /** + * Given a term, return the flag (text) of its label and + * the link to the term archive. + * + * Will return null if label isn't enabled for the term. + * + * @param WP_Term $term Term to check. + * + * @return array|null As ['flag' => FLAG_NAME, 'link' => TERM_LINK]. + */ + public static function get_tag_label_for_term( $term ) { + if ( ! $term || ! $term->term_id || ! self::is_tag_label( $term ) ) { + return null; + } + + // A little fancy in case someone wants to give a tag a + // falsy label flag. Empty string still gets default value. + $term_label_flag = get_term_meta( $term->term_id, self::TAG_LABEL_FLAG_META_KEY, true ); + $term_label_flag = isset( $term_label_flag ) ? ( ( '' !== $term_label_flag ) ? $term_label_flag : $term->name ) : $term->name; + + $term_label_link = get_term_link( $term->term_id ); + + return [ + 'flag' => $term_label_flag, + 'link' => $term_label_link, + ]; + } + + /** + * Given a post ID, grab array of tag labels (if any) for it. + * + * @param int $post_id Post ID. + * + * @return array Elements as ['flag' => FLAG_NAME, 'link' => TERM_LINK]. + */ + public static function get_labels_for_post( $post_id ) { + $post_terms = get_the_terms( $post_id, 'post_tag' ); + + if ( ! $post_terms ) { + return []; + } + + return array_filter( + array_map( + function( $term ) { + return self::get_tag_label_for_term( $term ); + }, + $post_terms + ) + ); + } + + /** + * Initialize hooks. + */ + public static function init() { + add_action( 'post_tag_term_edit_form_top', array( __CLASS__, 'enqueue_scripts' ) ); + + add_action( 'post_tag_edit_form_fields', [ __CLASS__, 'edit_term' ] ); + add_action( 'edited_post_tag', [ __CLASS__, 'save_term' ] ); + } + + /** + * Enqueues js script + * + * @return void + */ + public static function enqueue_scripts() { + wp_enqueue_script( + 'newspack_tag_labels', + Newspack::plugin_url() . '/dist/other-scripts/tag-labels.js', + [ 'jquery' ], + NEWSPACK_PLUGIN_VERSION, + true + ); + } + + /** + * Add term edit fields. + * + * Toggle to determine if the term is a label. + * Also, override for flag (text used on label). + * + * @param WP_Term $term The current WP_Term object. + */ + public static function edit_term( $term ) { + $is_label = self::is_tag_label( $term ); + + $label = self::get_tag_label_for_term( $term ); + $label_flag = $label ? $label['flag'] : $term->name; + ?> + + + + + > +

+ +

+ + + + + + name === $label_flag ) { + echo ' value=""'; + } else { + echo ' value="' . esc_attr( $label_flag ) . '"'; + } + + if ( ! $is_label ) { + echo ' disabled'; } + ?> + > +

+ +

+ + + Date: Thu, 8 Jan 2026 13:31:12 -0700 Subject: [PATCH 2/7] fix: apply suggestions from Copilot code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- includes/tag-labels/class-tag-labels.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php index 99350125ce..a02d21ae96 100644 --- a/includes/tag-labels/class-tag-labels.php +++ b/includes/tag-labels/class-tag-labels.php @@ -24,7 +24,7 @@ class Tag_Labels { const TAG_LABEL_FLAG_META_KEY = '_label_flag'; - // TODO: Helper functions for themes to get array of labels + flags. + // Helper functions for themes to get arrays of labels and flags. /** * Given a term, check if labels are enabled for it. * @@ -36,7 +36,7 @@ public static function is_tag_label( $term ) { if ( ! $term || ! $term->term_id ) { return false; } - return (bool) ( true == get_term_meta( $term->term_id, self::TAG_LABEL_META_KEY, true ) ); + return (bool) ( true === get_term_meta( $term->term_id, self::TAG_LABEL_META_KEY, true ) ); } /** @@ -57,7 +57,9 @@ public static function get_tag_label_for_term( $term ) { // A little fancy in case someone wants to give a tag a // falsy label flag. Empty string still gets default value. $term_label_flag = get_term_meta( $term->term_id, self::TAG_LABEL_FLAG_META_KEY, true ); - $term_label_flag = isset( $term_label_flag ) ? ( ( '' !== $term_label_flag ) ? $term_label_flag : $term->name ) : $term->name; + if ( ! isset( $term_label_flag ) || '' === $term_label_flag ) { + $term_label_flag = $term->name; + } $term_label_link = get_term_link( $term->term_id ); @@ -86,8 +88,8 @@ public static function get_labels_for_post( $post_id ) { function( $term ) { return self::get_tag_label_for_term( $term ); }, - $post_terms - ) + $post_terms + ) ); } From 0fe60fb10fdf8f7f1fc211670db676d98ac09034 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Thu, 8 Jan 2026 14:42:52 -0700 Subject: [PATCH 3/7] fix: cleanup; Copilot suggestions --- includes/tag-labels/class-tag-labels.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php index a02d21ae96..599a2f8272 100644 --- a/includes/tag-labels/class-tag-labels.php +++ b/includes/tag-labels/class-tag-labels.php @@ -127,17 +127,21 @@ public static function enqueue_scripts() { * @param WP_Term $term The current WP_Term object. */ public static function edit_term( $term ) { + $checkbox_id = self::TAG_LABEL_META_KEY; $is_label = self::is_tag_label( $term ); $label = self::get_tag_label_for_term( $term ); $label_flag = $label ? $label['flag'] : $term->name; + + $input_label_flag = ( $term->name === $label_flag ) ? '' : $label_flag; ?> name === $label_flag ) { - echo ' value=""'; - } else { - echo ' value="' . esc_attr( $label_flag ) . '"'; - } - if ( ! $is_label ) { echo ' disabled'; } ?> @@ -184,6 +184,9 @@ public static function save_term( $term_id ) { // See wp-admin/edit-tag-form.php for where this is set. check_admin_referer( 'update-tag_' . $term_id ); + if ( ! current_user_can( 'edit_term', $term_id ) ) { + return; } + // Save label data if label is enabled; otherwise kill it. if ( ! empty( $_POST[ self::TAG_LABEL_META_KEY ] ) ) { update_term_meta( $term_id, self::TAG_LABEL_META_KEY, true ); From 36e8403906f356c622cf2f4b8eb88b0a5377d43e Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Thu, 8 Jan 2026 15:00:44 -0700 Subject: [PATCH 4/7] fix: tweaks; Copilot suggestions --- includes/tag-labels/class-tag-labels.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php index 599a2f8272..ae72daa113 100644 --- a/includes/tag-labels/class-tag-labels.php +++ b/includes/tag-labels/class-tag-labels.php @@ -36,7 +36,7 @@ public static function is_tag_label( $term ) { if ( ! $term || ! $term->term_id ) { return false; } - return (bool) ( true === get_term_meta( $term->term_id, self::TAG_LABEL_META_KEY, true ) ); + return (bool) ( true == get_term_meta( $term->term_id, self::TAG_LABEL_META_KEY, true ) ); // Meta value is 1 when enabled; use less-strict equivalence here. } /** @@ -185,7 +185,8 @@ public static function save_term( $term_id ) { check_admin_referer( 'update-tag_' . $term_id ); if ( ! current_user_can( 'edit_term', $term_id ) ) { - return; } + return; + } // Save label data if label is enabled; otherwise kill it. if ( ! empty( $_POST[ self::TAG_LABEL_META_KEY ] ) ) { From 2b427beae1341ed2b4f5b54be60bda8520f1f0ba Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Fri, 9 Jan 2026 10:42:43 -0700 Subject: [PATCH 5/7] chore: clean up comments --- includes/tag-labels/class-tag-labels.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php index ae72daa113..d5c3070002 100644 --- a/includes/tag-labels/class-tag-labels.php +++ b/includes/tag-labels/class-tag-labels.php @@ -7,8 +7,6 @@ namespace Newspack; -// TODO: Semaphore to only init once. - defined( 'ABSPATH' ) || exit; /** From 25214593507568213aa22c97565a4eb717bcbfc0 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Tue, 13 Jan 2026 13:55:39 -0700 Subject: [PATCH 6/7] fix: incorporate feedback on names, outdated variables --- includes/tag-labels/class-tag-labels.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php index d5c3070002..8b8ad97daa 100644 --- a/includes/tag-labels/class-tag-labels.php +++ b/includes/tag-labels/class-tag-labels.php @@ -17,9 +17,8 @@ class Tag_Labels { /** * Key names. */ - const TAG_LABEL_SLUG = 'label'; - const TAG_LABEL_META_KEY = '_label_enabled'; - const TAG_LABEL_FLAG_META_KEY = '_label_flag'; + const TAG_LABEL_META_KEY = '_np_label_enabled'; + const TAG_LABEL_FLAG_META_KEY = '_np_label_flag'; // Helper functions for themes to get arrays of labels and flags. @@ -34,7 +33,7 @@ public static function is_tag_label( $term ) { if ( ! $term || ! $term->term_id ) { return false; } - return (bool) ( true == get_term_meta( $term->term_id, self::TAG_LABEL_META_KEY, true ) ); // Meta value is 1 when enabled; use less-strict equivalence here. + return ! empty( get_term_meta( $term->term_id, self::TAG_LABEL_META_KEY, true ) ); } /** From ae531b4acba72d0848c87327773df91d5a4e06c0 Mon Sep 17 00:00:00 2001 From: Thomas Guillot Date: Fri, 16 Jan 2026 11:12:53 +0000 Subject: [PATCH 7/7] feat: rename settings; display flag_meta_key only if checkbox is checked --- includes/tag-labels/class-tag-labels.php | 10 +++++----- src/other-scripts/tag-labels/index.js | 21 ++++++++++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php index 8b8ad97daa..68417bf626 100644 --- a/includes/tag-labels/class-tag-labels.php +++ b/includes/tag-labels/class-tag-labels.php @@ -133,7 +133,7 @@ public static function edit_term( $term ) { $input_label_flag = ( $term->name === $label_flag ) ? '' : $label_flag; ?> - + >

- +

- - + > + >

- +

diff --git a/src/other-scripts/tag-labels/index.js b/src/other-scripts/tag-labels/index.js index 57f1d374b1..c320a2fc06 100644 --- a/src/other-scripts/tag-labels/index.js +++ b/src/other-scripts/tag-labels/index.js @@ -1,11 +1,22 @@ /* globals jQuery */ ( function ( $ ) { - $( '.newspack-label-enable input[type="checkbox"]' ).on( 'change', function () { - if ( $( this ).is( ':checked' ) ) { - $( '.newspack-label-setting input' ).prop( 'disabled', false ); + function toggleLabelSetting() { + const checkbox = $( '.newspack-label-enable input[type="checkbox"]' ); + const labelSettingRow = $( '.newspack-label-setting' ); + + if ( checkbox.is( ':checked' ) ) { + labelSettingRow.show(); + labelSettingRow.find( 'input' ).prop( 'disabled', false ); } else { - $( '.newspack-label-setting input' ).prop( 'disabled', true ); + labelSettingRow.hide(); + labelSettingRow.find( 'input' ).prop( 'disabled', true ); } - } ); + } + + // Set initial state on page load. + toggleLabelSetting(); + + // Update on checkbox change. + $( '.newspack-label-enable input[type="checkbox"]' ).on( 'change', toggleLabelSetting ); } )( jQuery );