PluginProbe
Gutenberg / 9.2.2
Gutenberg v9.2.2
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / templates.php

templates.php in Gutenberg 9.2.2, at lib/templates.php

234 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Block template functions.
4 *
5 * @package gutenberg
6 */
7
8 /**
9 * Returns all block template file path of the current theme and its parent theme.
10 * Includes demo block template files if demo experiment is enabled.
11 *
12 * @return array $block_template_files A list of paths to all template files.
13 */
14 function gutenberg_get_template_paths() {
15 $block_template_files = glob( get_stylesheet_directory() . '/block-templates/*.html' );
16 $block_template_files = is_array( $block_template_files ) ? $block_template_files : array();
17
18 if ( is_child_theme() ) {
19 $child_block_template_files = glob( get_template_directory() . '/block-templates/*.html' );
20 $child_block_template_files = is_array( $child_block_template_files ) ? $child_block_template_files : array();
21 $block_template_files = array_merge( $block_template_files, $child_block_template_files );
22 }
23
24 if ( gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing-demo' ) ) {
25 $demo_block_template_files = glob( dirname( __FILE__ ) . '/demo-block-templates/*.html' );
26 $demo_block_template_files = is_array( $demo_block_template_files ) ? $demo_block_template_files : array();
27 $block_template_files = array_merge( $block_template_files, $demo_block_template_files );
28 }
29
30 return $block_template_files;
31 }
32
33 /**
34 * Registers block editor 'wp_template' post type.
35 */
36 function gutenberg_register_template_post_type() {
37 $labels = array(
38 'name' => __( 'Templates', 'gutenberg' ),
39 'singular_name' => __( 'Template', 'gutenberg' ),
40 'menu_name' => _x( 'Templates', 'Admin Menu text', 'gutenberg' ),
41 'add_new' => _x( 'Add New', 'Template', 'gutenberg' ),
42 'add_new_item' => __( 'Add New Template', 'gutenberg' ),
43 'new_item' => __( 'New Template', 'gutenberg' ),
44 'edit_item' => __( 'Edit Template', 'gutenberg' ),
45 'view_item' => __( 'View Template', 'gutenberg' ),
46 'all_items' => __( 'All Templates', 'gutenberg' ),
47 'search_items' => __( 'Search Templates', 'gutenberg' ),
48 'parent_item_colon' => __( 'Parent Template:', 'gutenberg' ),
49 'not_found' => __( 'No templates found.', 'gutenberg' ),
50 'not_found_in_trash' => __( 'No templates found in Trash.', 'gutenberg' ),
51 'archives' => __( 'Template archives', 'gutenberg' ),
52 'insert_into_item' => __( 'Insert into template', 'gutenberg' ),
53 'uploaded_to_this_item' => __( 'Uploaded to this template', 'gutenberg' ),
54 'filter_items_list' => __( 'Filter templates list', 'gutenberg' ),
55 'items_list_navigation' => __( 'Templates list navigation', 'gutenberg' ),
56 'items_list' => __( 'Templates list', 'gutenberg' ),
57 );
58
59 $args = array(
60 'labels' => $labels,
61 'description' => __( 'Templates to include in your theme.', 'gutenberg' ),
62 'public' => false,
63 'has_archive' => false,
64 'show_ui' => true,
65 'show_in_menu' => 'themes.php',
66 'show_in_admin_bar' => false,
67 'show_in_rest' => true,
68 'rest_base' => 'templates',
69 'capability_type' => array( 'template', 'templates' ),
70 'map_meta_cap' => true,
71 'supports' => array(
72 'title',
73 'slug',
74 'editor',
75 'revisions',
76 ),
77 );
78
79 register_post_type( 'wp_template', $args );
80 }
81 add_action( 'init', 'gutenberg_register_template_post_type' );
82
83 /**
84 * Filters the capabilities of a user to conditionally grant them capabilities for managing 'wp_template' posts.
85 *
86 * Any user who can 'edit_theme_options' will have access.
87 *
88 * @param array $allcaps A user's capabilities.
89 * @return array Filtered $allcaps.
90 */
91 function gutenberg_grant_template_caps( array $allcaps ) {
92 if ( isset( $allcaps['edit_theme_options'] ) ) {
93 $allcaps['edit_templates'] = $allcaps['edit_theme_options'];
94 $allcaps['edit_others_templates'] = $allcaps['edit_theme_options'];
95 $allcaps['edit_published_templates'] = $allcaps['edit_theme_options'];
96 $allcaps['edit_private_templates'] = $allcaps['edit_theme_options'];
97 $allcaps['delete_templates'] = $allcaps['edit_theme_options'];
98 $allcaps['delete_others_templates'] = $allcaps['edit_theme_options'];
99 $allcaps['delete_published_templates'] = $allcaps['edit_theme_options'];
100 $allcaps['delete_private_templates'] = $allcaps['edit_theme_options'];
101 $allcaps['publish_templates'] = $allcaps['edit_theme_options'];
102 $allcaps['read_private_templates'] = $allcaps['edit_theme_options'];
103 }
104
105 return $allcaps;
106 }
107 add_filter( 'user_has_cap', 'gutenberg_grant_template_caps' );
108
109 /**
110 * Filters `wp_template` posts slug resolution to bypass deduplication logic as
111 * template slugs should be unique.
112 *
113 * @param string $slug The resolved slug (post_name).
114 * @param int $post_ID Post ID.
115 * @param string $post_status No uniqueness checks are made if the post is still draft or pending.
116 * @param string $post_type Post type.
117 * @param int $post_parent Post parent ID.
118 * @param int $original_slug The desired slug (post_name).
119 * @return string The original, desired slug.
120 */
121 function gutenberg_filter_wp_template_wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
122 if ( 'wp_template' === $post_type ) {
123 return $original_slug;
124 }
125 return $slug;
126 }
127 add_filter( 'wp_unique_post_slug', 'gutenberg_filter_wp_template_wp_unique_post_slug', 10, 6 );
128
129 /**
130 * Fixes the label of the 'wp_template' admin menu entry.
131 */
132 function gutenberg_fix_template_admin_menu_entry() {
133 global $submenu;
134 if ( ! isset( $submenu['themes.php'] ) ) {
135 return;
136 }
137 $post_type = get_post_type_object( 'wp_template' );
138 if ( ! $post_type ) {
139 return;
140 }
141 foreach ( $submenu['themes.php'] as $key => $submenu_entry ) {
142 if ( $post_type->labels->all_items === $submenu['themes.php'][ $key ][0] ) {
143 $submenu['themes.php'][ $key ][0] = $post_type->labels->menu_name; // phpcs:ignore WordPress.WP.GlobalVariablesOverride
144 break;
145 }
146 }
147 }
148 add_action( 'admin_menu', 'gutenberg_fix_template_admin_menu_entry' );
149
150 /**
151 * Filters the 'wp_template' post type columns in the admin list table.
152 *
153 * @param array $columns Columns to display.
154 * @return array Filtered $columns.
155 */
156 function gutenberg_filter_template_list_table_columns( array $columns ) {
157 $columns['slug'] = __( 'Slug', 'gutenberg' );
158 if ( isset( $columns['date'] ) ) {
159 unset( $columns['date'] );
160 }
161 return $columns;
162 }
163 add_filter( 'manage_wp_template_posts_columns', 'gutenberg_filter_template_list_table_columns' );
164
165 /**
166 * Renders column content for the 'wp_template' post type list table.
167 *
168 * @param string $column_name Column name to render.
169 * @param int $post_id Post ID.
170 */
171 function gutenberg_render_template_list_table_column( $column_name, $post_id ) {
172 if ( 'slug' !== $column_name ) {
173 return;
174 }
175 $post = get_post( $post_id );
176 echo esc_html( $post->post_name );
177 }
178 add_action( 'manage_wp_template_posts_custom_column', 'gutenberg_render_template_list_table_column', 10, 2 );
179
180 /**
181 * Filter for adding a `resolved` parameter to `wp_template` queries.
182 *
183 * @param array $query_params The query parameters.
184 * @return array Filtered $query_params.
185 */
186 function filter_rest_wp_template_collection_params( $query_params ) {
187 $query_params += array(
188 'resolved' => array(
189 'description' => __( 'Whether to filter for resolved templates', 'gutenberg' ),
190 'type' => 'boolean',
191 ),
192 );
193 return $query_params;
194 }
195 apply_filters( 'rest_wp_template_collection_params', 'filter_rest_wp_template_collection_params', 99, 1 );
196
197 /**
198 * Filter for supporting the `resolved` parameter in `wp_template` queries.
199 *
200 * @param array $args The query arguments.
201 * @param WP_REST_Request $request The request object.
202 * @return array Filtered $args.
203 */
204 function filter_rest_wp_template_query( $args, $request ) {
205 // Create auto-drafts for each theme template files.
206 $block_template_files = gutenberg_get_template_paths();
207 foreach ( $block_template_files as $path ) {
208 $template_type = basename( $path, '.html' );
209 gutenberg_find_template_post_and_parts( $template_type, array( $template_type ) );
210 }
211
212 if ( $request['resolved'] ) {
213 $template_ids = array( 0 ); // Return nothing by default (the 0 is needed for `post__in`).
214 $template_types = $request['slug'] ? $request['slug'] : get_template_types();
215
216 foreach ( $template_types as $template_type ) {
217 // Skip 'embed' for now because it is not a regular template type.
218 if ( in_array( $template_type, array( 'embed' ), true ) ) {
219 continue;
220 }
221
222 $current_template = gutenberg_find_template_post_and_parts( $template_type );
223 if ( isset( $current_template ) ) {
224 $template_ids[] = $current_template['template_post']->ID;
225 }
226 }
227 $args['post__in'] = $template_ids;
228 $args['post_status'] = array( 'publish', 'auto-draft' );
229 }
230
231 return $args;
232 }
233 add_filter( 'rest_wp_template_query', 'filter_rest_wp_template_query', 99, 2 );
234