Простий модуль очистки html кода в Drupal 9 полях
Сьогодні ми створемо пройти модуль для очистки html коду в довгому форматованому полі від класів, айді, стилів, скриптів, зображень та посилань (зберігаються лише текст посилання). Це буде доволі зручно у випадках коли ви імпортуєте контент після парсингу різних джерел та не маєте змоги чи бажання редагувати вручну кожну ноду.
Спочатку, в module/custom створюємо теку модуля - dartharth_content_cleaner. Всередині створюємо основні файли модуля - dartharth_content_cleaner.info.yml
name: 'Content Cleaner'
type: module
description: 'Provides a tool to clean HTML content of specified content types.'
core_version_requirement: ^9
package: DARTHARTH
dependencies:
- drupal:node
dartharth_content_cleaner.links.menu.yml
dartharth_content_cleaner.admin_settings:
title: 'DARTHARTH Content Cleaner Settings'
description: 'Configure content cleaning options.'
parent: system.admin_config_content
route_name: dartharth_content_cleaner.admin_settings
weight: 10
dartharth_content_cleaner.routing.yml
dartharth_content_cleaner.admin_settings:
path: '/admin/config/dartharth-content-cleaner'
defaults:
_form: '\Drupal\dartharth_content_cleaner\Form\ContentCleanerSettingsForm'
_title: 'DARTHARTH Content Cleaner Settings'
requirements:
_permission: 'administer site configuration'
Далі, створюємо теки src/Form і всередині файл ContentCleanerSettingsForm.php
<?php
namespace Drupal\dartharth_content_cleaner\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\filter\Entity\FilterFormat;
class ContentCleanerSettingsForm extends ConfigFormBase {
protected function getEditableConfigNames() {
return ['dartharth_content_cleaner.settings'];
}
public function getFormId() {
return 'dartharth_content_cleaner_settings_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
// Get a list of content types.
$content_types = \Drupal::entityTypeManager()->getStorage('node_type')->loadMultiple();
$content_type_options = [];
foreach ($content_types as $content_type) {
$content_type_options[$content_type->id()] = $content_type->label();
}
// Add content type select element.
$form['content_type'] = [
'#type' => 'select',
'#title' => $this->t('Content type'),
'#options' => $content_type_options,
'#required' => TRUE,
];
// Get a list of text formats.
$text_formats = FilterFormat::loadMultiple();
$text_format_options = [];
foreach ($text_formats as $text_format) {
$text_format_options[$text_format->id()] = $text_format->label();
}
// Add text format select element.
$form['text_format'] = [
'#type' => 'select',
'#title' => $this->t('Text format'),
'#options' => $text_format_options,
'#required' => TRUE,
'#description' => $this->t('Select the text format for the cleaned content.'),
];
// Add cleaning options fieldset.
$form['cleaning_options'] = [
'#type' => 'fieldset',
'#title' => $this->t('Cleaning options'),
];
// Add cleaning option checkboxes.
$form['cleaning_options']['remove_scripts'] = [
'#type' => 'checkbox',
'#title' => $this->t('Remove scripts'),
];
$form['cleaning_options']['remove_links'] = [
'#type' => 'checkbox',
'#title' => $this->t('Remove links'),
];
$form['cleaning_options']['remove_images'] = [
'#type' => 'checkbox',
'#title' => $this->t('Remove images'),
];
// Add submit button.
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Start cleaning'),
];
return parent::buildForm($form, $form_state);
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$content_type = $form_state->getValue('content_type');
$remove_scripts = $form_state->getValue('remove_scripts');
$remove_links = $form_state->getValue('remove_links');
$remove_images = $form_state->getValue('remove_images');
$content_filter = $form_state->getValue('text_format');
// Get the list of nodes of the selected content type.
$query = \Drupal::entityQuery('node')->condition('type', $content_type);
$nids = $query->execute();
$node_storage = \Drupal::entityTypeManager()->getStorage('node');
// Counter for corrected nodes.
$corrected_nodes = 0;
foreach ($nids as $nid) {
/** @var \Drupal\node\NodeInterface $node */
$node = $node_storage->load($nid);
if ($node) {
// Clean up the node's body field.
$body_value = $node->get('body')->value;
$body_value_cleaned = $this->cleanUpHtml($body_value, $remove_scripts, $remove_links, $remove_images);
$node->set('body', [
'value' => $body_value_cleaned,
'format' => $content_filter,
]);
// Save the node.
$node->save();
// Increment the counter.
$corrected_nodes++;
}
}
// Set a message indicating the number of corrected nodes.
$this->messenger()->addMessage($this->t('@count nodes have been cleaned.', ['@count' => $corrected_nodes]));
}
private function cleanUpHtml($html, $remove_scripts, $remove_links, $remove_images) {
// Remove scripts if the option is selected.
if ($remove_scripts) {
$html = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/', '', $html);
}
// Remove links if the option is selected.
if ($remove_links) {
$html = preg_replace('/<a\s+(?:[^>]*?\s+)?href="([^"]*)"([^>]*)>(.*?)<\/a>/', '$3', $html);
}
// Remove images if the option is selected.
if ($remove_images) {
$html = preg_replace('/<img\s+.*?>/', '', $html);
}
// Remove unnecessary attributes (classes, ids, styles).
$html = preg_replace('/(<[^>]+) (class|id|style)=".*?"/i', '$1', $html);
return $html;
}
}
Майже все. Вмикаємо модуль та переходимо до його адмін сторінки /admin/config/dartharth-content-cleaner, де ми можемо обрати тип матеріала та очистити ноди.