-
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
Query Title: add Search and 404 page titles #33515
Changes from 48 commits
1744a97
a6ceb90
03b2704
47aae1b
00d949f
3b694a9
82ec6c7
b2fb7d7
258dc44
4ebfe53
be5836c
9dd89e5
900c95b
7e3f308
3244717
22d458d
08da5a2
1f40aca
ecdd94b
600204c
ff7179c
0e17396
fb20f58
a571c6f
ad39fe9
2420657
3fa11cc
9ca7923
e02f72d
a527d24
5845908
710759e
018dbb0
38b7675
cf5f3e5
64738dc
9ca257a
ca7498c
b2ebbc8
5e0eef7
9ed105b
152103b
358cb81
b5b52a8
9df71fa
b1c26ae
5d37503
91b79cd
ca655a2
b88c5de
cc02de1
6ccbdad
9f15ae5
eff88a8
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 |
---|---|---|
|
@@ -6,49 +6,102 @@ import classnames from 'classnames'; | |
/** | ||
* WordPress dependencies | ||
*/ | ||
// import { useSelect, useDispatch } from '@wordpress/data'; | ||
import { useDispatch } from '@wordpress/data'; | ||
import { | ||
AlignmentControl, | ||
BlockControls, | ||
useBlockProps, | ||
Warning, | ||
store as blockEditorStore, | ||
InspectorControls, | ||
} from '@wordpress/block-editor'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { TextControl, PanelBody } from '@wordpress/components'; | ||
import { __, _x } from '@wordpress/i18n'; | ||
import { useEffect } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import HeadingLevelDropdown from '../heading/heading-level-dropdown'; | ||
|
||
const SUPPORTED_TYPES = [ 'archive' ]; | ||
const SUPPORTED_TEMPLATES = [ 'archive', 'search', '404', 'index' ]; | ||
|
||
export default function QueryTitleEdit( { | ||
attributes: { type, level, textAlign }, | ||
attributes: { content, searchTitle, nothingFoundTitle, level, textAlign }, | ||
setAttributes, | ||
context: { templateSlug }, | ||
} ) { | ||
const TagName = `h${ level }`; | ||
const blockProps = useBlockProps( { | ||
className: classnames( { | ||
className: classnames( 'wp-block-query-title__placeholder', { | ||
[ `has-text-align-${ textAlign }` ]: textAlign, | ||
'wp-block-query-title__placeholder': type === 'archive', | ||
} ), | ||
} ); | ||
// The plan is to augment this block with more | ||
// block variations like `Search Title`. | ||
if ( ! SUPPORTED_TYPES.includes( type ) ) { | ||
const { __unstableMarkNextChangeAsNotPersistent } = useDispatch( | ||
blockEditorStore | ||
); | ||
let titleContent; | ||
|
||
// translators: Title for index template. | ||
const defaultTitle = _x( | ||
'Query title placeholder', | ||
'index template title' | ||
); | ||
|
||
// translators: Title for archive template. | ||
const defaultArchiveTitle = _x( | ||
'Archive title placeholder', | ||
'archive template title' | ||
); | ||
|
||
// translators: Title for 404 template. | ||
const defaultNothingFoundTitle = _x( | ||
'Nothing found', | ||
'404 template title' | ||
); | ||
|
||
// translators: Title for search template with dynamic content placeholders. | ||
const defaultSearchTitle = _x( | ||
'Search results for "%search%"', | ||
'search template title' | ||
); | ||
|
||
// Infer title content from template slug context | ||
switch ( templateSlug ) { | ||
case 'archive': | ||
titleContent = defaultArchiveTitle; | ||
break; | ||
case 'search': | ||
titleContent = searchTitle; | ||
break; | ||
case '404': | ||
titleContent = nothingFoundTitle; | ||
break; | ||
default: | ||
titleContent = content; | ||
break; | ||
} | ||
|
||
const titleElement = <TagName { ...blockProps }>{ titleContent }</TagName>; | ||
|
||
// Update content based on current template | ||
useEffect( () => { | ||
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. This seems hacky to me 😄 . We use React's implementation details to update the content after the first render and by updating the An alternative, if this approach is preferred, is to 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. Haha I wasn't sure where else to turn so I jumped to As soon as I moved this logic from the variations file to edit.js, I could see the advantage of using variations. However, as @scruffian has just mentioned above, I think the advantage to not using variations is that the user (or a theme) only needs to insert one block, and the block works the content out itself based on context (i.e. the template). With that in mind, I'm going to attempt your suggested alternative. Thanks for the suggestion and input, it's really helped me understand this more. |
||
__unstableMarkNextChangeAsNotPersistent(); | ||
setAttributes( { | ||
content: defaultTitle, | ||
searchTitle: defaultSearchTitle, | ||
nothingFoundTitle: defaultNothingFoundTitle, | ||
} ); | ||
}, [] ); | ||
|
||
if ( ! SUPPORTED_TEMPLATES.includes( templateSlug ) ) { | ||
return ( | ||
<div { ...blockProps }> | ||
<Warning>{ __( 'Provided type is not supported.' ) }</Warning> | ||
<Warning>{ __( 'Template is not supported.' ) }</Warning> | ||
</div> | ||
); | ||
} | ||
|
||
let titleElement; | ||
if ( type === 'archive' ) { | ||
titleElement = ( | ||
<TagName { ...blockProps }>{ __( 'Archive title' ) }</TagName> | ||
); | ||
} | ||
return ( | ||
<> | ||
<BlockControls group="block"> | ||
|
@@ -65,6 +118,32 @@ export default function QueryTitleEdit( { | |
} } | ||
/> | ||
</BlockControls> | ||
<InspectorControls> | ||
<PanelBody title={ __( 'Custom Title Contents' ) }> | ||
<TextControl | ||
label={ __( 'Search Page Title' ) } | ||
help={ `${ __( | ||
'Edit the search template title. Dynamic content is available with: ' | ||
) } %search%, %total%` } | ||
value={ searchTitle } | ||
onChange={ ( value ) => | ||
setAttributes( { | ||
searchTitle: value, | ||
} ) | ||
} | ||
/> | ||
<TextControl | ||
label={ __( '404 Page Title' ) } | ||
help={ __( 'Edit the 404 template title.' ) } | ||
value={ nothingFoundTitle } | ||
onChange={ ( value ) => | ||
setAttributes( { | ||
nothingFoundTitle: value, | ||
} ) | ||
} | ||
/> | ||
</PanelBody> | ||
</InspectorControls> | ||
{ titleElement } | ||
</> | ||
); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,18 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { archiveTitle as icon } from '@wordpress/icons'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import metadata from './block.json'; | ||
import edit from './edit'; | ||
import variations from './variations'; | ||
|
||
const { name } = metadata; | ||
export { metadata, name }; | ||
|
||
export const settings = { | ||
icon, | ||
edit, | ||
variations, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,26 +7,35 @@ | |
|
||
/** | ||
* Renders the `core/query-title` block on the server. | ||
* For now it only supports Archive title, | ||
* For now it supports Archive title, Search title and 404 title, | ||
* using queried object information | ||
* | ||
* @param array $attributes Block attributes. | ||
* | ||
* @return string Returns the query title based on the queried object. | ||
*/ | ||
function render_block_core_query_title( $attributes ) { | ||
$type = isset( $attributes['type'] ) ? $attributes['type'] : null; | ||
$is_search = is_search(); | ||
$is_archive = is_archive(); | ||
if ( ! $type || ( 'archive' === $type && ! $is_archive ) ) { | ||
return ''; | ||
} | ||
$title = ''; | ||
$is_404 = is_404(); | ||
$title = isset( $attributes['content'] ) ? $attributes['content'] : ''; | ||
if ( $is_archive ) { | ||
$title = get_the_archive_title(); | ||
} elseif ( $is_search ) { | ||
$title = isset( $attributes['searchTitle'] ) ? $attributes['searchTitle'] : ''; | ||
global $wp_query; | ||
$formats = array( '%total%', '%search%' ); | ||
$replacements = array( $wp_query->found_posts, get_search_query() ); | ||
$title = str_replace( $formats, $replacements, $title ); | ||
} elseif ( $is_404 ) { | ||
$title = isset( $attributes['nothingFoundTitle'] ) ? $attributes['nothingFoundTitle'] : ''; | ||
} | ||
$tag_name = isset( $attributes['level'] ) ? 'h' . (int) $attributes['level'] : 'h1'; | ||
$align_class_name = empty( $attributes['textAlign'] ) ? '' : "has-text-align-{$attributes['textAlign']}"; | ||
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $align_class_name ) ); | ||
if ( 'Query title placeholder' === $title || empty( $title ) ) { | ||
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. As per my other comment, this should be translatable |
||
return; | ||
} | ||
return sprintf( | ||
'<%1$s %2$s>%3$s</%1$s>', | ||
$tag_name, | ||
|
This file was deleted.
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.
I'd avoid non-translatable default values in
block.json
attributes
.Put the default text in the edit component instead and make it translatable.