';
}
// renderPage() exits during admin_init and manually fires wp_enqueue_scripts in
// both the admin and frontend branches. admin_enqueue_scripts never runs here, so
// the apiFetch preload must ride wp_enqueue_scripts or the editor falls back to a
// live GET /wp/v2/fcom-dummy/{id}?context=edit — which 403s for users without
// edit_others_posts (e.g. contributors) on the shared, admin-authored dummy post.
add_action('wp_enqueue_scripts', function () use ($post) {
wp_enqueue_script('postbox', admin_url('js/postbox.min.js'), array('jquery-ui-sortable'), FLUENT_COMMUNITY_PLUGIN_VERSION, true);
wp_enqueue_style('dashicons');
wp_enqueue_style('media');
wp_enqueue_style('admin-menu');
wp_enqueue_style('admin-bar');
wp_enqueue_style('l10n');
wp_add_inline_script(
'wp-api-fetch',
\sprintf(
'wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( %s ) );',
wp_json_encode(
array(
'/wp/v2/' . $post->post_type . '/' . $post->ID . '?context=edit' => array(
'body' => array(
'id' => $post->ID,
'title' => array('raw' => $post->post_title),
'content' => array(
'block_format' => 1,
'raw' => $post->post_content,
),
'excerpt' => array('raw' => ''),
'date' => '',
'date_gmt' => '',
'modified' => '',
'modified_gmt' => '',
'link' => home_url('/'),
'guid' => array(),
'parent' => 0,
'menu_order' => 0,
'author' => 0,
'featured_media' => 0,
'comment_status' => 'closed',
'ping_status' => 'closed',
'template' => '',
'meta' => array(),
'_links' => array(),
'type' => $post->post_type,
'status' => 'pending', // pending is the best state to remove draft saving possibilities.
'slug' => '',
'generated_slug' => '',
'permalink_template' => home_url('/'),
),
),
)
)
),
'after'
);
}, 11);
add_action('wp_enqueue_scripts', function ($hook) use ($post) {
// Gutenberg requires the post-locking functions defined within:
// See `show_post_locked_dialog` and `get_post_metadata` filters below.
include_once ABSPATH . 'wp-admin/includes/post.php';
$this->gutenberg_editor_scripts_and_styles($hook, $post);
});
// Disable post locking dialogue.
add_filter('show_post_locked_dialog', '__return_false');
// Everyone can richedit! This avoids a case where a page can be cached where a user can't richedit.
$GLOBALS['wp_rich_edit'] = true;
add_filter('user_can_richedit', '__return_true', 1000);
// Homepage is always locked by @wordpressdotorg
// This prevents other logged-in users taking a lock of the post on the front-end.
add_filter('get_post_metadata', function ($value, $post_id, $meta_key) {
if ($meta_key !== '_edit_lock') {
return $value;
}
return time() . ':' . get_current_user_id(); // WordPressdotorg user ID
}, 10, 3);
// Disable Jetpack Blocks for now.
add_filter('jetpack_gutenberg', '__return_false');
}
private function gutenberg_editor_scripts_and_styles($hook, $post)
{
$initial_edits = array(
'title' => $post->post_title,
'content' => $post->post_content,
'excerpt' => $post->post_excerpt,
);
$editor_settings = $this->getEditorSettings($post);
$init_script =
"(function() {
window._wpLoadBlockEditor = new Promise(function(resolve) {
wp.domReady(function() {
resolve(wp.editPost.initializeEditor('editor', \"%s\", %d, %s, %s));
});
});
})();";
$script = sprintf(
$init_script,
$post->post_type,
$post->ID,
wp_json_encode($editor_settings),
wp_json_encode($initial_edits)
);
wp_add_inline_script('wp-edit-post', $script);
/**
* Scripts
*/
wp_enqueue_media();
add_filter('user_can_richedit', '__return_true');
wp_tinymce_inline_scripts();
wp_enqueue_editor();
/**
* Styles
*/
wp_enqueue_style('wp-edit-post');
// Include block styles needed when user is not signed in. See: https://github.com/WordPress/wporg-gutenberg/issues/26
wp_enqueue_style('global-styles');
wp_enqueue_style('wp-block-library');
wp_enqueue_style('wp-block-image');
wp_enqueue_style('wp-block-group');
wp_enqueue_style('wp-block-heading');
wp_enqueue_style('wp-block-button');
wp_enqueue_style('wp-block-paragraph');
wp_enqueue_style('wp-block-separator');
wp_enqueue_style('wp-block-columns');
wp_enqueue_style('wp-block-cover');
wp_enqueue_style('global-styles-css-custom-properties');
wp_enqueue_style('wp-block-spacer');
wp_register_style('fluent_com_editor_styles', FLUENT_COMMUNITY_PLUGIN_URL . 'Modules/Gutenberg/editor/style.css', [], FLUENT_COMMUNITY_PLUGIN_VERSION, 'all');
add_action('fluent_enqueue_block_editor_assets', 'wp_enqueue_editor_format_library_assets');
// WP 6.9+ loads the LaTeX-to-MathML converter as a script module; core wires this on
// 'enqueue_block_editor_assets', which this standalone editor page never fires.
if (function_exists('wp_enqueue_block_editor_script_modules')) {
add_action('fluent_enqueue_block_editor_assets', 'wp_enqueue_block_editor_script_modules');
}
/**
* Fires after block assets have been enqueued for the editing interface.
*
* Call `add_action` on any hook before 'admin_enqueue_scripts'.
*
* In the function call you supply, simply use `wp_enqueue_script` and
* `wp_enqueue_style` to add your functionality to the Gutenberg editor.
*
* @since 0.4.0
*/
do_action('fluent_enqueue_block_editor_assets');
wp_enqueue_script('fcom_editor_custom', FLUENT_COMMUNITY_PLUGIN_URL . 'Modules/Gutenberg/editor/index.js', ['react', 'wp-components', 'wp-compose', 'wp-data', 'wp-edit-post', 'wp-i18n', 'wp-plugins'], FLUENT_COMMUNITY_PLUGIN_VERSION . time(), true);
wp_localize_script('fcom_editor_custom', 'fcomEditorI18n', $this->getEditorI18nStrings());
wp_localize_script('fcom_editor_custom', 'fcomEditorVars', [
'video_gate_default_threshold' => \FluentCommunity\Modules\Course\Services\LessonVideoGateService::getDefaultThreshold(),
'can_unfiltered_html' => current_user_can('unfiltered_html') ? 'yes' : 'no',
]);
}
private function getEditorI18nStrings()
{
$strings = [
'Enable Video Embed' => __('Enable Video Embed', 'fluent-community'),
'Enable Comments' => __('Enable Comments', 'fluent-community'),
'Free Preview Lesson' => __('Free Preview Lesson', 'fluent-community'),
'If enabled, public users can view this lesson without enrolling the course.' => __('If enabled, public users can view this lesson without enrolling the course.', 'fluent-community'),
'Media Embed' => __('Media Embed', 'fluent-community'),
'Documents & Files' => __('Documents & Files', 'fluent-community'),
'Smartcodes' => __('Smartcodes', 'fluent-community'),
'You may use following smartcode in your lesson:' => __('You may use following smartcode in your lesson:', 'fluent-community'),
"User's Name:" => __("User's Name:", 'fluent-community'),
"User's Email:" => __("User's Email:", 'fluent-community'),
"User's photo HTML:" => __("User's photo HTML:", 'fluent-community'),
"User's Profile Link:" => __("User's Profile Link:", 'fluent-community'),
'Failed to fetch embed. Please check the URL.' => __('Failed to fetch embed. Please check the URL.', 'fluent-community'),
'Video thumbnail' => __('Video thumbnail', 'fluent-community'),
'Media embedded successfully' => __('Media embedded successfully', 'fluent-community'),
'Edit media' => __('Edit media', 'fluent-community'),
'Oembed' => __('Oembed', 'fluent-community'),
'Custom HTML' => __('Custom HTML', 'fluent-community'),
'Custom HTML Code' => __('Custom HTML Code', 'fluent-community'),
'Your account cannot save custom HTML. Scripts, iframes and similar tags are removed on save.' => __('Your account cannot save custom HTML. Scripts, iframes and similar tags are removed on save.', 'fluent-community'),
'Paste an iframe code' => __('Paste an iframe code', 'fluent-community'),
'Embed' => __('Embed', 'fluent-community'),
'Paste a URL to embed' => __('Paste a URL to embed', 'fluent-community'),
'Embed from Vimeo, YouTube, Wistia and more' => __('Embed from Vimeo, YouTube, Wistia and more', 'fluent-community'),
'FluentPlayer' => __('FluentPlayer', 'fluent-community'),
'Select Player Block' => __('Select Player Block', 'fluent-community'),
'Use FluentPlayer Block' => __('Use FluentPlayer Block', 'fluent-community'),
'The feature video is managed by the FluentPlayer block in the editor.' => __('The feature video is managed by the FluentPlayer block in the editor.', 'fluent-community'),
'A FluentPlayer block will be added at the top of the lesson content. Add or edit the video directly from that block in the editor.' => __('A FluentPlayer block will be added at the top of the lesson content. Add or edit the video directly from that block in the editor.', 'fluent-community'),
'Video Completion' => __('Video Completion', 'fluent-community'),
'Require video watch to complete' => __('Require video watch to complete', 'fluent-community'),
'Students must watch the video before they can mark this lesson as completed.' => __('Students must watch the video before they can mark this lesson as completed.', 'fluent-community'),
'Auto-complete lesson when the video ends' => __('Auto-complete lesson when the video ends', 'fluent-community'),
'Marks the lesson complete a few seconds after the student watches the video to the end.' => __('Marks the lesson complete a few seconds after the student watches the video to the end.', 'fluent-community'),
'Required watch percentage' => __('Required watch percentage', 'fluent-community'),
'100% means the video must be watched to the end.' => __('100% means the video must be watched to the end.', 'fluent-community'),
'Lesson Duration' => __('Lesson Duration', 'fluent-community'),
'Minutes' => __('Minutes', 'fluent-community'),
'Seconds' => __('Seconds', 'fluent-community'),
'View' => __('View', 'fluent-community'),
'No documents attached yet.' => __('No documents attached yet.', 'fluent-community'),
'Manage Documents & Files' => __('Manage Documents & Files', 'fluent-community'),
"User's Name" => __("User's Name", 'fluent-community'),
"User's Email" => __("User's Email", 'fluent-community'),
"User's photo HTML" => __("User's photo HTML", 'fluent-community'),
'Profile Link' => __('Profile Link', 'fluent-community'),
];
return apply_filters('fluent_community/editor_i18n_strings', $strings);
}
private function gutenberg_get_available_image_sizes()
{
$size_names = apply_filters(
'fluent_community/image_size_names_choose',
array(
'thumbnail' => __('Thumbnail', 'fluent-community'),
'medium' => __('Medium', 'fluent-community'),
'large' => __('Large', 'fluent-community'),
'full' => __('Full Size', 'fluent-community'),
)
);
$all_sizes = array();
foreach ($size_names as $size_slug => $size_name) {
$all_sizes[] = array(
'slug' => $size_slug,
'name' => $size_name,
);
}
return $all_sizes;
}
protected function renderPage()
{
remove_action( 'wp_print_styles', 'print_emoji_styles' );
add_action('fluent_community/block_editor_footer', function () {
wp_underscore_playlist_templates();
wp_print_footer_scripts();
$this->printScriptModules();
wp_print_media_templates();
wp_enqueue_global_styles();
if (function_exists('wp_enqueue_stored_styles')) {
wp_enqueue_stored_styles();
}
wp_maybe_inline_styles();
});
add_action('fluent_block_editor/head', 'wp_enqueue_scripts', 1);
add_action('fluent_block_editor/head', 'wp_resource_hints', 2);
add_action('fluent_block_editor/head', 'wp_preload_resources', 1);
add_action('fluent_block_editor/head', 'wp_print_styles', 8);
add_action('fluent_block_editor/head', 'wp_print_head_scripts', 9);
add_action('fluent_block_editor/head', 'wp_custom_css_cb', 101);
$this->unloadOtherScripts();
?>
>
FluentCommunity Block Editor