-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Add Archives block #5495
Add Archives block #5495
Changes from 59 commits
c664b53
d7430c7
12cf65b
12094d8
527cdb1
e0413a2
5657a36
660bf4a
aba8455
cd58776
b0ede76
340136e
514dd4f
a90f40d
0c127e1
b0b977a
395a168
1d05c2d
c40dd25
f323651
c4abc69
6557877
228c756
b48ef81
e39332d
46506a9
ee169b9
d83a5e0
ce1f7c6
a046023
14e1ed2
e0fec83
17e404a
00489bb
9f282fb
39b867a
2c884cc
4c3129b
0dc74ab
3c60d4b
a10bfac
a166324
f0f4a77
6d1ee65
2bbbeb7
6f7d62e
a923f39
b3e3b36
f150741
67af6b7
071dc64
bb67a00
0b1156a
eb49866
8c822a6
4603e22
226616c
4a5754b
3b50729
d8ee393
128513c
d870d2d
a212cbc
931d08c
1eec0e0
74ca70f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { Component } from '@wordpress/element'; | ||
import { | ||
PanelBody, | ||
ServerSideRender, | ||
ToggleControl, | ||
} from '@wordpress/components'; | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
InspectorControls, | ||
BlockAlignmentToolbar, | ||
BlockControls, | ||
} from '@wordpress/blocks'; | ||
|
||
class ArchivesBlock extends Component { | ||
constructor() { | ||
super( ...arguments ); | ||
|
||
this.toggleShowPostCounts = this.toggleShowPostCounts.bind( this ); | ||
this.toggleDisplayAsDropdown = this.toggleDisplayAsDropdown.bind( this ); | ||
} | ||
|
||
toggleShowPostCounts() { | ||
const { attributes, setAttributes } = this.props; | ||
const { showPostCounts } = attributes; | ||
|
||
setAttributes( { showPostCounts: ! showPostCounts } ); | ||
} | ||
|
||
toggleDisplayAsDropdown() { | ||
const { attributes, setAttributes } = this.props; | ||
const { displayAsDropdown } = attributes; | ||
|
||
setAttributes( { displayAsDropdown: ! displayAsDropdown } ); | ||
} | ||
|
||
render() { | ||
const { attributes, isSelected, setAttributes } = this.props; | ||
const { align, showPostCounts, displayAsDropdown } = attributes; | ||
|
||
const inspectorControls = isSelected && ( | ||
<InspectorControls key="inspector"> | ||
<PanelBody title={ __( 'Archives Settings' ) }> | ||
<ToggleControl | ||
label={ __( 'Show post counts' ) } | ||
checked={ showPostCounts } | ||
onChange={ this.toggleShowPostCounts } | ||
/> | ||
<ToggleControl | ||
label={ __( 'Display as dropdown' ) } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same again here. label={ __( 'Display as Dropdown' ) } |
||
checked={ displayAsDropdown } | ||
onChange={ this.toggleDisplayAsDropdown } | ||
/> | ||
</PanelBody> | ||
</InspectorControls> | ||
); | ||
|
||
return [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed within 128513c. |
||
inspectorControls, | ||
isSelected && ( | ||
<BlockControls key="controls"> | ||
<BlockAlignmentToolbar | ||
value={ align } | ||
onChange={ ( nextAlign ) => { | ||
setAttributes( { align: nextAlign } ); | ||
} } | ||
controls={ [ 'left', 'center', 'right', 'full' ] } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Curious why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if it should support Edit: Originally based this on other dynamic blocks, e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not aware of a proper standard. I think it's fine to remove both for now. In any case, cc'ing @jasmussen to make sure you're aware of these differences :) |
||
/> | ||
</BlockControls> | ||
), | ||
<ServerSideRender key="archives" block="core/archives" attributes={ this.props.attributes } />, | ||
]; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Considering the life cycle of the ArchivesBlock component, and the fact that the block proper isn't very interactive, I'm not sure we need a class-based component and the ahead-of-time binding of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mcsf Curious if that's a matter of preference or would there be benefits for using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's sort of been a tendency throughout Gutenberg to avoid what is, in a way, a performance trade-off that prioritizes performance of repeated rendering, at the (slight) cost of init-time bindings and increased memory footprint (which may add up with every little component) and at the (arguably) higher cost of code complexity for newcomers. For a component like ArchivesBlock, I'm tempted to say we're better off going with something simpler (i.e. functional component) even if it means binding two event handlers when rendering. More on the subject of the cost of render-time inline functions: https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578 |
||
|
||
export default ArchivesBlock; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import ArchivesBlock from './block'; | ||
export const name = 'core/archives'; | ||
|
||
export const settings = { | ||
title: __( 'Archives' ), | ||
|
||
description: __( 'This block displays a monthly archive of your site’s Posts.' ), | ||
|
||
icon: 'calendar-alt', | ||
|
||
category: 'widgets', | ||
|
||
keywords: [ __( 'archives' ) ], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could remove this line. Gutenberg will treat the title (Archives) as an implicit search keyword. |
||
|
||
supports: { | ||
html: false, | ||
}, | ||
|
||
getEditWrapperProps( attributes ) { | ||
const { align } = attributes; | ||
if ( 'left' === align || 'right' === align || 'center' === align || 'full' === align ) { | ||
return { 'data-align': align }; | ||
} | ||
}, | ||
|
||
edit: ArchivesBlock, | ||
|
||
save() { | ||
// Handled by PHP. | ||
return null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there something we can return here as a fallback for clients like RSS readers that don't support dynamic blocks? (Probably not, just wondering.) |
||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
<?php | ||
/** | ||
* Server-side rendering of the `core/archives` block. | ||
* | ||
* @package gutenberg | ||
*/ | ||
|
||
/** | ||
* Renders the `core/archives` block on server. | ||
* | ||
* @see WP_Widget_Archives | ||
* | ||
* @param array $attributes The block attributes. | ||
* | ||
* @return string Returns the post content with archives added. | ||
*/ | ||
function render_block_core_archives( $attributes ) { | ||
static $block_id = 0; | ||
$block_id++; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way this is used in tandem with
returns multiple elements if I have more than one Archive block in my editor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth noting that implementing an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mcsf Also disabled the pointer-events of the links, this way it'll not cause the leaving page alert, however, the links are not clickable within the editor. Probably better but not ideal, thoughts? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That should do for now, thanks.
It doesn't solve for other interactions (e.g. when attribute Display as dropdown is on). It's indeed not ideal, but I don't have a good solution. I mean, sure, we could also disable pointer-events on |
||
|
||
$show_post_count = ! empty( $attributes['showPostCounts'] ) ? true : false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ternary unnecessary // for any boolean A,
( A ? true : false ) === A |
||
$class = "wp-block-archives align{$attributes['align']}"; | ||
|
||
if ( ! empty( $attributes['displayAsDropdown'] ) ) { | ||
|
||
$dropdown_id = esc_attr( 'wp-block-archives-' . $block_id ); | ||
$title = __( 'Archives', 'gutenberg' ); | ||
|
||
/** This filter is documented in wp-includes/widgets/class-wp-widget-archives.php */ | ||
$dropdown_args = apply_filters( 'widget_archives_dropdown_args', array( | ||
'type' => 'monthly', | ||
'format' => 'option', | ||
'show_post_count' => $show_post_count, | ||
) ); | ||
|
||
$dropdown_args['echo'] = 0; | ||
|
||
$archives = wp_get_archives( $dropdown_args ); | ||
|
||
switch ( $dropdown_args['type'] ) { | ||
case 'yearly': | ||
$label = __( 'Select Year', 'gutenberg' ); | ||
break; | ||
case 'monthly': | ||
$label = __( 'Select Month', 'gutenberg' ); | ||
break; | ||
case 'daily': | ||
$label = __( 'Select Day', 'gutenberg' ); | ||
break; | ||
case 'weekly': | ||
$label = __( 'Select Week', 'gutenberg' ); | ||
break; | ||
default: | ||
$label = __( 'Select Post', 'gutenberg' ); | ||
break; | ||
} | ||
|
||
$label = esc_attr( $label ); | ||
|
||
$block_content = '<label class="screen-reader-text" for="' . $dropdown_id . '">' . $title . '</label> | ||
<select id="' . $dropdown_id . '" name="archive-dropdown" onchange="document.location.href=this.options[this.selectedIndex].value;"> | ||
<option value="">' . $label . '</option>' . $archives . '</select>'; | ||
} else { | ||
|
||
/** This filter is documented in wp-includes/widgets/class-wp-widget-archives.php */ | ||
$archives_args = apply_filters( 'widget_archives_args', array( | ||
'type' => 'monthly', | ||
'show_post_count' => $show_post_count, | ||
) ); | ||
|
||
$archives_args['echo'] = 0; | ||
|
||
$block_content = wp_get_archives( $archives_args ); | ||
} | ||
|
||
$block_content = sprintf( | ||
'<div class="%1$s">%2$s</div>', | ||
esc_attr( $class ), | ||
$block_content | ||
); | ||
|
||
return $block_content; | ||
} | ||
|
||
/** | ||
* Register archives block. | ||
*/ | ||
function register_block_core_archives() { | ||
register_block_type( 'core/archives', array( | ||
'attributes' => array( | ||
'showPostCounts' => array( | ||
'type' => 'boolean', | ||
'default' => false, | ||
), | ||
'displayAsDropdown' => array( | ||
'type' => 'boolean', | ||
'default' => false, | ||
), | ||
'align' => array( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor/subjective, but the whitespace resulting from keeping certain elements aligned across lines can be distracting. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The linter enforces this, for better or worse 🙂 |
||
'type' => 'string', | ||
'default' => 'none', | ||
), | ||
), | ||
'render_callback' => 'render_block_core_archives', | ||
) ); | ||
} | ||
|
||
add_action( 'init', 'register_block_core_archives' ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<!-- wp:archives {"showPostCounts":false,"displayAsDropdown":false} /--> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[ | ||
{ | ||
"uid": "_uid_0", | ||
"name": "core/archives", | ||
"isValid": true, | ||
"attributes": {}, | ||
"innerBlocks": [], | ||
"originalContent": "" | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[ | ||
{ | ||
"blockName": "core/archives", | ||
"attrs": { | ||
"showPostCounts": false, | ||
"displayAsDropdown": false | ||
}, | ||
"innerBlocks": [], | ||
"innerHTML": "" | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<!-- wp:archives /--> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<!-- wp:archives {"showPostCounts":true,"displayAsDropdown":false} /--> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[ | ||
{ | ||
"uid": "_uid_0", | ||
"name": "core/archives", | ||
"isValid": true, | ||
"attributes": {}, | ||
"innerBlocks": [], | ||
"originalContent": "" | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[ | ||
{ | ||
"blockName": "core/archives", | ||
"attrs": { | ||
"showPostCounts": true, | ||
"displayAsDropdown": false | ||
}, | ||
"innerBlocks": [], | ||
"innerHTML": "" | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<!-- wp:archives /--> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably should make this title case for consistency with other inspector control labels in Gutenberg.