Drupal 8 в 2 шага

24 октября 2017 в 18:59

Drupal 8 - это последняя стабильная версия Drupal, современная, которая использует PHP 5.4+, REST совместимая, объектно-ориентированная. Концепция осталась прежней, но подход изменился. Drupal 8 использует возможности объектно-ориентированного программирования(ООП) для большинства подсистем, благодаря фреймворку Symfony 3.

Как мне объявить модуль?

В Drupal 8 для объявления модуля нужен только файл YAML (.info.yml):

name: D8 Test Module
description: D8 Test Module
type: module
core: 8.x
package: Custom

В Drupal 8 файл .module больше не является обязательным, таким образом, только файл .info.yml необходим для того, чтобы можно было включить модуль.

Как мне создать страницу

Создайте контроллер, который наследуется/расширяет ControllerBase класс и возвращает вывод страницы:
/modules/d8_example_module/src/Controller/D8ExampleModuleController.php

<?php
namespace Drupal\d8_example_module\Controller;

use 

Drupal\Core\Controller\ControllerBase;

class 

D8ExampleModuleController extends ControllerBase {

  public function 

test_page($from$to) {
    
$message $this->t('%from to %to', [
      
'%from' => $from,
      
'%to' => $to,
    ]);

    return [

'#markup' => $message];
  }
}
?>

После того как это сделано, совместно с файлом .routing.yml мы можем задать путь, контроллер, заголовок и права доступа:

/modules/d8_example_module/d8_example_module.routing.yml

d8_example_module.test_page:
  path: '/test-page/{from}/{to}'
  defaults:
    _controller: 'Drupal\d8_example_module\Controller\D8ExampleModuleController::test_page'
    _title: 'Test Page!'
  requirements:
    _permission: 'access content'

Как мне сделать контент темизируемым?

У нас до сих пор доступна функция hook_theme():

/modules/d8_example_module/d8_example_module.module

<?php
/**
 * Implements hook_theme().
 */
function d8_example_module_theme() {
  
$theme['d8_example_module_page_theme'] = [
    
'variables' => ['from' => NULL'to' => NULL],
    
'template' => 'd8-theme-page',
  ];

  return 

$theme;
}
?>

Для темизации Drupal 8 использует Twig - система шаблонизации используемая в основном проектами на PHP. Для того, чтобы узнать больше про Twig ознакомьтесь с Twig in Drupal 8. Одной из полезных особенностей Twig является подсистема перевода строк:

/modules/d8_example_module/template/d8-theme-page.html.twig

<section>
  {% trans %}
    <strong>{{ from }}</strong> to <em>{{ to }}</em>
  {% endtrans %}
</section>

А потом связываем тему оформления со страницей:

/modules/d8_example_module/src/Controller/D8ExampleModuleController.php

<?php
namespace Drupal\d8_example_module\Controller;

use 

Drupal\Core\Controller\ControllerBase;

class 

D8ExampleModuleController extends ControllerBase {

  public function 

test_page($from$to) {
    return [
      
'#theme' => 'd8_example_module_page_theme',
      
'#from' => $from,
      
'#to' => $to,
    ];
  }
}
?>

Как мне объявить переменную?

В Drupal 8 есть полностью новая система поддержки конфигураций, которая сохраняет конфигурации в YAML (.yml) файлах. Для дополнительной информации смотрите Managing configuration in Drupal 8.

Мы зададим переменные в config/install/*.settings.yml:

/modules/d8_example_module/config/install/d8_example_module.settings.yml

default_count: 3

Переменные будут сохранены в базе данных во время инсталляции модуля. Мы задаем схему для переменных в config/schema/*.settings.yml:

/modules/d8_example_module/config/schema/d8_example_module.settings.yml

d8_example_module.settings:
  type: mapping
  label: 'D8 Example Module settings'
  mapping:
    default_count:
      type: integer
      label: 'Default count'

Как мне создать форму?

Для создания формы мы расширим базовый класс ConfigFormBase:

/modules/d8_example_module/src/Form/TestForm.php

<?php
namespace Drupal\d8_example_module\Form;

use 

Drupal\Core\Form\ConfigFormBase;
use 
Drupal\Core\Form\FormStateInterface;

class 

TestForm extends ConfigFormBase {
  public function 
getFormId() {
    return 
'test_form';
  }

  public function 

buildForm(array $formFormStateInterface $form_state) {
    
$config $this->config('d8_example_module.settings');

    

$form['default_count'] = [
      
'#type' => 'number',
      
'#title' => $this->t('Default count'),
      
'#default_value' => $config->get('default_count'),
    ];
    return 
parent::buildForm($form$form_state);
  }

  public function 

submitForm(array &$formFormStateInterface $form_state) {
    
$config $this->config('d8_example_module.settings');
    
$config->set('default_count'$form_state->getValue('default_count'));
    
$config->save();
    
parent::submitForm($form$form_state);
  }
}
?>

Далее, используя файл .routing.yml мы можем задать путь, форму, заголовок и права доступа:

/modules/d8_example_module/d8_example_module.routing.yml

d8_example_module.test_form:
  path: /admin/config/system/test-form
  defaults:
    _form: 'Drupal\d8_example_module\Form\TestForm'
    _title: 'Test Form'
  requirements:
    _permission: 'configure_form'

Мы будем использовать друго YAML файл (.permissions.yml) для объявления прав доступа:

/modules/d8_example_module/d8_example_module.permissions.yml

'configure_form':
  title: 'Access to Test Form'
  description: 'Set the Default Count variable'

Также, мы используем еще один YAML файл (.links.menu.yml) для того, чтобы задать ссылки меню:

/modules/d8_example_module/d8_example_module.links.menu.yml

d8_example_module.test_form:
  title: 'Test Form'
  description: 'Set the Default Count variable'
  route_name: d8_example_module.test_form
  parent: system.admin_config_system

Как мне создать блок?

Для создания блока мы расширим класс ConfigFormBase:

/modules/d8_example_module/src/Plugin/Block/TestBlock.php

<?php
namespace Drupal\d8_example_module\Plugin\Block;

use 

Drupal\Core\Block\BlockBase;

/**
 * Test Block.
 *
 * Block(
 *   id = "test_block",
 *   admin_label = Translation("Test Block"),
 *   category = Translation("System")
 * )
 */
class TestBlock extends BlockBase {

  public function 

build() {
    return [
      
'#markup' => $this->t('Block content...'),
    ];
  }
}
?>

После этого блок будет доступен для изменения конфигурации в CMS(/admin/structure/block). Далее следует пример более сложного блока:

<?php
namespace Drupal\d8_example_module\Plugin\Block;

use 

Drupal\Core\Block\BlockBase;
use 
Drupal\Core\Form\FormStateInterface;

/**
 * Test Block.
 *
 * Block(
 *   id = "test_block",
 *   admin_label = Translation("Test Block"),
 *   category = Translation("System")
 * )
 */
class TestBlock extends BlockBase {

  public function 

defaultConfiguration() {
    return [
'enabled' => 1];
  }

  public function 

blockForm($formFormStateInterface $form_state) {
    
$form['enabled'] = [
      
'#type' => 'checkbox',
      
'#title' => $this->t('Configuration enabled'),
      
'#default_value' => $this->configuration['enabled'],
    ];

    return 

$form;
  }

  public function 

blockSubmit($formFormStateInterface $form_state) {
    
$this->configuration['enabled'] = (bool)$form_state->getValue('enabled');
  }

  public function 

build() {
    if (
$this->configuration['enabled']) {
      
$message $this->t('Configuration enabled');
    }
    else {
      
$message $this->t('Configuration disabled');
    }
    return [
      
'#markup' => $message,
    ];
  }
}
?>

Структура модуля

Структура модуля должна выглядеть как в примере d8_example_module:

d8_example_module/
 |
 |- config/
   |
   |- install/
     |
     |- d8_example_module.setting.yaml
     |
     |- schema/
       |
       |- d8_example_module.settings.yaml
 |
 |- src/
   |
   |- Controller/
     |
     |- D8ExampleModuleController.php
   |
   |- Form/
     |
     |- TestForm.php
   |
   |- Plugin/
     |
     |- Block/
       |
       |- TestBlock.php
 |
 |- templates/
   |
   |- d8-theme-page.html.twig
 |
 |- d8_example_module.info.yml
 |
 |- d8_example_module.links.menu.yml
 |
 |- d8_example_module.module
 |
 |- d8_example_module.permissions.yml
 |
 |- d8_example_module.routing.yml

Материалы

Авторы: 

Комментарии

Полезная информация, спасибо. Надо только ещё один материал, как во всех этих операциях помогает друпал-консоль Wink

24 октября 2017 в 20:51

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

Но! Так же, а может даже более, важно знать как все это работает, понимать, и уметь это делать. Именно это автор и раскрывает в ТОПе, за что ему благодарность.

ЗЫ - Symfony уже не 2, а 3.

25 октября 2017 в 10:51

Ну... Раскройте лучше, вроде не запрещает никто.

Или, хоть, "Но-но" Ваше раскройте. Как-то не конструктивно получилось.

25 октября 2017 в 12:19

Если вы меня не поняли или мои слова вызвали у вас бурные чувства, то прошу прощения.
Своим комментарием я прошу вас пояснить слово "раскрывает" и чем отлично, в данном случаем, раскрытие от инструкции.

26 октября 2017 в 0:51

Тем что интересующийся человек сможет найти эту информацию в поиске.
Документации много не бывает, она как "масло в каше".

26 октября 2017 в 1:36