Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions includes/class-newspack-blocks-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ public static function newspack_blocks_sponsor_info( $object_info ) {
return false;
}

/**
* Get tag labels for the REST API.
*
* @param array $object_info The object info.
* @return array|bool Tag labels, or false if none.
*/
public static function newspack_blocks_get_tag_labels( $object_info ) {
$tag_labels = Newspack_Blocks::get_tag_labels( $object_info['id'] );
return ! empty( $tag_labels ) ? array_values( $tag_labels ) : false;
}

/**
* Pass whether there is a custom excerpt to the editor.
*
Expand Down Expand Up @@ -269,6 +280,7 @@ public static function posts_endpoint( $request ) {
'newspack_post_sponsors' => self::newspack_blocks_sponsor_info( $data ),
'newspack_sponsors_show_author' => Newspack_Blocks::newspack_display_sponsors_and_authors( $sponsors ),
'newspack_sponsors_show_categories' => Newspack_Blocks::newspack_display_sponsors_and_categories( $sponsors ),
'newspack_tag_labels' => self::newspack_blocks_get_tag_labels( $data ),
Comment thread
jason10lee marked this conversation as resolved.
'newspack_post_avatars' => \newspack_blocks_format_avatars( $author_info ),
'newspack_post_byline' => \newspack_blocks_format_byline( $author_info ),
'post_status' => $post->post_status,
Expand Down
29 changes: 29 additions & 0 deletions includes/class-newspack-blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,35 @@ public static function newspack_display_sponsors_and_categories( $sponsors ) {
return false;
}

/**
* Support for Tag Labels.
*
* @param int|WP_Post|null $post Post to retrieve tag labels for.
*
* @return array|null Tag labels, if any, for this post.
*/
public static function get_tag_labels( $post = null ) {
if ( class_exists( '\Newspack\Tag_Labels' ) && method_exists( '\Newspack\Tag_Labels', 'get_labels_for_post' ) ) {
return \Newspack\Tag_Labels::get_labels_for_post( $post );
}

return null;
}

/**
* Outputs HTML for given tag labels.
*
* @param array|null $labels Labels to display.
* @param bool $links Whether to include links to tag archives.
*
* @return void
*/
Comment thread
Copilot marked this conversation as resolved.
public static function display_tag_labels( $labels = null, $links = true ) {
if ( class_exists( '\Newspack\Tag_Labels' ) && method_exists( '\Newspack\Tag_Labels', 'display' ) ) {
\Newspack\Tag_Labels::display( $labels, $links, 'div' );
}
}

/**
* Closure for excerpt filtering that can be added and removed.
*
Expand Down
4 changes: 4 additions & 0 deletions src/blocks/homepage-articles/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@
"type": "boolean",
"default": false
},
"showTagLabels": {
Comment thread
jason10lee marked this conversation as resolved.
"type": "boolean",
"default": true
},
"postLayout": {
"type": "string",
"default": "list"
Expand Down
22 changes: 22 additions & 0 deletions src/blocks/homepage-articles/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Edit extends Component< HomepageArticlesProps > {
showAvatar,
showDate,
showCategory,
showTagLabels,
sectionHeader,
} = attributes;

Expand Down Expand Up @@ -112,6 +113,21 @@ class Edit extends Component< HomepageArticlesProps > {
<RawHTML>{ decodeEntities( post.newspack_category_info ) }</RawHTML>
) }
</div>
) }{ ' ' }
{ showTagLabels && post.newspack_tag_labels && (
<div className="cat-links tag-labels">
{ post.newspack_tag_labels.map( ( newspack_tag_label, index ) => {
return newspack_tag_label.link ? (
<a key={ index } href="#" className="tag-label flag">
{ newspack_tag_label.flag }
</a>
Comment thread
jason10lee marked this conversation as resolved.
) : (
<span key={ index } className="tag-label flag">
{ newspack_tag_label.flag }
</span>
);
} ) }
</div>
) }
{ RichText.isEmpty( sectionHeader ) ? (
<h2 className="entry-title" key="title">
Expand Down Expand Up @@ -208,6 +224,7 @@ class Edit extends Component< HomepageArticlesProps > {
showAuthor,
showAvatar,
showCategory,
showTagLabels,
postLayout,
mediaPosition,
specificMode,
Expand Down Expand Up @@ -445,6 +462,11 @@ class Edit extends Component< HomepageArticlesProps > {
checked={ showCategory }
onChange={ () => setAttributes( { showCategory: ! showCategory } ) }
/>
<ToggleControl
label={ __( 'Show tag labels', 'newspack-blocks' ) }
checked={ showTagLabels }
onChange={ () => setAttributes( { showTagLabels: ! showTagLabels } ) }
/>
{ IS_SUBTITLE_SUPPORTED_IN_THEME && (
<ToggleControl
label={ __( 'Show subtitle', 'newspack-blocks' ) }
Expand Down
8 changes: 8 additions & 0 deletions src/blocks/homepage-articles/templates/article.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ function( $data ) {
// Get sponsors for this post.
$sponsors = Newspack_Blocks::get_all_sponsors( $post_id );

// Get tag labels for this post, but only when the block is set to show them
// (avoids a per-post taxonomy lookup when tag labels are disabled).
$tag_labels = ( $attributes['showTagLabels'] ?? true ) ? Newspack_Blocks::get_tag_labels( $post_id ) : null;

// Add classes based on the post's assigned categories and tags.
$classes[] = Newspack_Blocks::get_term_classes( $post_id );

Expand Down Expand Up @@ -113,6 +117,10 @@ class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>"
<?php
endif;

if ( ! empty( $tag_labels ) ) {
Newspack_Blocks::display_tag_labels( $tag_labels );
}

if ( '' === $attributes['sectionHeader'] ) {
// Don't link the title if the post lacks a valid URL.
if ( ! $post_link ) {
Expand Down
2 changes: 2 additions & 0 deletions src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ declare global {
flag: string;
}[]
| false;
newspack_tag_labels?: { flag: string; link: string }[] | false;
newspack_listings_hide_author?: boolean;
newspack_listings_hide_publish_date?: boolean;
};
Expand Down Expand Up @@ -130,6 +131,7 @@ declare global {
showAuthor: boolean;
showAvatar: boolean;
showCategory: boolean;
showTagLabels: boolean;
postLayout: string;
columns: integer;
colGap: integer;
Expand Down
37 changes: 37 additions & 0 deletions tests/class-newspack-tag-labels-stub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
/**
* Test stub for \Newspack\Tag_Labels.
*
* The newspack-blocks test suite runs without newspack-plugin loaded, so the
* real \Newspack\Tag_Labels class is absent. This lightweight stub lets the
* tests exercise the tag-label REST pass-through contract in isolation.
*
* @package Newspack_Blocks
*/

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedNamespaceFound -- Test stub deliberately impersonates the plugin's \Newspack\Tag_Labels.
namespace Newspack;

if ( ! class_exists( __NAMESPACE__ . '\Tag_Labels' ) ) {
/**
* Minimal stub of the plugin's Tag_Labels class.
*/
class Tag_Labels {
/**
* Labels returned by get_labels_for_post(). Set by the test.
*
* @var array|null
*/
public static $stub_labels = null;

/**
* Return the stubbed labels, ignoring the post.
*
* @param int|\WP_Post|null $post Post to look up (ignored by the stub).
* @return array|null
*/
public static function get_labels_for_post( $post ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Signature parity with the real class; the stub ignores the post.
return self::$stub_labels;
}
}
}
52 changes: 52 additions & 0 deletions tests/test-homepage-posts-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* @package Newspack_Blocks
*/

require_once __DIR__ . '/class-newspack-tag-labels-stub.php';

/**
* Homepage Posts Block test case.
*/
Expand Down Expand Up @@ -79,4 +81,54 @@ public function test_hpb_wp_query() {
self::assertEquals( 1, count( $query->posts ), 'There is one post returned.' );
self::assertEquals( $post_id, $query->posts[0]->ID, 'The post returned is the one with the CAP author assigned.' );
}

/**
* The newspack_tag_labels REST field exposes the { flag, link } shape
* returned by \Newspack\Tag_Labels, normalized to a 0-indexed list.
*
* Locks in the cross-repo contract: the field passes through whatever
* \Newspack\Tag_Labels::get_labels_for_post() returns, so the plugin,
* blocks, and theme must agree on this shape.
*/
public function test_tag_labels_rest_field_shape() {
if ( ! property_exists( '\Newspack\Tag_Labels', 'stub_labels' ) ) {
$this->markTestSkipped( 'Real \Newspack\Tag_Labels present; stub-based contract test skipped.' );
}
$post_id = self::factory()->post->create();

// Keyed input (as returned by Tag_Labels::get_labels_for_post()).
\Newspack\Tag_Labels::$stub_labels = [
42 => [
'flag' => 'Breaking',
'link' => 'https://example.org/tag/breaking/',
],
];

$result = Newspack_Blocks_API::newspack_blocks_get_tag_labels( [ 'id' => $post_id ] );

self::assertIsArray( $result );
self::assertSame( [ 0 ], array_keys( $result ), 'Keyed input is normalized to a 0-indexed list.' );
self::assertArrayHasKey( 'flag', $result[0] );
self::assertArrayHasKey( 'link', $result[0] );
self::assertSame( 'Breaking', $result[0]['flag'] );
self::assertSame( 'https://example.org/tag/breaking/', $result[0]['link'] );

\Newspack\Tag_Labels::$stub_labels = null;
}

/**
* The newspack_tag_labels REST field returns false when there are no labels.
*/
public function test_tag_labels_rest_field_empty_returns_false() {
if ( ! property_exists( '\Newspack\Tag_Labels', 'stub_labels' ) ) {
$this->markTestSkipped( 'Real \Newspack\Tag_Labels present; stub-based contract test skipped.' );
}
$post_id = self::factory()->post->create();

\Newspack\Tag_Labels::$stub_labels = [];
self::assertFalse( Newspack_Blocks_API::newspack_blocks_get_tag_labels( [ 'id' => $post_id ] ) );

\Newspack\Tag_Labels::$stub_labels = null;
self::assertFalse( Newspack_Blocks_API::newspack_blocks_get_tag_labels( [ 'id' => $post_id ] ) );
}
}
Loading