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

Add Archives block #5495

Closed
wants to merge 66 commits into from
Closed
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
c664b53
First pass at archives block
swissspidy Jun 27, 2017
d7430c7
Merge master & resolve conflicts.
miina Mar 6, 2018
12cf65b
Refactor code to match current gutenberg architecture.
miina Mar 6, 2018
12094d8
Fixes to frontend rendering.
miina Mar 7, 2018
527cdb1
Fix dropdown ID.
miina Mar 7, 2018
e0413a2
Merge remote-tracking branch 'origin/master' into add/archives-block
miina Mar 8, 2018
5657a36
Fix some CS issues.
miina Mar 8, 2018
660bf4a
Resolve conflicts.
miina Mar 8, 2018
aba8455
Merge master.
miina Mar 8, 2018
cd58776
Add blocks-renderer API endpoint. Add skeleton for ServerSideRender c…
miina Mar 12, 2018
b0ede76
Update SSR preview when editing attributes.
miina Mar 13, 2018
340136e
Fix binding preview change.
miina Mar 13, 2018
514dd4f
Fix binding preview change.
miina Mar 13, 2018
a90f40d
Add tests. Fix permission check for get_item.
miina Mar 13, 2018
0c127e1
Remove debugger line.
miina Mar 14, 2018
b0b977a
Fix some phpcs.
miina Mar 14, 2018
395a168
Fix some jscs.
miina Mar 14, 2018
1d05c2d
Show 'loading' when changing response.
miina Mar 14, 2018
c40dd25
Use wp.apiRequest for consistency.
miina Mar 14, 2018
f323651
Update ServerSideRender readme to note intended usage
westonruter Mar 14, 2018
c4abc69
Rename classes, methods, and property to be more aligned with the res…
westonruter Mar 14, 2018
6557877
Register block-renderer endpoint for each dynamic block
westonruter Mar 14, 2018
228c756
Fixes to README. Use isEqual. Renaming method.
miina Mar 16, 2018
b48ef81
Fix checking for existing response.
miina Mar 16, 2018
e39332d
Add putting together query URL from object.
miina Mar 16, 2018
46506a9
Fix some jscs.
miina Mar 16, 2018
ee169b9
Merge remote-tracking branch 'origin/add/780-server-side-render' into…
miina Mar 16, 2018
d83a5e0
Merge SSR component from #5602
miina Mar 16, 2018
ce1f7c6
Fix using correct props with fetching.
miina Mar 16, 2018
a046023
Merge remote-tracking branch 'origin/add/780-server-side-render' into…
miina Mar 16, 2018
14e1ed2
Fix after-merge jscs.
miina Mar 16, 2018
e0fec83
Improve putting together query URL. Use attributes as separate param.
miina Mar 17, 2018
17e404a
Make path constant more readable.
miina Mar 17, 2018
00489bb
Merge remote-tracking branch 'origin/add/780-server-side-render' into…
miina Mar 17, 2018
9f282fb
Merge SSR component. Update archives block accordingly.
miina Mar 17, 2018
39b867a
Add setting global if is present.
miina Mar 29, 2018
2c884cc
Merge remote-tracking branch 'origin/add/780-server-side-render' into…
miina Apr 6, 2018
4c3129b
Merge branch 'master' of github.com:WordPress/gutenberg into add/780-…
miina Apr 6, 2018
0dc74ab
Merge master.
miina Apr 6, 2018
3c60d4b
Update Readme.
miina Apr 6, 2018
a10bfac
Register post_id. Add context. Fix tests.
miina Apr 16, 2018
a166324
Fix CS.
miina Apr 16, 2018
f0f4a77
Merge remote-tracking branch 'origin/master' into add/780-server-side…
miina Apr 16, 2018
6d1ee65
Add more tests. Add exception for namespace to as ruleset.
miina Apr 25, 2018
2bbbeb7
Fix eslint.
miina Apr 25, 2018
6f7d62e
Merge branch 'master' of github.com:WordPress/gutenberg into add/780-…
miina Apr 25, 2018
a923f39
Merge remote-tracking branch 'origin/add/780-server-side-render' into…
miina Apr 25, 2018
b3e3b36
Merge SSR component PR.
miina Apr 25, 2018
f150741
Fix imports.
miina Apr 25, 2018
67af6b7
Add context param to API request.
miina Apr 25, 2018
071dc64
Merge remote-tracking branch 'origin/add/780-server-side-render' into…
miina Apr 25, 2018
bb67a00
Merge master & resolve conflicts.
miina May 1, 2018
0b1156a
Add fixture files.
miina May 1, 2018
eb49866
Use PanelBody instead of h3.
miina May 1, 2018
8c822a6
Merge remote-tracking branch 'origin/master' into add/archives-block
miina May 3, 2018
4603e22
Align left by default.
miina May 3, 2018
226616c
Change default align to none.
miina May 17, 2018
4a5754b
Merge remote-tracking branch 'origin/master' into add/archives-block
miina May 17, 2018
3b50729
Merge remote-tracking branch 'origin/master' into add/archives-block
miina May 22, 2018
d8ee393
Merge branch 'master' into add/archives-block
miina May 23, 2018
128513c
Use Fragment. Use wp.editor instead of wp.blocks.
miina May 23, 2018
d870d2d
Merge remote-tracking branch 'origin/master' into add/archives-block
miina May 29, 2018
a212cbc
Minor fixes.
miina May 29, 2018
931d08c
Use uniqid for dropdown. Disable link events.
miina Jun 1, 2018
1eec0e0
Merge remote-tracking branch 'origin/master' into add/archives-block
miina Jun 1, 2018
74ca70f
Merge remote-tracking branch 'origin/master' into add/archives-block
miina Jul 5, 2018
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
82 changes: 82 additions & 0 deletions core-blocks/archives/block.js
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' ) }
Copy link
Member

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.

label={ __( 'Show Post Counts' ) }

checked={ showPostCounts }
onChange={ this.toggleShowPostCounts }
/>
<ToggleControl
label={ __( 'Display as dropdown' ) }
Copy link
Member

Choose a reason for hiding this comment

The 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 [
Copy link
Member

Choose a reason for hiding this comment

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

Can use Fragment now instead of array syntax. Also, shouldn't need the isSelected boolean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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' ] }
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious why full is supported but not wide. (If both should be, the controls prop doesn't need to be passed at all.)

Copy link
Contributor Author

@miina miina Jun 1, 2018

Choose a reason for hiding this comment

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

Not sure if it should support full either, removed it.

Edit: Originally based this on other dynamic blocks, e.g. Categories and Latest Posts. Not sure if there's a standard for which controls to support. Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The 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 } />,
];
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The 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 toggle* methods. In other words, edit could just be a functional component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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 edit as functional component instead?

Copy link
Contributor

Choose a reason for hiding this comment

The 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;
40 changes: 40 additions & 0 deletions core-blocks/archives/index.js
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' ) ],
Copy link
Member

Choose a reason for hiding this comment

The 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;
Copy link
Member

Choose a reason for hiding this comment

The 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.)

},
};
108 changes: 108 additions & 0 deletions core-blocks/archives/index.php
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++;
Copy link
Contributor

Choose a reason for hiding this comment

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

The way this is used in tandem with ServerSideRender, this will generally lead to ID conflicts. From my own local testing:

document.querySelectorAll( '#wp-block-archives-1' )

returns multiple elements if I have more than one Archive block in my editor.

Copy link
Contributor

Choose a reason for hiding this comment

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

Worth noting that implementing an edit for this block type would allow the editor to retain more control over this kind of information.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added using uniqid instead, thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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?

Copy link
Contributor

Choose a reason for hiding this comment

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

Added using uniqid

That should do for now, thanks.

disabled the pointer-events of the links

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 select elements, but then even more interaction is lost, perhaps leading the user to perceive the experience as "buggy" and, thus, confusing. On the other hand, hijacking select elements to remove their onchange attribute could technically help, but that sounds like a very bad precedent to set. /cc @mtias


$show_post_count = ! empty( $attributes['showPostCounts'] ) ? true : false;
Copy link
Contributor

Choose a reason for hiding this comment

The 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(
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Member

Choose a reason for hiding this comment

The 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' );
2 changes: 2 additions & 0 deletions core-blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import * as image from './image';
import * as heading from './heading';
import * as quote from './quote';
import * as gallery from './gallery';
import * as archives from './archives';
import * as audio from './audio';
import * as button from './button';
import * as categories from './categories';
Expand Down Expand Up @@ -55,6 +56,7 @@ export const registerCoreBlocks = () => {

// Register all remaining core blocks.
shortcode,
archives,
audio,
button,
categories,
Expand Down
1 change: 1 addition & 0 deletions core-blocks/test/fixtures/core__archives.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!-- wp:archives {"showPostCounts":false,"displayAsDropdown":false} /-->
10 changes: 10 additions & 0 deletions core-blocks/test/fixtures/core__archives.json
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": ""
}
]
11 changes: 11 additions & 0 deletions core-blocks/test/fixtures/core__archives.parsed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{
"blockName": "core/archives",
"attrs": {
"showPostCounts": false,
"displayAsDropdown": false
},
"innerBlocks": [],
"innerHTML": ""
}
]
1 change: 1 addition & 0 deletions core-blocks/test/fixtures/core__archives.serialized.html
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} /-->
10 changes: 10 additions & 0 deletions core-blocks/test/fixtures/core__archives__showPostCounts.json
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 /-->