Skip to content

Commit

Permalink
Block Library: Add features to the Post Excerpt block. (#19715)
Browse files Browse the repository at this point in the history
* Lib: Add single demo block template.

* Core Data: Provide full raw properties from `useEntityProp`.

* Block Library: Add features to the Post Excerpt block.

* E2E Tests: Update Post Excerpt block fixtures.

* Block Library: Change Post Excerpt block `excerptLength` to `wordCount`.

* Delete single.html
  • Loading branch information
epiqueras committed Feb 18, 2020
1 parent ec91b39 commit 3d3c3e1
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 15 deletions.
1 change: 1 addition & 0 deletions packages/block-library/src/editor.scss
Expand Up @@ -28,6 +28,7 @@
@import "./navigation-link/editor.scss";
@import "./nextpage/editor.scss";
@import "./paragraph/editor.scss";
@import "./post-excerpt/editor.scss";
@import "./pullquote/editor.scss";
@import "./quote/editor.scss";
@import "./rss/editor.scss";
Expand Down
15 changes: 14 additions & 1 deletion packages/block-library/src/post-excerpt/block.json
@@ -1,4 +1,17 @@
{
"name": "core/post-excerpt",
"category": "layout"
"category": "layout",
"attributes": {
"wordCount": {
"type": "number",
"default": 55
},
"moreText": {
"type": "string"
},
"showMoreOnNewLine": {
"type": "boolean",
"default": true
}
}
}
108 changes: 103 additions & 5 deletions packages/block-library/src/post-excerpt/edit.js
Expand Up @@ -2,20 +2,118 @@
* WordPress dependencies
*/
import { useEntityProp, useEntityId } from '@wordpress/core-data';
import { PlainText } from '@wordpress/block-editor';
import { useMemo } from '@wordpress/element';
import { InspectorControls, RichText } from '@wordpress/block-editor';
import { PanelBody, RangeControl, ToggleControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

function PostExcerptDisplay() {
function usePostContentExcerpt( wordCount ) {
const [ , , { raw: rawPostContent } ] = useEntityProp(
'postType',
'post',
'content'
);
return useMemo( () => {
if ( ! rawPostContent ) {
return '';
}
const excerptElement = document.createElement( 'div' );
excerptElement.innerHTML = rawPostContent;
const excerpt =
excerptElement.textContent || excerptElement.innerText || '';
return excerpt
.trim()
.split( ' ', wordCount )
.join( ' ' );
}, [ rawPostContent, wordCount ] );
}

function PostExcerptEditor( {
attributes: { wordCount, moreText, showMoreOnNewLine },
setAttributes,
isSelected,
} ) {
const [ excerpt, setExcerpt ] = useEntityProp(
'postType',
'post',
'excerpt'
);
return <PlainText value={ excerpt } onChange={ setExcerpt } />;
const postContentExcerpt = usePostContentExcerpt( wordCount );
return (
<>
<InspectorControls>
<PanelBody title={ __( 'Post Excerpt Settings' ) }>
{ ! excerpt && (
<RangeControl
label={ __( 'Max words' ) }
value={ wordCount }
onChange={ ( newExcerptLength ) =>
setAttributes( { wordCount: newExcerptLength } )
}
min={ 10 }
max={ 100 }
/>
) }
<ToggleControl
label={ __( 'Show link on new line' ) }
checked={ showMoreOnNewLine }
onChange={ ( newShowMoreOnNewLine ) =>
setAttributes( {
showMoreOnNewLine: newShowMoreOnNewLine,
} )
}
/>
</PanelBody>
</InspectorControls>
<RichText
className={
! showMoreOnNewLine &&
'wp-block-post-excerpt__excerpt is-inline'
}
placeholder={ postContentExcerpt }
value={ excerpt || ( isSelected ? '' : postContentExcerpt ) }
onChange={ setExcerpt }
keepPlaceholderOnFocus
/>
{ ! showMoreOnNewLine && ' ' }
{ showMoreOnNewLine ? (
<p>
<RichText
tagName="a"
placeholder={ __( 'Read more…' ) }
value={ moreText }
onChange={ ( newMoreText ) =>
setAttributes( { moreText: newMoreText } )
}
/>
</p>
) : (
<RichText
tagName="a"
placeholder={ __( 'Read more…' ) }
value={ moreText }
onChange={ ( newMoreText ) =>
setAttributes( { moreText: newMoreText } )
}
/>
) }
</>
);
}

export default function PostExcerptEdit() {
export default function PostExcerptEdit( {
attributes,
setAttributes,
isSelected,
} ) {
if ( ! useEntityId( 'postType', 'post' ) ) {
return 'Post Excerpt Placeholder';
}
return <PostExcerptDisplay />;
return (
<PostExcerptEditor
attributes={ attributes }
setAttributes={ setAttributes }
isSelected={ isSelected }
/>
);
}
3 changes: 3 additions & 0 deletions packages/block-library/src/post-excerpt/editor.scss
@@ -0,0 +1,3 @@
.wp-block-post-excerpt__excerpt.is-inline {
display: inline-block;
}
42 changes: 40 additions & 2 deletions packages/block-library/src/post-excerpt/index.php
Expand Up @@ -8,14 +8,39 @@
/**
* Renders the `core/post-excerpt` block on the server.
*
* @param array $attributes The block attributes.
*
* @return string Returns the filtered post excerpt for the current post wrapped inside "p" tags.
*/
function render_block_core_post_excerpt() {
function render_block_core_post_excerpt( $attributes ) {
$post = gutenberg_get_post_from_context();
if ( ! $post ) {
return '';
}
return '<p>' . get_the_excerpt( $post ) . '</p>';

$more_text = isset( $attributes['moreText'] ) ? '<a href="' . esc_url( get_the_permalink( $post ) ) . '">' . $attributes['moreText'] . '</a>' : '';

$filter_excerpt_length = function() use ( $attributes ) {
return isset( $attributes['wordCount'] ) ? $attributes['wordCount'] : 55;
};
add_filter(
'excerpt_length',
$filter_excerpt_length
);

$output = '<p>' . get_the_excerpt( $post );
if ( ! isset( $attributes['showMoreOnNewLine'] ) || $attributes['showMoreOnNewLine'] ) {
$output .= '</p>' . '<p>' . $more_text . '</p>';
} else {
$output .= ' ' . $more_text . '</p>';
}

remove_filter(
'excerpt_length',
$filter_excerpt_length
);

return $output;
}

/**
Expand All @@ -25,6 +50,19 @@ function register_block_core_post_excerpt() {
register_block_type(
'core/post-excerpt',
array(
'attributes' => array(
'wordCount' => array(
'type' => 'number',
'default' => 55,
),
'moreText' => array(
'type' => 'string',
),
'showMoreOnNewLine' => array(
'type' => 'boolean',
'default' => true,
),
),
'render_callback' => 'render_block_core_post_excerpt',
)
);
Expand Down
16 changes: 11 additions & 5 deletions packages/core-data/src/entity-provider.js
Expand Up @@ -85,12 +85,18 @@ export function useEntityId( kind, type ) {
export function useEntityProp( kind, type, prop ) {
const id = useEntityId( kind, type );

const value = useSelect(
const { value, fullValue } = useSelect(
( select ) => {
const { getEntityRecord, getEditedEntityRecord } = select( 'core' );
getEntityRecord( kind, type, id ); // Trigger resolver.
const entity = getEditedEntityRecord( kind, type, id );
return entity && entity[ prop ];
const entity = getEntityRecord( kind, type, id ); // Trigger resolver.
const editedEntity = getEditedEntityRecord( kind, type, id );
return (
entity &&
editedEntity && {
value: editedEntity[ prop ],
fullValue: entity[ prop ],
}
);
},
[ kind, type, id, prop ]
);
Expand All @@ -105,7 +111,7 @@ export function useEntityProp( kind, type, prop ) {
[ kind, type, id, prop ]
);

return [ value, setValue ];
return [ value, setValue, fullValue ];
}

/**
Expand Down
5 changes: 4 additions & 1 deletion packages/e2e-tests/fixtures/blocks/core__post-excerpt.json
Expand Up @@ -3,7 +3,10 @@
"clientId": "_clientId_0",
"name": "core/post-excerpt",
"isValid": true,
"attributes": {},
"attributes": {
"wordCount": 55,
"showMoreOnNewLine": true
},
"innerBlocks": [],
"originalContent": ""
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/full-content/server-registered.json
@@ -1 +1 @@
{"core\/archives":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/block":{"attributes":{"ref":{"type":"number"}}},"core\/calendar":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"month":{"type":"integer"},"year":{"type":"integer"}}},"core\/categories":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showHierarchy":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/latest-comments":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"commentsToShow":{"type":"number","default":5,"minimum":1,"maximum":100},"displayAvatar":{"type":"boolean","default":true},"displayDate":{"type":"boolean","default":true},"displayExcerpt":{"type":"boolean","default":true}}},"core\/latest-posts":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"categories":{"type":"string"},"postsToShow":{"type":"number","default":5},"displayPostContent":{"type":"boolean","default":false},"displayPostContentRadio":{"type":"string","default":"excerpt"},"excerptLength":{"type":"number","default":55},"displayPostDate":{"type":"boolean","default":false},"postLayout":{"type":"string","default":"list"},"columns":{"type":"number","default":3},"order":{"type":"string","default":"desc"},"orderBy":{"type":"string","default":"date"},"displayFeaturedImage":{"type":"boolean","default":false},"featuredImageAlign":{"type":"string","enum":["left","center","right"]},"featuredImageSizeSlug":{"type":"string","default":"thumbnail"},"featuredImageSizeWidth":{"type":"number","default":null},"featuredImageSizeHeight":{"type":"number","default":null}}},"core\/legacy-widget":{"attributes":{"widgetClass":{"type":"string"},"id":{"type":"string"},"idBase":{"type":"string"},"number":{"type":"number"},"instance":{"type":"object"}}},"core\/navigation":{"attributes":{"className":{"type":"string"},"textColor":{"type":"string"},"customTextColor":{"type":"string"},"rgbTextColor":{"type":"string"},"backgroundColor":{"type":"string"},"customBackgroundColor":{"type":"string"},"rgbBackgroundColor":{"type":"string"},"fontSize":{"type":"string"},"customFontSize":{"type":"number"},"itemsJustification":{"type":"string"},"showSubmenuIcon":{"type":"boolean","default":true}}},"core\/post-comments-count":{"attributes":{"className":{"type":"string"}}},"core\/rss":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"columns":{"type":"number","default":2},"blockLayout":{"type":"string","default":"list"},"feedURL":{"type":"string","default":""},"itemsToShow":{"type":"number","default":5},"displayExcerpt":{"type":"boolean","default":false},"displayAuthor":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":false},"excerptLength":{"type":"number","default":55}}},"core\/search":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"label":{"type":"string","default":"Search"},"placeholder":{"type":"string","default":""},"buttonText":{"type":"string","default":"Search"}}},"core\/tag-cloud":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"taxonomy":{"type":"string","default":"post_tag"},"showTagCounts":{"type":"boolean","default":false}}},"core\/template-part":{"attributes":{"postId":{"type":"number"},"slug":{"type":"string"},"theme":{"type":"string"}}}}
{"core\/archives":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/block":{"attributes":{"ref":{"type":"number"}}},"core\/calendar":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"month":{"type":"integer"},"year":{"type":"integer"}}},"core\/categories":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"displayAsDropdown":{"type":"boolean","default":false},"showHierarchy":{"type":"boolean","default":false},"showPostCounts":{"type":"boolean","default":false}}},"core\/latest-comments":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"commentsToShow":{"type":"number","default":5,"minimum":1,"maximum":100},"displayAvatar":{"type":"boolean","default":true},"displayDate":{"type":"boolean","default":true},"displayExcerpt":{"type":"boolean","default":true}}},"core\/latest-posts":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"categories":{"type":"string"},"postsToShow":{"type":"number","default":5},"displayPostContent":{"type":"boolean","default":false},"displayPostContentRadio":{"type":"string","default":"excerpt"},"excerptLength":{"type":"number","default":55},"displayPostDate":{"type":"boolean","default":false},"postLayout":{"type":"string","default":"list"},"columns":{"type":"number","default":3},"order":{"type":"string","default":"desc"},"orderBy":{"type":"string","default":"date"},"displayFeaturedImage":{"type":"boolean","default":false},"featuredImageAlign":{"type":"string","enum":["left","center","right"]},"featuredImageSizeSlug":{"type":"string","default":"thumbnail"},"featuredImageSizeWidth":{"type":"number","default":null},"featuredImageSizeHeight":{"type":"number","default":null}}},"core\/legacy-widget":{"attributes":{"widgetClass":{"type":"string"},"id":{"type":"string"},"idBase":{"type":"string"},"number":{"type":"number"},"instance":{"type":"object"}}},"core\/navigation":{"attributes":{"className":{"type":"string"},"textColor":{"type":"string"},"customTextColor":{"type":"string"},"rgbTextColor":{"type":"string"},"backgroundColor":{"type":"string"},"customBackgroundColor":{"type":"string"},"rgbBackgroundColor":{"type":"string"},"fontSize":{"type":"string"},"customFontSize":{"type":"number"},"itemsJustification":{"type":"string"},"showSubmenuIcon":{"type":"boolean","default":true}}},"core\/post-comments-count":{"attributes":{"className":{"type":"string"}}},"core\/post-excerpt":{"attributes":{"wordCount":{"type":"number","default":55},"moreText":{"type":"string"},"showMoreOnNewLine":{"type":"boolean","default":true}}},"core\/rss":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"columns":{"type":"number","default":2},"blockLayout":{"type":"string","default":"list"},"feedURL":{"type":"string","default":""},"itemsToShow":{"type":"number","default":5},"displayExcerpt":{"type":"boolean","default":false},"displayAuthor":{"type":"boolean","default":false},"displayDate":{"type":"boolean","default":false},"excerptLength":{"type":"number","default":55}}},"core\/search":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"label":{"type":"string","default":"Search"},"placeholder":{"type":"string","default":""},"buttonText":{"type":"string","default":"Search"}}},"core\/tag-cloud":{"attributes":{"align":{"type":"string","enum":["left","center","right","wide","full"]},"className":{"type":"string"},"taxonomy":{"type":"string","default":"post_tag"},"showTagCounts":{"type":"boolean","default":false}}},"core\/template-part":{"attributes":{"postId":{"type":"number"},"slug":{"type":"string"},"theme":{"type":"string"}}}}

0 comments on commit 3d3c3e1

Please sign in to comment.