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

Blog Stats Block: Include Visitors Data #35427

Merged
merged 9 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function get_blog_stats( $request ) {
( new WPCOM_Stats() )->get_stats( array( 'fields' => 'stats' ) )
);

if ( ! isset( $blog_data->stats->views ) ) {
if ( ! isset( $blog_data->stats->views ) || ! isset( $blog_data->stats->visitors ) ) {
return false;
}

Expand All @@ -72,8 +72,9 @@ public function get_blog_stats( $request ) {
}

return array(
'post-views' => $post_data->views,
'blog-views' => $blog_data->stats->views,
'post-views' => $post_data->views,
'blog-visitors' => $blog_data->stats->visitors,
'blog-views' => $blog_data->stats->views,
);
}
}
Expand Down
4 changes: 4 additions & 0 deletions projects/plugins/jetpack/changelog/add-blog-stats-visitors
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: enhancement

Blog Stats Block: allow displaying site's number of visitors.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"name": "jetpack/blog-stats",
"title": "Blog Stats",
"description": "Show a stats counter for your blog.",
"keywords": [ "views", "hits", "analytics", "counter" ],
"keywords": [ "views", "hits", "analytics", "counter", "visitors" ],
"version": "1.0",
"textdomain": "jetpack",
"category": "grow",
Expand All @@ -31,6 +31,10 @@
"label": {
"type": "string"
},
"statsData": {
"type": "string",
"default": "views"
},
"statsOption": {
"type": "string",
"default": "site"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function register_block() {
function load_assets( $attributes ) {
Jetpack_Gutenberg::load_assets_as_required( __DIR__ );

$views = 0;
$stats = 0;

// For when there's no post ID - eg. search pages.
if ( $attributes['statsOption'] === 'post' && ! get_the_ID() ) {
Expand All @@ -71,36 +71,40 @@ function load_assets( $attributes ) {
);

if ( isset( $data->views ) ) {
$views = $data->views;
$stats = $data->views;
}
} else {
$data = convert_stats_array_to_object(
( new WPCOM_Stats() )->get_stats( array( 'fields' => 'stats' ) )
);

if ( isset( $data->stats->views ) ) {
$views = $data->stats->views;
if ( $attributes['statsData'] === 'views' && isset( $data->stats->views ) ) {
$stats = $data->stats->views;
}

if ( $attributes['statsData'] === 'visitors' && isset( $data->stats->visitors ) ) {
$stats = $data->stats->visitors;
}
}

$label = $attributes['label'] ? $attributes['label'] : esc_html(
$fallback_label = $attributes['statsData'] === 'visitors' ? esc_html(
/* Translators: Number of visitors */
_n( 'visitor', 'visitors', $stats, 'jetpack' )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_n( 'visitor', 'visitors', $stats, 'jetpack' )
/* Translators: Number of visitors */
_n( 'visitor', 'visitors', $stats, 'jetpack' )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try this 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build is still failing 🤔

Copy link
Contributor

@kangzj kangzj Feb 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any insights please @jeherve @anomiex? Thanks

[plugins/jetpack 2:10.354] [build-production-extensions] ERROR in editor-beta.js: Translator comments have gone missing for "hit"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks a bit ugly, but I think it relates to where the comment goes: #28351 (comment)

Just added a commit that will maybe fix it? Not sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was worth a try, but nope, issue seems to persist!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to work around that by adding a dummy third argument, like it's done here:

label:
provider === 'mapkit'
? __( 'Muted', 'jetpack', /* dummy arg to avoid bad minification */ 0 )
: __( 'Black & White', 'jetpack' ),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done! Not sure how to check locally, but hopefully that fixes the tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of the confusion is that this isn't the code causing that error, it's the JS code in edit.js. I'll comment there with details.

You should be able to check locally with jetpack build --production plugins/jetpack, or in projects/plugins/jetpack/ run pnpm build-production-extensions.

) : esc_html(
/* Translators: Number of views */
_n(
'hit',
'hits',
$views,
'jetpack'
)
_n( 'hit', 'hits', $stats, 'jetpack' )
);

$label = $attributes['label'] ? $attributes['label'] : $fallback_label;

$wrapper_attributes = \WP_Block_Supports::get_instance()->apply_block_supports();

return sprintf(
'<div class="jetpack-blog-stats%s%s"%s><p>%s %s</p></div>',
! empty( $attributes['className'] ) ? ' ' . esc_attr( $attributes['className'] ) : '',
! empty( $wrapper_attributes['class'] ) ? ' ' . esc_attr( $wrapper_attributes['class'] ) : '',
! empty( $wrapper_attributes['style'] ) ? ' style="' . esc_attr( $wrapper_attributes['style'] ) . '"' : '',
esc_html( number_format_i18n( $views ) ),
esc_html( number_format_i18n( $stats ) ),
wp_kses_post( $label )
);
}
33 changes: 30 additions & 3 deletions projects/plugins/jetpack/extensions/blocks/blog-stats/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@ import { PanelBody, RadioControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export function BlogStatsInspectorControls( { attributes, setAttributes } ) {
const { statsOption } = attributes;
const { statsData, statsOption } = attributes;

const RADIO_OPTIONS = [
const STATS_DATA_RADIO = [
{
value: 'views',
label: __( 'Views', 'jetpack' ),
},
{
value: 'visitors',
label: __( 'Visitors', 'jetpack' ),
},
];

const STATS_OPTION_RADIO = [
{
value: 'site',
label: __( 'My whole site', 'jetpack' ),
Expand All @@ -18,11 +29,27 @@ export function BlogStatsInspectorControls( { attributes, setAttributes } ) {
return (
<>
<PanelBody title={ __( 'Settings', 'jetpack' ) }>
<RadioControl
label={ __( 'Views or visitors', 'jetpack' ) }
selected={ statsData }
onChange={ value => setAttributes( { statsData: value } ) }
options={ STATS_DATA_RADIO }
help={ __(
'Views represent site visits, whereas visitors represent unique individuals.',
'jetpack'
) }
/>
<RadioControl
label={ __( 'Show stats data for', 'jetpack' ) }
selected={ statsOption }
onChange={ value => setAttributes( { statsOption: value } ) }
options={ RADIO_OPTIONS }
options={ STATS_OPTION_RADIO }
disabled={ statsData === 'visitors' }
help={
statsData === 'visitors'
? __( "Visitor counts aren't available for individual posts.", 'jetpack' )
: null
}
/>
<span className="jetpack-blog-stats__delay-notice">
{ __( 'Stats are delayed for up to 5 minutes.', 'jetpack' ) }
Expand Down
27 changes: 20 additions & 7 deletions projects/plugins/jetpack/extensions/blocks/blog-stats/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import { InactiveStatsPlaceholder } from './inactive-placeholder';
function BlogStatsEdit( { attributes, className, setAttributes } ) {
const { isLoadingModules, isChangingStatus, isModuleActive, changeStatus } =
useModuleStatus( 'stats' );
const { label, statsOption } = attributes;
const { label, statsData, statsOption } = attributes;
const [ blogViews, setBlogViews ] = useState( null );
const [ blogVisitors, setBlogVisitors ] = useState();
const [ postViews, setPostViews ] = useState();
const views = statsOption === 'post' ? postViews : blogViews;

const blogStats = statsData === 'views' ? blogViews : blogVisitors;
const stats = statsOption === 'post' ? postViews : blogStats;

const postId = useSelect( select => select( 'core/editor' ).getCurrentPostId(), [] );

Expand All @@ -26,6 +29,7 @@ function BlogStatsEdit( { attributes, className, setAttributes } ) {
: '/wpcom/v2/blog-stats',
} ).then( response => {
setBlogViews( response[ 'blog-views' ] );
setBlogVisitors( response[ 'blog-visitors' ] );

// Display "12,345" as an obvious placeholder when we have no Post ID.
// Applies to widgets, FSE templates etc.
Expand All @@ -34,6 +38,13 @@ function BlogStatsEdit( { attributes, className, setAttributes } ) {
}
}, [ postId, isModuleActive ] );

// We don't collect visitor data for individual posts.
useEffect( () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

if ( statsData === 'visitors' ) {
setAttributes( { statsOption: 'site' } );
}
}, [ statsData, setAttributes ] );

if ( ! isModuleActive && ! isLoadingModules ) {
return (
<InactiveStatsPlaceholder
Expand All @@ -44,6 +55,11 @@ function BlogStatsEdit( { attributes, className, setAttributes } ) {
);
}

const visitorsPlaceholder = _n( 'visitor', 'visitors', parseInt( stats ), 'jetpack' );

/* Translators: Number of views */
const viewsPlaceholder = _n( 'hit', 'hits', parseInt( stats ), 'jetpack' );

return (
<>
<InspectorControls>
Expand All @@ -55,13 +71,10 @@ function BlogStatsEdit( { attributes, className, setAttributes } ) {
<p className="jetpack-blog-stats__loading">{ __( 'Loading stats…', 'jetpack' ) }</p>
) : (
<p>
<span>{ numberFormat( views ) } </span>
<span>{ numberFormat( stats ) } </span>
<RichText
tagName="span"
placeholder={
/* Translators: Number of views */
_n( 'hit', 'hits', parseInt( views ), 'jetpack' )
}
placeholder={ statsData === 'visitors' ? visitorsPlaceholder : viewsPlaceholder }
value={ label }
allowedFormats={ [ 'core/bold', 'core/italic', 'core/link' ] }
onChange={ newLabel => setAttributes( { label: newLabel } ) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
@import '@automattic/jetpack-base-styles/gutenberg-base-styles';

.wp-block-jetpack-blog-stats {
.jetpack-blog-stats__loading {
// Same as RichText component's placeholder opacity from Core.
Expand All @@ -12,5 +10,5 @@
}

.jetpack-blog-stats__delay-notice {
color: $gray-700;
font-size: 12px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { BlogStatsInspectorControls } from '../controls';
describe( 'BlogStatsControls', () => {
const defaultAttributes = {
label: 'hits',
statsData: 'views',
statsOption: 'site',
};

Expand All @@ -19,10 +20,30 @@ describe( 'BlogStatsControls', () => {
} );

describe( 'Inspector settings', () => {
test( 'loads and displays settings', () => {
test( 'loads and displays views or visitors settings', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

render( <BlogStatsInspectorControls { ...defaultProps } /> );

expect( screen.getByLabelText( 'Views' ) ).toBeInTheDocument();
expect( screen.getByLabelText( 'Visitors' ) ).toBeInTheDocument();
} );

test( 'defaults stats data to views', () => {
render( <BlogStatsInspectorControls { ...defaultProps } /> );

expect( screen.getByLabelText( 'Views' ) ).toBeChecked();
} );

test( 'sets the statsData attribute', async () => {
const user = userEvent.setup();
render( <BlogStatsInspectorControls { ...defaultProps } /> );
await user.click( screen.getByLabelText( 'Visitors' ) );

expect( setAttributes ).toHaveBeenCalledWith( { statsData: 'visitors' } );
} );

test( 'loads and displays option settings', () => {
render( <BlogStatsInspectorControls { ...defaultProps } /> );

expect( screen.getByText( 'Settings' ) ).toBeInTheDocument();
expect( screen.getByLabelText( 'My whole site' ) ).toBeInTheDocument();
expect( screen.getByLabelText( 'This individual post' ) ).toBeInTheDocument();
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"name": "jetpack/blog-stats",
"isValid": true,
"attributes": {
"statsData": "views",
"statsOption": "site"
},
"innerBlocks": [],
Expand Down
Loading