gin_gutenberg-1.0.x-dev/gin_gutenberg.module
gin_gutenberg.module
<?php
/**
* @file
* Contains the logic for handling Gin Gutenberg related features.
*/
use Drupal\node\Entity\NodeType;
use Drupal\node\Entity\Node;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeInterface;
/**
* Implements hook_help().
*/
function gin_gutenberg_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.gin_gutenberg':
$output = '<h3>' . t('Gin Gutenberg Integration') . '</h3>';
$output .= '<p>' . t('The Gin Gutenberg module provides an integration between Gutenberg editor and Gin theme') . '</p>';
return $output;
}
}
/**
* Implements hook_preprocess_HOOK() for html.
*/
function gin_gutenberg_preprocess_html(&$variables) {
$route_match = \Drupal::routeMatch();
$route_name = $route_match->getRouteName();
$route_entity = NULL;
// Handle both node edit and node add scenarios.
if (in_array($route_name, ['entity.node.edit_form', 'node.add'])) {
if ($route_name === 'entity.node.edit_form') {
$route_entity = $route_match->getParameter('node');
}
elseif ($route_name === 'node.add') {
$node_type = $route_match->getParameter('node_type');
if ($node_type instanceof NodeType) {
$route_entity = Node::create(['type' => $node_type->id()]);
}
}
// Check to see if Gutenberg is enabled and on a node form.
if ($route_entity && _gin_gutenberg_is_content_form() && _gin_gutenberg_is_gutenberg_enabled($route_entity)) {
$variables['attributes']['class'][] = 'gutenberg--enabled';
}
}
}
/**
* Implements hook_page_attachments_alter().
*/
function gin_gutenberg_page_attachments_alter(array &$attachments) {
$node = \Drupal::routeMatch()->getParameter('node');
if (!$node && $node_type = \Drupal::routeMatch()->getParameter('node_type')) {
$type = $node_type instanceof NodeType ? $node_type->id() : $node_type;
$node = Node::create(['type' => $type]);
}
// Check to see if Gutenberg is enabled on the node entity.
if (($node instanceof NodeInterface) && !_gin_gutenberg_is_gutenberg_enabled($node)) {
return;
}
$config = \Drupal::config('gin_gutenberg.configuration');
$cache_tags = $attachments['#cache']['tags'] ?? [];
$attachments['#cache']['tags'] = Cache::mergeTags($cache_tags, $config->getCacheTags());
if (_gin_gutenberg_gin_is_active()) {
$attachments['#attached']['library'][] = 'gin_gutenberg/gin_gutenberg';
}
}
/**
* Implements hook_form_FORM_ID_alter() for node forms.
*/
function gin_gutenberg_form_node_form_alter(&$form, FormStateInterface $form_state) {
$node = $form_state->getFormObject()->getEntity();
// Leave early if Gutenberg is not enabled for this entity.
if ($node instanceof NodeInterface && !_gin_gutenberg_is_gutenberg_enabled($node)) {
return;
}
$form['metabox_fields']['#open'] = TRUE;
$form['#attached']['library'][] = 'gin_gutenberg/gin_gutenberg';
// @todo There's a better way to change status element group?
// It seems Gin alter always overrides the group change.
if (isset($form['status'])) {
unset($form['status']['#group']);
$form['meta']['status'] = $form['status'];
$form['meta']['status']['#weight'] = 1;
unset($form['status']);
}
}
/**
* Implements hook_preprocess_HOOK() for page--node--edit--gutenberg.html.twig.
*/
function gin_gutenberg_preprocess_page__node__edit__gutenberg(&$variables) {
$node_type = _gin_gutenberg_get_node_type();
$variables['node_type'] = $node_type;
}
/**
* Implements hook_preprocess_HOOK() for page--node--add--gutenberg.html.twig.
*/
function gin_gutenberg_preprocess_page__node__add__gutenberg(&$variables) {
$node_type = _gin_gutenberg_get_node_type();
$variables['node_type'] = $node_type;
}
/**
* Implements hook_theme().
*/
function gin_gutenberg_theme($existing, $type, $theme, $path) {
$path = \Drupal::service('extension.path.resolver')->getPath('module', 'gin_gutenberg');
return [
'page__node__edit__gutenberg' => [
'render element' => 'elements',
'template' => 'page--node--edit--gutenberg',
'path' => $path . '/templates',
],
'page__node__add__gutenberg' => [
'render element' => 'elements',
'template' => 'page--node--add--gutenberg',
'path' => $path . '/templates',
],
];
}
/**
* Implements hook_theme_suggestions_HOOK_alter() for page templates.
*/
function gin_gutenberg_theme_suggestions_page_alter(array &$suggestions, array $variables) {
$route_name = \Drupal::routeMatch()->getRouteName();
if ($route_name === 'entity.node.edit_form' || $route_name === 'entity.node.content_translation_add') {
$node = \Drupal::routeMatch()->getParameter('node');
if ($node instanceof NodeInterface) {
if (_gin_gutenberg_is_gutenberg_enabled($node)) {
$suggestions[] = 'page__node__edit__gutenberg';
}
}
}
elseif ($route_name === 'entity.node.add_form') {
$node_type = \Drupal::routeMatch()->getParameter('node_type');
if ($node_type instanceof NodeType) {
if (_gin_gutenberg_is_gutenberg_enabled($node_type)) {
$suggestions[] = 'page__node__add__gutenberg';
}
}
}
}
/**
* Helper function to get the node type from the current route.
*
* @return string
* The node type.
*/
function _gin_gutenberg_get_node_type() {
$route_match = \Drupal::routeMatch();
$node = $route_match->getParameter('node');
if ($node instanceof NodeInterface) {
return $node->bundle();
}
$node_type_param = $route_match->getParameter('node_type');
if ($node_type_param instanceof NodeType) {
return $node_type_param->id();
}
$current_path = \Drupal::service('path.current')->getPath();
$path_args = explode('/', $current_path);
if (isset($path_args[1]) && $path_args[1] === 'node' && isset($path_args[2]) && $path_args[2] === 'add' && isset($path_args[3])) {
return $path_args[3];
}
return '';
}
/**
* Helper function for check if Gin/Claro is active.
*/
function _gin_gutenberg_gin_is_active() {
$logged_in = \Drupal::currentUser()->isAuthenticated();
$theme_handler = \Drupal::service('theme_handler')->listInfo();
$frontend_theme_name = \Drupal::config('system.theme')->get('default');
if (isset($theme_handler[$frontend_theme_name]->base_themes)) {
$frontend_base_themes = $theme_handler[$frontend_theme_name]->base_themes;
}
$frontend_base_themes[$frontend_theme_name] = $frontend_theme_name;
$admin_theme_name = \Drupal::config('system.theme')->get('admin');
if ($admin_theme_name && isset($theme_handler[$admin_theme_name]->base_themes)) {
$admin_base_themes = $theme_handler[$admin_theme_name]->base_themes;
$admin_base_themes[$admin_theme_name] = $admin_theme_name;
}
else {
$admin_base_themes = $frontend_base_themes;
}
if ($logged_in) {
$gin_activated = array_key_exists('gin', $admin_base_themes);
$claro_activated = array_key_exists('claro', $admin_base_themes) && !array_key_exists('gin', $admin_base_themes);
}
else {
$gin_activated = array_key_exists('gin', $frontend_base_themes);
$claro_activated = array_key_exists('claro', $frontend_base_themes) && !array_key_exists('gin', $frontend_base_themes);
}
$theme_activated = $gin_activated || $claro_activated;
return $theme_activated;
}
/**
* Gets the admin theme setting.
*
* @param string $setting
* Setting name.
*
* @return mixed
* Return NULL if setting doesn't exist.
*/
function _gin_gutenberg_get_admin_theme_setting($setting) {
$admin_theme = \Drupal::configFactory()->get('system.theme')->get('admin');
return theme_get_setting($setting, $admin_theme);
}
/**
* Checks whether Gutenberg is enabled for an entity.
*/
function _gin_gutenberg_is_gutenberg_enabled(?EntityInterface $entity = NULL) {
if (!$entity) {
return FALSE;
}
if ($entity->getEntityTypeId() !== 'node') {
return FALSE;
}
$config = \Drupal::service('config.factory')->get('gutenberg.settings');
$node_type = $entity->bundle();
return (bool) $config->get($node_type . '_enable_full');
}
/**
* Check if were on a content edit form.
*/
function _gin_gutenberg_is_content_form($form = NULL, $form_state = NULL, $form_id = '') {
$is_content_form = FALSE;
// Get route name.
$route_name = \Drupal::routeMatch()->getRouteName();
// Routes to include.
$route_names = [
'node.add',
'entity.node.content_translation_add',
'quick_node_clone.node.quick_clone',
'entity.node.edit_form',
];
if (
in_array($route_name, $route_names, TRUE) ||
($form_state && ($form_state->getBuildInfo()['base_form_id'] ?? NULL) === 'node_form') ||
($route_name === 'entity.group_content.create_form' && strpos($form_id, 'group_node') === FALSE)
) {
$is_content_form = TRUE;
}
// Forms to exclude.
// If media library widget, don't use new content edit form.
// gin_preprocess_html is not triggered here, so checking
// the form id is enough.
$form_ids_to_ignore = [
'media_library_add_form_',
'views_form_media_library_widget_',
'views_exposed_form',
];
foreach ($form_ids_to_ignore as $form_id_to_ignore) {
if ($form_id && strpos($form_id, $form_id_to_ignore) !== FALSE) {
$is_content_form = FALSE;
}
}
return $is_content_form;
}
