-
Notifications
You must be signed in to change notification settings - Fork 35
/
pattern-creator.php
268 lines (235 loc) · 8.33 KB
/
pattern-creator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
<?php
/**
* Plugin Name: Block Pattern Creator
* Description: Create block patterns on the frontend of a site.
* Version: 1.0.0
* Requires at least: 5.5
* Author: WordPress Meta Team
* Text Domain: wporg-patterns
* License: GPL v2 or later
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/
namespace WordPressdotorg\Pattern_Creator;
use const WordPressdotorg\Pattern_Directory\Pattern_Post_Type\POST_TYPE;
use WP_Block_Editor_Context;
const AUTOSAVE_INTERVAL = 30;
const IS_EDIT_VAR = 'edit-pattern';
const PATTERN_ID_VAR = 'pattern-id';
require_once __DIR__ . '/includes/mock-blocks.php';
/**
* Check the conditions of the page to determine if the editor should load.
* - It should be a single pattern page.
* - The query variable is present.
*
* Permissions are checked in the template itself, so the correct status/login messages can be shown.
*
* @return boolean
*/
function should_load_creator() {
global $wp_query;
$is_editor = $wp_query->is_singular( POST_TYPE ) && false !== $wp_query->get( IS_EDIT_VAR, false );
$is_new = is_page( 'new-pattern' );
return $is_editor || $is_new;
}
/**
* Returns whether the pattern is being edited
*
* @return boolean
*/
function is_editing_pattern() {
return '' !== get_query_var( PATTERN_ID_VAR );
}
/**
* Add our custom parameter to the list of public query variables.
*
* @param string[] $query_vars The array of allowed query variable names.
* @return stringp[] New query vars.
*/
function add_query_var( $query_vars ) {
$query_vars[] = IS_EDIT_VAR;
$query_vars[] = PATTERN_ID_VAR;
return $query_vars;
}
add_filter( 'query_vars', __NAMESPACE__ . '\add_query_var' );
/**
* Register & load the assets, initialize pattern creator.
*
* @throws \Error If the build files don't exist.
*/
function pattern_creator_init() {
global $editor_styles;
if ( ! should_load_creator() ) {
return;
}
if (
! ( is_editing_pattern() && current_user_can( 'edit_pattern', get_query_var( PATTERN_ID_VAR ) ) ) &&
! ( ! is_editing_pattern() && is_user_logged_in() )
) {
return;
}
wp_deregister_style( 'wporg-style' );
$dir = dirname( __FILE__ );
$script_asset_path = "$dir/build/index.asset.php";
if ( ! file_exists( $script_asset_path ) ) {
throw new \Error( 'You need to run `yarn start` or `yarn build` for the Pattern Creator.' );
}
$script_asset = require( $script_asset_path );
wp_enqueue_script(
'wp-pattern-creator',
plugins_url( 'build/index.js', __FILE__ ),
$script_asset['dependencies'],
$script_asset['version'],
true
);
wp_set_script_translations( 'wp-pattern-creator', 'wporg-patterns' );
wp_add_inline_script(
'wp-pattern-creator',
sprintf(
'var wporgLocale = JSON.parse( decodeURIComponent( \'%s\' ) );',
rawurlencode( wp_json_encode( get_locale() ) )
),
'before'
);
wp_add_inline_script(
'wp-pattern-creator',
sprintf(
'var wporgBlockPattern = JSON.parse( decodeURIComponent( \'%s\' ) );',
rawurlencode( wp_json_encode( array(
'siteUrl' => esc_url( home_url() ),
) ) )
),
'before'
);
wp_enqueue_style(
'wp-pattern-creator',
plugins_url( 'build/style-index.css', __FILE__ ),
array( 'wp-components' ),
filemtime( "$dir/build/style-index.css" )
);
/** Load in admin post functions for `get_default_post_to_edit`. */
require_once ABSPATH . 'wp-admin/includes/post.php';
if ( is_singular( POST_TYPE ) || is_editing_pattern() ) {
$post_id = is_editing_pattern() ? $post_id = get_query_var( PATTERN_ID_VAR ) : get_the_ID();
$post = get_post( $post_id );
} else {
$post = get_default_post_to_edit( POST_TYPE, true );
$post_id = $post->ID;
// Set up the default locale.
update_post_meta( $post_id, 'wpop_locale', 'en_US' );
}
$custom_settings = array(
'postId' => $post_id,
'siteUrl' => site_url(),
'postsPerPage' => get_option( 'posts_per_page' ),
'styles' => gutenberg_get_editor_styles(),
'__experimentalBlockPatterns' => array(),
'__experimentalBlockPatternCategories' => array(),
);
wp_deregister_script( 'wporg-global-header-script' );
$editor_context = new WP_Block_Editor_Context( array( 'post' => $post ) );
$settings = get_block_editor_settings( $custom_settings, $editor_context );
$settings['defaultStatus'] = get_option( 'wporg-pattern-default_status', 'publish' );
gutenberg_initialize_editor(
'block-pattern-creator',
'pattern-creator',
array(
'preload_paths' => array(),
'initializer_name' => 'initialize',
'editor_settings' => $settings,
)
);
wp_add_inline_script(
'wp-blocks',
sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( get_block_categories( $post ) ) ),
'after'
);
wp_enqueue_script( 'wp-edit-site' );
wp_enqueue_script( 'wp-format-library' );
wp_enqueue_style( 'wp-edit-site' );
wp_enqueue_style( 'wp-format-library' );
// Load layout and margin styles.
wp_enqueue_style( 'wp-editor-classic-layout-styles' );
wp_enqueue_media();
}
add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\pattern_creator_init', 20 );
/**
* Bypass WordPress template system to load only our editor app.
*/
function inject_editor_template( $template ) {
if ( should_load_creator() ) {
return __DIR__ . '/view/editor.php';
}
return $template;
}
add_filter( 'template_include', __NAMESPACE__ . '\inject_editor_template' );
/**
* Add a rewrite rule to handle editing a pattern.
*/
function rewrite_for_pattern_editing() {
add_rewrite_rule( '^pattern/(\d+)/edit', 'index.php?pagename=new-pattern&' . PATTERN_ID_VAR . '=$matches[1]', 'top' );
}
add_action( 'init', __NAMESPACE__ . '\rewrite_for_pattern_editing' );
/**
* Always disable the admin bar on the creator page.
*
* @param bool $show_admin_bar Whether the admin bar should be shown. Default false.
* @return bool Filtered value.
*/
function show_admin_bar( $show_admin_bar ) {
if ( ! should_load_creator() ) {
return $show_admin_bar;
}
return false;
}
// Priority needs to be over 1000 to override `logged-out-admin-bar`.
add_filter( 'show_admin_bar', __NAMESPACE__ . '\show_admin_bar', 1001 );
/**
* Filter out `upload_files` from all non-admin users.
*
* @param bool[] $allcaps Array of key/value pairs where keys represent a capability name
* and boolean values represent whether the user has that capability.
*/
function disallow_uploads( $allcaps ) {
if ( ! isset( $allcaps['manage_options'] ) ) {
$allcaps['upload_files'] = false;
}
return $allcaps;
}
add_filter( 'user_has_cap', __NAMESPACE__ . '\disallow_uploads' );
/**
* Set up any custom endpoints.
*/
function rest_api_init() {
require_once __DIR__ . '/includes/openverse-client.php';
require_once __DIR__ . '/includes/openverse-rest-controller.php';
$controller = new \Openverse_REST_Controller();
$controller->register_routes();
}
add_action( 'rest_api_init', __NAMESPACE__ . '\rest_api_init' );
/**
* Filter editor settings to add extra styles to the Pattern Creator editor.
*
* This adds `link` & `style` tags to be loaded into the editor's iframe.
* - Load Twenty Twenty-One styles for a theme preview
* - Set the editor background to white for a cleaner preview
* - Add layout styles for the pattern container so that alignments work
*
* @param array $settings Default editor settings.
* @return array Updated settings.
*/
function add_theme_styles_to_editor( $settings ) {
if ( ! isset( $settings['__unstableResolvedAssets']['styles'] ) ) {
return $settings;
}
// Build up the alignment styles to match the layout set in theme.json.
// See https://github.com/WordPress/gutenberg/blob/9d4b83cbbafcd6c6cbd20c86b572f458fc65ff16/lib/block-supports/layout.php#L38
$block_gap = wp_get_global_styles( array( 'spacing', 'blockGap' ) );
$layout = wp_get_global_settings( array( 'layout' ) );
$style = gutenberg_get_layout_style( '.pattern-block-editor__block-list.is-root-container', $layout, true, $block_gap );
$settings['__unstableResolvedAssets']['styles'] .=
'\n<link rel="stylesheet" id="theme-styles" href="https://wp-themes.com/wp-content/themes/twentytwentyone/style.css" media="all" />'; //phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet
$settings['__unstableResolvedAssets']['styles'] .=
'\n<style>body.editor-styles-wrapper { background-color: white; }' . $style . '</style>';
return $settings;
}
add_filter( 'block_editor_settings_all', __NAMESPACE__ . '\add_theme_styles_to_editor', 20 );