xandeadx.ru Блог музицирующего веб-девелопера

DrupalДобавляем на страницу управления отображением комментария поля "автор" и "дата создания"

Простой способ добавить поля "автор" и "дата создания" на страницу управления отображением комментария:

// MODULENAME.module
 
/**
 * Implements hook_entity_base_field_info_alter().
 */
function MODULENAME_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
  if ($entity_type->id() == 'comment') {
    /** @see \Drupal\comment\Entity\Comment::baseFieldDefinitions() */
    $fields['uid']->setDisplayConfigurable('view', TRUE);
    $fields['created']->setDisplayConfigurable('view', TRUE);
  }
}

DrupalViews фильтр "товар имеет опубликованную вариацию"

Опубликовано в

Простой плагин для Views, добавляющий фильтр "Товар имеет хоть одну опубликованную вариацию". Полезен когда у товаров может быть несколько вариаций и не хочется мучатся с агрегацией.

// src/Plugin/views/filter/ProductHasPublishedVariationViewsFilter.php
 
/**
 * @ViewsFilter("product_has_published_variation")
 */
class ProductHasPublishedVariationViewsFilter extends FilterPluginBase {
 
  /**
   * {@inheritDoc}
   */
  public function query() {
    $this->ensureMyTable();
    $query = $this->query; /** @var \Drupal\views\Plugin\views\query\Sql $query */

DrupalОптимизация кэширования больших меню

Опубликовано в

Всем блокам меню друпал добавляет кэш-контекст route.menu_active_trails, который создаёт новый кэш блока в зависимости от активной ссылки (т.е. если меню содержит сто ссылок, то по итогу в cache_render будет 101 вариант этого блока).

Если меню достаточно большое и все пункты в нём раскрыты по умолчанию, то можно безболезненно удалить этот кэш-контекст, позволив держать в кэше только одну версию блока.

Пример для меню main:

/**
 * Implements hook_block_build_BASE_BLOCK_ID_alter(): system_menu_block.
 */

DrupalКэш-контекст по хэшу значения куки

Опубликовано в

В восьмёрке есть кэш-контекст cookies, который возвращает значение куки. Значение возвращается без какой-либо обработки, что временами нежелательно, так как кука может быть оооочень длинной (например, как у меня - пользовательские фильтры вьюхи и настройки сортировки). Выход — создать новый кэш-контекст, который вместо raw значения куки будет возвращать его хэш:

// src/Cache/CookiesHashContext.php
 
namespace Drupal\modulename\Cache;
 
use Drupal\Core\Cache\Context\CookiesCacheContext;
 
class CookiesHashContext extends CookiesCacheContext {
 
  /**

DrupalДобавляем возможность указывать атрибуты для элементов option

Опубликовано в

12 лет, как в друпал не могут добавить возможность указывать атрибуты для элементов <option> в select-ах. Делаем сами:

1. Копируем core/modules/system/templates/select.html.twig в папку своей темы.

2. Изменяем строчку

<option value="{{ option.value }}"{{ option.selected ? ' selected="selected"' }}>{{ option.label }}</option>

на

 

DrupalВыносим определение поддержки javascript в head

Опубликовано в

Для пользователей с включённым javascript друпал добавляет тегу <html> класс js, что позволяет писать более "доступные" стили. Например если на форме включена автоотправка, то можно не просто скрыть кнопку сабмита для всех, а скрыть только для пользователей с js:

.js .example-form .form-submit {
  display: none;
}

Проблема только в одном — скрипт, добавляющий класс js подключается в подвале и поэтому пока страница загружается пользователь будет видеть кнопку, потому что соответствующего класса у <html> ещё нет.

DrupalПоказать форму входа при попытке анонимного пользователя поставить флаг

Опубликовано в

Плагин для модуля Flag, который при попытке анонимного пользователя поставить флаг покажет в диалоге форму входа.

// src/Plugin/ActionLink/AjaxLinkWithAuth.php
 
/**
 * @ActionLinkType(
 *   id = "ajax_link_with_auth",
 *   label = @Translation("AJAX link with authentication"),
 *   description = "An AJAX JavaScript request will be made without reloading the page."
 * )
 */
class AjaxLinkWithAuth extends AJAXactionLink {
 
  /**
   * {@inheritDoc}
   */
  public function getAsFlagLink(FlagInterface $flag, EntityInterface $entity) {

DrupalСоздать свою ajax команду (8)

Опубликовано в

Пример создания ajax команды для вывода сообщений в консоль браузера.

// src/Ajax/ConsoleLogCommand.php
 
namespace Drupal\modulename\Ajax;
 
use Drupal\Core\Ajax\CommandInterface;
 
class ConsoleLogCommand implements CommandInterface {
 
  protected $message;
 
  /**
   * Command constructor.
   */
  public function __construct($message) {
    $this->message = $message;
  }
 
  /**
   * {@inheritDoc}
   */
  public function render() {
    return [
      'command' => 'consoleLog',
      'message' => $this->message,
    ];
  }
 
}

 

DrupalСоздать свой ajax индикатор прогресса

Опубликовано в

Пример создания индикатора прогресса с именем toggleClass, который добавляет/удаляет класс у элемента:

(function ($, Drupal) {
 
  /**
   * Create custom progress type "toggleClass".
   * @see Drupal.Ajax.prototype.beforeSend()
   */
  Drupal.Ajax.prototype.setProgressIndicatorToggleclass = function () {
    var $progressTarget = this.progress.target ? $(this.progress.target) : $(this.element);
    var progressClass = this.progress.class ? this.progress.class : 'ajax-progress-animation';
 
    // Add class
    $progressTarget.addClass(progressClass);

DrupalОтправить уведомление о новом заказе в Commerce 2

Опубликовано в

Во втором комерце практически все хуки заменили на события, поэтому теперь вместо реализации hook_commerce_checkout_complete() надо подписываться на событие commerce_order.place.post_transition:

// src/EventSubscriber/ModulenameEventSubscriber.php
 
namespace Drupal\modulename\EventSubscriber;
 
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\state_machine\Event\WorkflowTransitionEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
class ModulenameEventSubscriber implements EventSubscriberInterface {
 
  /**