Drupal 8 предоставляет несколько api для хранения данных вашего приложения, к ним относятся;entity api, configuration api и state api.
Есть несколько способов определить, какой api использовать в зависимости от того, какие данные вы хотите хранить, и в этом блоге мы рассмотрим config api.
Мы увидим, как мы можем определить значения по умолчанию при установке модуля, а затем отредактировать их через форму конфигурации, и, наконец, мы будем использовать эти настройки в контроллере для отображения элементов на странице, включая фотографии кошек, из _ the cats api _. (Я выбрал этот api, потому что он требует ключ, а он нам нужен для демонстрации возможностей drupal config api).
Код для этого блога на github здесь;
Прежде чем мы перейдем к коду, я сначала обрисую необходимые структуры папок и файлов, а затем перейду к тому, что входит в каждый файл.
Назовем модуль rw_config, что также будет названием папки модуля.
В корне этой папки у нас будут:
- config (папка, содержащая настройки по умолчанию при установке и файл схемы)
- src (папка, которая будет содержать классы нашего модуля)
- templates (папка, содержащая файлы шаблонов этого модуля)
- rw_config.info.yml
- rw_config.module
- rw_config.routing.yml
Папка config будет содержать две подпапки: ‘install’ и ‘schema’, и каждая из этих папок будет содержать по одному файлу, а именно ‘rw_config.settings.yml’ и ‘rw_config.schema.yml’, соответственно. Что касается папки src, мы рассмотрим, какие файлы и папки туда входят, позже, когда это будет необходимо. Сейчас мы перейдем непосредственно к тому, что входит в
каждый из файлов.
Ниже показано, как должен быть структурирован модуль rw_config.
##Ниже приведен код, который входит в rw_config.info.yml и определяет наш модуль.
# see https://www.drupal.org/docs/drupal-apis/configuration-api/configuration-api-overview
name: 'Read Write Config'
type: module
description: 'Example on how to write and read to drupal config'
core: 8.x
package: 'Dev Examples'
В файле ‘rw_config.module’ мы просто определим/зарегистрируем шаблон, который мы будем использовать для этого проекта, чтобы другие классы (в нашем случае Controller) могли использовать его.
Ниже приведен код, который находится в файле rw_config.module
<?php
/**
* Implements hook_theme().
*/
function rw_config_theme($existing, $type, $theme, $path) {
return [
'rw_config_listing' => [
'render element' => 'children',
'template' => 'rw-config-listing', #name of the template file +.html.twig
'variables' => [
'data' => FALSE
]
]
];
}
Файл ‘rw_config.routing.yml’ будет содержать два маршрута, один для вывода формы конфигурации (редактирование/обновление конфигурации), а другой для вывода страницы, которая будет выводить данные, полагаясь на наши пользовательские настройки конфигурации. Этот файл опирается на все, что мы добавим в папку src, но о папке src мы поговорим позже.
##Ниже приведен код, который входит в rw_config.routing.yml
#see srcControllerConController class
rw_config.r_test:
path: '/rwconfig/tests/page'
defaults:
_controller: 'Drupalrw_configControllerConController::showCats'
_title: 'Rw Config Test Page'
requirements:
_permission: 'access content'
#see srcFormRwConfigSettingsForm class
rw_config.config_form:
path: '/rw_config/config_settings'
defaults:
_form: 'Drupalrw_configFormRwConfigSettingsForm'
_title: 'Rw Config Test Page'
requirements:
_permission: 'access content' # should be a defined better permission
Помните наши два файла в папке config ‘congifinstallrw_config.settings.yml’ и ‘configschemarw_config.schema.yml’. Как следует из их названия, rw_config.schema.yml определяет схему объектов нашего конфига, а rw_config.settings.yml определяет значения по умолчанию при установке модуля, и может быть обновлен или удален. (NB: начиная с Drupal 8 нам не нужно определять структуру схемы для конфигурационного api, вы можете игнорировать rw_config.schema.yml и ваш модуль будет работать нормально).
## Ниже приведен код, который входит в каждый файл.
# ---- Start of rw_config.settings.yml file --------------
# Contains the default values on install and can be
# overridden in our config settings form, accessible
# on route `<yoursite.com>/rw_config/config_settings`
api_key: 'Test default api_key on install'
app_title: 'Test default app title on install'
show_pictures: false
# ---- End of rw_config.settings.yml file --------------
# ---- Start of rw_config.schema.yml file --------------
# Defines rw_config.settings schema
rw_config.settings:
type: config_object
label: 'Read Write Config Example'
mapping:
api_key:
type: string
label: 'API key'
app_title:
type: string
label: 'The app title'
show_pictures:
type: boolean
label: 'Control if picture display on test page'
# ---- End of rw_config.schema.yml file --------------
Помня наш файл маршрутизации и папку src, давайте создадим то, что нам нужно, и соединим оставшиеся части. Нам нужны еще два файла в папке src, а именно: ‘srcFormRwConfigSettingsForm.php’ и ‘srcControllerConController.php’, которые определяют нашу форму/страницу конфигурации и страницу отображения приложений соответственно.
## Ниже приведен код, который входит в каждый файл;
<?php
// RwConfigSettingsForm.php start ------------------------------------------------
namespace Drupalrw_configForm;
use DrupalCoreFormConfigFormBase;
use DrupalCoreFormFormStateInterface;
/**
* Class RwConfigSettingsForm
*
* @package Drupalrw_configForm
*
* see https://www.drupal.org/docs/drupal-apis/configuration-api/working-with-configuration-forms
*/
class RwConfigSettingsForm extends ConfigFormBase {
protected function getEditableConfigNames() {
return ['rw_config.settings'];
}
public function getFormId() {
return 'rw_config_app_settings';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('rw_config.settings');
$form['api_key'] = [
'#default_value' => $config->get('api_key'),
'#description' => $this->t('Your api key give at https://thecatapi.com/'),
'#maxlength' => 40,
'#required' => TRUE,
'#title' => $this->t('API key'),
'#type' => 'textfield',
];
$form['app_title'] = [
'#default_value' => $config->get('app_title'),
'#description' => $this->t('Example page title'),
'#maxlength' => 40,
'#required' => TRUE,
'#title' => $this->t('App title'),
'#type' => 'textfield',
];
$form['show_pictures'] = [
'#default_value' => $config->get('show_pictures'),
'#description' => $this->t('Show pictures '),
'#title' => $this->t('Control if picture display on test page : ..../rwconfig/tests/page'),
'#type' => 'checkbox',
];
return parent::buildForm($form, $form_state);
}
public function submitForm(array &$form, FormStateInterface $form_state) {
# save to config and clear cache
$config = $this->config('rw_config.settings');
$config
->set('api_key', $form_state->getValue('api_key'))
->set('app_title', $form_state->getValue('app_title'))
->set('show_pictures', $form_state->getValue('show_pictures'))
->save();
// clear cache
drupal_flush_all_caches();
parent::submitForm($form, $form_state);
}
}
// RwConfigSettingsForm.php End ------------------------------------------------
<?php
// ConController.php Start ------------------------------------------------
namespace Drupalrw_configController;
use DrupalComponentSerializationJson;
use DrupalCoreConfigConfigFactoryInterface;
use DrupalCoreControllerControllerBase;
use GuzzleHttpClient;
use SymfonyComponentDependencyInjectionContainerInterface;
class ConController extends ControllerBase {
/**
* @var DrupalCoreConfigConfigFactoryInterface
*/
protected $configFactory;
/**
* @var GuzzleHttpClient
*/
private $client;
public function __construct(ConfigFactoryInterface $configFactory, Client $client) {
$this->configFactory = $configFactory;
$this->client = $client;
}
public static function create(ContainerInterface $container) {
return new static(
# see https://www.drupal.org/docs/drupal-apis/configuration-api/simple-configuration-api#s-interacting-with-configuration
$container->get('config.factory'),
# see https://www.drupal.org/docs/contributed-modules/http-client-manager
$container->get('http_client')
);
}
public function showCats(){
$config = $this->configFactory->getEditable('rw_config.settings');
$api_url = 'https://api.thecatapi.com/v1/images/search?limit=20&page=1&order=Desc';
$options = [
'headers' => [
'Content-Type' => 'application/json',
'x-api-key' => $config->get('api_key')
]
];
$data = $this->client->request('GET', $api_url, $options);
$items = Json::decode($data->getBody()->getContents());
return [
'#theme' => 'rw_config_listing', # remember template definition in rw_config.module
'#data' => [ # data to the template file
'app_title' => $config->get('app_title'),
'items' => $items,
'show_pictures' => $config->get('show_pictures'),
]
];
}
}
// ConController.php End ------------------------------------------------
Наконец, перед тестированием модуля создадим последний файл с именем ‘rw-config-listing.html.twig’ в нашей папке templates (см. rw_config_theme() в файле rw_config.module ).
## Ниже приведен код, который входит в этот файл;
<h1> App Name: {{ data['app_title'] }}</h1>
<hr/>
{% for key, item in data['items'] %}
<div style="width: 300px">
<hr/>
<h1> Picture id: {{ item['id'] }}</h1>
{% if data['show_pictures'] %}
Show Picture:
<img src={{ item['url'] }} alt={{ item['url'] }}>
{% else %}
<h4> Picture display set to off!!!</h4>
{% endif %}
</div>
{% endfor %}
Теперь, если мы включим модуль и перейдем по url «/rw_config/config_settings», форма конфигурации, которую мы определили в ‘srcFormRwConfigSettingsForm.php будет отображена, а поля формы будут заполнены значениями по умолчанию, которые мы определили в ‘congifinstallrw_config.settings.yml’.
Теперь зайдите на https://thecatapi.com/ и зарегистрируйтесь, чтобы получить api ключ, присланный на ваш email, и используйте его в форме конфигурации выше, не забудьте отметить ‘Show pictures’ и дать вашему приложению название (вы можете вернуться на эту страницу и изменить настройки), а затем перейдите на ‘/rwconfig/tests/page’, чтобы увидеть настройки конфигурации в действии.
ЗАКЛЮЧЕНИЕ:
Определения конфигурации могут быть экспортированы в виде файлов между сайтами, если вы делаете это и работаете с конфиденциальными ключами, вы можете рассмотреть вопрос об осторожном обращении с файлами конфигурации (конфиденциальность).
РЕСУРСЫ:
- Обзор API конфигурации https://www.drupal.org/docs/drupal-apis/configuration-api/configuration-api-overview
- Документация Yaml https://yaml.org/spec/1.2/spec.html#id2760395
- пользовательские шаблоны twig для пользовательского модуля https://www.drupal.org/docs/theming-drupal/twig-in-drupal/create-custom-twig-templates-for-custom-module
- Управление конфигурацией сайта drupal https://www.drupal.org/docs/configuration-management/managing-your-sites-configuration