Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Newsletter categories: Render non-interactive newsletter category pills in the editor #32666

Merged
merged 9 commits into from
Sep 7, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
/**
* REST API endpoint for the Jetpack Blogroll block.
*
* @package automattic/jetpack
* @since 12.2
TimBroddin marked this conversation as resolved.
Show resolved Hide resolved
*/

use Automattic\Jetpack\Status\Host;

require_once __DIR__ . '/trait-wpcom-rest-api-proxy-request-trait.php';

/**
* Class WPCOM_REST_API_V2_Endpoint_Following
*/
class WPCOM_REST_API_V2_Endpoint_Newsletter_Categories_List extends WP_REST_Controller {
use WPCOM_REST_API_Proxy_Request_Trait;

/**
* Constructor.
*/
public function __construct() {
$this->wpcom_is_wpcom_only_endpoint = true;
$this->wpcom_is_site_specific_endpoint = true;
$this->base_api_path = 'wpcom';
$this->version = 'v2';
$this->namespace = $this->base_api_path . '/' . $this->version;
$this->rest_base = '/newsletter-categories';
$this->wpcom_is_wpcom_only_endpoint = true;
$this->wpcom_is_site_specific_endpoint = true;

add_action( 'rest_api_init', array( $this, 'register_routes' ) );
}

/**
* Register routes.
*/
public function register_routes() {
$options = array(
'show_in_index' => true,
'methods' => 'GET',
// if this is not a wpcom site, we need to proxy the request to wpcom
'callback' => ( ( new Host() )->is_wpcom_simple() ) ? array(
$this,
'get_newsletter_categories',
) : array( $this, 'proxy_request_to_wpcom_as_user' ),
'permission_callback' => '__return_true',
TimBroddin marked this conversation as resolved.
Show resolved Hide resolved
);

register_rest_route(
$this->namespace,
$this->rest_base,
$options
);
}

/**
* Gets the site's newsletter categories
*
* @return array|WP_Error list of newsletter categories
*/
public function get_newsletter_categories() {

if ( defined( 'IS_WPCOM' ) && IS_WPCOM && function_exists( 'require_lib' ) ) {
TimBroddin marked this conversation as resolved.
Show resolved Hide resolved
require_lib( 'newsletter-categories' );

$newsletter_categories = get_newsletter_categories();

// Include subscription counts for each category if the user can manage categories.
if ( $this->can_manage_categories() === true ) {
$subscription_counts_per_category = get_blog_subscription_counts_per_category();
array_walk(
$newsletter_categories,
function ( &$category ) use ( $subscription_counts_per_category ) {
$category['subscription_count'] = $subscription_counts_per_category[ $category['id'] ] ? $subscription_counts_per_category[ $category['id'] ] : 0;
}
);
}

return rest_ensure_response(
array(
'enabled' => (bool) get_option( 'wpcom_newsletter_categories_enabled', false ),
'newsletter_categories' => $newsletter_categories,
)
);

}
}
}

wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Newsletter_Categories_List' );
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ public function proxy_request_to_wpcom_as_user( $request, $path = '' ) {
'method' => $request->get_method(),
);

$response = Client::wpcom_json_api_request_as_user( $api_url, $this->version, $request_options, $request->get_body(), $this->base_api_path );
// If no body is present, passing it as $request->get_body() will cause an error.
$body = $request->get_body() ? $request->get_body() : null;

$response = Client::wpcom_json_api_request_as_user( $api_url, $this->version, $request_options, $body, $this->base_api_path );

if ( is_wp_error( $response ) ) {
return $response;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: enhancement

Adds support for newsletter categories
26 changes: 25 additions & 1 deletion projects/plugins/jetpack/extensions/blocks/subscriptions/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
DEFAULT_FONTSIZE_VALUE,
} from './constants';
import SubscriptionControls from './controls';
import { useNewsletterCategories } from './hooks/use-newsletter-categories';
import { SubscriptionsPlaceholder } from './subscription-placeholder';
import SubscriptionSkeletonLoader from './subscription-skeleton-loader';
import { name } from './';
Expand Down Expand Up @@ -116,6 +117,9 @@ export function SubscriptionEdit( props ) {
};
} );

const { data: newsletterCategories, enabled: newsletterCategoriesEnabled } =
useNewsletterCategories();

const emailFieldGradient = isGradientAvailable
? useGradient( {
gradientAttribute: 'emailFieldGradient',
Expand Down Expand Up @@ -179,6 +183,10 @@ export function SubscriptionEdit( props ) {
padding: getPaddingStyleValue( padding ),
};

const cssVars = {
'--border-radius': borderRadius ? borderRadius + 'px' : DEFAULT_BORDER_RADIUS_VALUE + 'px',
TimBroddin marked this conversation as resolved.
Show resolved Hide resolved
};

const emailFieldStyles = {
...sharedStyles,
...( ! emailFieldBackgroundColor.color && emailFieldGradient.gradientValue
Expand All @@ -202,6 +210,9 @@ export function SubscriptionEdit( props ) {
className,
'wp-block-jetpack-subscriptions__container',
'wp-block-jetpack-subscriptions__supports-newline',
newsletterCategoriesEnabled
? 'wp-block-jetpack-subscriptions__newsletter-categories-enabled'
: undefined,
buttonOnNewLine ? 'wp-block-jetpack-subscriptions__use-newline' : undefined,
showSubscribersTotal ? 'wp-block-jetpack-subscriptions__show-subs' : undefined
);
Expand Down Expand Up @@ -279,7 +290,20 @@ export function SubscriptionEdit( props ) {
</BlockControls>
) }

<div className={ getBlockClassName() }>
<div className={ getBlockClassName() } style={ cssVars }>
<div className="wp-block-jetpack-subscriptions__newsletter-categories">
{ newsletterCategories.map( category => {
return (
<div
key={ `newsletter-category-${ category.id }` }
className="wp-block-jetpack-subscriptions__newsletter-category"
>
{ category.name }
</div>
);
} ) }
</div>

<div className="wp-block-jetpack-subscriptions__form" role="form">
<TextControl
placeholder={ subscribePlaceholder }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import apiFetch from '@wordpress/api-fetch';
import { useEffect, useState } from '@wordpress/element';

const useNewsletterCategories = () => {
const [ data, setData ] = useState( [] );
const [ enabled, setEnabled ] = useState( false );
const [ error, setError ] = useState( false );
const [ loading, setLoading ] = useState( true );

useEffect( () => {
const fetchData = async () => {
try {
const newsLetterCategories = await apiFetch( {
path: `/wpcom/v2/newsletter-categories`,
} );
setData( newsLetterCategories?.newsletter_categories );
setEnabled( newsLetterCategories?.enabled ?? false );
} catch ( e ) {
setError( true );
} finally {
setLoading( false );
}
};

fetchData();
}, [] );

return { data, enabled, error, loading };
};

export { useNewsletterCategories };
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,20 @@ jest.mock( '@wordpress/element', () => ( {

jest.mock( '@wordpress/notices', () => {}, { virtual: true } );

jest.mock( '../hooks/use-newsletter-categories', () => ( {
useNewsletterCategories: () => {
return {
data: [],
enabled: false,
error: false,
loading: false,
};
},
} ) );

describe( 'SubscriptionEdit', () => {
test( 'adds correct classes to container', async () => {
const { container } = render( <SubscriptionEdit { ...defaultProps } /> );

// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
expect( container.querySelector( `.${ defaultProps.className }` ) ).toBeInTheDocument();
} );
Expand Down
31 changes: 31 additions & 0 deletions projects/plugins/jetpack/extensions/blocks/subscriptions/view.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import '@automattic/jetpack-base-styles/gutenberg-base-styles';

.is-style-compact {
.wp-block-jetpack-subscriptions__button,
.wp-block-button__link {
Expand Down Expand Up @@ -96,3 +98,32 @@
}
}
}

.wp-block-jetpack-subscriptions__newsletter-categories {
margin-top: 8px;
margin-bottom: 24px;
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 8px;

.wp-block-jetpack-subscriptions__newsletter-category {
padding: 6px 10px;
font-family: "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
TimBroddin marked this conversation as resolved.
Show resolved Hide resolved
font-size: 14px;
TimBroddin marked this conversation as resolved.
Show resolved Hide resolved
font-weight: 500;
line-height: 20px;
color: $gray-600;
border: 1px solid #dcdcde;
TimBroddin marked this conversation as resolved.
Show resolved Hide resolved
border-radius: var(--border-radius);
}
}

// make the form less wide when there are categories
.wp-block-jetpack-subscriptions__newsletter-categories-enabled {
.wp-block-jetpack-subscriptions__form {
width: 80%;
margin-left: auto;
margin-right: auto;
}
}
Loading