default services conflit ?
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\CKEditorPlugin;
|
||||
|
||||
use Drupal\ckeditor\CKEditorPluginBase;
|
||||
use Drupal\editor\Entity\Editor;
|
||||
|
||||
/**
|
||||
* Defines the "{{ plugin_label }}" plugin.
|
||||
*
|
||||
* @CKEditorPlugin(
|
||||
* id = "{{ plugin_id }}",
|
||||
* label = @Translation("{{ plugin_label }}"),
|
||||
* module = "{{ machine_name }}"
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends CKEditorPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFile() {
|
||||
return drupal_get_path('module', '{{ machine_name }}') . '/js/plugins/{{ short_plugin_id }}/plugin.js';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConfig(Editor $editor) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getButtons() {
|
||||
$module_path = drupal_get_path('module', '{{ machine_name }}');
|
||||
return [
|
||||
'{{ short_plugin_id }}' => [
|
||||
'label' => $this->t('{{ plugin_label }}'),
|
||||
'image' => $module_path . '/js/plugins/{{ short_plugin_id }}/icons/{{ short_plugin_id }}.png',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @file
|
||||
* Defines dialog for {{ plugin_label }} CKEditor plugin.
|
||||
*/
|
||||
|
||||
(function (Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
// Dialog definition.
|
||||
CKEDITOR.dialog.add('{{ command_name }}Dialog', function (editor) {
|
||||
|
||||
return {
|
||||
|
||||
// Basic properties of the dialog window: title, minimum size.
|
||||
title: Drupal.t('Abbreviation properties'),
|
||||
minWidth: 400,
|
||||
minHeight: 150,
|
||||
|
||||
// Dialog window content definition.
|
||||
contents: [
|
||||
{
|
||||
// Definition of the settings dialog tab.
|
||||
id: 'tab-settings',
|
||||
label: 'Settings',
|
||||
|
||||
// The tab content.
|
||||
elements: [
|
||||
{
|
||||
// Text input field for the abbreviation text.
|
||||
type: 'text',
|
||||
id: 'abbr',
|
||||
label: Drupal.t('Abbreviation'),
|
||||
|
||||
// Validation checking whether the field is not empty.
|
||||
validate: CKEDITOR.dialog.validate.notEmpty(Drupal.t('Abbreviation field cannot be empty.'))
|
||||
},
|
||||
{
|
||||
// Text input field for the abbreviation title (explanation).
|
||||
type: 'text',
|
||||
id: 'title',
|
||||
label: Drupal.t('Explanation'),
|
||||
validate: CKEDITOR.dialog.validate.notEmpty(Drupal.t('Explanation field cannot be empty.'))
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
// This method is invoked once a user clicks the OK button, confirming the
|
||||
// dialog.
|
||||
onOk: function () {
|
||||
|
||||
// The context of this function is the dialog object itself.
|
||||
// See http://docs.ckeditor.com/#!/api/CKEDITOR.dialog.
|
||||
var dialog = this;
|
||||
|
||||
// Create a new <abbr> element.
|
||||
var abbr = editor.document.createElement('abbr');
|
||||
|
||||
// Set element attribute and text by getting the defined field values.
|
||||
abbr.setAttribute('title', dialog.getValueOf('tab-settings', 'title'));
|
||||
abbr.setText(dialog.getValueOf('tab-settings', 'abbr'));
|
||||
|
||||
// Finally, insert the element into the editor at the caret position.
|
||||
editor.insertElement(abbr);
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
} (Drupal));
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 597 B |
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @file
|
||||
* {{ plugin_label }} CKEditor plugin.
|
||||
*
|
||||
* Basic plugin inserting abbreviation elements into the CKEditor editing area.
|
||||
*
|
||||
* @DCG The code is based on an example from CKEditor Plugin SDK tutorial.
|
||||
*
|
||||
* @see http://docs.ckeditor.com/#!/guide/plugin_sdk_sample_1
|
||||
*/
|
||||
|
||||
(function (Drupal) {
|
||||
|
||||
'use strict';
|
||||
|
||||
CKEDITOR.plugins.add('{{ plugin_id }}', {
|
||||
|
||||
// Register the icons.
|
||||
icons: '{{ short_plugin_id }}',
|
||||
|
||||
// The plugin initialization logic goes inside this method.
|
||||
init: function (editor) {
|
||||
|
||||
// Define an editor command that opens our dialog window.
|
||||
editor.addCommand('{{ command_name }}', new CKEDITOR.dialogCommand('{{ command_name }}Dialog'));
|
||||
|
||||
// Create a toolbar button that executes the above command.
|
||||
editor.ui.addButton('{{ short_plugin_id }}', {
|
||||
|
||||
// The text part of the button (if available) and the tooltip.
|
||||
label: Drupal.t('Insert abbreviation'),
|
||||
|
||||
// The command to execute on click.
|
||||
command: '{{ command_name }}',
|
||||
|
||||
// The button placement in the toolbar (toolbar group name).
|
||||
toolbar: 'insert'
|
||||
});
|
||||
|
||||
// Register our dialog file, this.path is the plugin folder path.
|
||||
CKEDITOR.dialog.add('{{ command_name }}Dialog', this.path + 'dialogs/{{ short_plugin_id }}.js');
|
||||
}
|
||||
});
|
||||
|
||||
} (Drupal));
|
||||
@@ -0,0 +1,7 @@
|
||||
action.configuration.{{ plugin_id }}:
|
||||
type: mapping
|
||||
label: 'Configuration for "{{ plugin_label }}" action'
|
||||
mapping:
|
||||
title:
|
||||
type: string
|
||||
label: Title
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\Action;
|
||||
|
||||
{% if configurable %}
|
||||
use Drupal\Core\Action\ConfigurableActionBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
{% else %}
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
{% endif %}
|
||||
|
||||
/**
|
||||
* Provides a {{ plugin_label|article }} action.
|
||||
*
|
||||
* @Action(
|
||||
* id = "{{ plugin_id }}",
|
||||
* label = @Translation("{{ plugin_label }}"),
|
||||
* type = "node",
|
||||
* category = @Translation("{{ category }}")
|
||||
* )
|
||||
*
|
||||
* @DCG
|
||||
* For a simple updating entity fields consider extending FieldUpdateActionBase.
|
||||
*/
|
||||
class {{ class }} extends {{ configurable ? 'ConfigurableActionBase' : 'ActionBase' }} {
|
||||
|
||||
{% if configurable %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return ['title' => ''];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$form['title'] = [
|
||||
'#title' => $this->t('New title'),
|
||||
'#type' => 'textfield',
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $this->configuration['title'],
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->configuration['title'] = $form_state->getValue('title');
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($node, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
$access = $node->access('update', $account, TRUE)
|
||||
->andIf($node->title->access('edit', $account, TRUE));
|
||||
return $return_as_object ? $access : $access->isAllowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($node = NULL) {
|
||||
/** @var \Drupal\node\NodeInterface $node */
|
||||
{% if configurable %}
|
||||
$node->setTitle($this->configuration['title'])->save();
|
||||
{% else %}
|
||||
$node->setTitle($this->t('New title'))->save();
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
block.settings.{{ plugin_id }}:
|
||||
type: block_settings
|
||||
label: '{{ plugin_label }} block'
|
||||
mapping:
|
||||
foo:
|
||||
type: string
|
||||
label: Foo
|
||||
@@ -0,0 +1,119 @@
|
||||
{% import 'lib/di.twig' as di %}
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\Block;
|
||||
|
||||
{% sort %}
|
||||
{% if access %}
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
{% endif %}
|
||||
use Drupal\Core\Block\BlockBase;
|
||||
{% if configurable %}
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
{% endif %}
|
||||
{% if services %}
|
||||
{{ di.use(services) }}
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
{% endif %}
|
||||
{% endsort %}
|
||||
|
||||
/**
|
||||
* Provides {{ plugin_label|article|lower }} block.
|
||||
*
|
||||
* @Block(
|
||||
* id = "{{ plugin_id }}",
|
||||
* admin_label = @Translation("{{ plugin_label }}"),
|
||||
* category = @Translation("{{ category }}")
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends BlockBase {% if services %}implements ContainerFactoryPluginInterface {% endif %}{
|
||||
|
||||
{% if services %}
|
||||
{{ di.properties(services) }}
|
||||
|
||||
/**
|
||||
* Constructs a new {{ class }} instance.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The plugin configuration, i.e. an array with configuration values keyed
|
||||
* by configuration option name. The special key 'context' may be used to
|
||||
* initialize the defined contexts by setting it to an array of context
|
||||
* values keyed by context names.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
{{ di.annotation(services) }}
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, {{ di.signature(services) }}) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
{{ di.assignment(services) }}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
{{ di.container(services) }}
|
||||
);
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% if configurable %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'foo' => $this->t('Hello world!'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function blockForm($form, FormStateInterface $form_state) {
|
||||
$form['foo'] = [
|
||||
'#type' => 'textarea',
|
||||
'#title' => $this->t('Foo'),
|
||||
'#default_value' => $this->configuration['foo'],
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function blockSubmit($form, FormStateInterface $form_state) {
|
||||
$this->configuration['foo'] = $form_state->getValue('foo');
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% if access %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function blockAccess(AccountInterface $account) {
|
||||
// @DCG Evaluate the access condition here.
|
||||
$condition = TRUE;
|
||||
return AccessResult::allowedIf($condition);
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function build() {
|
||||
$build['content'] = [
|
||||
'#markup' => $this->t('It works!'),
|
||||
];
|
||||
return $build;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
condition.plugin.{{ plugin_id }}:
|
||||
type: condition.plugin
|
||||
label: '{{ plugin_label }} condition'
|
||||
mapping:
|
||||
age:
|
||||
type: integer
|
||||
label: Age
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\Condition;
|
||||
|
||||
use Drupal\Component\Datetime\TimeInterface;
|
||||
use Drupal\Core\Condition\ConditionPluginBase;
|
||||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a '{{ plugin_label }}' condition.
|
||||
*
|
||||
* @Condition(
|
||||
* id = "{{ plugin_id }}",
|
||||
* label = @Translation("{{ plugin_label }}"),
|
||||
* context_definitions = {
|
||||
* "node" = @ContextDefinition(
|
||||
* "entity:node",
|
||||
* label = @Translation("Node")
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @DCG prior to Drupal 8.7 the 'context_definitions' key was called 'context'.
|
||||
*/
|
||||
class {{ class }} extends ConditionPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The date formatter.
|
||||
*
|
||||
* @var \Drupal\Core\Datetime\DateFormatterInterface
|
||||
*/
|
||||
protected $dateFormatter;
|
||||
|
||||
/**
|
||||
* The time service.
|
||||
*
|
||||
* @var \Drupal\Component\Datetime\TimeInterface
|
||||
*/
|
||||
protected $time;
|
||||
|
||||
/**
|
||||
* Creates a new {{ class }} instance.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The plugin configuration, i.e. an array with configuration values keyed
|
||||
* by configuration option name. The special key 'context' may be used to
|
||||
* initialize the defined contexts by setting it to an array of context
|
||||
* values keyed by context names.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
|
||||
* The date formatter.
|
||||
* @param \Drupal\Component\Datetime\TimeInterface $time
|
||||
* The time service.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, DateFormatterInterface $date_formatter, TimeInterface $time) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->dateFormatter = $date_formatter;
|
||||
$this->time = $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('date.formatter'),
|
||||
$container->get('datetime.time')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return ['age' => NULL] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
|
||||
$form['age'] = [
|
||||
'#title' => $this->t('Node age, sec'),
|
||||
'#type' => 'number',
|
||||
'#min' => 0,
|
||||
'#default_value' => $this->configuration['age'],
|
||||
];
|
||||
|
||||
return parent::buildConfigurationForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->configuration['age'] = $form_state->getValue('age');
|
||||
parent::submitConfigurationForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function summary() {
|
||||
return $this->t(
|
||||
'Node age: @age',
|
||||
['@age' => $this->dateFormatter->formatInterval($this->configuration['age'])]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function evaluate() {
|
||||
if (!$this->configuration['age'] && !$this->isNegated()) {
|
||||
return TRUE;
|
||||
}
|
||||
$age = $this->time->getRequestTime() - $this->getContextValue('node')->getCreatedTime();
|
||||
return $age < $this->configuration['age'];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\Validation\Constraint;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
/**
|
||||
* Validates the {{ plugin_label }} constraint.
|
||||
*/
|
||||
class {{ class }}Validator extends ConstraintValidator {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
{% if input_type == 'entity' %}
|
||||
public function validate($entity, Constraint $constraint) {
|
||||
|
||||
// @DCG Validate the entity here.
|
||||
if ($entity->label() == 'foo') {
|
||||
$this->context->buildViolation($constraint->errorMessage)
|
||||
// @DCG The path depends on entity type. It can be title, name, etc.
|
||||
->atPath('title')
|
||||
->addViolation();
|
||||
}
|
||||
|
||||
}
|
||||
{% elseif input_type == 'item_list' %}
|
||||
public function validate($items, Constraint $constraint) {
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
// @DCG Validate the item here.
|
||||
if ($item->value == 'foo') {
|
||||
$this->context->buildViolation($constraint->errorMessage)
|
||||
->atPath($delta)
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
{% elseif input_type == 'item' %}
|
||||
public function validate($item, Constraint $constraint) {
|
||||
|
||||
$value = $item->getValue()['value'];
|
||||
// @DCG Validate the value here.
|
||||
if ($value == 'foo') {
|
||||
$this->context->addViolation($constraint->errorMessage);
|
||||
}
|
||||
|
||||
}
|
||||
{% else %}
|
||||
public function validate($value, Constraint $constraint) {
|
||||
|
||||
// @DCG Validate the value here.
|
||||
if ($value == 'foo') {
|
||||
$this->context->addViolation($constraint->errorMessage);
|
||||
}
|
||||
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\Validation\Constraint;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
/**
|
||||
* Provides {{ plugin_label|article }} constraint.
|
||||
*
|
||||
* @Constraint(
|
||||
* id = "{{ plugin_id }}",
|
||||
* label = @Translation("{{ plugin_label }}", context = "Validation"),
|
||||
* )
|
||||
{% if input_type == 'entity' %}
|
||||
*
|
||||
* @DCG
|
||||
* To apply this constraint on a particular field implement
|
||||
* hook_entity_type_build().
|
||||
{% elseif input_type == 'item_list' %}
|
||||
*
|
||||
* @DCG
|
||||
* To apply this constraint on third party entity types implement either
|
||||
* hook_entity_base_field_info_alter() or hook_entity_bundle_field_info_alter().
|
||||
{% elseif input_type == 'item' %}
|
||||
*
|
||||
* @DCG
|
||||
* To apply this constraint on third party field types. Implement
|
||||
* hook_field_info_alter().
|
||||
{% endif %}
|
||||
*/
|
||||
class {{ class }} extends Constraint {
|
||||
|
||||
public $errorMessage = 'The error message.';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
entity_reference_selection.{{ plugin_id }}:
|
||||
{# User selection plugin provides has some additional options. #}
|
||||
type: entity_reference_selection.default{{ entity_type == 'user' ? ':user' }}
|
||||
label: '{{ plugin_label }} handler settings'
|
||||
{% if configurable %}
|
||||
mapping:
|
||||
foo:
|
||||
type: string
|
||||
label: Foo
|
||||
{% endif %}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\EntityReferenceSelection;
|
||||
|
||||
{% sort %}
|
||||
{% if configurable %}
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
{% endif %}
|
||||
use {{ base_class_full }};
|
||||
{% endsort %}
|
||||
|
||||
/**
|
||||
* Plugin description.
|
||||
*
|
||||
* @EntityReferenceSelection(
|
||||
* id = "{{ plugin_id }}",
|
||||
* label = @Translation("{{ plugin_label }}"),
|
||||
* group = "{{ plugin_id }}",
|
||||
* entity_types = {"{{ entity_type }}"},
|
||||
* weight = 0
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends {{ base_class }} {
|
||||
|
||||
{% if configurable %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
|
||||
$default_configuration = [
|
||||
'foo' => 'bar',
|
||||
];
|
||||
|
||||
return $default_configuration + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
$form['foo'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Foo'),
|
||||
'#default_value' => $this->configuration['foo'],
|
||||
];
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
|
||||
$query = parent::buildEntityQuery($match, $match_operator);
|
||||
|
||||
// @DCG
|
||||
// Here you can apply addition conditions, sorting, etc to the query.
|
||||
// Also see self::entityQueryAlter().
|
||||
$query->condition('field_example', 123);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
field.formatter.settings.{{ plugin_id }}:
|
||||
type: mapping
|
||||
label: {{ plugin_label }} formatter settings
|
||||
mapping:
|
||||
foo:
|
||||
type: string
|
||||
label: Foo
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
{% if configurable %}
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
{% endif %}
|
||||
|
||||
/**
|
||||
* Plugin implementation of the '{{ plugin_label }}' formatter.
|
||||
*
|
||||
* @FieldFormatter(
|
||||
* id = "{{ plugin_id }}",
|
||||
* label = @Translation("{{ plugin_label }}"),
|
||||
* field_types = {
|
||||
* "string"
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends FormatterBase {
|
||||
|
||||
{% if configurable %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
return [
|
||||
'foo' => 'bar',
|
||||
] + parent::defaultSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
|
||||
$elements['foo'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Foo'),
|
||||
'#default_value' => $this->getSetting('foo'),
|
||||
];
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsSummary() {
|
||||
$summary[] = $this->t('Foo: @foo', ['@foo' => $this->getSetting('foo')]);
|
||||
return $summary;
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$element = [];
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
$element[$delta] = [
|
||||
'#markup' => $item->value,
|
||||
];
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{% if configurable_storage %}
|
||||
field.storage_settings.{{ plugin_id }}:
|
||||
type: mapping
|
||||
label: {{ plugin_label }} storage settings
|
||||
mapping:
|
||||
foo:
|
||||
type: string
|
||||
label: Foo
|
||||
|
||||
{% endif %}
|
||||
{% if configurable_instance %}
|
||||
field.field_settings.{{ plugin_id }}:
|
||||
type: mapping
|
||||
label: {{ plugin_label }} field settings
|
||||
mapping:
|
||||
bar:
|
||||
type: string
|
||||
label: Bar
|
||||
|
||||
{% endif %}
|
||||
field.value.{{ plugin_id }}:
|
||||
type: mapping
|
||||
label: Default value
|
||||
mapping:
|
||||
value:
|
||||
type: label
|
||||
label: Value
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\Field\FieldType;
|
||||
|
||||
use Drupal\Component\Utility\Random;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemBase;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
{% if configurable_storage or configurable_instance %}
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
{% endif %}
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
|
||||
/**
|
||||
* Defines the '{{ plugin_id }}' field type.
|
||||
*
|
||||
* @FieldType(
|
||||
* id = "{{ plugin_id }}",
|
||||
* label = @Translation("{{ plugin_label }}"),
|
||||
* category = @Translation("General"),
|
||||
* default_widget = "string_textfield",
|
||||
* default_formatter = "string"
|
||||
* )
|
||||
*
|
||||
* @DCG
|
||||
* If you are implementing a single value field type you may want to inherit
|
||||
* this class form some of the field type classes provided by Drupal core.
|
||||
* Check out /core/lib/Drupal/Core/Field/Plugin/Field/FieldType directory for a
|
||||
* list of available field type implementations.
|
||||
*/
|
||||
class {{ class }} extends FieldItemBase {
|
||||
|
||||
{% if configurable_storage %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultStorageSettings() {
|
||||
$settings = ['foo' => 'wine'];
|
||||
return $settings + parent::defaultStorageSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
|
||||
|
||||
$element['foo'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Foo'),
|
||||
'#default_value' => $this->getSetting('foo'),
|
||||
'#disabled' => $has_data,
|
||||
];
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% if configurable_instance %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultFieldSettings() {
|
||||
$settings = ['bar' => 'beer'];
|
||||
return $settings + parent::defaultFieldSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
|
||||
|
||||
$element['bar'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Bar'),
|
||||
'#default_value' => $this->getSetting('bar'),
|
||||
];
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isEmpty() {
|
||||
$value = $this->get('value')->getValue();
|
||||
return $value === NULL || $value === '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
|
||||
|
||||
// @DCG
|
||||
// See /core/lib/Drupal/Core/TypedData/Plugin/DataType directory for
|
||||
// available data types.
|
||||
$properties['value'] = DataDefinition::create('string')
|
||||
->setLabel(t('Text value'))
|
||||
->setRequired(TRUE);
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConstraints() {
|
||||
$constraints = parent::getConstraints();
|
||||
|
||||
$constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
|
||||
|
||||
// @DCG Suppose our value must not be longer than 10 characters.
|
||||
$options['value']['Length']['max'] = 10;
|
||||
|
||||
// @DCG
|
||||
// See /core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint
|
||||
// directory for available constraints.
|
||||
$constraints[] = $constraint_manager->create('ComplexData', $options);
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function schema(FieldStorageDefinitionInterface $field_definition) {
|
||||
|
||||
$columns = [
|
||||
'value' => [
|
||||
'type' => 'varchar',
|
||||
'not null' => FALSE,
|
||||
'description' => 'Column description.',
|
||||
'length' => 255,
|
||||
],
|
||||
];
|
||||
|
||||
$schema = [
|
||||
'columns' => $columns,
|
||||
// @DCG Add indexes here if necessary.
|
||||
];
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
|
||||
$random = new Random();
|
||||
$values['value'] = $random->word(mt_rand(1, 50));
|
||||
return $values;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
field.widget.settings.{{ plugin_id }}:
|
||||
type: mapping
|
||||
label: {{ plugin_label }} widget settings
|
||||
mapping:
|
||||
foo:
|
||||
type: string
|
||||
label: Foo
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\Field\FieldWidget;
|
||||
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\WidgetBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Defines the '{{ plugin_id }}' field widget.
|
||||
*
|
||||
* @FieldWidget(
|
||||
* id = "{{ plugin_id }}",
|
||||
* label = @Translation("{{ plugin_label }}"),
|
||||
* field_types = {"string"},
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends WidgetBase {
|
||||
|
||||
{% if configurable %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function defaultSettings() {
|
||||
return [
|
||||
'foo' => 'bar',
|
||||
] + parent::defaultSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
|
||||
$element['foo'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Foo'),
|
||||
'#default_value' => $this->getSetting('foo'),
|
||||
];
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsSummary() {
|
||||
$summary[] = $this->t('Foo: @foo', ['@foo' => $this->getSetting('foo')]);
|
||||
return $summary;
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
|
||||
|
||||
$element['value'] = $element + [
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
|
||||
];
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
filter_settings.{{ plugin_id }}:
|
||||
type: filter
|
||||
label: '{{ plugin_label }} filter'
|
||||
mapping:
|
||||
example:
|
||||
type: string
|
||||
label: Example
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\Filter;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\filter\FilterProcessResult;
|
||||
use Drupal\filter\Plugin\FilterBase;
|
||||
|
||||
/**
|
||||
* Provides a '{{ plugin_label }}' filter.
|
||||
*
|
||||
* @Filter(
|
||||
* id = "{{ plugin_id }}",
|
||||
* title = @Translation("{{ plugin_label }}"),
|
||||
* type = Drupal\filter\Plugin\FilterInterface::{{ filter_type }},
|
||||
* settings = {
|
||||
* "example" = "foo",
|
||||
* },
|
||||
* weight = -10
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends FilterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function settingsForm(array $form, FormStateInterface $form_state) {
|
||||
$form['example'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Example'),
|
||||
'#default_value' => $this->settings['example'],
|
||||
'#description' => $this->t('Description of the setting.'),
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process($text, $langcode) {
|
||||
// @DCG Process text here.
|
||||
$example = $this->settings['example'];
|
||||
$text = str_replace($example, "<b>$example</b>", $text);
|
||||
return new FilterProcessResult($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function tips($long = FALSE) {
|
||||
return $this->t('Some filter tips here.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\Menu;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Menu\MenuLinkDefault;
|
||||
use Drupal\Core\Menu\StaticMenuLinkOverridesInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* A menu link that displays count of messages.
|
||||
*/
|
||||
class {{ class }} extends MenuLinkDefault {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $dbConnection;
|
||||
|
||||
/**
|
||||
* Constructs the plugin object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Menu\StaticMenuLinkOverridesInterface $static_override
|
||||
* The static override storage.
|
||||
* @param \Drupal\Core\Database\Connection $db_connection
|
||||
* The database connection.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, StaticMenuLinkOverridesInterface $static_override, Connection $db_connection) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $static_override);
|
||||
$this->dbConnection = $db_connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('menu_link.static.overrides'),
|
||||
$container->get('database')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle() {
|
||||
$count = $this->dbConnection->query('SELECT COUNT(*) FROM {messages}')->fetchField();
|
||||
return $this->t('Messages (@count)', ['@count' => $count]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRouteName() {
|
||||
return '{{ machine_name }}.messages';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheTags() {
|
||||
// @DCG Invalidate this tags when messages are created or removed.
|
||||
return ['{{ machine_name }}.messages_count'];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\migrate\destination;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\migrate\Plugin\migrate\destination\DestinationBase;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* The '{{ plugin_id }}' destination plugin.
|
||||
*
|
||||
* @MigrateDestination(
|
||||
* id = "{{ plugin_id }}"
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends DestinationBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* Constructs the plugin.
|
||||
*
|
||||
* @param array $configuration
|
||||
* Plugin configuration.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin definition.
|
||||
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The current migration.
|
||||
* @param \Drupal\Core\Database\Connection $connection
|
||||
* The database connection.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, Connection $connection) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$migration,
|
||||
$container->get('database')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function import(Row $row, array $old_destination_id_values = []) {
|
||||
|
||||
// Save the row to custom table.
|
||||
$this->connection
|
||||
->insert('example')
|
||||
->fields([
|
||||
'id' => $row->getDestinationProperty('id'),
|
||||
'name' => $row->getDestinationProperty('name'),
|
||||
'status' => $row->getDestinationProperty('status'),
|
||||
])
|
||||
->execute();
|
||||
|
||||
return [$row->getDestinationProperty('id')];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['id']['type'] = [
|
||||
'type' => 'integer',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'big',
|
||||
];
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields(MigrationInterface $migration = NULL) {
|
||||
return [
|
||||
'id' => $this->t('The record ID.'),
|
||||
'name' => $this->t('The record name.'),
|
||||
'status' => $this->t('The record status'),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\migrate\process;
|
||||
|
||||
use Drupal\Component\Transliteration\TransliterationInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides {{ plugin_id|article }} plugin.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* @code
|
||||
* process:
|
||||
* bar:
|
||||
* plugin: {{ plugin_id }}
|
||||
* source: foo
|
||||
* @endcode
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "{{ plugin_id }}"
|
||||
* )
|
||||
*
|
||||
* @DCG
|
||||
* ContainerFactoryPluginInterface is optional here. If you have no need for
|
||||
* external services just remove it and all other stuff except transform()
|
||||
* method.
|
||||
*/
|
||||
class {{ class }} extends ProcessPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The transliteration service.
|
||||
*
|
||||
* @var \Drupal\Component\Transliteration\TransliterationInterface
|
||||
*/
|
||||
protected $transliteration;
|
||||
|
||||
/**
|
||||
* Constructs {{ class|article }} plugin.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The plugin configuration.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin definition.
|
||||
* @param \Drupal\Component\Transliteration\TransliterationInterface $transliteration
|
||||
* The transliteration service.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, TransliterationInterface $transliteration) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->transliteration = $transliteration;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('transliteration')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
return $this->transliteration->transliterate($value, LanguageInterface::LANGCODE_DEFAULT);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\migrate\source;
|
||||
|
||||
use Drupal\migrate\Plugin\migrate\source\{{ base_class }};
|
||||
use Drupal\migrate\Row;
|
||||
|
||||
/**
|
||||
* The '{{ plugin_id }}' source plugin.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "{{ plugin_id }}",
|
||||
* source_module = "{{ machine_name }}"
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends {{ base_class }} {
|
||||
|
||||
{% if source_type == 'sql' %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$query = $this->select('example', 'e')
|
||||
->fields('e', ['id', 'name', 'status']);
|
||||
return $query;
|
||||
}
|
||||
|
||||
{% else %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString() {
|
||||
// @DCG You may return something meaningful here.
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function initializeIterator() {
|
||||
|
||||
// @DCG
|
||||
// In this example we return a hardcoded set of records.
|
||||
//
|
||||
// For large sets of data consider using generators like follows:
|
||||
// @code
|
||||
// foreach ($foo->nextRecord() as $record) {
|
||||
// yield $record;
|
||||
// }
|
||||
// @endcode
|
||||
$records = [
|
||||
[
|
||||
'id' => 1,
|
||||
'name' => 'Alpha',
|
||||
'status' => TRUE,
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'name' => 'Beta',
|
||||
'status' => FALSE,
|
||||
],
|
||||
[
|
||||
'id' => 3,
|
||||
'name' => 'Gamma',
|
||||
'status' => TRUE,
|
||||
],
|
||||
];
|
||||
|
||||
return new \ArrayIterator($records);
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return [
|
||||
'id' => $this->t('The record ID.'),
|
||||
'name' => $this->t('The record name.'),
|
||||
'status' => $this->t('The record status'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['id']['type'] = [
|
||||
'type' => 'integer',
|
||||
'unsigned' => TRUE,
|
||||
'size' => 'big',
|
||||
];
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function prepareRow(Row $row) {
|
||||
|
||||
// @DCG
|
||||
// Extend/modify the row here if needed.
|
||||
//
|
||||
// Example:
|
||||
// @code
|
||||
// $name = $row->getSourceProperty('name');
|
||||
// $row->setSourceProperty('name', Html::escape('$name');
|
||||
// @endcode
|
||||
return parent::prepareRow($row);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\QueueWorker;
|
||||
|
||||
use Drupal\Core\Queue\QueueWorkerBase;
|
||||
|
||||
/**
|
||||
* Defines '{{ plugin_id }}' queue worker.
|
||||
*
|
||||
* @QueueWorker(
|
||||
* id = "{{ plugin_id }}",
|
||||
* title = @Translation("{{ plugin_label }}"),
|
||||
* cron = {"time" = 60}
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends QueueWorkerBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function processItem($data) {
|
||||
// @todo Process data here.
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\rest\resource;
|
||||
|
||||
use Drupal\Component\Plugin\DependentPluginInterface;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Routing\BcRoute;
|
||||
use Drupal\rest\ModifiedResourceResponse;
|
||||
use Drupal\rest\Plugin\ResourceBase;
|
||||
use Drupal\rest\ResourceResponse;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
/**
|
||||
* Represents {{ plugin_label }} records as resources.
|
||||
*
|
||||
* @RestResource (
|
||||
* id = "{{ plugin_id }}",
|
||||
* label = @Translation("{{ plugin_label }}"),
|
||||
* uri_paths = {
|
||||
* "canonical" = "/api/{{ plugin_id|u2h }}/{id}",
|
||||
* "https://www.drupal.org/link-relations/create" = "/api/{{ plugin_id|u2h }}"
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @DCG
|
||||
* This plugin exposes database records as REST resources. In order to enable it
|
||||
* import the resource configuration into active configuration storage. You may
|
||||
* find an example of such configuration in the following file:
|
||||
* core/modules/rest/config/optional/rest.resource.entity.node.yml.
|
||||
* Alternatively you can make use of REST UI module.
|
||||
* @see https://www.drupal.org/project/restui
|
||||
* For accessing Drupal entities through REST interface use
|
||||
* \Drupal\rest\Plugin\rest\resource\EntityResource plugin.
|
||||
*/
|
||||
class {{ class }} extends ResourceBase implements DependentPluginInterface {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $dbConnection;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\rest\Plugin\rest\resource\EntityResource object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param array $serializer_formats
|
||||
* The available serialization formats.
|
||||
* @param \Psr\Log\LoggerInterface $logger
|
||||
* A logger instance.
|
||||
* @param \Drupal\Core\Database\Connection $db_connection
|
||||
* The database connection.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, array $serializer_formats, LoggerInterface $logger, Connection $db_connection) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
|
||||
$this->dbConnection = $db_connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->getParameter('serializer.formats'),
|
||||
$container->get('logger.factory')->get('rest'),
|
||||
$container->get('database')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to GET requests.
|
||||
*
|
||||
* @param int $id
|
||||
* The ID of the record.
|
||||
*
|
||||
* @return \Drupal\rest\ResourceResponse
|
||||
* The response containing the record.
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
|
||||
*/
|
||||
public function get($id) {
|
||||
return new ResourceResponse($this->loadRecord($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to POST requests and saves the new record.
|
||||
*
|
||||
* @param mixed $data
|
||||
* Data to write into the database.
|
||||
*
|
||||
* @return \Drupal\rest\ModifiedResourceResponse
|
||||
* The HTTP response object.
|
||||
*/
|
||||
public function post($data) {
|
||||
|
||||
$this->validate($data);
|
||||
|
||||
$id = $this->dbConnection->insert('{{ plugin_id }}')
|
||||
->fields($data)
|
||||
->execute();
|
||||
|
||||
$this->logger->notice('New {{ plugin_label|lower }} record has been created.');
|
||||
|
||||
$created_record = $this->loadRecord($id);
|
||||
|
||||
// Return the newly created record in the response body.
|
||||
return new ModifiedResourceResponse($created_record, 201);
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to entity PATCH requests.
|
||||
*
|
||||
* @param int $id
|
||||
* The ID of the record.
|
||||
* @param mixed $data
|
||||
* Data to write into the database.
|
||||
*
|
||||
* @return \Drupal\rest\ModifiedResourceResponse
|
||||
* The HTTP response object.
|
||||
*/
|
||||
public function patch($id, $data) {
|
||||
$this->validate($data);
|
||||
return $this->updateRecord($id, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to entity DELETE requests.
|
||||
*
|
||||
* @param int $id
|
||||
* The ID of the record.
|
||||
*
|
||||
* @return \Drupal\rest\ModifiedResourceResponse
|
||||
* The HTTP response object.
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
|
||||
*/
|
||||
public function delete($id) {
|
||||
|
||||
// Make sure the record still exists.
|
||||
$this->loadRecord($id);
|
||||
|
||||
$this->dbConnection->delete('{{ plugin_id }}')
|
||||
->condition('id', $id)
|
||||
->execute();
|
||||
|
||||
$this->logger->notice('{{ plugin_label }} record @id has been deleted.', ['@id' => $id]);
|
||||
|
||||
// Deleted responses have an empty body.
|
||||
return new ModifiedResourceResponse(NULL, 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getBaseRoute($canonical_path, $method) {
|
||||
$route = parent::getBaseRoute($canonical_path, $method);
|
||||
|
||||
// Change ID validation pattern.
|
||||
if ($method != 'POST') {
|
||||
$route->setRequirement('id', '\d+');
|
||||
}
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function calculateDependencies() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function routes() {
|
||||
$collection = parent::routes();
|
||||
|
||||
// Take out BC routes added in base class.
|
||||
// @see https://www.drupal.org/node/2865645
|
||||
// @todo Remove this in Drupal 9.
|
||||
foreach ($collection as $route_name => $route) {
|
||||
if ($route instanceof BcRoute) {
|
||||
$collection->remove($route_name);
|
||||
}
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates incoming record.
|
||||
*
|
||||
* @param mixed $record
|
||||
* Data to validate.
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
|
||||
*/
|
||||
protected function validate($record) {
|
||||
if (!is_array($record) || count($record) == 0) {
|
||||
throw new BadRequestHttpException('No record content received.');
|
||||
}
|
||||
|
||||
$allowed_fields = [
|
||||
'title',
|
||||
'description',
|
||||
'price',
|
||||
];
|
||||
|
||||
if (count(array_diff(array_keys($record), $allowed_fields)) > 0) {
|
||||
throw new BadRequestHttpException('Record structure is not correct.');
|
||||
}
|
||||
|
||||
if (empty($record['title'])) {
|
||||
throw new BadRequestHttpException('Title is required.');
|
||||
}
|
||||
elseif (isset($record['title']) && strlen($record['title']) > 255) {
|
||||
throw new BadRequestHttpException('Title is too big.');
|
||||
}
|
||||
// @DCG Add more validation rules here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads record from database.
|
||||
*
|
||||
* @param int $id
|
||||
* The ID of the record.
|
||||
*
|
||||
* @return array
|
||||
* The database record.
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
*/
|
||||
protected function loadRecord($id) {
|
||||
$record = $this->dbConnection->query('SELECT * FROM {{ '{' }}{{ plugin_id }}{{ '}' }} WHERE id = :id', [':id' => $id])->fetchAssoc();
|
||||
if (!$record) {
|
||||
throw new NotFoundHttpException('The record was not found.');
|
||||
}
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates record.
|
||||
*
|
||||
* @param int $id
|
||||
* The ID of the record.
|
||||
* @param array $record
|
||||
* The record to validate.
|
||||
*
|
||||
* @return \Drupal\rest\ModifiedResourceResponse
|
||||
* The HTTP response object.
|
||||
*/
|
||||
protected function updateRecord($id, array $record) {
|
||||
|
||||
// Make sure the record already exists.
|
||||
$this->loadRecord($id);
|
||||
|
||||
$this->validate($record);
|
||||
|
||||
$this->dbConnection->update('{{ plugin_id }}')
|
||||
->fields($record)
|
||||
->condition('id', $id)
|
||||
->execute();
|
||||
|
||||
$this->logger->notice('{{ plugin_label }} record @id has been updated.', ['@id' => $id]);
|
||||
|
||||
// Return the updated record in the response body.
|
||||
$updated_record = $this->loadRecord($id);
|
||||
return new ModifiedResourceResponse($updated_record, 200);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
views.argument_default.{{ plugin_id }}:
|
||||
type: mapping
|
||||
label: '{{ plugin_label }}'
|
||||
mapping:
|
||||
example:
|
||||
type: string
|
||||
label: 'Example'
|
||||
@@ -0,0 +1,116 @@
|
||||
{% import 'lib/di.twig' as di %}
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\views\argument_default;
|
||||
|
||||
{% sort %}
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
{% if configurable %}
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
{% endif %}
|
||||
use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
|
||||
{% if services %}
|
||||
{{ di.use(services) }}
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
{% endif %}
|
||||
{% endsort %}
|
||||
|
||||
/**
|
||||
* {{ plugin_label }} argument default plugin.
|
||||
*
|
||||
* @ViewsArgumentDefault(
|
||||
* id = "{{ plugin_id }}",
|
||||
* title = @Translation("{{ plugin_label }}")
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {
|
||||
|
||||
{% if services %}
|
||||
{{ di.properties(services) }}
|
||||
|
||||
/**
|
||||
* Constructs a new {{ class }} instance.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The plugin configuration, i.e. an array with configuration values keyed
|
||||
* by configuration option name. The special key 'context' may be used to
|
||||
* initialize the defined contexts by setting it to an array of context
|
||||
* values keyed by context names.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
{{ di.annotation(services) }}
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, {{ di.signature(services) }}) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
{{ di.assignment(services) }}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
{{ di.container(services) }}
|
||||
);
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% if configurable %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['example'] = ['default' => ''];
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
$form['example'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Example'),
|
||||
'#default_value' => $this->options['example'],
|
||||
];
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getArgument() {
|
||||
|
||||
// @DCG
|
||||
// Here is the place where you should create a default argument for the
|
||||
// contextual filter. The source of this argument depends on your needs.
|
||||
// For example, you can extract the value from the URL or fetch it from
|
||||
// some fields of the current viewed entity.
|
||||
$argument = 123;
|
||||
|
||||
return $argument;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
return Cache::PERMANENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
// @DCG Use 'url' context if the argument comes from URL.
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
views.field.{{ plugin_id }}:
|
||||
type: views.field.field
|
||||
label: '{{ plugin_label }}'
|
||||
mapping:
|
||||
example:
|
||||
type: string
|
||||
label: 'Example'
|
||||
@@ -0,0 +1,98 @@
|
||||
{% import 'lib/di.twig' as di %}
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\views\field;
|
||||
|
||||
{% sort %}
|
||||
use Drupal\views\Plugin\views\field\FieldPluginBase;
|
||||
use Drupal\views\ResultRow;
|
||||
{% if configurable %}
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
{% endif %}
|
||||
{% if services %}
|
||||
{{ di.use(services) }}
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
{% endif %}
|
||||
{% endsort %}
|
||||
|
||||
/**
|
||||
* Provides {{ plugin_label }} field handler.
|
||||
*
|
||||
* @ViewsField("{{ plugin_id }}")
|
||||
*
|
||||
* @DCG
|
||||
* The plugin needs to be assigned to a specific table column through
|
||||
* hook_views_data() or hook_views_data_alter().
|
||||
* For non-existent columns (i.e. computed fields) you need to override
|
||||
* self::query() method.
|
||||
*/
|
||||
class {{ class }} extends FieldPluginBase {
|
||||
|
||||
{% if services %}
|
||||
{{ di.properties(services) }}
|
||||
|
||||
/**
|
||||
* Constructs a new {{ class }} instance.
|
||||
*
|
||||
* @param array $configuration
|
||||
* The plugin configuration, i.e. an array with configuration values keyed
|
||||
* by configuration option name. The special key 'context' may be used to
|
||||
* initialize the defined contexts by setting it to an array of context
|
||||
* values keyed by context names.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
{{ di.annotation(services) }}
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, {{ di.signature(services) }}) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
{{ di.assignment(services) }}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
{{ di.container(services) }}
|
||||
);
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% if configurable %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['example'] = ['default' => ''];
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
$form['example'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Example'),
|
||||
'#default_value' => $this->options['example'],
|
||||
];
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function render(ResultRow $values) {
|
||||
$value = parent::render($values);
|
||||
// @DCG Modify or replace the rendered value here.
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\{{ machine_name }}\Plugin\views\style;
|
||||
|
||||
{% if configurable %}
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
{% endif %}
|
||||
use Drupal\views\Plugin\views\style\StylePluginBase;
|
||||
|
||||
/**
|
||||
* {{ plugin_label }} style plugin.
|
||||
*
|
||||
* @ViewsStyle(
|
||||
* id = "{{ plugin_id }}",
|
||||
* title = @Translation("{{ plugin_label }}"),
|
||||
* help = @Translation("Foo style plugin help."),
|
||||
* theme = "views_style_{{ plugin_id }}",
|
||||
* display_types = {"normal"}
|
||||
* )
|
||||
*/
|
||||
class {{ class }} extends StylePluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $usesRowPlugin = TRUE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $usesRowClass = TRUE;
|
||||
|
||||
{% if configurable %}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
$options['wrapper_class'] = ['default' => 'item-list'];
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
$form['wrapper_class'] = [
|
||||
'#title' => $this->t('Wrapper class'),
|
||||
'#description' => $this->t('The class to provide on the wrapper, outside rows.'),
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => $this->options['wrapper_class'],
|
||||
];
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
use Drupal\Core\Template\Attribute;
|
||||
|
||||
/**
|
||||
* Prepares variables for views-style-{{ plugin_id|u2h }}.html.twig template.
|
||||
*/
|
||||
function template_preprocess_views_style_{{ plugin_id }}(&$variables) {
|
||||
|
||||
$view = $variables['view'];
|
||||
$options = $view->style_plugin->options;
|
||||
|
||||
{% if configurable %}
|
||||
// Fetch wrapper classes from handler options.
|
||||
if ($options['wrapper_class']) {
|
||||
$variables['attributes']['class'] = explode(' ', $options['wrapper_class']);
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
$variables['default_row_class'] = $options['default_row_class'];
|
||||
foreach ($variables['rows'] as $id => $row) {
|
||||
$variables['rows'][$id] = [];
|
||||
$variables['rows'][$id]['content'] = $row;
|
||||
$variables['rows'][$id]['attributes'] = new Attribute();
|
||||
if ($row_class = $view->style_plugin->getRowClass($id)) {
|
||||
$variables['rows'][$id]['attributes']->addClass($row_class);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
views.style.{{ plugin_id }}:
|
||||
type: views_style
|
||||
label: '{{ plugin_label }}'
|
||||
mapping:
|
||||
wrapper_class:
|
||||
type: string
|
||||
label: Wrapper class
|
||||
@@ -0,0 +1,27 @@
|
||||
{{ '{#' }}
|
||||
/**
|
||||
* @file
|
||||
* Default theme implementation for a view template to display a list of rows.
|
||||
*
|
||||
* Available variables:
|
||||
* - attributes: HTML attributes for the container.
|
||||
* - rows: A list of rows.
|
||||
* - attributes: The row's HTML attributes.
|
||||
* - content: The row's contents.
|
||||
* - title: The title of this group of rows. May be empty.
|
||||
*
|
||||
* @see template_preprocess_views_style_{{ plugin_id }}()
|
||||
*/
|
||||
{{ '#}' }}{% verbatim %}
|
||||
<div{{ attributes }}>
|
||||
{%
|
||||
set row_classes = [
|
||||
default_row_class ? 'views-row',
|
||||
]
|
||||
%}
|
||||
{% for row in rows %}
|
||||
<div{{ row.attributes.addClass(row_classes) }}>
|
||||
{{ row.content }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>{% endverbatim %}
|
||||
Reference in New Issue
Block a user