From 1144256540046c8fef7c9bda5714e4fba00cfe9d Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Tue, 6 Jan 2026 15:04:35 -0700
Subject: [PATCH 01/23] 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 02/23] 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 03/23] 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 04/23] 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 05/23] 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 06/23] 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 07/23] 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 );
From 75786a1b5ba873d235da57637259dc46fcdcaa63 Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Tue, 20 Jan 2026 16:12:19 -0700
Subject: [PATCH 08/23] refactor: accept WP_Post object or post ID, as is done
elsewhere
---
includes/tag-labels/class-tag-labels.php | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index 68417bf626..3735383250 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -69,11 +69,16 @@ public static function get_tag_label_for_term( $term ) {
/**
* Given a post ID, grab array of tag labels (if any) for it.
*
- * @param int $post_id Post ID.
+ * @param int|WP_Post|null $post Post to check.
*
- * @return array Elements as ['flag' => FLAG_NAME, 'link' => TERM_LINK].
+ * @return array|null Elements as ['flag' => FLAG_NAME, 'link' => TERM_LINK].
*/
- public static function get_labels_for_post( $post_id ) {
+ public static function get_labels_for_post( $post ) {
+ if ( ! $post ) {
+ return null;
+ }
+
+ $post_id = ( is_a( 'WP_POST', $post ) ? $post->ID : (int) $post );
$post_terms = get_the_terms( $post_id, 'post_tag' );
if ( ! $post_terms ) {
From 62cd9c7b598ca87e9553e8349c6bc4c17641e069 Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Thu, 22 Jan 2026 15:35:40 -0700
Subject: [PATCH 09/23] feat: add support for setting tag labels on term
creation
---
includes/tag-labels/class-tag-labels.php | 90 +++++++++++++++++++++---
1 file changed, 79 insertions(+), 11 deletions(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index 3735383250..28a5e9ba1d 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -99,10 +99,14 @@ function( $term ) {
* Initialize hooks.
*/
public static function init() {
+ add_action( 'post_tag_pre_add_form', array( __CLASS__, 'enqueue_scripts' ) );
add_action( 'post_tag_term_edit_form_top', array( __CLASS__, 'enqueue_scripts' ) );
+ add_action( 'post_tag_add_form_fields', [ __CLASS__, 'add_term' ] );
add_action( 'post_tag_edit_form_fields', [ __CLASS__, 'edit_term' ] );
- add_action( 'edited_post_tag', [ __CLASS__, 'save_term' ] );
+
+ add_action( 'created_post_tag', [ __CLASS__, 'save_new_term' ] );
+ add_action( 'edited_post_tag', [ __CLASS__, 'save_existing_term' ] );
}
/**
@@ -121,7 +125,45 @@ public static function enqueue_scripts() {
}
/**
- * Add term edit fields.
+ * Term creation fields.
+ *
+ * Toggle to determine if the term is a label.
+ * Also, override for flag (text used on label).
+ */
+ public static function add_term() {
+ $checkbox_id = self::TAG_LABEL_META_KEY;
+ ?>
+
+
+
Date: Fri, 23 Jan 2026 17:06:46 -0700
Subject: [PATCH 10/23] refactor: upstream handles nonce verification; handling
here breaks our unit tests
---
includes/tag-labels/class-tag-labels.php | 37 ++----------------------
1 file changed, 3 insertions(+), 34 deletions(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index 28a5e9ba1d..9948fd6d86 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -105,8 +105,8 @@ public static function init() {
add_action( 'post_tag_add_form_fields', [ __CLASS__, 'add_term' ] );
add_action( 'post_tag_edit_form_fields', [ __CLASS__, 'edit_term' ] );
- add_action( 'created_post_tag', [ __CLASS__, 'save_new_term' ] );
- add_action( 'edited_post_tag', [ __CLASS__, 'save_existing_term' ] );
+ add_action( 'created_post_tag', [ __CLASS__, 'save_term' ] );
+ add_action( 'edited_post_tag', [ __CLASS__, 'save_term' ] );
}
/**
@@ -218,7 +218,7 @@ public static function edit_term( $term ) {
Date: Fri, 23 Jan 2026 17:12:47 -0700
Subject: [PATCH 11/23] refactor: upstream handles nonce verification; handling
here breaks our unit tests
---
includes/tag-labels/class-tag-labels.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index 9948fd6d86..66e345898d 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -224,7 +224,7 @@ public static function edit_term( $term ) {
*
* @param int $term_id Term ID.
*/
- private static function save_term( $term_id ) {
+ public static function save_term( $term_id ) {
// Save label data if label is enabled; otherwise kill it.
if ( ! empty( $_POST[ self::TAG_LABEL_META_KEY ] ) ) {
From 31e8baf7a75a149be5a91712e2b6715e11f96177 Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Fri, 23 Jan 2026 18:25:33 -0700
Subject: [PATCH 12/23] fix: reversed function parameters
---
includes/tag-labels/class-tag-labels.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index 66e345898d..9464c9ff6e 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -78,7 +78,7 @@ public static function get_labels_for_post( $post ) {
return null;
}
- $post_id = ( is_a( 'WP_POST', $post ) ? $post->ID : (int) $post );
+ $post_id = ( is_a( $post, 'WP_Post' ) ? $post->ID : (int) $post );
$post_terms = get_the_terms( $post_id, 'post_tag' );
if ( ! $post_terms ) {
From 77c21e3b4cbda441a58a169ea8a4884116302764 Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Fri, 23 Jan 2026 18:32:01 -0700
Subject: [PATCH 13/23] refactor: renamed 'is_tag_label' to 'has_label'
---
includes/tag-labels/class-tag-labels.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index 9464c9ff6e..a577847c2b 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -29,7 +29,7 @@ class Tag_Labels {
*
* @return bool
*/
- public static function is_tag_label( $term ) {
+ public static function has_label( $term ) {
if ( ! $term || ! $term->term_id ) {
return false;
}
@@ -47,7 +47,7 @@ public static function is_tag_label( $term ) {
* @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 ) ) {
+ if ( ! $term || ! $term->term_id || ! self::has_label( $term ) ) {
return null;
}
@@ -172,7 +172,7 @@ public static function add_term() {
*/
public static function edit_term( $term ) {
$checkbox_id = self::TAG_LABEL_META_KEY;
- $is_label = self::is_tag_label( $term );
+ $is_label = self::has_label( $term );
$label = self::get_tag_label_for_term( $term );
$label_flag = $label ? $label['flag'] : $term->name;
From 53597d50ff6ea2ce1044ae7f8dc81f062caa90dc Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Fri, 23 Jan 2026 18:34:49 -0700
Subject: [PATCH 14/23] fix: apply Copilot suggestion
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
includes/tag-labels/class-tag-labels.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index a577847c2b..ede975db50 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -151,7 +151,7 @@ public static function add_term() {
aria-describedby="-description"
type="text"
name=""
- placeholder="Enter custom label text"
+ placeholder=""
value=""
disabled
>
From b8b0e0f886e8915d2ddfa768738c23b75077d3b9 Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Mon, 9 Mar 2026 01:17:16 -0700
Subject: [PATCH 15/23] refactor: centralized HTML generation function and
interface to `newspack-plugin`
---
includes/tag-labels/class-tag-labels.php | 49 ++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index ede975db50..835d1851db 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -95,6 +95,55 @@ function( $term ) {
);
}
+ /**
+ * Generates HTML for given tag labels.
+ *
+ * @param array $labels Labels to display.
+ * @param bool $links Whether to include links to tag archives.
+ * @param array $outer_classes Classes to apply to the outer container.
+ * @param array $inner_classes Classes to apply to the inner container.
+ * @param string $outer_element HTML element to use for the outer container.
+ *
+ * @return string Tag labels as HTML.
+ */
+ public static function generate_html( $labels = null, $links = true, $outer_classes = array( 'tag-labels' ), $inner_classes = array( 'tag-label', 'flag' ), $outer_element = 'span' ) {
+ if ( empty( $labels ) ) {
+ return '';
+ }
+
+ $outer_element = in_array( $outer_element, [ 'span', 'div' ], true ) ? $outer_element : 'span';
+
+ $labels_html = '';
+ $labels_html .= '<' . $outer_element . ' class="' . join( ' ', array_map( 'esc_attr', $outer_classes ) ) . '">';
+ foreach ( $labels as $label ) {
+ if ( $links && isset( $label['flag'] ) && $label['link'] ) {
+ $labels_html .= '' . esc_html( $label['flag'] ) . '';
+ } elseif ( isset( $label['flag'] ) ) {
+ $labels_html .= '' . esc_html( $label['flag'] ) . '';
+ }
+ }
+ $labels_html .= '' . $outer_element . '>';
+
+ return $labels_html;
+ }
+
+ /**
+ * Outputs HTML for given tag labels.
+ *
+ * @param array $labels Labels to display.
+ * @param bool $links Whether to include links to tag archives.
+ * @param string $outer_element HTML element to use for the outer container.
+ *
+ * @return void
+ */
+ public static function display( $labels = null, $links = true, $outer_element = 'span' ) {
+ if ( empty( $labels ) ) {
+ return;
+ }
+
+ echo wp_kses_post( self::generate_html( $labels, $links, array( 'tag-labels', 'cat-links' ), array( 'tag-label', 'flag' ), $outer_element ) . ' ' );
+ }
+
/**
* Initialize hooks.
*/
From f52c9441b740dcca774f20d8d2512fa356693b90 Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Wed, 11 Mar 2026 22:29:08 -0700
Subject: [PATCH 16/23] fix: add capabilities test
---
includes/tag-labels/class-tag-labels.php | 3 +++
1 file changed, 3 insertions(+)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index 835d1851db..77e6b37225 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -274,6 +274,9 @@ public static function edit_term( $term ) {
* @param int $term_id Term ID.
*/
public static function save_term( $term_id ) {
+ if ( ! current_user_can( 'manage_categories' ) ) {
+ return;
+ }
// Save label data if label is enabled; otherwise kill it.
if ( ! empty( $_POST[ self::TAG_LABEL_META_KEY ] ) ) {
From 43e70eedb59fbc04fedf75fce9888e8787f6bb83 Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Mon, 30 Mar 2026 12:54:04 -0700
Subject: [PATCH 17/23] fix: populate `id` attributes to improve usability
---
includes/tag-labels/class-tag-labels.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index 77e6b37225..a71cd79fc8 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -187,6 +187,7 @@ public static function add_term() {
@@ -199,6 +200,7 @@ public static function add_term() {
Date: Mon, 30 Mar 2026 12:56:50 -0700
Subject: [PATCH 18/23] fix: handle potential `WP_Error`, as suggested by
Copilot
---
includes/tag-labels/class-tag-labels.php | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index a71cd79fc8..efda7fc1c8 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -59,6 +59,9 @@ public static function get_tag_label_for_term( $term ) {
}
$term_label_link = get_term_link( $term->term_id );
+ if ( is_wp_error( $term_label_link ) ) {
+ return null;
+ }
return [
'flag' => $term_label_flag,
@@ -81,7 +84,7 @@ public static function get_labels_for_post( $post ) {
$post_id = ( is_a( $post, 'WP_Post' ) ? $post->ID : (int) $post );
$post_terms = get_the_terms( $post_id, 'post_tag' );
- if ( ! $post_terms ) {
+ if ( empty( $post_terms ) || is_wp_error( $post_terms ) ) {
return [];
}
From 626bcc5cfb1e6f3ca963f7f68be89824334c61ab Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Mon, 30 Mar 2026 13:06:53 -0700
Subject: [PATCH 19/23] fix: do not clear `_np_label_flag` when labels disabled
---
includes/tag-labels/class-tag-labels.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index efda7fc1c8..2c1a8b0cd1 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -297,7 +297,6 @@ public static function save_term( $term_id ) {
}
} else {
delete_term_meta( $term_id, self::TAG_LABEL_META_KEY );
- delete_term_meta( $term_id, self::TAG_LABEL_FLAG_META_KEY );
}
}
// phpcs:enable WordPress.Security.NonceVerification.Missing
From 849d7c85cdf48b952a39f88474a0875e9fc7a50e Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Mon, 25 May 2026 22:38:46 -0700
Subject: [PATCH 20/23] refactor: drop dead isset() check on get_term_meta
result
---
includes/tag-labels/class-tag-labels.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index 2c1a8b0cd1..b4168325c6 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -54,7 +54,7 @@ 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 );
- if ( ! isset( $term_label_flag ) || '' === $term_label_flag ) {
+ if ( '' === $term_label_flag ) {
$term_label_flag = $term->name;
}
From cdcc843ba76ac9671e5031dd120598d032fe70fe Mon Sep 17 00:00:00 2001
From: Jason Lee
Date: Mon, 25 May 2026 23:57:46 -0700
Subject: [PATCH 21/23] fix: scope save_term to this UI's form submissions via
nonce
---
includes/tag-labels/class-tag-labels.php | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index b4168325c6..a4e003e3b7 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -213,6 +213,7 @@ public static function add_term() {
+
|
+
Date: Tue, 26 May 2026 00:20:59 -0700
Subject: [PATCH 22/23] style: wrap edit_term nonce in tr/td for valid HTML
inside form-table
---
includes/tag-labels/class-tag-labels.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index a4e003e3b7..a581aeb159 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -272,7 +272,7 @@ public static function edit_term( $term ) {
-
+ |
Date: Tue, 26 May 2026 00:28:56 -0700
Subject: [PATCH 23/23] fix: preserve _np_label_flag in edit form across
enable/disable cycles
---
includes/tag-labels/class-tag-labels.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/includes/tag-labels/class-tag-labels.php b/includes/tag-labels/class-tag-labels.php
index a581aeb159..560aa8ca4d 100644
--- a/includes/tag-labels/class-tag-labels.php
+++ b/includes/tag-labels/class-tag-labels.php
@@ -229,10 +229,10 @@ public static function edit_term( $term ) {
$checkbox_id = self::TAG_LABEL_META_KEY;
$is_label = self::has_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;
+ // Read the stored flag directly so the input value survives disable→re-enable cycles —
+ // get_tag_label_for_term() returns null when has_label() is false, which would hide it.
+ $stored_flag = get_term_meta( $term->term_id, self::TAG_LABEL_FLAG_META_KEY, true );
+ $input_label_flag = ( '' === $stored_flag || $term->name === $stored_flag ) ? '' : $stored_flag;
?>
|