Skip to content

Commit 88656eb

Browse files
Site Editor > Templates: move config to the server (WordPress#76622)
Co-authored-by: oandregal <oandregal@git.wordpress.org> Co-authored-by: ntsekouras <ntsekouras@git.wordpress.org>
1 parent fe5d9ce commit 88656eb

File tree

5 files changed

+268
-67
lines changed

5 files changed

+268
-67
lines changed

backport-changelog/7.1/11272.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ https://github.com/WordPress/wordpress-develop/pull/11272
22

33
* https://github.com/WordPress/gutenberg/pull/76573
44
* https://github.com/WordPress/gutenberg/pull/76734
5+
* https://github.com/WordPress/gutenberg/pull/76622

lib/compat/wordpress-7.1/class-gutenberg-rest-view-config-controller-7-1.php

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ public function get_items( $request ) {
122122
} elseif ( 'postType' === $kind && 'wp_template_part' === $name ) {
123123
$default_layouts = $this->get_default_layouts_for_wp_template_part();
124124
$default_view = $this->get_default_view_for_wp_template_part( $default_layouts );
125+
} elseif ( 'postType' === $kind && 'wp_template' === $name ) {
126+
$default_view = $this->get_default_view_for_wp_template();
127+
$default_layouts = $this->get_default_layouts_for_wp_template();
128+
$view_list = $this->get_view_list_for_wp_template();
125129
}
126130

127131
$response = array(
@@ -675,4 +679,185 @@ private function get_default_view_for_wp_template_part( $default_layouts ) {
675679
'layout' => $default_layouts['grid']['layout'],
676680
);
677681
}
682+
683+
/**
684+
* Returns the original source of a template.
685+
*
686+
* @param WP_Block_Template $template_object Template instance.
687+
* @return string The original source ('theme', 'plugin', 'site', or 'user').
688+
*/
689+
private static function get_wp_templates_original_source_field( $template_object ) {
690+
if ( 'wp_template' === $template_object->type || 'wp_template_part' === $template_object->type ) {
691+
/*
692+
* Added by theme.
693+
* Template originally provided by a theme, but customized by a user.
694+
* Templates originally didn't have the 'origin' field so identify
695+
* older customized templates by checking for no origin and a 'theme'
696+
* or 'custom' source.
697+
*/
698+
if ( $template_object->has_theme_file &&
699+
( 'theme' === $template_object->origin || (
700+
empty( $template_object->origin ) && in_array(
701+
$template_object->source,
702+
array(
703+
'theme',
704+
'custom',
705+
),
706+
true
707+
) )
708+
)
709+
) {
710+
return 'theme';
711+
}
712+
713+
// Added by plugin.
714+
if ( 'plugin' === $template_object->origin ) {
715+
return 'plugin';
716+
}
717+
718+
/*
719+
* Added by site.
720+
* Template was created from scratch, but has no author. Author support
721+
* was only added to templates in WordPress 5.9. Fallback to showing the
722+
* site logo and title.
723+
*/
724+
if ( empty( $template_object->has_theme_file ) && 'custom' === $template_object->source && empty( $template_object->author ) ) {
725+
return 'site';
726+
}
727+
}
728+
729+
// Added by user.
730+
return 'user';
731+
}
732+
733+
/**
734+
* Returns a human readable text for the author of a template.
735+
*
736+
* @param WP_Block_Template $template_object Template instance.
737+
* @return string Human readable text for the author.
738+
*/
739+
private static function get_wp_templates_author_text_field( $template_object ) {
740+
$original_source = self::get_wp_templates_original_source_field( $template_object );
741+
switch ( $original_source ) {
742+
case 'theme':
743+
$theme_name = wp_get_theme( $template_object->theme )->get( 'Name' );
744+
return empty( $theme_name ) ? $template_object->theme : $theme_name;
745+
case 'plugin':
746+
if ( ! function_exists( 'get_plugins' ) ) {
747+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
748+
}
749+
if ( isset( $template_object->plugin ) ) {
750+
$plugins = wp_get_active_and_valid_plugins();
751+
752+
foreach ( $plugins as $plugin_file ) {
753+
$plugin_basename = plugin_basename( $plugin_file );
754+
list( $plugin_slug, ) = explode( '/', $plugin_basename );
755+
756+
if ( $plugin_slug === $template_object->plugin ) {
757+
$plugin_data = get_plugin_data( $plugin_file );
758+
759+
if ( ! empty( $plugin_data['Name'] ) ) {
760+
return $plugin_data['Name'];
761+
}
762+
763+
break;
764+
}
765+
}
766+
}
767+
768+
/*
769+
* Fall back to the theme name if the plugin is not defined. That's needed to keep backwards
770+
* compatibility with templates that were registered before the plugin attribute was added.
771+
*/
772+
$plugins = get_plugins();
773+
$plugin_basename = plugin_basename( sanitize_text_field( $template_object->theme . '.php' ) );
774+
if ( isset( $plugins[ $plugin_basename ] ) && isset( $plugins[ $plugin_basename ]['Name'] ) ) {
775+
return $plugins[ $plugin_basename ]['Name'];
776+
}
777+
return $template_object->plugin ?? $template_object->theme;
778+
case 'site':
779+
return get_bloginfo( 'name' );
780+
case 'user':
781+
$author = get_user_by( 'id', $template_object->author );
782+
if ( ! $author ) {
783+
return __( 'Unknown author', 'gutenberg' );
784+
}
785+
return $author->get( 'display_name' );
786+
}
787+
788+
// Fail-safe to return a string should the original source ever fall through.
789+
return '';
790+
}
791+
792+
private function get_default_view_for_wp_template() {
793+
return array(
794+
'type' => 'grid',
795+
'perPage' => 20,
796+
'sort' => array(
797+
'field' => 'title',
798+
'direction' => 'asc',
799+
),
800+
'titleField' => 'title',
801+
'descriptionField' => 'description',
802+
'mediaField' => 'preview',
803+
'fields' => array( 'author', 'active', 'slug', 'theme' ),
804+
'filters' => array(),
805+
'showMedia' => true,
806+
);
807+
}
808+
809+
private function get_default_layouts_for_wp_template() {
810+
return array(
811+
'table' => array( 'showMedia' => false ),
812+
'grid' => array( 'showMedia' => true ),
813+
'list' => array( 'showMedia' => false ),
814+
);
815+
}
816+
817+
private function get_view_list_for_wp_template() {
818+
$view_list = array(
819+
array(
820+
'title' => __( 'All templates', 'gutenberg' ),
821+
'slug' => 'all',
822+
),
823+
);
824+
825+
$templates = get_block_templates( array(), 'wp_template' );
826+
827+
// Collect unique authors, tracking whether they come from a registered
828+
// source (theme, plugin, site) so we can sort those before user ones.
829+
$seen_authors = array();
830+
$registered_authors = array();
831+
$user_authors = array();
832+
foreach ( $templates as $template ) {
833+
$original_source = self::get_wp_templates_original_source_field( $template );
834+
$author_text = self::get_wp_templates_author_text_field( $template );
835+
if ( ! empty( $author_text ) && ! isset( $seen_authors[ $author_text ] ) ) {
836+
$seen_authors[ $author_text ] = true;
837+
$entry = array(
838+
'title' => $author_text,
839+
'slug' => $author_text,
840+
'view' => array(
841+
'filters' => array(
842+
array(
843+
'field' => 'author',
844+
'operator' => 'is',
845+
'value' => $author_text,
846+
'isLocked' => true,
847+
),
848+
),
849+
),
850+
);
851+
if ( 'user' === $original_source ) {
852+
$user_authors[] = $entry;
853+
} else {
854+
$registered_authors[] = $entry;
855+
}
856+
}
857+
}
858+
859+
$view_list = array_merge( $view_list, $registered_authors, $user_authors );
860+
861+
return $view_list;
862+
}
678863
}

packages/edit-site/src/components/page-templates/index-legacy.js

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
1010
import { privateApis as editorPrivateApis } from '@wordpress/editor';
1111
import { addQueryArgs } from '@wordpress/url';
1212
import { useEvent } from '@wordpress/compose';
13-
import { useView } from '@wordpress/views';
13+
import { useView, useViewConfig } from '@wordpress/views';
1414

1515
/**
1616
* Internal dependencies
@@ -20,32 +20,35 @@ import { TEMPLATE_POST_TYPE } from '../../utils/constants';
2020
import { unlock } from '../../lock-unlock';
2121
import { useEditPostAction } from '../dataviews-actions';
2222
import { authorField, descriptionField, previewField } from './fields';
23-
import {
24-
defaultLayouts,
25-
DEFAULT_VIEW,
26-
getActiveViewOverridesForTab,
27-
} from './view-utils';
2823

2924
const { usePostActions, templateTitleField } = unlock( editorPrivateApis );
3025
const { useHistory, useLocation } = unlock( routerPrivateApis );
3126
const { useEntityRecordsWithPermissions } = unlock( corePrivateApis );
3227

3328
export default function PageTemplates() {
3429
const { path, query } = useLocation();
35-
const { activeView = 'active', postId } = query;
30+
const { activeView = 'all', postId } = query;
3631
const [ selection, setSelection ] = useState( [ postId ] );
3732

38-
const defaultView = DEFAULT_VIEW;
33+
const {
34+
default_view: defaultView,
35+
default_layouts: defaultLayouts,
36+
view_list: viewList,
37+
} = useViewConfig( {
38+
kind: 'postType',
39+
name: TEMPLATE_POST_TYPE,
40+
} );
3941
const activeViewOverrides = useMemo(
40-
() => getActiveViewOverridesForTab( activeView ),
41-
[ activeView ]
42+
() => viewList?.find( ( v ) => v.slug === activeView )?.view ?? {},
43+
[ viewList, activeView ]
4244
);
4345
const { view, updateView, isModified, resetToDefault } = useView( {
4446
kind: 'postType',
4547
name: TEMPLATE_POST_TYPE,
4648
slug: 'default',
4749
defaultView,
4850
activeViewOverrides,
51+
defaultLayouts,
4952
queryParams: {
5053
page: query.pageNumber,
5154
search: query.search,
@@ -150,7 +153,7 @@ export default function PageTemplates() {
150153
history.navigate( `/wp_template/${ id }?canvas=edit` );
151154
} }
152155
selection={ selection }
153-
defaultLayouts={ defaultLayouts }
156+
defaultLayouts={ defaultLayouts ?? {} }
154157
onReset={
155158
isModified
156159
? () => {

0 commit comments

Comments
 (0)