-
Notifications
You must be signed in to change notification settings - Fork 800
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Gutenberg: Add Goodreads Block (#33395)
* Add slug * First stab at Goodreads block * Load block front-end * Handle author profiles * Endpoint for getting user ID * Remove unneeded parameter * Add tests * Address feedback * Update class-wpcom-rest-api-v2-endpoint-goodreads.php * Update goodreads.php * Rewrite to functional component * Address feedback * Update edit.js * Fix block registration * Fix block registration * Refactor block * Remove legacy widget * Indentation fix * Fix tests * Manually update files * Manually update file * Fix bookNumber not saving --------- Co-authored-by: Jeremy Herve <[email protected]>
- Loading branch information
Showing
22 changed files
with
1,168 additions
and
0 deletions.
There are no files selected for viewing
78 changes: 78 additions & 0 deletions
78
.../jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-goodreads.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<?php | ||
/** | ||
* Get the User ID of a Goodreads account using its Author ID. | ||
* | ||
* @package automattic/jetpack | ||
*/ | ||
|
||
/** | ||
* Goodreads block endpoint. | ||
*/ | ||
class WPCOM_REST_API_V2_Endpoint_Goodreads extends WP_REST_Controller { | ||
/** | ||
* Constructor. | ||
*/ | ||
public function __construct() { | ||
add_action( 'rest_api_init', array( $this, 'register_routes' ) ); | ||
} | ||
|
||
/** | ||
* Register endpoint route. | ||
*/ | ||
public function register_routes() { | ||
register_rest_route( | ||
'wpcom/v2', | ||
'/goodreads/user-id', | ||
array( | ||
array( | ||
'methods' => WP_REST_Server::READABLE, | ||
'callback' => array( $this, 'get_goodreads_user_id' ), | ||
'permission_callback' => function () { | ||
return current_user_can( 'edit_posts' ); | ||
}, | ||
'args' => array( | ||
'id' => array( | ||
'description' => __( 'Goodreads user ID', 'jetpack' ), | ||
'type' => 'integer', | ||
'required' => true, | ||
'minimum' => 1, | ||
'validate_callback' => function ( $param ) { | ||
return is_numeric( $param ) && (int) $param > 0; | ||
}, | ||
), | ||
), | ||
), | ||
) | ||
); | ||
} | ||
|
||
/** | ||
* Get the user ID from the author ID. | ||
* | ||
* @param \WP_REST_Request $request request object. | ||
* | ||
* @return int Goodreads user ID (or 404 if not found). | ||
*/ | ||
public function get_goodreads_user_id( $request ) { | ||
$profile_id = $request->get_param( 'id' ); | ||
$url = 'https://www.goodreads.com/author/show/' . $profile_id; | ||
$response = wp_remote_get( esc_url_raw( $url ) ); | ||
$not_found = new WP_Error( 'not_found', 'Goodreads user not found.', array( 'status' => 404 ) ); | ||
|
||
if ( is_wp_error( $response ) ) { | ||
return $not_found; | ||
} | ||
|
||
$body = wp_remote_retrieve_body( $response ); | ||
$pattern = '/goodreads\.com\/user\/updates_rss\/(\d+)/'; | ||
|
||
if ( preg_match( $pattern, $body, $matches ) ) { | ||
$user_id = intval( $matches[1] ); | ||
return $user_id; | ||
} | ||
|
||
return $not_found; | ||
} | ||
} | ||
|
||
wpcom_rest_api_v2_load_plugin( 'WPCOM_REST_API_V2_Endpoint_Goodreads' ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: minor | ||
Type: enhancement | ||
|
||
Comment: Add Goodreads embed block in Gutenberg. |
89 changes: 89 additions & 0 deletions
89
projects/plugins/jetpack/extensions/blocks/goodreads/block.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
{ | ||
"$schema": "https://schemas.wp.org/trunk/block.json", | ||
"apiVersion": 1, | ||
"name": "jetpack/goodreads", | ||
"title": "Goodreads", | ||
"description": "Features books from the shelves of your Goodreads account.", | ||
"keywords": [ "book", "read", "author" ], | ||
"version": "1.0", | ||
"textdomain": "jetpack", | ||
"category": "embed", | ||
"icon": "<svg height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg' aria-hidden='true' focusable='false'><path d='M19.525 15.977V.49h-2.059v2.906h-.064c-.211-.455-.481-.891-.842-1.307-.36-.412-.767-.777-1.232-1.094-.466-.314-.962-.561-1.519-.736C13.256.09 12.669 0 12.038 0c-1.21 0-2.3.225-3.246.67-.947.447-1.743 1.057-2.385 1.83-.642.773-1.133 1.676-1.47 2.711-.336 1.037-.506 2.129-.506 3.283 0 1.199.141 2.326.425 3.382.286 1.057.737 1.976 1.368 2.762.631.78 1.412 1.397 2.375 1.833.961.436 2.119.661 3.471.661 1.248 0 2.33-.315 3.262-.946s1.638-1.473 2.119-2.525h.061v2.284c0 2.044-.421 3.607-1.264 4.705-.84 1.081-2.224 1.638-4.146 1.638-.572 0-1.128-.061-1.669-.181-.542-.12-1.036-.315-1.487-.57-.437-.271-.827-.601-1.143-1.038-.316-.435-.526-.961-.632-1.593H5.064c.067.887.315 1.654.737 2.3.424.646.961 1.172 1.602 1.593.641.406 1.367.706 2.172.902.811.194 1.639.3 2.494.3 1.383 0 2.541-.195 3.486-.555.947-.376 1.714-.902 2.301-1.608.601-.708 1.021-1.549 1.293-2.556.27-1.007.42-2.134.42-3.367l-.044.062zm-7.484-.557c-.955 0-1.784-.189-2.479-.571-.697-.38-1.277-.882-1.732-1.503-.467-.621-.797-1.332-1.022-2.139s-.332-1.633-.332-2.484c0-.871.105-1.725.301-2.563.21-.84.54-1.587.992-2.24.451-.652 1.037-1.182 1.728-1.584s1.533-.605 2.51-.605 1.803.209 2.495.621c.676.415 1.247.959 1.683 1.634.436.677.751 1.429.947 2.255.195.826.285 1.656.285 2.482 0 .852-.12 1.678-.345 2.484-.226.807-.572 1.518-1.038 2.139-.465.621-1.021 1.123-1.698 1.503-.676.382-1.458.571-2.359.571h.064z'></path></svg>", | ||
"supports": { | ||
"html": false, | ||
"align": true | ||
}, | ||
"attributes": { | ||
"bookNumber": { | ||
"type": "string", | ||
"default": "5" | ||
}, | ||
"class": { | ||
"type": "string" | ||
}, | ||
"customTitle": { | ||
"type": "string", | ||
"default": "My Bookshelf" | ||
}, | ||
"goodreadsId": { | ||
"type": "string" | ||
}, | ||
"id": { | ||
"type": "string" | ||
}, | ||
"link": { | ||
"type": "string" | ||
}, | ||
"orderOption": { | ||
"type": "string", | ||
"default": "a" | ||
}, | ||
"shelfOption": { | ||
"type": "string", | ||
"default": "read" | ||
}, | ||
"showAuthor": { | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"showCover": { | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"showRating": { | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"showReview": { | ||
"type": "boolean", | ||
"default": false | ||
}, | ||
"showTags": { | ||
"type": "boolean", | ||
"default": false | ||
}, | ||
"showTitle": { | ||
"type": "boolean", | ||
"default": true | ||
}, | ||
"sortOption": { | ||
"type": "string", | ||
"default": "date_added" | ||
}, | ||
"style": { | ||
"type": "string", | ||
"default": "default" | ||
}, | ||
"userInput": { | ||
"type": "string" | ||
}, | ||
"widgetId": { | ||
"type": "number" | ||
} | ||
}, | ||
"example": { | ||
"attributes": { | ||
"goodreadsId": 1176283 | ||
} | ||
} | ||
} |
131 changes: 131 additions & 0 deletions
131
projects/plugins/jetpack/extensions/blocks/goodreads/controls.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import { | ||
PanelBody, | ||
SelectControl, | ||
TextControl, | ||
ToggleControl, | ||
ToolbarButton, | ||
ToolbarGroup, | ||
} from '@wordpress/components'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { GOODREADS_SHELF_OPTIONS, GOODREADS_ORDER_OPTIONS, GOODREADS_SORT_OPTIONS } from './utils'; | ||
|
||
const renderGoodreadsDisplaySettings = ( { attributes, setAttributes } ) => { | ||
const { showCover, showAuthor, showTitle, showRating, showReview, showTags } = attributes; | ||
|
||
return ( | ||
<PanelBody PanelBody title={ __( 'Display Settings', 'jetpack' ) } initialOpen> | ||
<ToggleControl | ||
label={ __( 'Show cover', 'jetpack' ) } | ||
checked={ showCover } | ||
onChange={ () => setAttributes( { showCover: ! showCover } ) } | ||
/> | ||
|
||
<ToggleControl | ||
label={ __( 'Show author', 'jetpack' ) } | ||
checked={ showAuthor } | ||
onChange={ () => setAttributes( { showAuthor: ! showAuthor } ) } | ||
/> | ||
|
||
<ToggleControl | ||
label={ __( 'Show title', 'jetpack' ) } | ||
checked={ showTitle } | ||
onChange={ () => setAttributes( { showTitle: ! showTitle } ) } | ||
/> | ||
|
||
<ToggleControl | ||
label={ __( 'Show rating', 'jetpack' ) } | ||
checked={ showRating } | ||
onChange={ () => setAttributes( { showRating: ! showRating } ) } | ||
/> | ||
|
||
<ToggleControl | ||
label={ __( 'Show review', 'jetpack' ) } | ||
checked={ showReview } | ||
onChange={ () => setAttributes( { showReview: ! showReview } ) } | ||
/> | ||
|
||
<ToggleControl | ||
label={ __( 'Show tags', 'jetpack' ) } | ||
checked={ showTags } | ||
onChange={ () => setAttributes( { showTags: ! showTags } ) } | ||
/> | ||
</PanelBody> | ||
); | ||
}; | ||
|
||
export function GoodreadsInspectorControls( { attributes, setAttributes } ) { | ||
const { style, shelfOption, bookNumber, orderOption, customTitle, sortOption } = attributes; | ||
|
||
return ( | ||
<> | ||
<PanelBody PanelBody title={ __( 'Block Settings', 'jetpack' ) } initialOpen> | ||
<SelectControl | ||
label={ __( 'Shelf', 'jetpack' ) } | ||
value={ shelfOption } | ||
onChange={ value => setAttributes( { shelfOption: value } ) } | ||
options={ GOODREADS_SHELF_OPTIONS } | ||
/> | ||
|
||
<TextControl | ||
label={ __( 'Title', 'jetpack' ) } | ||
value={ customTitle || __( 'My Bookshelf', 'jetpack' ) } | ||
onChange={ value => setAttributes( { customTitle: value } ) } | ||
/> | ||
|
||
<SelectControl | ||
label={ __( 'Sort by', 'jetpack' ) } | ||
value={ sortOption } | ||
onChange={ value => setAttributes( { sortOption: value } ) } | ||
options={ GOODREADS_SORT_OPTIONS } | ||
/> | ||
|
||
<SelectControl | ||
label={ __( 'Order', 'jetpack' ) } | ||
value={ orderOption } | ||
onChange={ value => setAttributes( { orderOption: value } ) } | ||
options={ GOODREADS_ORDER_OPTIONS } | ||
/> | ||
|
||
<TextControl | ||
label={ __( 'Number of books', 'jetpack' ) } | ||
type="number" | ||
inputMode="numeric" | ||
min="1" | ||
max={ style === 'grid' ? 200 : 100 } | ||
value={ bookNumber || 5 } | ||
onChange={ value => setAttributes( { bookNumber: value } ) } | ||
/> | ||
</PanelBody> | ||
{ style === 'default' && renderGoodreadsDisplaySettings( { attributes, setAttributes } ) } | ||
</> | ||
); | ||
} | ||
|
||
export function GoodreadsBlockControls( { attributes, setAttributes, setDisplayPreview } ) { | ||
const { style } = attributes; | ||
const layoutControls = [ | ||
{ | ||
icon: 'list-view', | ||
title: __( 'Default view', 'jetpack' ), | ||
onClick: () => setAttributes( { style: 'default' } ), | ||
isActive: style === 'default', | ||
}, | ||
{ | ||
icon: 'grid-view', | ||
title: __( 'Grid view', 'jetpack' ), | ||
onClick: () => setAttributes( { style: 'grid' } ), | ||
isActive: style === 'grid', | ||
}, | ||
]; | ||
|
||
return ( | ||
<> | ||
<ToolbarButton | ||
label={ __( 'Edit URL', 'jetpack' ) } | ||
icon="edit" | ||
onClick={ () => setDisplayPreview( false ) } | ||
/> | ||
<ToolbarGroup controls={ layoutControls } /> | ||
</> | ||
); | ||
} |
Oops, something went wrong.