Skip to content

Commit

Permalink
Add new RSS Block (#7966)
Browse files Browse the repository at this point in the history
  • Loading branch information
Soean authored and youknowriad committed Jan 25, 2019
1 parent 4afda93 commit be9870d
Show file tree
Hide file tree
Showing 13 changed files with 425 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
if ( ! function_exists( 'render_block_core_latest_posts' ) ) {
require dirname( __FILE__ ) . '/../packages/block-library/src/latest-posts/index.php';
}
if ( ! function_exists( 'render_block_core_rss' ) ) {
require dirname( __FILE__ ) . '/../packages/block-library/src/rss/index.php';
}
if ( ! function_exists( 'render_block_core_shortcode' ) ) {
require dirname( __FILE__ ) . '/../packages/block-library/src/shortcode/index.php';
}
1 change: 1 addition & 0 deletions packages/block-library/src/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
@import "./preformatted/editor.scss";
@import "./pullquote/editor.scss";
@import "./quote/editor.scss";
@import "./rss/editor.scss";
@import "./shortcode/editor.scss";
@import "./spacer/editor.scss";
@import "./subhead/editor.scss";
Expand Down
2 changes: 2 additions & 0 deletions packages/block-library/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import * as nextpage from './nextpage';
import * as preformatted from './preformatted';
import * as pullquote from './pullquote';
import * as reusableBlock from './block';
import * as rss from './rss';
import * as separator from './separator';
import * as shortcode from './shortcode';
import * as spacer from './spacer';
Expand Down Expand Up @@ -85,6 +86,7 @@ export const registerCoreBlocks = () => {
nextpage,
preformatted,
pullquote,
rss,
separator,
reusableBlock,
spacer,
Expand Down
169 changes: 169 additions & 0 deletions packages/block-library/src/rss/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/**
* WordPress dependencies
*/
import { Component, Fragment } from '@wordpress/element';
import {
Button,
Disabled,
PanelBody,
Placeholder,
RangeControl,
ServerSideRender,
TextControl,
ToggleControl,
Toolbar,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import {
BlockControls,
InspectorControls,
} from '@wordpress/editor';

const DEFAULT_MIN_ITEMS = 1;
const DEFAULT_MAX_ITEMS = 10;

class RSSEdit extends Component {
constructor() {
super( ...arguments );

this.state = {
editing: ! this.props.attributes.feedURL,
};

this.toggleAttribute = this.toggleAttribute.bind( this );
this.onSubmitURL = this.onSubmitURL.bind( this );
}

toggleAttribute( propName ) {
return () => {
const value = this.props.attributes[ propName ];
const { setAttributes } = this.props;

setAttributes( { [ propName ]: ! value } );
};
}

onSubmitURL( event ) {
event.preventDefault();

const { feedURL } = this.props.attributes;
if ( feedURL ) {
this.setState( { editing: false } );
}
}

render() {
const {
blockLayout,
columns,
displayAuthor,
displayExcerpt,
displayDate,
excerptLength,
feedURL,
itemsToShow,
} = this.props.attributes;
const { setAttributes } = this.props;

if ( this.state.editing ) {
return (
<Placeholder
icon="rss"
label="RSS"
>
<form onSubmit={ this.onSubmitURL }>
<TextControl
placeholder={ __( 'Enter URL here…' ) }
value={ feedURL }
onChange={ ( value ) => setAttributes( { feedURL: value } ) }
className={ 'components-placeholder__input' }
/>
<Button isLarge type="submit">
{ __( 'Use URL' ) }
</Button>
</form>
</Placeholder>
);
}

const toolbarControls = [
{
icon: 'edit',
title: __( 'Edit RSS URL' ),
onClick: () => this.setState( { editing: true } ),
},
{
icon: 'list-view',
title: __( 'List View' ),
onClick: () => setAttributes( { blockLayout: 'list' } ),
isActive: blockLayout === 'list',
},
{
icon: 'grid-view',
title: __( 'Grid View' ),
onClick: () => setAttributes( { blockLayout: 'grid' } ),
isActive: blockLayout === 'grid',
},
];

return (
<Fragment>
<BlockControls>
<Toolbar controls={ toolbarControls } />
</BlockControls>
<InspectorControls>
<PanelBody title={ __( 'RSS Settings' ) }>
<RangeControl
label={ __( 'Number of items' ) }
value={ itemsToShow }
onChange={ ( value ) => setAttributes( { itemsToShow: value } ) }
min={ DEFAULT_MIN_ITEMS }
max={ DEFAULT_MAX_ITEMS }
/>
<ToggleControl
label={ __( 'Display author' ) }
checked={ displayAuthor }
onChange={ this.toggleAttribute( 'displayAuthor' ) }
/>
<ToggleControl
label={ __( 'Display date' ) }
checked={ displayDate }
onChange={ this.toggleAttribute( 'displayDate' ) }
/>
<ToggleControl
label={ __( 'Display excerpt' ) }
checked={ displayExcerpt }
onChange={ this.toggleAttribute( 'displayExcerpt' ) }
/>
{ displayExcerpt &&
<RangeControl
label={ __( 'Max length of the excerpt' ) }
value={ excerptLength }
onChange={ ( value ) => setAttributes( { excerptLength: value } ) }
min={ 0 }
max={ 100 }
/>
}
{ blockLayout === 'grid' &&
<RangeControl
label={ __( 'Columns' ) }
value={ columns }
onChange={ ( value ) => setAttributes( { columns: value } ) }
min={ 2 }
max={ 6 }
/>
}
</PanelBody>
</InspectorControls>
<Disabled>
<ServerSideRender
block="core/rss"
attributes={ this.props.attributes }
/>
</Disabled>
</Fragment>
);
}
}

export default RSSEdit;
6 changes: 6 additions & 0 deletions packages/block-library/src/rss/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.block-editor .wp-block-rss {
padding-left: 2.5em;
&.is-grid {
padding-left: 0;
}
}
33 changes: 33 additions & 0 deletions packages/block-library/src/rss/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import edit from './edit';

export const name = 'core/rss';

export const settings = {
title: __( 'RSS' ),

description: __( 'Display entries from any RSS or Atom feed.' ),

icon: 'rss',

category: 'widgets',

keywords: [ __( 'atom' ), __( 'feed' ) ],

supports: {
html: false,
},

edit,

save() {
return null;
},
};
137 changes: 137 additions & 0 deletions packages/block-library/src/rss/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php
/**
* Server-side rendering of the `core/rss` block.
*
* @package WordPress
*/

/**
* Renders the `core/rss` block on server.
*
* @param array $attributes The block attributes.
*
* @return string Returns the block content with received rss items.
*/
function render_block_core_rss( $attributes ) {
$rss = fetch_feed( $attributes['feedURL'] );

if ( is_wp_error( $rss ) ) {
return '<div class="components-placeholder"><div class="notice notice-error"><strong>' . __( 'RSS Error:' ) . '</strong> ' . $rss->get_error_message() . '</div></div>';
}

if ( ! $rss->get_item_quantity() ) {
// PHP 5.2 compatibility. See: http://simplepie.org/wiki/faq/i_m_getting_memory_leaks.
$rss->__destruct();
unset( $rss );

return '<div class="components-placeholder"><div class="notice notice-error">' . __( 'An error has occurred, which probably means the feed is down. Try again later.' ) . '</div></div>';
}

$rss_items = $rss->get_items( 0, $attributes['itemsToShow'] );
$list_items = '';
foreach ( $rss_items as $item ) {
$title = esc_html( trim( strip_tags( $item->get_title() ) ) );
if ( empty( $title ) ) {
$title = __( '(Untitled)' );
}
$link = $item->get_link();
$link = esc_url( $link );
if ( $link ) {
$title = "<a href='{$link}'>{$title}</a>";
}
$title = "<div class='wp-block-rss__item-title'>{$title}</div>";

$date = '';
if ( $attributes['displayDate'] ) {
$date = $item->get_date( 'U' );

if ( $date ) {
$date = sprintf(
'<time datetime="%1$s" class="wp-block-rss__item-publish-date">%2$s</time> ',
date_i18n( get_option( 'c' ), $date ),
date_i18n( get_option( 'date_format' ), $date )
);
}
}

$author = '';
if ( $attributes['displayAuthor'] ) {
$author = $item->get_author();
if ( is_object( $author ) ) {
$author = $author->get_name();
$author = '<span class="wp-block-rss__item-author">' . __( 'by' ) . ' ' . esc_html( strip_tags( $author ) ) . '</span>';
}
}

$excerpt = '';
if ( $attributes['displayExcerpt'] ) {
$excerpt = html_entity_decode( $item->get_description(), ENT_QUOTES, get_option( 'blog_charset' ) );
$excerpt = esc_attr( wp_trim_words( $excerpt, $attributes['excerptLength'], ' [&hellip;]' ) );

// Change existing [...] to [&hellip;].
if ( '[...]' == substr( $excerpt, -5 ) ) {
$excerpt = substr( $excerpt, 0, -5 ) . '[&hellip;]';
}

$excerpt = '<div class="wp-block-rss__item-excerpt">' . esc_html( $excerpt ) . '</div>';
}

$list_items .= "<li class='wp-block-rss__item'>{$title}{$date}{$author}{$excerpt}</li>";
}

$classes = 'grid' === $attributes['blockLayout'] ? ' is-grid columns-' . $attributes['columns'] : '';
$list_items_markup = "<ul class='wp-block-rss{$classes}'>{$list_items}</ul>";

// PHP 5.2 compatibility. See: http://simplepie.org/wiki/faq/i_m_getting_memory_leaks.
$rss->__destruct();
unset( $rss );

return $list_items_markup;
}

/**
* Registers the `core/rss` block on server.
*/
function register_block_core_rss() {
register_block_type( 'core/rss',
array(
'attributes' => array(
'columns' => array(
'type' => 'number',
'default' => 2,
),
'blockLayout' => array(
'type' => 'string',
'default' => 'list',
),
'feedURL' => array(
'type' => 'string',
'default' => '',
),
'itemsToShow' => array(
'type' => 'number',
'default' => 5,
),
'displayExcerpt' => array(
'type' => 'boolean',
'default' => false,
),
'displayAuthor' => array(
'type' => 'boolean',
'default' => false,
),
'displayDate' => array(
'type' => 'boolean',
'default' => false,
),
'excerptLength' => array(
'type' => 'number',
'default' => 55,
),
),
'render_callback' => 'render_block_core_rss',
)
);
}

add_action( 'init', 'register_block_core_rss' );
Loading

0 comments on commit be9870d

Please sign in to comment.