PluginProbe
Gutenberg / 14.7.0
Gutenberg v14.7.0
24.0.0 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 All 403 releases
gutenberg / lib / compat / wordpress-6.1 / block-patterns.php

block-patterns.php in Gutenberg 14.7.0, at lib/compat/wordpress-6.1/block-patterns.php

177 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Block patterns registration from within a theme
4 *
5 * @package gutenberg
6 */
7
8 /**
9 * Register any patterns that the active theme may provide under its
10 * `./patterns/` directory. Each pattern is defined as a PHP file and defines
11 * its metadata using plugin-style headers. The minimum required definition is:
12 *
13 * /**
14 * * Title: My Pattern
15 * * Slug: my-theme/my-pattern
16 * *
17 *
18 * The output of the PHP source corresponds to the content of the pattern, e.g.:
19 *
20 * <main><p><?php echo "Hello"; ?></p></main>
21 *
22 * If applicable, this will collect from both parent and child theme.
23 *
24 * Other settable fields include:
25 *
26 * - Description
27 * - Viewport Width
28 * - Categories (comma-separated values)
29 * - Keywords (comma-separated values)
30 * - Block Types (comma-separated values)
31 * - Post Types (comma-separated values)
32 * - Inserter (yes/no)
33 *
34 * @since 6.0.0
35 * @access private
36 */
37 function gutenberg_register_theme_block_patterns() {
38 $default_headers = array(
39 'title' => 'Title',
40 'slug' => 'Slug',
41 'description' => 'Description',
42 'viewportWidth' => 'Viewport Width',
43 'categories' => 'Categories',
44 'keywords' => 'Keywords',
45 'blockTypes' => 'Block Types',
46 'postTypes' => 'Post Types',
47 'inserter' => 'Inserter',
48 );
49
50 /*
51 * Register patterns for the active theme. If the theme is a child theme,
52 * let it override any patterns from the parent theme that shares the same slug.
53 */
54 $themes = array();
55 $wp_theme = wp_get_theme();
56 if ( $wp_theme->parent() ) {
57 $themes[] = $wp_theme->parent();
58 }
59 $themes[] = $wp_theme;
60
61 foreach ( $themes as $theme ) {
62 $dirpath = $theme->get_stylesheet_directory() . '/patterns/';
63 if ( ! is_dir( $dirpath ) || ! is_readable( $dirpath ) ) {
64 continue;
65 }
66 if ( file_exists( $dirpath ) ) {
67 $files = glob( $dirpath . '*.php' );
68 if ( $files ) {
69 foreach ( $files as $file ) {
70 $pattern_data = get_file_data( $file, $default_headers );
71
72 if ( empty( $pattern_data['slug'] ) ) {
73 _doing_it_wrong(
74 '_register_theme_block_patterns',
75 sprintf(
76 /* translators: %s: file name. */
77 __( 'Could not register file "%s" as a block pattern ("Slug" field missing)', 'gutenberg' ),
78 $file
79 ),
80 '6.0.0'
81 );
82 continue;
83 }
84
85 if ( ! preg_match( '/^[A-z0-9\/_-]+$/', $pattern_data['slug'] ) ) {
86 _doing_it_wrong(
87 '_register_theme_block_patterns',
88 sprintf(
89 /* translators: %1s: file name; %2s: slug value found. */
90 __( 'Could not register file "%1$s" as a block pattern (invalid slug "%2$s")', 'gutenberg' ),
91 $file,
92 $pattern_data['slug']
93 ),
94 '6.0.0'
95 );
96 }
97
98 if ( WP_Block_Patterns_Registry::get_instance()->is_registered( $pattern_data['slug'] ) ) {
99 continue;
100 }
101
102 // Title is a required property.
103 if ( ! $pattern_data['title'] ) {
104 _doing_it_wrong(
105 '_register_theme_block_patterns',
106 sprintf(
107 /* translators: %1s: file name; %2s: slug value found. */
108 __( 'Could not register file "%s" as a block pattern ("Title" field missing)', 'gutenberg' ),
109 $file
110 ),
111 '6.0.0'
112 );
113 continue;
114 }
115
116 // For properties of type array, parse data as comma-separated.
117 foreach ( array( 'categories', 'keywords', 'blockTypes', 'postTypes' ) as $property ) {
118 if ( ! empty( $pattern_data[ $property ] ) ) {
119 $pattern_data[ $property ] = array_filter(
120 preg_split(
121 '/[\s,]+/',
122 (string) $pattern_data[ $property ]
123 )
124 );
125 } else {
126 unset( $pattern_data[ $property ] );
127 }
128 }
129
130 // Parse properties of type int.
131 foreach ( array( 'viewportWidth' ) as $property ) {
132 if ( ! empty( $pattern_data[ $property ] ) ) {
133 $pattern_data[ $property ] = (int) $pattern_data[ $property ];
134 } else {
135 unset( $pattern_data[ $property ] );
136 }
137 }
138
139 // Parse properties of type bool.
140 foreach ( array( 'inserter' ) as $property ) {
141 if ( ! empty( $pattern_data[ $property ] ) ) {
142 $pattern_data[ $property ] = in_array(
143 strtolower( $pattern_data[ $property ] ),
144 array( 'yes', 'true' ),
145 true
146 );
147 } else {
148 unset( $pattern_data[ $property ] );
149 }
150 }
151
152 // Translate the pattern metadata.
153 $text_domain = $theme->get( 'TextDomain' );
154 //phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText, WordPress.WP.I18n.NonSingularStringLiteralContext, WordPress.WP.I18n.NonSingularStringLiteralDomain, WordPress.WP.I18n.LowLevelTranslationFunction
155 $pattern_data['title'] = translate_with_gettext_context( $pattern_data['title'], 'Pattern title', $text_domain );
156 if ( ! empty( $pattern_data['description'] ) ) {
157 //phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralText, WordPress.WP.I18n.NonSingularStringLiteralContext, WordPress.WP.I18n.NonSingularStringLiteralDomain, WordPress.WP.I18n.LowLevelTranslationFunction
158 $pattern_data['description'] = translate_with_gettext_context( $pattern_data['description'], 'Pattern description', $text_domain );
159 }
160
161 // The actual pattern content is the output of the file.
162 ob_start();
163 include $file;
164 $pattern_data['content'] = ob_get_clean();
165 if ( ! $pattern_data['content'] ) {
166 continue;
167 }
168
169 register_block_pattern( $pattern_data['slug'], $pattern_data );
170 }
171 }
172 }
173 }
174 }
175 remove_action( 'init', '_register_theme_block_patterns' );
176 add_action( 'init', 'gutenberg_register_theme_block_patterns' );
177