default services conflit ?

This commit is contained in:
armansansd
2022-04-27 11:30:43 +02:00
parent 28190a5749
commit 8bb1064a3b
8132 changed files with 900138 additions and 426 deletions

View File

@@ -0,0 +1,47 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Tests\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Tests;
{% endblock %}
{% block use_class %}
use Drupal\simpletest\WebTestBase;
{% endblock %}
{% block class_declaration %}
/**
* Provides automated tests for the {{module}} module.
*/
class {{class_name}}Test extends WebTestBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public static function getInfo() {
return [
'name' => "{{module}} {{class_name}}'s controller functionality",
'description' => 'Test Unit for module {{module}} and controller {{class_name}}.',
'group' => 'Other',
];
}
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
}
/**
* Tests {{module}} functionality.
*/
public function test{{class_name}}() {
// Check that the basic functions of module {{module}}.
$this->assertEquals(TRUE, TRUE, 'Test Unit Generated via Drupal Console.');
}
{% endblock %}

View File

@@ -0,0 +1,56 @@
{
"name": "{{ machine_name }}",
"type": "{{ type }}",
"description": "{{ description }}",
{% if keywords is defined and keywords is not empty %}
"keywords": [
{% for keyword in keywords %}
"{{ keyword }}"{% if not loop.last %},{% endif %}
{% endfor %}
],
{% endif %}
{% if lincense is defined and lincense is not empty %}
"license": "{{ license }}",
{% endif %}
{% if homepage is defined and homepage is not empty %}
"homepage": "{{ homepage }}",
{% endif %}
{% if minimum_stability is defined and minimum_stability is not empty %}
"minimum-stability": "{{ minimum_stability }}",
{% endif %}
{% if authors is defined and authors is not empty %}
"authors": [
{% for author in authors %}
{
{% if author.name is defined and author.name is not empty %}
"name" : "{{ author.name }}",
{% endif %}
{% if author.email is defined and author.email is not empty %}
"email" : "{{ author.email }}",
{% endif %}
{% if author.homepage is defined and author.homepage is not empty %}
"homepage" : "{{ author.homepage }}",
{% endif %}
{% if author.role is defined and author.role is not empty %}
"role" : "{{ author.role }}"
{% endif %}
}{% if not loop.last %},{% endif %}
{% endfor %}
],
{% endif %}
{% if support_items is defined and support_items is not empty %}
"support": {
{% for support in support_items %}
"{{ support.channel }}": "{{ support.url }}",
{% endfor %}
},
{% endif %}
{% if required_items is defined and required_items is not empty %}
"require": {
{% for required_item in required_items %}
"{{ required_item.name }}": "{{ required_item.version }}",
{% endfor %}
}
{% endif %}
}

View File

@@ -0,0 +1,17 @@
{{ module_name }}:
{% for input in inputs %}
{% if input.default_value is defined and input.default_value|length %}
{% if input.default_value is iterable %}
{{ input.name }}:
{% for value in input.default_value %}
- {{ value }}
{% endfor %}
{% else %}
{% if input.type in ['checkbox','number','radio'] %}
{{ input.name }}: {{ input.default_value }}
{% else %}
{{ input.name }}: "{{ input.default_value }}"
{% endif %}
{% endif %}
{% endif %}
{% endfor %}

View File

@@ -0,0 +1,12 @@
{{ module }}.{{ entity_name }}.*:
type: config_entity
label: '{{ label }} config'
mapping:
id:
type: string
label: 'ID'
label:
type: label
label: 'Label'
uuid:
type: string

View File

@@ -0,0 +1,34 @@
{% extends "base/file.php.twig" %}
{% block file_path %}
{{ entity_name }}.page.inc{% endblock %}
{% block extra_info %}
*
* Page callback for {{ label }} entities.
{% endblock %}
{% block use_class %}
use Drupal\Core\Render\Element;
{% endblock %}
{% block file_methods %}
/**
* Prepares variables for {{ label }} templates.
*
* Default template: {{ entity_name }}.html.twig.
*
* @param array $variables
* An associative array containing:
* - elements: An associative array containing the user information and any
* - attributes: HTML attributes for the containing element.
*/
function template_preprocess_{{ entity_name | machine_name }}(array &$variables) {
// Fetch {{ entity_class }} Entity Object.
${{ entity_name | machine_name }} = $variables['elements']['#{{ entity_name }}'];
// Helpful $content variable for templates.
foreach (Element::children($variables['elements']) as $key) {
$variables['content'][$key] = $variables['elements'][$key];
}
}
{% endblock %}

View File

@@ -0,0 +1 @@
bundle: {{ bundle }}

View File

@@ -0,0 +1,28 @@
{% block file_methods %}
{% if not file_exists %}
{% include 'module/php_tag.php.twig' %}
/**
* @file
* Main module help for the {{ machine_name }} module.
*/
{% endif %}
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_help().
*/
function {{machine_name}}_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the {{ machine_name }} module.
case 'help.page.{{ machine_name }}':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('{{ description|escape }}') . '</p>';
return $output;
default:
}
}
{% endblock %}

View File

@@ -0,0 +1,11 @@
name: '{{ module }}'
type: {{ type }}
description: '{{ description }}'
core: {{ core }}
package: '{{ package }}'
{% if dependencies %}
dependencies:
{% for dependency in dependencies %}
- {{ dependency }}
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,10 @@
/**
* @file
*/
(function ($, Drupal) {
Drupal.AjaxCommands.prototype.{{ method }} = function (ajax, response, status) {
console.log(response.message);
}
})(jQuery, Drupal);

View File

@@ -0,0 +1,10 @@
entity.{{ entity_name }}.add_form:
{# Note: a content entity with bundles will add via a dedicated controller. #}
{% if not bundle_entity_type %}
route_name: entity.{{ entity_name }}.add_form
{% else %}
route_name: entity.{{ entity_name }}.add_page
{% endif %}
title: 'Add {{ label }}'
appears_on:
- entity.{{ entity_name }}.collection

View File

@@ -0,0 +1,5 @@
entity.{{ entity_name }}.add_form:
route_name: entity.{{ entity_name }}.add_form
title: 'Add {{ label }}'
appears_on:
- entity.{{ entity_name }}.collection

View File

@@ -0,0 +1,9 @@
{# Initial new line ensures that the new definitions starts on a new line #}
# {{ label }} menu items definition
entity.{{ entity_name }}.collection:
title: '{{ label }}'
route_name: entity.{{ entity_name }}.collection
description: 'List {{ label }} (bundles)'
parent: system.admin_structure
weight: 99

View File

@@ -0,0 +1,18 @@
{# Initial new line ensures that the new definitions starts on a new line #}
# {{ label }} menu items definition
entity.{{ entity_name }}.collection:
title: '{{ label }} list'
route_name: entity.{{ entity_name }}.collection
description: 'List {{ label }} entities'
parent: system.admin_structure
weight: 100
{# Note: a content entity with bundles will have the settings configured on the bundle (config) entity. #}
{% if not bundle_entity_type %}
{{ entity_name }}.admin.structure.settings:
title: '{{ label }} settings'
description: 'Configure {{ label }} entities'
route_name: {{ entity_name }}.settings
parent: system.admin_structure
{% endif %}

View File

@@ -0,0 +1,6 @@
{{ module_name }}.{{form_id}}:
title: '{{ menu_link_title }}'
route_name: {{ module_name }}.{{form_id}}
description: '{{ menu_link_desc }}'
parent: {{ menu_parent }}
weight: 99

View File

@@ -0,0 +1,31 @@
# {{ label }} routing definition
{# Note: a content entity with bundles will have the settings configured on the bundle (config) entity. #}
{% if not bundle_entity_type %}
{{ entity_name }}.settings_tab:
route_name: {{ entity_name }}.settings
title: 'Settings'
base_route: {{ entity_name }}.settings
{% endif %}
entity.{{ entity_name }}.canonical:
route_name: entity.{{ entity_name }}.canonical
base_route: entity.{{ entity_name }}.canonical
title: 'View'
entity.{{ entity_name }}.edit_form:
route_name: entity.{{ entity_name }}.edit_form
base_route: entity.{{ entity_name }}.canonical
title: 'Edit'
{% if revisionable %}
entity.{{ entity_name }}.version_history:
route_name: entity.{{ entity_name }}.version_history
base_route: entity.{{ entity_name }}.canonical
title: 'Revisions'
{% endif %}
entity.{{ entity_name }}.delete_form:
route_name: entity.{{ entity_name }}.delete_form
base_route: entity.{{ entity_name }}.canonical
title: Delete
weight: 10

View File

@@ -0,0 +1,22 @@
{% if file_exist == false %}
<?php
/**
* @file
* module file.
*/
{% endif %}
/**
* Implements hook_theme().
*/
function {{module}}_theme() {
return [
'{{machine_name}}' => [
'variables' => [
'content' => NULL
],
'render element' => 'children',
],
];
}

View File

@@ -0,0 +1,6 @@
{% include 'module/php_tag.php.twig' %}
/**
* @file
* Contains {{machine_name}}.module.
*/

View File

@@ -0,0 +1,5 @@
{{ module }}-library:
js:
js/{{ js_name }}.js: {}
dependencies:
- core/drupal.ajax

View File

@@ -0,0 +1,11 @@
/**
* Implements hook_theme().
*/
function {{machine_name}}_theme() {
return [
'{{machine_name}}' => [
'render element' => 'children',
],
];
}

View File

@@ -0,0 +1,27 @@
{% extends "base/file.php.twig" %}
{% block file_path %}{{machine_name}}.module{% endblock %}
{% block use_class %}
use Drupal\Core\Routing\RouteMatchInterface;
{% endblock %}
{% block file_methods %}
/**
* Implements hook_help().
*/
function {{machine_name}}_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help for the {{ machine_name }} module.
case 'help.page.{{ machine_name }}':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
{% if description %}
$output .= '<p>' . t('{{ description|escape }}') . '</p>';
{% endif %}
return $output;
default:
}
}
{% endblock %}

View File

@@ -0,0 +1,30 @@
{% extends "base/file.php.twig" %}
{% block file_path %}{{ module }}\{{ module }}.views.inc.{% endblock %}
{% block extra_info %} * Provide a custom views field data that isn't tied to any other module.{% endblock %}
{% block file_methods %}
/**
* Implements hook_views_data().
*/
function {{module}}_views_data() {
$data['views']['table']['group'] = t('Custom Global');
$data['views']['table']['join'] = [
// #global is a special flag which allows a table to appear all the time.
'#global' => [],
];
{% for field in fields %}
$data['views']['{{ field.class_machine_name }}'] = [
'title' => t('{{ field.title }}'),
'help' => t('{{ field.description }}'),
'field' => [
'id' => '{{ field.class_machine_name }}',
],
];
{% endfor %}
return $data;
}
{% endblock %}

View File

@@ -0,0 +1,10 @@
{% block routing_file %}
{% endblock %}
{% if permissions|length %}
{% for permission in permissions %}
{{ module_name }}.route:
requirements:
_permission: {{ permission.permission }}:
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,10 @@
{% if permissions|length %}
{% for permission in permissions %}
{{ permission.permission }}:
title: '{{ permission.title }}'
description: '{{ permission.description }}'
{% if permission.restrict_access != 'none' %}
restrict access: {{ permission.restrict_access }}
{% endif %}
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,37 @@
add {{ label|lower }} entities:
title: 'Create new {{ label }} entities'
administer {{ label|lower }} entities:
title: 'Administer {{ label }} entities'
description: 'Allow to access the administration form to configure {{ label }} entities.'
restrict access: true
delete {{ label|lower }} entities:
title: 'Delete {{ label }} entities'
edit {{ label|lower }} entities:
title: 'Edit {{ label }} entities'
view published {{ label|lower }} entities:
title: 'View published {{ label }} entities'
view unpublished {{ label|lower }} entities:
title: 'View unpublished {{ label }} entities'
{% if revisionable %}
view all {{ label|lower }} revisions:
title: 'View all {{ label }} revisions'
revert all {{ label|lower }} revisions:
title: 'Revert all {{ label }} revisions'
description: 'Role requires permission <em>view {{ label }} revisions</em> and <em>edit rights</em> for {{ label|lower }} entities in question or <em>administer {{ label|lower }} entities</em>.'
delete all {{ label|lower }} revisions:
title: 'Delete all revisions'
description: 'Role requires permission to <em>view {{ label }} revisions</em> and <em>delete rights</em> for {{ label|lower }} entities in question or <em>administer {{ label|lower }} entities</em>.'
{% endif %}
{% if has_bundle_permissions %}
permission_callbacks:
- \Drupal\{{ module }}\{{ entity_class}}Permissions::generatePermissions
{% endif %}

View File

@@ -0,0 +1 @@
<?php

View File

@@ -0,0 +1,6 @@
{% if not file_exists %}
services:
{% endif %}
plugin.manager.{{ machine_name | lower }}:
class: Drupal\{{ module }}\Plugin\{{ class_name }}Manager
parent: default_plugin_manager

View File

@@ -0,0 +1,6 @@
{% if not file_exists %}
services:
{% endif %}
plugin.manager.{{ plugin_name | lower }}:
class: Drupal\{{ module }}\{{ class_name }}Manager
arguments: ['@module_handler', '@cache.discovery']

View File

@@ -0,0 +1,8 @@
# Example {{ plugin_name }} plugin definitions.
# Plugin property $defaults are defined in {{ class_name }}Manager.
first:
id: one
label: One
second:
id: two
label: Two

View File

@@ -0,0 +1,12 @@
{% block file_methods %}
{% if not file_exists %}
{% include 'module/php_tag.php.twig' %}
{% endif %}
/**
* Implements hook_post_update_NAME() on Module {{ module }} Post Update {{ post_update_name }}.
*/
function {{ module }}_post_update_{{ post_update_name }}(&$sandbox) {
\Drupal::messenger()->addMessage('Module {{ module }} Post Update # {{ post_update_name }} () was executed successfully.');
}
{% endblock %}

View File

@@ -0,0 +1,15 @@
{% if class_name is defined %}
{% for route in routes %}
{% if learning is defined and learning %}
{{ yaml_comment('application.messages.learning.route') }}
{% endif %}
{{ route.name }}:
path: '{{ route.path }}'
defaults:
_controller: '\Drupal\{{ module }}\Controller\{{ class_name }}::{{ route.method }}'
_title: '{{route.title}}'
requirements:
_permission: 'access content'
{% endfor %}
{% endif %}

View File

@@ -0,0 +1,16 @@
{% if class_name is defined %}
{{ module_name }}.{{form_id}}:
path: '{{ path }}'
defaults:
_form: '\Drupal\{{ module_name }}\Form\{{ class_name }}'
_title: '{{ class_name }}'
{% if config_form %}
requirements:
_permission: 'access administration pages'
options:
_admin_route: TRUE
{% else %}
requirements:
_access: 'TRUE'
{% endif %}
{% endif %}

View File

@@ -0,0 +1,10 @@
field.widget.settings.{{ plugin_id }}:
type: mapping
label: '{{ label }} widget settings'
mapping:
size:
type: integer
label: 'Size'
placeholder:
type: textfield
label: 'Placeholder'

View File

@@ -0,0 +1,19 @@
{% if not file_exists %}
services:
{% endif %}
{% if logger_channel is defined %}
logger.channel.{{ module }}:
parent: logger.channel_base
arguments: ['{{ module }}']
{% endif %}
{% if name is defined %}
{{ name | lower }}:
class: {{ class_path }}
{% if services is defined %}
arguments: [{{ servicesAsParametersKeys(services)|join(', ') }}]
{% endif %}
{% if tags is defined %}
tags:
- { {{ tagsAsArray(tags)|join(', ') }} }
{% endif %}
{% endif %}

View File

@@ -0,0 +1,33 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Ajax\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Ajax;
{% endblock %}
{% block use_class %}
use Drupal\Core\Ajax\CommandInterface;
{% endblock %}
{% block class_declaration %}
/**
* Class {{ class_name }}.
*/
class {{ class_name }} implements CommandInterface {% endblock %}
{% block class_methods %}
/**
* Render custom ajax command.
*
* @return ajax
* Command function.
*/
public function render() {
return [
'command' => '{{ method }}',
'message' => 'My Awesome Message',
];
}
{% endblock %}

View File

@@ -0,0 +1,42 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Annotation\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Annotation;
{% endblock %}
{% block use_class %}
use Drupal\Component\Annotation\Plugin;
{% endblock %}
{% block class_declaration %}
/**
* Defines a {{ label }} item annotation object.
*
* @see \Drupal\{{ module }}\Plugin\{{ class_name }}Manager
* @see plugin_api
*
* @Annotation
*/
class {{ class_name }} extends Plugin {% endblock %}
{% block class_methods %}
/**
* The plugin ID.
*
* @var string
*/
public $id;
/**
* The label of the plugin.
*
* @var \Drupal\Core\Annotation\Translation
*
* @ingroup plugin_translatable
*/
public $label;
{% endblock %}

View File

@@ -0,0 +1,112 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Authentication\Provider\{{class}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Authentication\Provider;
{% endblock %}
{% block use_class %}
use Drupal\Core\Authentication\AuthenticationProviderInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
{% endblock %}
{% block class_declaration %}
/**
* Class {{ class }}.
*/
class {{ class }} implements AuthenticationProviderInterface {% endblock %}
{% block class_variables %}
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
{% endblock %}
{% block class_construct %}
/**
* Constructs a HTTP basic authentication provider object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
*/
public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager) {
$this->configFactory = $config_factory;
$this->entityTypeManager = $entity_type_manager;
}
{% endblock %}
{% block class_create %}
{% endblock %}
{% block class_methods %}
/**
* Checks whether suitable authentication credentials are on the request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
*
* @return bool
* TRUE if authentication credentials suitable for this provider are on the
* request, FALSE otherwise.
*/
public function applies(Request $request) {
// If you return TRUE and the method Authentication logic fails,
// you will get out from Drupal navigation if you are logged in.
return FALSE;
}
/**
* {@inheritdoc}
*/
public function authenticate(Request $request) {
$consumer_ip = $request->getClientIp();
$ips = [];
if (in_array($consumer_ip, $ips)) {
// Return Anonymous user.
return $this->entityTypeManager->getStorage('user')->load(0);
}
else {
throw new AccessDeniedHttpException();
}
}
/**
* {@inheritdoc}
*/
public function cleanup(Request $request) {}
/**
* {@inheritdoc}
*/
public function handleException(GetResponseForExceptionEvent $event) {
$exception = $event->getException();
if ($exception instanceof AccessDeniedHttpException) {
$event->setException(
new UnauthorizedHttpException('Invalid consumer origin.', $exception)
);
return TRUE;
}
return FALSE;
}
{% endblock %}

View File

@@ -0,0 +1,84 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{extension}}\Command\{{ class }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{extension}}\Command;
{% endblock %}
{% block use_class %}
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
{% if container_aware %}
use Drupal\Console\Core\Command\ContainerAwareCommand;
{% else %}
use Drupal\Console\Core\Command\Command;
{% endif %}
{% endblock %}
{% block class_declaration %}
/**
* Class {{ class_name }}.
*
* Drupal\Console\Annotations\DrupalCommand (
* extension="{{extension}}",
* extensionType="{{ extension_type }}"
* )
*/
class {{ class_name }} extends {% if container_aware %}ContainerAwareCommand{% else %}Command{% endif %} {% endblock %}
{% block class_construct %}
{% if services is not empty %}
/**
* Constructs a new {{ class_name }} object.
*/
public function __construct({{ servicesAsParameters(services)|join(', ') }}) {
{{ serviceClassInitialization(services) }}
parent::__construct();
}
{% endif %}
{% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
protected function configure() {
$this
->setName('{{ name }}')
->setDescription($this->trans('commands.{{ command_key }}.description'));
}
{% if initialize %}
/**
* {@inheritdoc}
*/
protected function initialize(InputInterface $input, OutputInterface $output) {
parent::initialize($input, $output);
$this->getIo()->info('initialize');
}
{% endif %}
{% if interact %}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output) {
$this->getIo()->info('interact');
}
{% endif %}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output) {
$this->getIo()->info('execute');
$this->getIo()->info($this->trans('commands.{{ command_key }}.messages.success'));
{% if class_generator %}
$this->generator->generate([]);
{% endif %}
}
{% endblock %}

View File

@@ -0,0 +1,5 @@
description: 'Drupal Console generated command.'
options: {}
arguments: {}
messages:
success: 'I am a new generated command.'

View File

@@ -0,0 +1,62 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Controller\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Controller;
{% endblock %}
{% block use_class %}
use Drupal\Core\Controller\ControllerBase;
{% if services is not empty %}
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endif %}
{% endblock %}
{% block use_class_services %}
{% endblock %}
{% block class_declaration %}
/**
* Class {{ class_name }}.
*/
class {{ class_name }} extends ControllerBase {% endblock %}
{% block class_create %}
{% if services is not empty %}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
{{ serviceClassInjectionNoOverride(services) }}
return $instance;
}
{% endif %}
{% endblock %}
{% block class_methods %}
{% for route in routes %}
/**
* {{ route.method | capitalize }}.
*
* @return string
* Return Hello string.
*/
public function {{route.method}}({{ argumentsFromRoute(route.path)|join(', ') }}) {
{% if argumentsFromRoute(route.path) is not empty %}
return [
'#type' => 'markup',
'#markup' => $this->t('Implement method: {{route.method}} with parameter(s): {{ argumentsFromRoute(route.path)|join(', ') }}'),
];
{% else %}
return [
'#type' => 'markup',
'#markup' => $this->t('Implement method: {{route.method}}')
];
{% endif %}
}
{% endfor %}
{% endblock %}

View File

@@ -0,0 +1,231 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Controller\{{ entity_class }}Controller.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Controller;
{% endblock %}
{% block use_class %}
use Drupal\Component\Utility\Xss;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Url;
use Drupal\{{ module }}\Entity\{{ entity_class }}Interface;
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endblock %}
{% block class_declaration %}
/**
* Class {{ entity_class }}Controller.
*
* Returns responses for {{ label }} routes.
*/
class {{ entity_class }}Controller extends ControllerBase implements ContainerInjectionInterface {% endblock %}
{% block class_methods %}
/**
* The date formatter.
*
* @var \Drupal\Core\Datetime\DateFormatter
*/
protected $dateFormatter;
/**
* The renderer.
*
* @var \Drupal\Core\Render\Renderer
*/
protected $renderer;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->dateFormatter = $container->get('date.formatter');
$instance->renderer = $container->get('renderer');
return $instance;
}
/**
* Displays a {{ label }} revision.
*
* @param int ${{ entity_name }}_revision
* The {{ label }} revision ID.
*
* @return array
* An array suitable for drupal_render().
*/
public function revisionShow(${{ entity_name }}_revision) {
${{ entity_name }} = $this->entityTypeManager()->getStorage('{{ entity_name }}')
->loadRevision(${{ entity_name }}_revision);
$view_builder = $this->entityTypeManager()->getViewBuilder('{{ entity_name }}');
return $view_builder->view(${{ entity_name }});
}
/**
* Page title callback for a {{ label }} revision.
*
* @param int ${{ entity_name }}_revision
* The {{ label }} revision ID.
*
* @return string
* The page title.
*/
public function revisionPageTitle(${{ entity_name }}_revision) {
${{ entity_name }} = $this->entityTypeManager()->getStorage('{{ entity_name }}')
->loadRevision(${{ entity_name }}_revision);
return $this->t('Revision of %title from %date', [
'%title' => ${{ entity_name }}->label(),
'%date' => $this->dateFormatter->format(${{ entity_name }}->getRevisionCreationTime()),
]);
}
/**
* Generates an overview table of older revisions of a {{ label }}.
*
* @param \Drupal\{{ module }}\Entity\{{ entity_class }}Interface ${{ entity_name }}
* A {{ label }} object.
*
* @return array
* An array as expected by drupal_render().
*/
public function revisionOverview({{ entity_class }}Interface ${{ entity_name }}) {
$account = $this->currentUser();
${{ entity_name }}_storage = $this->entityTypeManager()->getStorage('{{ entity_name }}');
{% if is_translatable %}
$langcode = ${{ entity_name }}->language()->getId();
$langname = ${{ entity_name }}->language()->getName();
$languages = ${{ entity_name }}->getTranslationLanguages();
$has_translations = (count($languages) > 1);
$build['#title'] = $has_translations ? $this->t('@langname revisions for %title', ['@langname' => $langname, '%title' => ${{ entity_name }}->label()]) : $this->t('Revisions for %title', ['%title' => ${{ entity_name }}->label()]);
{% else %}
$build['#title'] = $this->t('Revisions for %title', ['%title' => ${{ entity_name }}->label()]);
{% endif %}
$header = [$this->t('Revision'), $this->t('Operations')];
$revert_permission = (($account->hasPermission("revert all {{ label|lower }} revisions") || $account->hasPermission('administer {{ label|lower }} entities')));
$delete_permission = (($account->hasPermission("delete all {{ label|lower }} revisions") || $account->hasPermission('administer {{ label|lower }} entities')));
$rows = [];
$vids = ${{ entity_name }}_storage->revisionIds(${{ entity_name }});
$latest_revision = TRUE;
foreach (array_reverse($vids) as $vid) {
/** @var \Drupal\{{ module }}\{{ entity_class }}Interface $revision */
$revision = ${{ entity_name }}_storage->loadRevision($vid);
{% if is_translatable %}
// Only show revisions that are affected by the language that is being
// displayed.
if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
{% endif %}
$username = [
'#theme' => 'username',
'#account' => $revision->getRevisionUser(),
];
// Use revision link to link to revisions that are not active.
$date = $this->dateFormatter->format($revision->getRevisionCreationTime(), 'short');
if ($vid != ${{ entity_name }}->getRevisionId()) {
$link = $this->l($date, new Url('entity.{{ entity_name }}.revision', [
'{{ entity_name }}' => ${{ entity_name }}->id(),
'{{ entity_name }}_revision' => $vid,
]));
}
else {
$link = ${{ entity_name }}->link($date);
}
$row = [];
$column = [
'data' => [
'#type' => 'inline_template',
'#template' => '{{ '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}' }}',
'#context' => [
'date' => $link,
'username' => $this->renderer->renderPlain($username),
'message' => [
'#markup' => $revision->getRevisionLogMessage(),
'#allowed_tags' => Xss::getHtmlTagList(),
],
],
],
];
$row[] = $column;
if ($latest_revision) {
$row[] = [
'data' => [
'#prefix' => '<em>',
'#markup' => $this->t('Current revision'),
'#suffix' => '</em>',
],
];
foreach ($row as &$current) {
$current['class'] = ['revision-current'];
}
$latest_revision = FALSE;
}
else {
$links = [];
if ($revert_permission) {
$links['revert'] = [
'title' => $this->t('Revert'),
{% if is_translatable %}
'url' => $has_translations ?
Url::fromRoute('entity.{{ entity_name }}.translation_revert', [
'{{ entity_name }}' => ${{ entity_name }}->id(),
'{{ entity_name }}_revision' => $vid,
'langcode' => $langcode,
]) :
Url::fromRoute('entity.{{ entity_name }}.revision_revert', [
'{{ entity_name }}' => ${{ entity_name }}->id(),
'{{ entity_name }}_revision' => $vid,
]),
{% else %}
'url' => Url::fromRoute('entity.{{ entity_name }}.revision_revert', [
'{{ entity_name }}' => ${{ entity_name }}->id(),
'{{ entity_name }}_revision' => $vid,
]),
{% endif %}
];
}
if ($delete_permission) {
$links['delete'] = [
'title' => $this->t('Delete'),
'url' => Url::fromRoute('entity.{{ entity_name }}.revision_delete', [
'{{ entity_name }}' => ${{ entity_name }}->id(),
'{{ entity_name }}_revision' => $vid,
]),
];
}
$row[] = [
'data' => [
'#type' => 'operations',
'#links' => $links,
],
];
}
$rows[] = $row;
{% if is_translatable %}
}
{% endif %}
}
$build['{{ entity_name }}_revisions_table'] = [
'#theme' => 'table',
'#rows' => $rows,
'#header' => $header,
];
return $build;
}
{% endblock %}

View File

@@ -0,0 +1,60 @@
langcode: en
status: true
dependencies:
config:
- field.field.node.{{ bundle_name }}.body
- node.type.{{ bundle_name }}
module:
- path
- text
id: node.{{ bundle_name }}.default
targetEntityType: node
bundle: {{ bundle_name }}
mode: default
content:
body:
type: text_textarea_with_summary
weight: 31
settings:
rows: 9
summary_rows: 3
placeholder: ''
third_party_settings: { }
created:
type: datetime_timestamp
weight: 10
settings: { }
third_party_settings: { }
path:
type: path
weight: 30
settings: { }
third_party_settings: { }
promote:
type: boolean_checkbox
settings:
display_label: true
weight: 15
third_party_settings: { }
sticky:
type: boolean_checkbox
settings:
display_label: true
weight: 16
third_party_settings: { }
title:
type: string_textfield
weight: -5
settings:
size: 60
placeholder: ''
third_party_settings: { }
uid:
type: entity_reference_autocomplete
weight: 5
settings:
match_operator: CONTAINS
size: 60
placeholder: ''
third_party_settings: { }
hidden: { }

View File

@@ -0,0 +1,23 @@
langcode: en
status: true
dependencies:
config:
- field.field.node.{{ bundle_name }}.body
- node.type.{{ bundle_name }}
module:
- text
- user
id: node.{{ bundle_name }}.default
targetEntityType: node
bundle: {{ bundle_name }}
mode: default
content:
body:
label: hidden
type: text_default
weight: 101
settings: { }
third_party_settings: { }
links:
weight: 100
hidden: { }

View File

@@ -0,0 +1,25 @@
langcode: en
status: true
dependencies:
config:
- core.entity_view_mode.node.teaser
- field.field.node.{{ bundle_name }}.body
- node.type.{{ bundle_name }}
module:
- text
- user
id: node.{{ bundle_name }}.teaser
targetEntityType: node
bundle: {{ bundle_name }}
mode: teaser
content:
body:
label: hidden
type: text_summary_or_trimmed
weight: 101
settings:
trim_length: 600
third_party_settings: { }
links:
weight: 100
hidden: { }

View File

@@ -0,0 +1,20 @@
{% block use_class %}
use Drupal\Core\Entity\EntityTypeInterface;
{% endblock %}
/**
* Implements hook_entity_bundle_field_info_alter().
*/
function {{module}}_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
{% if bundle %}
if ($bundle === '{{ bundle }}') {
{% endif %}
if (isset($fields['{{ field_id }}'])) {
// Use the ID as defined in the annotation of the constraint definition.
$fields['{{ field_id }}']->addConstraint('{{ plugin_id }}', []);
}
{% if bundle %}
}
{% endif %}
}

View File

@@ -0,0 +1,21 @@
langcode: en
status: true
dependencies:
config:
- field.storage.node.body
- node.type.{{ bundle_name }}
module:
- text
id: node.{{ bundle_name }}.body
field_name: body
entity_type: node
bundle: {{ bundle_name }}
label: Body
description: ''
required: false
translatable: true
default_value: { }
default_value_callback: ''
settings:
display_summary: true
field_type: text_with_summary

View File

@@ -0,0 +1,17 @@
langcode: en
status: true
dependencies:
module:
- menu_ui
third_party_settings:
menu_ui:
available_menus:
- main
parent: 'main:'
name: '{{ bundle_title }}'
type: {{ bundle_name }}
description: 'Generated by Drupal Console'
help: ''
new_revision: false
preview_mode: 1
display_submitted: true

View File

@@ -0,0 +1,21 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Form\{{ entity_class }}DeleteForm.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Form;
{% endblock %}
{% block use_class %}
use Drupal\Core\Entity\ContentEntityDeleteForm;
{% endblock %}
{% block class_declaration %}
/**
* Provides a form for deleting {{ label }} entities.
*
* @ingroup {{module}}
*/
class {{ entity_class }}DeleteForm extends ContentEntityDeleteForm {% endblock %}

View File

@@ -0,0 +1,116 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Form\{{ entity_class }}RevisionDeleteForm.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Form;
{% endblock %}
{% block use_class %}
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endblock %}
{% block class_declaration %}
/**
* Provides a form for deleting a {{ label }} revision.
*
* @ingroup {{module}}
*/
class {{ entity_class }}RevisionDeleteForm extends ConfirmFormBase {% endblock %}
{% block class_methods %}
/**
* The {{ label }} revision.
*
* @var \Drupal\{{module}}\Entity\{{ entity_class }}Interface
*/
protected $revision;
/**
* The {{ label }} storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected ${{ entity_class[:1]|lower ~ entity_class[1:] }}Storage;
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $connection;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->{{ entity_class[:1]|lower ~ entity_class[1:] }}Storage = $container->get('entity_type.manager')->getStorage('{{ entity_name }}');
$instance->connection = $container->get('database');
return $instance;
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return '{{ entity_name }}_revision_delete_confirm';
}
/**
* {@inheritdoc}
*/
public function getQuestion() {
return $this->t('Are you sure you want to delete the revision from %revision-date?', [
'%revision-date' => \Drupal::service('date.formatter')->format($this->revision->getRevisionCreationTime()),
]);
}
/**
* {@inheritdoc}
*/
public function getCancelUrl() {
return new Url('entity.{{ entity_name }}.version_history', ['{{ entity_name }}' => $this->revision->id()]);
}
/**
* {@inheritdoc}
*/
public function getConfirmText() {
return $this->t('Delete');
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, ${{ entity_name }}_revision = NULL) {
$this->revision = $this->{{ entity_class }}Storage->loadRevision(${{ entity_name }}_revision);
$form = parent::buildForm($form, $form_state);
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->{{ entity_class }}Storage->deleteRevision($this->revision->getRevisionId());
$this->logger('content')->notice('{{ label }}: deleted %title revision %revision.', ['%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]);
$this->messenger()->addMessage(t('Revision from %revision-date of {{ label }} %title has been deleted.', ['%revision-date' => \Drupal::service('date.formatter')->format($this->revision->getRevisionCreationTime()), '%title' => $this->revision->label()]));
$form_state->setRedirect(
'entity.{{ entity_name }}.canonical',
['{{ entity_name }}' => $this->revision->id()]
);
if ($this->connection->query('SELECT COUNT(DISTINCT vid) FROM {{ '{'~entity_name~'_field_revision}' }} WHERE id = :id', [':id' => $this->revision->id()])->fetchField() > 1) {
$form_state->setRedirect(
'entity.{{ entity_name }}.version_history',
['{{ entity_name }}' => $this->revision->id()]
);
}
}
{% endblock %}

View File

@@ -0,0 +1,105 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Form\{{ entity_class }}RevisionRevertTranslationForm.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Form;
{% endblock %}
{% block use_class %}
use Drupal\Core\Form\FormStateInterface;
use Drupal\{{module}}\Entity\{{ entity_class }}Interface;
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endblock %}
{% block class_declaration %}
/**
* Provides a form for reverting a {{ label }} revision for a single trans.
*
* @ingroup {{module}}
*/
class {{ entity_class }}RevisionRevertTranslationForm extends {{ entity_class }}RevisionRevertForm {% endblock %}
{% block class_methods %}
/**
* The language to be reverted.
*
* @var string
*/
protected $langcode;
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->languageManager = $container->get('language_manager');
return $instance;
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return '{{ entity_name }}_revision_revert_translation_confirm';
}
/**
* {@inheritdoc}
*/
public function getQuestion() {
return $this->t('Are you sure you want to revert @language translation to the revision from %revision-date?', [
'@language' => $this->languageManager->getLanguageName($this->langcode),
'%revision-date' => $this->dateFormatter->format($this->revision->getRevisionCreationTime()),
]);
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, ${{ entity_name }}_revision = NULL, $langcode = NULL) {
$this->langcode = $langcode;
$form = parent::buildForm($form, $form_state, ${{ entity_name }}_revision);
$form['revert_untranslated_fields'] = [
'#type' => 'checkbox',
'#title' => $this->t('Revert content shared among translations'),
'#default_value' => FALSE,
];
return $form;
}
/**
* {@inheritdoc}
*/
protected function prepareRevertedRevision({{ entity_class }}Interface $revision, FormStateInterface $form_state) {
$revert_untranslated_fields = $form_state->getValue('revert_untranslated_fields');
/** @var \Drupal\{{module}}\Entity\{{ entity_class }}Interface $default_revision */
$latest_revision = $this->{{ entity_class }}Storage->load($revision->id());
$latest_revision_translation = $latest_revision->getTranslation($this->langcode);
$revision_translation = $revision->getTranslation($this->langcode);
foreach ($latest_revision_translation->getFieldDefinitions() as $field_name => $definition) {
if ($definition->isTranslatable() || $revert_untranslated_fields) {
$latest_revision_translation->set($field_name, $revision_translation->get($field_name)->getValue());
}
}
$latest_revision_translation->setNewRevision();
$latest_revision_translation->isDefaultRevision(TRUE);
$revision->setRevisionCreationTime(\Drupal::time()->getRequestTime());
return $latest_revision_translation;
}
{% endblock %}

View File

@@ -0,0 +1,145 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Form\{{ entity_class }}RevisionRevertForm.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Form;
{% endblock %}
{% block use_class %}
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\{{module}}\Entity\{{ entity_class }}Interface;
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endblock %}
{% block class_declaration %}
/**
* Provides a form for reverting a {{ label }} revision.
*
* @ingroup {{module}}
*/
class {{ entity_class }}RevisionRevertForm extends ConfirmFormBase {% endblock %}
{% block class_methods %}
/**
* The {{ label }} revision.
*
* @var \Drupal\{{module}}\Entity\{{ entity_class }}Interface
*/
protected $revision;
/**
* The {{ label }} storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected ${{ entity_class[:1]|lower ~ entity_class[1:] }}Storage;
/**
* The date formatter service.
*
* @var \Drupal\Core\Datetime\DateFormatterInterface
*/
protected $dateFormatter;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->{{ entity_class[:1]|lower ~ entity_class[1:] }}Storage = $container->get('entity_type.manager')->getStorage('{{ entity_name }}');
$instance->dateFormatter = $container->get('date.formatter');
return $instance;
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return '{{ entity_name }}_revision_revert_confirm';
}
/**
* {@inheritdoc}
*/
public function getQuestion() {
return $this->t('Are you sure you want to revert to the revision from %revision-date?', [
'%revision-date' => $this->dateFormatter->format($this->revision->getRevisionCreationTime()),
]);
}
/**
* {@inheritdoc}
*/
public function getCancelUrl() {
return new Url('entity.{{ entity_name }}.version_history', ['{{ entity_name }}' => $this->revision->id()]);
}
/**
* {@inheritdoc}
*/
public function getConfirmText() {
return $this->t('Revert');
}
/**
* {@inheritdoc}
*/
public function getDescription() {
return '';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, ${{ entity_name }}_revision = NULL) {
$this->revision = $this->{{ entity_class }}Storage->loadRevision(${{ entity_name }}_revision);
$form = parent::buildForm($form, $form_state);
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// The revision timestamp will be updated when the revision is saved. Keep
// the original one for the confirmation message.
$original_revision_timestamp = $this->revision->getRevisionCreationTime();
$this->revision = $this->prepareRevertedRevision($this->revision, $form_state);
$this->revision->revision_log = $this->t('Copy of the revision from %date.', [
'%date' => $this->dateFormatter->format($original_revision_timestamp),
]);
$this->revision->save();
$this->logger('content')->notice('{{ label }}: reverted %title revision %revision.', ['%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]);
$this->messenger()->addMessage(t('{{ label }} %title has been reverted to the revision from %revision-date.', ['%title' => $this->revision->label(), '%revision-date' => $this->dateFormatter->format($original_revision_timestamp)]));
$form_state->setRedirect(
'entity.{{ entity_name }}.version_history',
['{{ entity_name }}' => $this->revision->id()]
);
}
/**
* Prepares a revision to be reverted.
*
* @param \Drupal\{{module}}\Entity\{{ entity_class }}Interface $revision
* The revision to be reverted.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return \Drupal\{{module}}\Entity\{{ entity_class }}Interface
* The prepared revision ready to be stored.
*/
protected function prepareRevertedRevision({{ entity_class }}Interface $revision, FormStateInterface $form_state) {
$revision->setNewRevision();
$revision->isDefaultRevision(TRUE);
$revision->setRevisionCreationTime(\Drupal::time()->getRequestTime());
return $revision;
}
{% endblock %}

View File

@@ -0,0 +1,99 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Form\{{ entity_class }}Form.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Form;
{% endblock %}
{% block use_class %}
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endblock %}
{% block class_declaration %}
/**
* Form controller for {{ label }} edit forms.
*
* @ingroup {{module}}
*/
class {{ entity_class }}Form extends ContentEntityForm {% endblock %}
{% block class_methods %}
/**
* The current user account.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $account;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
// Instantiates this form class.
$instance = parent::create($container);
$instance->account = $container->get('current_user');
return $instance;
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
/* @var \Drupal\{{module}}\Entity\{{ entity_class }} $entity */
$form = parent::buildForm($form, $form_state);
{% if revisionable %}
if (!$this->entity->isNew()) {
$form['new_revision'] = [
'#type' => 'checkbox',
'#title' => $this->t('Create new revision'),
'#default_value' => FALSE,
'#weight' => 10,
];
}
{% endif %}
return $form;
}
/**
* {@inheritdoc}
*/
public function save(array $form, FormStateInterface $form_state) {
$entity = $this->entity;
{% if revisionable %}
// Save as a new revision if requested to do so.
if (!$form_state->isValueEmpty('new_revision') && $form_state->getValue('new_revision') != FALSE) {
$entity->setNewRevision();
// If a new revision is created, save the current user as revision author.
$entity->setRevisionCreationTime($this->time->getRequestTime());
$entity->setRevisionUserId($this->account->id());
}
else {
$entity->setNewRevision(FALSE);
}
{% endif %}
$status = parent::save($form, $form_state);
switch ($status) {
case SAVED_NEW:
$this->messenger()->addMessage($this->t('Created the %label {{ label }}.', [
'%label' => $entity->label(),
]));
break;
default:
$this->messenger()->addMessage($this->t('Saved the %label {{ label }}.', [
'%label' => $entity->label(),
]));
}
$form_state->setRedirect('entity.{{ entity_name }}.canonical', ['{{ entity_name }}' => $entity->id()]);
}
{% endblock %}

View File

@@ -0,0 +1,61 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Form\{{ entity_class }}SettingsForm.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Form;
{% endblock %}
{% block use_class %}
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
{% endblock %}
{% block class_declaration %}
/**
* Class {{ entity_class }}SettingsForm.
*
* @ingroup {{module}}
*/
class {{ entity_class }}SettingsForm extends FormBase {% endblock %}
{% block class_methods %}
/**
* Returns a unique string identifying the form.
*
* @return string
* The unique string identifying the form.
*/
public function getFormId() {
return '{{ entity_class|lower }}_settings';
}
/**
* Form submission handler.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// Empty implementation of the abstract submit class.
}
/**
* Defines the settings form for {{ label }} entities.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return array
* Form definition array.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['{{ entity_class|lower }}_settings']['#markup'] = 'Settings form for {{ label }} entities. Manage field settings here.';
return $form;
}
{% endblock %}

View File

@@ -0,0 +1,31 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Entity\{{ entity_class }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Entity;
{% endblock %}
{% block use_class %}
use Drupal\views\EntityViewsData;
{% endblock %}
{% block class_declaration %}
/**
* Provides Views data for {{ label }} entities.
*/
class {{ entity_class }}ViewsData extends EntityViewsData {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function getViewsData() {
$data = parent::getViewsData();
// Additional information for Views integration, such as table joins, can be
// put here.
return $data;
}
{% endblock %}

View File

@@ -0,0 +1,16 @@
{% block hook_theme %}
/**
* Implements hook_theme().
*/
function {{ module }}_theme() {
$theme = [];
{% include '/module/src/Entity/entity-content.theme.php.twig' with {'entity_name': entity_name, } %}
$theme['{{ entity_name }}_content_add_list'] = [
'render element' => 'content',
'variables' => ['content' => NULL],
'file' => '{{ entity_name }}.page.inc',
];
return $theme;
}
{% endblock %}

View File

@@ -0,0 +1,18 @@
{% block hook_theme_suggestions_hook %}
/**
* Implements hook_theme_suggestions_HOOK().
*/
function {{ module }}_theme_suggestions_{{ entity_name }}(array $variables) {
$suggestions = [];
$entity = $variables['elements']['#{{ entity_name }}'];
$sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
$suggestions[] = '{{ entity_name }}__' . $sanitized_view_mode;
$suggestions[] = '{{ entity_name }}__' . $entity->bundle();
$suggestions[] = '{{ entity_name }}__' . $entity->bundle() . '__' . $sanitized_view_mode;
$suggestions[] = '{{ entity_name }}__' . $entity->id();
$suggestions[] = '{{ entity_name }}__' . $entity->id() . '__' . $sanitized_view_mode;
return $suggestions;
}
{% endblock %}

View File

@@ -0,0 +1,340 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Entity\{{ entity_class }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Entity;
{% endblock %}
{% block use_class %}
{% if has_owner or revisionable%}
use Drupal\Core\Entity\EntityStorageInterface;
{% endif %}
use Drupal\Core\Field\BaseFieldDefinition;
{% if revisionable %}
use Drupal\Core\Entity\EditorialContentEntityBase;
use Drupal\Core\Entity\RevisionableInterface;
{% else %}
use Drupal\Core\Entity\ContentEntityBase;
{% endif %}
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityPublishedTrait;
use Drupal\Core\Entity\EntityTypeInterface;
{% if has_owner %}
use Drupal\user\UserInterface;
{% endif %}
{% endblock %}
{% block class_declaration %}
/**
* Defines the {{ label }} entity.
*
* @ingroup {{ module }}
*
* @ContentEntityType(
* id = "{{ entity_name }}",
* label = @Translation("{{ label }}"),
{% if bundle_entity_type %}
* bundle_label = @Translation("{{ label }} type"),
{% endif %}
* handlers = {
{% if revisionable %}
* "storage" = "Drupal\{{ module }}\{{ entity_class }}Storage",
{% endif %}
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "list_builder" = "Drupal\{{ module }}\{{ entity_class }}ListBuilder",
* "views_data" = "Drupal\{{ module }}\Entity\{{ entity_class }}ViewsData",
{% if is_translatable %}
* "translation" = "Drupal\{{ module }}\{{ entity_class }}TranslationHandler",
{% endif %}
*
{% if has_forms %}
* "form" = {
* "default" = "Drupal\{{ module }}\Form\{{ entity_class }}Form",
* "add" = "Drupal\{{ module }}\Form\{{ entity_class }}Form",
* "edit" = "Drupal\{{ module }}\Form\{{ entity_class }}Form",
* "delete" = "Drupal\{{ module }}\Form\{{ entity_class }}DeleteForm",
* },
* "route_provider" = {
* "html" = "Drupal\{{ module }}\{{ entity_class }}HtmlRouteProvider",
* },
{% endif %}
* "access" = "Drupal\{{ module }}\{{ entity_class }}AccessControlHandler",
* },
* base_table = "{{ entity_name }}",
{% if is_translatable %}
* data_table = "{{ entity_name }}_field_data",
{% endif %}
{% if revisionable %}
* revision_table = "{{ entity_name }}_revision",
* revision_data_table = "{{ entity_name }}_field_revision",
{% endif %}
* translatable = {{ is_translatable ? 'TRUE' : 'FALSE' }},
{% if has_bundle_permissions %}
* permission_granularity = "bundle",
{% endif %}
* admin_permission = "administer {{ label|lower }} entities",
* entity_keys = {
* "id" = "id",
{% if revisionable %}
* "revision" = "vid",
{% endif %}
{% if bundle_entity_type %}
* "bundle" = "type",
{% endif %}
* "label" = "name",
* "uuid" = "uuid",
{% if has_owner %}
* "uid" = "user_id",
{% endif %}
* "langcode" = "langcode",
* "published" = "status",
* },
{% if has_forms %}
* links = {
* "canonical" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}",
{% if bundle_entity_type %}
* "add-page" = "{{ base_path }}/{{ entity_name }}/add",
* "add-form" = "{{ base_path }}/{{ entity_name }}/add/{{ '{'~bundle_entity_type~'}' }}",
{% else %}
* "add-form" = "{{ base_path }}/{{ entity_name }}/add",
{% endif %}
* "edit-form" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}/edit",
* "delete-form" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}/delete",
{% if revisionable %}
* "version-history" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}/revisions",
* "revision" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}/revisions/{{ '{'~entity_name~'_revision}' }}/view",
* "revision_revert" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}/revisions/{{ '{'~entity_name~'_revision}' }}/revert",
* "revision_delete" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}/revisions/{{ '{'~entity_name~'_revision}' }}/delete",
{% if is_translatable %}
* "translation_revert" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}/revisions/{{ '{'~entity_name~'_revision}' }}/revert/{langcode}",
{% endif %}
{% endif %}
* "collection" = "{{ base_path }}/{{ entity_name }}",
* },
{% endif %}
{% if bundle_entity_type %}
* bundle_entity_type = "{{ bundle_entity_type }}",
* field_ui_base_route = "entity.{{ bundle_entity_type }}.edit_form"
{% else %}
{% if has_forms %}
* field_ui_base_route = "{{ entity_name }}.settings"
{% endif %}
{% endif %}
* )
*/
class {{ entity_class }} extends {% if revisionable %}EditorialContentEntityBase{% else %}ContentEntityBase{% endif %} implements {{ entity_class }}Interface {% endblock %}
{% block use_trait %}
use EntityChangedTrait;
use EntityPublishedTrait;
{% endblock %}
{% block class_methods %}
{% if has_owner %}
/**
* {@inheritdoc}
*/
public static function preCreate(EntityStorageInterface $storage_controller, array &$values) {
parent::preCreate($storage_controller, $values);
$values += [
'user_id' => \Drupal::currentUser()->id(),
];
}
{% endif %}
{% if revisionable %}
/**
* {@inheritdoc}
*/
protected function urlRouteParameters($rel) {
$uri_route_parameters = parent::urlRouteParameters($rel);
if ($rel === 'revision_revert' && $this instanceof RevisionableInterface) {
$uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
}
elseif ($rel === 'revision_delete' && $this instanceof RevisionableInterface) {
$uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
}
return $uri_route_parameters;
}
/**
* {@inheritdoc}
*/
public function preSave(EntityStorageInterface $storage) {
parent::preSave($storage);
{% if is_translatable %}
foreach (array_keys($this->getTranslationLanguages()) as $langcode) {
$translation = $this->getTranslation($langcode);
// If no owner has been set explicitly, make the anonymous user the owner.
if (!$translation->getOwner()) {
$translation->setOwnerId(0);
}
}
{% endif %}
// If no revision author has been set explicitly,
// make the {{ entity_name }} owner the revision author.
if (!$this->getRevisionUser()) {
$this->setRevisionUserId($this->getOwnerId());
}
}
{% endif %}
/**
* {@inheritdoc}
*/
public function getName() {
return $this->get('name')->value;
}
/**
* {@inheritdoc}
*/
public function setName($name) {
$this->set('name', $name);
return $this;
}
/**
* {@inheritdoc}
*/
public function getCreatedTime() {
return $this->get('created')->value;
}
/**
* {@inheritdoc}
*/
public function setCreatedTime($timestamp) {
$this->set('created', $timestamp);
return $this;
}
{% if has_owner %}
/**
* {@inheritdoc}
*/
public function getOwner() {
return $this->get('user_id')->entity;
}
/**
* {@inheritdoc}
*/
public function getOwnerId() {
return $this->get('user_id')->target_id;
}
/**
* {@inheritdoc}
*/
public function setOwnerId($uid) {
$this->set('user_id', $uid);
return $this;
}
/**
* {@inheritdoc}
*/
public function setOwner(UserInterface $account) {
$this->set('user_id', $account->id());
return $this;
}
{% endif %}
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);
// Add the published field.
$fields += static::publishedBaseFieldDefinitions($entity_type);
{% if has_owner %}
$fields['user_id'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Authored by'))
->setDescription(t('The user ID of author of the {{ label }} entity.'))
->setRevisionable(TRUE)
->setSetting('target_type', 'user')
->setSetting('handler', 'default')
{% if is_translatable %}
->setTranslatable(TRUE)
{% endif %}
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'author',
'weight' => 0,
])
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => 5,
'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'autocomplete_type' => 'tags',
'placeholder' => '',
],
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
{% endif %}
$fields['name'] = BaseFieldDefinition::create('string')
->setLabel(t('Name'))
->setDescription(t('The name of the {{ label }} entity.'))
{% if revisionable %}
->setRevisionable(TRUE)
{% endif %}
->setSettings([
'max_length' => 50,
'text_processing' => 0,
])
->setDefaultValue('')
->setDisplayOptions('view', [
'label' => 'above',
'type' => 'string',
'weight' => -4,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => -4,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE)
->setRequired(TRUE);
$fields['status']->setDescription(t('A boolean indicating whether the {{ label }} is published.'))
->setDisplayOptions('form', [
'type' => 'boolean_checkbox',
'weight' => -3,
]);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time that the entity was created.'));
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
->setDescription(t('The time that the entity was last edited.'));
{% if revisionable and is_translatable %}
$fields['revision_translation_affected'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Revision translation affected'))
->setDescription(t('Indicates if the last edit of a translation belongs to current revision.'))
->setReadOnly(TRUE)
->setRevisionable(TRUE)
->setTranslatable(TRUE);
{% endif %}
return $fields;
}
{% endblock %}

View File

@@ -0,0 +1,7 @@
{% block hook_theme %}
$theme['{{ entity_name }}'] = [
'render element' => 'elements',
'file' => '{{ entity_name }}.page.inc',
'template' => '{{ entity_name }}',
];
{% endblock %}

View File

@@ -0,0 +1,72 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Entity\{{ entity_class }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Entity;
{% endblock %}
{% block use_class %}
{% if bundle_of %}
use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
{% else %}
use Drupal\Core\Config\Entity\ConfigEntityBase;
{% endif %}
{% endblock %}
{% block class_declaration %}
/**
* Defines the {{ label }} entity.
*
* @ConfigEntityType(
* id = "{{ entity_name }}",
* label = @Translation("{{ label }}"),
* handlers = {
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "list_builder" = "Drupal\{{ module }}\{{ entity_class }}ListBuilder",
* "form" = {
* "add" = "Drupal\{{ module }}\Form\{{ entity_class }}Form",
* "edit" = "Drupal\{{ module }}\Form\{{ entity_class }}Form",
* "delete" = "Drupal\{{ module }}\Form\{{ entity_class }}DeleteForm"
* },
* "route_provider" = {
* "html" = "Drupal\{{ module }}\{{ entity_class }}HtmlRouteProvider",
* },
* },
* config_prefix = "{{ entity_name }}",
* admin_permission = "administer site configuration",
{% if bundle_of %}
* bundle_of = "{{ bundle_of }}",
{% endif %}
* entity_keys = {
* "id" = "id",
* "label" = "label",
* "uuid" = "uuid"
* },
* links = {
* "canonical" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}",
* "add-form" = "{{ base_path }}/{{ entity_name }}/add",
* "edit-form" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}/edit",
* "delete-form" = "{{ base_path }}/{{ entity_name }}/{{ '{'~entity_name~'}' }}/delete",
* "collection" = "{{ base_path }}/{{ entity_name }}"
* }
* )
*/
class {{ entity_class }} extends {% if bundle_of %}ConfigEntityBundleBase{% else %}ConfigEntityBase{% endif %} implements {{ entity_class }}Interface {% endblock %}
{% block class_methods %}
/**
* The {{ label }} ID.
*
* @var string
*/
protected $id;
/**
* The {{ label }} label.
*
* @var string
*/
protected $label;
{% endblock %}

View File

@@ -0,0 +1,112 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Entity\{{ entity_class }}Interface.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Entity;
{% endblock %}
{% block use_class %}
use Drupal\Core\Entity\ContentEntityInterface;
{% if revisionable %}
use Drupal\Core\Entity\RevisionLogInterface;
{% endif %}
use Drupal\Core\Entity\EntityChangedInterface;
use Drupal\Core\Entity\EntityPublishedInterface;
{% if has_owner %}
use Drupal\user\EntityOwnerInterface;
{% endif %}
{% endblock %}
{% block class_declaration %}
/**
* Provides an interface for defining {{ label }} entities.
*
* @ingroup {{module}}
*/
interface {{ entity_class }}Interface extends ContentEntityInterface{% if revisionable %}, RevisionLogInterface{% endif %}, EntityChangedInterface, EntityPublishedInterface{% if has_owner %}, EntityOwnerInterface{% endif %} {% endblock %}
{% block class_methods %}
/**
* Add get/set methods for your configuration properties here.
*/
/**
* Gets the {{ label }} name.
*
* @return string
* Name of the {{ label }}.
*/
public function getName();
/**
* Sets the {{ label }} name.
*
* @param string $name
* The {{ label }} name.
*
* @return \Drupal\{{ module }}\Entity\{{ entity_class }}Interface
* The called {{ label }} entity.
*/
public function setName($name);
/**
* Gets the {{ label }} creation timestamp.
*
* @return int
* Creation timestamp of the {{ label }}.
*/
public function getCreatedTime();
/**
* Sets the {{ label }} creation timestamp.
*
* @param int $timestamp
* The {{ label }} creation timestamp.
*
* @return \Drupal\{{ module }}\Entity\{{ entity_class }}Interface
* The called {{ label }} entity.
*/
public function setCreatedTime($timestamp);
{% if revisionable %}
/**
* Gets the {{ label }} revision creation timestamp.
*
* @return int
* The UNIX timestamp of when this revision was created.
*/
public function getRevisionCreationTime();
/**
* Sets the {{ label }} revision creation timestamp.
*
* @param int $timestamp
* The UNIX timestamp of when this revision was created.
*
* @return \Drupal\{{ module }}\Entity\{{ entity_class }}Interface
* The called {{ label }} entity.
*/
public function setRevisionCreationTime($timestamp);
/**
* Gets the {{ label }} revision author.
*
* @return \Drupal\user\UserInterface
* The user entity for the revision author.
*/
public function getRevisionUser();
/**
* Sets the {{ label }} revision author.
*
* @param int $uid
* The user ID of the revision author.
*
* @return \Drupal\{{ module }}\Entity\{{ entity_class }}Interface
* The called {{ label }} entity.
*/
public function setRevisionUserId($uid);
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,21 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Entity\{{ entity_class }}Interface.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Entity;
{% endblock %}
{% block use_class %}
use Drupal\Core\Config\Entity\ConfigEntityInterface;
{% endblock %}
{% block class_declaration %}
/**
* Provides an interface for defining {{ label }} entities.
*/
interface {{ entity_class }}Interface extends ConfigEntityInterface {% endblock %}
{% block class_methods %}
// Add get/set methods for your configuration properties here.{% endblock %}

View File

@@ -0,0 +1,59 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Form\{{ entity_class }}DeleteForm.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Form;
{% endblock %}
{% block use_class %}
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
{% endblock %}
{% block class_declaration %}
/**
* Builds the form to delete {{ label }} entities.
*/
class {{ entity_class }}DeleteForm extends EntityConfirmFormBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function getQuestion() {
return $this->t('Are you sure you want to delete %name?', ['%name' => $this->entity->label()]);
}
/**
* {@inheritdoc}
*/
public function getCancelUrl() {
return new Url('entity.{{ entity_name }}.collection');
}
/**
* {@inheritdoc}
*/
public function getConfirmText() {
return $this->t('Delete');
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->entity->delete();
$this->messenger()->addMessage(
$this->t('content @type: deleted @label.', [
'@type' => $this->entity->bundle(),
'@label' => $this->entity->label(),
])
);
$form_state->setRedirectUrl($this->getCancelUrl());
}
{% endblock %}

View File

@@ -0,0 +1,73 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Form\{{ entity_class }}Form.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Form;
{% endblock %}
{% block use_class %}
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
{% endblock %}
{% block class_declaration %}
/**
* Class {{ entity_class }}Form.
*/
class {{ entity_class }}Form extends EntityForm {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
${{ entity_name | machine_name }} = $this->entity;
$form['label'] = [
'#type' => 'textfield',
'#title' => $this->t('Label'),
'#maxlength' => 255,
'#default_value' => ${{ entity_name | machine_name }}->label(),
'#description' => $this->t("Label for the {{ label }}."),
'#required' => TRUE,
];
$form['id'] = [
'#type' => 'machine_name',
'#default_value' => ${{ entity_name | machine_name }}->id(),
'#machine_name' => [
'exists' => '\Drupal\{{ module }}\Entity\{{ entity_class }}::load',
],
'#disabled' => !${{ entity_name | machine_name }}->isNew(),
];
/* You will need additional form elements for your custom properties. */
return $form;
}
/**
* {@inheritdoc}
*/
public function save(array $form, FormStateInterface $form_state) {
${{ entity_name | machine_name }} = $this->entity;
$status = ${{ entity_name | machine_name }}->save();
switch ($status) {
case SAVED_NEW:
$this->messenger()->addMessage($this->t('Created the %label {{ label }}.', [
'%label' => ${{ entity_name | machine_name }}->label(),
]));
break;
default:
$this->messenger()->addMessage($this->t('Saved the %label {{ label }}.', [
'%label' => ${{ entity_name | machine_name }}->label(),
]));
}
$form_state->setRedirectUrl(${{ entity_name | machine_name }}->toUrl('collection'));
}
{% endblock %}

View File

@@ -0,0 +1,71 @@
{% if not file_exists %}
{% include 'module/php_tag.php.twig' %}
/**
* @file
* Contains {{ module }} form alter.
*/
{% endif %}
{% block use_class %}
use Drupal\Core\Form\FormStateInterface;
{% endblock %}
{% block file_methods %}
{% if form_id is not empty %}
/**
* Implements hook_form_FORM_ID_alter() on behalf of {{ module }}.module.
{% if metadata.class is defined %}
* @see \{{ metadata.class }} method {{ metadata.method }} at {{ metadata.file }}
{% endif %}
*/
function {{ module }}_form_{{ form_id }}_alter(&$form, FormStateInterface $form_state) {
\Drupal::messenger()->addMessage('{{ module }}_form_{{ form_id }}_alter() executed.');
{% else %}
/**
* Implements hook_form_alter().
*/
function {{ module }}_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Change form id here.
if ($form_id == 'form_test_alter_form') {
\Drupal::messenger()->addMessage('form_test_form_alter() executed.');
{% endif %}
{%- if metadata.unset -%}
{% for field in metadata.unset %}
$form['{{ field }}']['#access'] = FALSE;
{% endfor %}
{% endif %}
{% if inputs %}
{% for input in inputs %}
$form['{{ input.name }}'] = [
'#type' => '{{ input.type }}',
'#title' => t('{{ input.label|e }}'),
{% if input.description is defined and input.description is not empty %}
'#description' => t('{{ input.description|e }}'),
{% endif %}
{% if input.options is defined and input.options|length %}
'#options' => {{ input.options }},
{% endif %}
{% if input.maxlength is defined and input.maxlength|length %}
'#maxlength' => {{ input.maxlength }},
{% endif %}
{% if input.size is defined and input.size|length %}
'#size' => {{ input.size }},
{% endif %}
{% if input.default_value is defined and input.default_value|length %}
'#default_value' => '{{ input.default_value }}',
{% endif %}
{% if input.weight is defined and input.weight is not empty%}
'#weight' => '{{ input.weight }}',
{% endif %}
];
{% endfor %}
{% endif %}
{% if form_id is empty %}
}
{% endif %}
}
{% endblock %}

View File

@@ -0,0 +1,104 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module_name}}\Form\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module_name}}\Form;
{% endblock %}
{% block use_class %}
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
{% if services is not empty %}
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endif %}
{% endblock %}
{% block use_class_services %}
{% endblock %}
{% block class_declaration %}
/**
* Class {{ class_name }}.
*/
class {{ class_name }} extends ConfigFormBase {% endblock %}
{% block class_create %}
{% if services is not empty %}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
{{ serviceClassInjectionNoOverride(services) }}
return $instance;
}
{% endif %}
{% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'{{module_name}}.{{class_name_short}}',
];
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return '{{form_id}}';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('{{module_name}}.{{class_name_short}}');
{% for input in inputs %}
{% if input.fieldset is defined and input.fieldset is not empty %}
$form['{{ input.fieldset }}']['{{ input.name }}'] = [
{% else %}
$form['{{ input.name }}'] = [
{% endif %}
'#type' => '{{ input.type }}',
'#title' => $this->t('{{ input.label|e }}'),
{% if input.description is defined and input.description|length %}
'#description' => $this->t('{{ input.description|e }}'),
{% endif %}
{% if input.options is defined and input.options is not empty %}
'#options' => {{ input.options }},
{% endif %}
{% if input.maxlength is defined and input.maxlength is not empty %}
'#maxlength' => {{ input.maxlength }},
{% endif %}
{% if input.size is defined and input.size is not empty %}
'#size' => {{ input.size }},
{% endif %}
{% if input.type != 'password_confirm' and input.type != 'fieldset' %}
'#default_value' => $config->get('{{ input.name }}'),
{% endif %}
];
{% endfor %}
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$this->config('{{module_name}}.{{class_name_short}}')
{% for input in inputs %}
->set('{{ input.name }}', $form_state->getValue('{{ input.name }}'){% if input.type == 'text_format' %}['value']{% endif %})
{% endfor %}
->save();
}
{% endblock %}

View File

@@ -0,0 +1,113 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module_name}}\Form\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module_name}}\Form;
{% endblock %}
{% block use_class %}
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
{% if services is not empty %}
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endif %}
{% endblock %}
{% block use_class_services %}
{% endblock %}
{% block class_declaration %}
/**
* Class {{ class_name }}.
*/
class {{ class_name }} extends FormBase {% endblock %}
{% block class_create %}
{% if services is not empty %}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
{{ serviceClassInjectionNoOverride(services) }}
return $instance;
}
{% endif %}
{% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function getFormId() {
return '{{form_id}}';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
{% for input in inputs %}
{% if input.fieldset is defined and input.fieldset|length %}
$form['{{ input.fieldset }}']['{{ input.name }}'] = [
{% else %}
$form['{{ input.name }}'] = [
{% endif %}
'#type' => '{{ input.type }}',
'#title' => $this->t('{{ input.label|e }}'),
{% if input.description is defined and input.description|length %}
'#description' => $this->t('{{ input.description|e }}'),
{% endif %}
{% if input.options is defined and input.options|length %}
'#options' => {{ input.options }},
{% endif %}
{% if input.maxlength is defined and input.maxlength|length %}
'#maxlength' => {{ input.maxlength }},
{% endif %}
{% if input.size is defined and input.size|length %}
'#size' => {{ input.size }},
{% endif %}
{% if input.default_value is defined and input.default_value|length %}
'#default_value' => '{{ input.default_value }}',
{% endif %}
{% if input.weight is defined and input.weight|length %}
'#weight' => '{{ input.weight }}',
{% endif %}
];
{% endfor %}
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
foreach ($form_state->getValues() as $key => $value) {
// @TODO: Validate fields.
}
parent::validateForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// Display result.
foreach ($form_state->getValues() as $key => $value) {
{% if 'messenger' in services|keys %}
$this->messenger->addMessage($key . ': ' . ($key === 'text_format'?$value['value']:$value));
{% else %}
\Drupal::messenger()->addMessage($key . ': ' . ($key === 'text_format'?$value['value']:$value));
{% endif %}
}
}
{% endblock %}

View File

@@ -0,0 +1,36 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{extension}}\Generator\{{ class }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{extension}}\Generator;
{% endblock %}
{% block use_class %}
use Drupal\Console\Core\Generator\Generator;
use Drupal\Console\Core\Generator\GeneratorInterface;
{% endblock %}
{% block class_declaration %}
/**
* Class {{ class_name }}.
*
* @package Drupal\Console\Generator
*/
class {{ class_name }} extends Generator implements GeneratorInterface {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function generate(array $parameters) {
// Example how to render a twig template using the renderFile method
// $this->renderFile(
// 'path/to/file.php.twig',
// 'path/to/file.php',
// $parameters
// );.
}
{% endblock %}

View File

@@ -0,0 +1,124 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\Block\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\Block;
{% endblock %}
{% block use_class %}
use Drupal\Core\Block\BlockBase;
{% if inputs %}
use Drupal\Core\Form\FormStateInterface;
{% endif %}
{% if services is not empty %}
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endif %}
{% endblock %}
{% block use_class_services %}
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{class_name}}' block.
*
* @Block(
* id = "{{plugin_id}}",
* admin_label = @Translation("{{label}}"),
* )
*/
class {{class_name}} extends BlockBase {% if services is not empty %}implements ContainerFactoryPluginInterface {% endif %}{% endblock %}
{% block class_create %}
{% if services is not empty %}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = new static($configuration, $plugin_id, $plugin_definition);
{{ serviceClassInjectionNoOverride(services) }}
return $instance;
}
{% endif %}
{% endblock %}
{% block class_methods %}
{% if inputs %}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
{% for input in inputs %}
{% if input.default_value is defined and input.default_value|length %}
'{{ input.name }}' => {{ input.default_value }},
{% endif %}
{% endfor %}
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
{% for input in inputs %}
$form['{{ input.name }}'] = [
'#type' => '{{ input.type }}',
'#title' => $this->t('{{ input.label|escape }}'),
{% if input.description is defined and input.description is not empty %}
'#description' => $this->t('{{ input.description|e }}'),
{% endif %}
{% if input.options is defined and input.options|length %}
'#options' => {{ input.options }},
{% endif %}
'#default_value' => $this->configuration['{{ input.name }}'],
{% if input.maxlength is defined and input.maxlength|length %}
'#maxlength' => {{ input.maxlength }},
{% endif %}
{% if input.size is defined and input.size|length %}
'#size' => {{ input.size }},
{% endif %}
{% if input.weight is defined and input.weight|length %}
'#weight' => '{{ input.weight }}',
{% endif %}
];
{% endfor %}
return $form;
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
{% for input in inputs %}
$this->configuration['{{ input.name }}'] = $form_state->getValue('{{ input.name }}'){% if input.type == 'text_format' %}['value']{% endif %};
{% endfor %}
}
{% endif %}
/**
* {@inheritdoc}
*/
public function build() {
$build = [];
{% if twig_template is defined %}
$build['#theme'] = '{{ plugin_id }}';
{% endif %}
{% for input in inputs %}
{% if twig_template is defined %}
$build['#conten'][] = $this->configuration['{{ input.name }}'];
{% else %}
$build['{{plugin_id}}_{{ input.name }}']['#markup'] = '<p>' . $this->configuration['{{ input.name }}'] . '</p>';
{% endif %}
{% else %}
$build['{{plugin_id}}']['#markup'] = 'Implement {{class_name}}.';
{% endfor %}
return $build;
}
{% endblock %}

View File

@@ -0,0 +1,93 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\Block\{{class}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\Block;
{% endblock %}
{% block use_class %}
use Drupal\block\BlockBase;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityViewBuilderInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{class}}' block.
*
* @Block(
* id = "{{block_id}}",
* admin_label = @Translation("{{block_label}}"),
* category = @Translation("{{block_description}}"),
* deriver = "Drupal\{{module}}\Plugin\Derivative\{{class}}"
* )
*/
class {{class}} extends BlockBase
{% endblock %}
{% block class_properties %}
/**
* @var EntityViewBuilderInterface.
*/
private $_viewBuilder;
/**
* @var NodeInterface.
*/
private $_node;
{% endblock %}
{% block class_construct %}
/**
* Creates a {{class}} instance.
*
* @param array $configuration
* @param string $plugin_id
* @param mixed $plugin_definition
* @param EntityManagerInterface $entity_manager
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager)
{
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->viewBuilder = $entity_manager->getViewBuilder('node');
$this->nodeStorage = $entity_manager->getStorage('node');
$this->node = $entity_manager->getStorage('node')->load($this->getDerivativeId());
}
{% endblock %}
{% block class_create %}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition)
{
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity.manager')
);
}
{% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function build()
{
if (!$this->node instanceof NodeInterface) {
return;
}
$build = $this->viewBuilder->view($this->node, 'full');
return $build;
}
{% endblock %}

View File

@@ -0,0 +1,25 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\Block\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\Block;
{% endblock %}
{% block use_class %}
use Drupal\Core\Block\BlockBase;
{% endblock %}
{% block class_declaration %}
/**
* {@inheritdoc}
*/
public function build() {
$build = [];
$build['{{block_id}}']['#markup'] = 'Implement {{class_name}}.';
return $build;
}
{% endblock %}

View File

@@ -0,0 +1,94 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Plugin\CKEditorPlugin\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Plugin\CKEditorPlugin;
{% endblock %}
{% block use_class %}
use Drupal\ckeditor\CKEditorPluginBase;
use Drupal\editor\Entity\Editor;
{% endblock %}
{% block class_declaration %}
/**
* Defines the "{{ plugin_id }}" plugin.
*
* NOTE: The plugin ID ('id' key) corresponds to the CKEditor plugin name.
* It is the first argument of the CKEDITOR.plugins.add() function in the
* plugin.js file.
*
* @CKEditorPlugin(
* id = "{{ plugin_id }}",
* label = @Translation("{{ label }}"),
* module = "{{ module }}"
* )
*/
class {{ class_name }} extends CKEditorPluginBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*
* NOTE: The keys of the returned array corresponds to the CKEditor button
* names. They are the first argument of the editor.ui.addButton() or
* editor.ui.addRichCombo() functions in the plugin.js file.
*/
public function getButtons() {
// Make sure that the path to the image matches the file structure of
// the CKEditor plugin you are implementing.
return [
{% for button in buttons %}
'{{ button.name }}' => [
'label' => t('{{ button.label }}'),
'image' => '{{ button.icon }}',
],
{% endfor %}
];
}
/**
* {@inheritdoc}
*/
public function isEnabled(Editor $editor) {
}
/**
* {@inheritdoc}
*/
public function getFile() {
// Make sure that the path to the plugin.js matches the file structure of
// the CKEditor plugin you are implementing.
return drupal_get_path('module', '{{ module }}') . '/js/Plugin/{{ plugin_id }}/plugin.js';
}
/**
* {@inheritdoc}
*/
public function isInternal() {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function getDependencies(Editor $editor) {
return [];
}
/**
* {@inheritdoc}
*/
public function getLibraries(Editor $editor) {
return [];
}
/**
* {@inheritdoc}
*/
public function getConfig(Editor $editor) {
return [];
}
{% endblock %}

View File

@@ -0,0 +1,20 @@
/**
* DO NOT EDIT THIS FILE.
* See the following change record for more information,
* https://www.drupal.org/node/2815083
* @preserve
**/
{% for button in buttons %}
CKEDITOR.plugins.add('{{ pligins_id }}', {
init: function( editor ) {
if ( editor.ui.addButton ) {
editor.ui.addButton( '{{ button.name }}', {
label: 'default ckeditor button',
id: '{{ button.name }}',
command: '',
toolbar: '{{ button.name }},10',
} );
}
}
} );
{% endfor %}

View File

@@ -0,0 +1,107 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Plugin\Condition\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Plugin\Condition;
{% endblock %}
{% block use_class %}
use Drupal\Core\Condition\ConditionPluginBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\Context\ContextDefinition;
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{ label }}' condition to enable a condition based in module selected status.
*
* @Condition(
* id = "{{ plugin_id }}",
* label = @Translation("{{ label }}"),
* context = {
* "{{ context_id }}" = @ContextDefinition("{{ context_definition_id }}", required = {{ context_definition_required }} , label = @Translation("{{ context_definition_label }}"))
* }
* )
*
*/
class {{ class_name }} extends ConditionPluginBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
return $instance;
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
// Sort all modules by their names.
$modules = \Drupal::service('extension.list.module')->getList();
uasort($modules, 'system_sort_modules_by_info_name');
$options = [NULL => t('Select a module')];
foreach ($modules as $module_id => $module) {
$options[$module_id] = $module->info['name'];
}
$form['module'] = [
'#type' => 'select',
'#title' => $this->t('Select a module to validate'),
'#default_value' => $this->configuration['module'],
'#options' => $options,
'#description' => $this->t('Module selected status will be use to evaluate condition.'),
];
return parent::buildConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration['module'] = $form_state->getValue('module');
parent::submitConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return ['module' => ''] + parent::defaultConfiguration();
}
/**
* Evaluates the condition and returns TRUE or FALSE accordingly.
*
* @return bool
* TRUE if the condition has been met, FALSE otherwise.
*/
public function evaluate() {
if (empty($this->configuration['module']) && !$this->isNegated()){
return TRUE;
}
$module = $this->configuration['module'];
$modules = \Drupal::service('extension.list.module')->getList();
return $modules[$module]->status;
}
/**
* Provides a human readable summary of the condition's configuration.
*/
public function summary() {
$module = $this->getContextValue('module');
$modules = \Drupal::service('extension.list.module')->getList();
$status = ($modules[$module]->status)?t('enabled'):t('disabled');
return t('The module @module is @status.', ['@module' => $module, '@status' => $status]);
}
{% endblock %}

View File

@@ -0,0 +1,43 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\Condition\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\Condition;
{% endblock %}
{% block use_class %}
use Drupal\rules\Core\RulesConditionBase;
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{class_name}}' condition.
*
* @Condition(
* id = "{{plugin_id}}",
* label = @Translation("{{label}}"),
* category = @Translation("{{category}}"),
{% if context %}
* context = {
{% for item in context %}
* "{{ item.name }}" = @ContextDefinition("{{ item.type }}",
* label = @Translation("{{ item.label }}"),
* description = @Translation("{{ item.description }}")
* ),
{% endfor %}
* }
{% endif %}
* )
*/
class {{class_name}} extends RulesConditionBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function doEvaluate($object = NULL) {
// Insert code here.
}
{% endblock %}

View File

@@ -0,0 +1,75 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\Block\{{class}}.
{% endblock %}
{% block namespace_class %}
/**
* @file
* Contains \Drupal\{{module}}\Plugin\Derivative\{{class}}.php.
*/
namespace Drupal\{{module}}\Plugin\Derivative;
{% endblock %}
{% block use_class %}
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endblock %}
{% block class_declaration %}
/**
* Provides block plugin definitions.
*
* @see \Drupal\{{module}}\Plugin\Block\{{class}}
*/
class {{class}} extends DeriverBase implements ContainerDeriverInterface
{% endblock %}
{% block class_properties %}
/**
* The node storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $nodeStorage;
{% endblock %}
{% block class_construct %}
/**
* Creates a new NodeBlock.
*
* @param \Drupal\Core\Entity\EntityStorageInterface $node_storage
* The node storage.
*/
public function __construct(EntityStorageInterface $node_storage)
{
$this->nodeStorage = $node_storage;
}
{% endblock %}
{% block class_create %}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id)
{
return new static(
$container->get('entity.manager')->getStorage('node')
);
}
{% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition)
{
$nodes = $this->nodeStorage->loadByProperties(['type' => 'article']);
foreach ($nodes as $node) {
$this->derivatives[$node->id()] = $base_plugin_definition;
$this->derivatives[$node->id()]['admin_label'] = t('Node block: ') . $node->label();
}
return $this->derivatives;
}
{% endblock %}

View File

@@ -0,0 +1,93 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Plugin\Field\FieldFormatter\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Plugin\Field\FieldFormatter;
{% endblock %}
{% block use_class %}
use Drupal\Component\Utility\Html;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
{% endblock %}
{% block class_declaration %}
/**
* Plugin implementation of the '{{ plugin_id }}' formatter.
*
* @FieldFormatter(
* id = "{{ plugin_id }}",
* label = @Translation("{{ label }}"){% if field_type %},
* field_types = {
* "{{ field_type }}"
* }
{% else %}
* At least one field_types annotation array entry is necessary to display this formatter in the UI.
* ex. field_types = { "field_type" }
{% endif %}
* )
*/
class {{ class_name }} extends FormatterBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
// Implement default settings.
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
return [
// Implement settings form.
] + parent::settingsForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = [];
// Implement settings summary.
return $summary;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
foreach ($items as $delta => $item) {
$elements[$delta] = ['#markup' => $this->viewValue($item)];
}
return $elements;
}
/**
* Generate the output appropriate for one field item.
*
* @param \Drupal\Core\Field\FieldItemInterface $item
* One field item.
*
* @return string
* The textual output generated.
*/
protected function viewValue(FieldItemInterface $item) {
// The text value has no text format assigned to it, so the user input
// should equal the output, including newlines.
return nl2br(Html::escape($item->value));
}
{% endblock %}

View File

@@ -0,0 +1,182 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Plugin\Field\FieldFormatter\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Plugin\Field\FieldFormatter;
{% endblock %}
{% block use_class %}
use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Cache\Cache;
{% endblock %}
{% block class_declaration %}
/**
* Plugin implementation of the '{{ plugin_id }}' formatter.
*
* @FieldFormatter(
* id = "{{ plugin_id }}",
* label = @Translation("{{ label }}"),
* field_types = {
* "image"
* }
* )
*/
class {{ class_name }} extends ImageFormatterBase implements ContainerFactoryPluginInterface {% endblock %}
{% block class_methods %}
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* The link generator.
*
* @var \Drupal\Core\Utility\LinkGeneratorInterface
*/
protected $linkGenerator;
/**
* The image style entity storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $imageStyleStorage;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = new static($configuration, $plugin_id, $plugin_definition);
$instance->currentUser = $container->get('current_user');
$instance->linkGenerator = $container->get('link_generator');
$instance->imageStyleStorage = $container->get('entity_type.manager')->getStorage('image_style');
return $instance;
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'image_style' => '',
'image_link' => '',
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$image_styles = image_style_options(FALSE);
$element['image_style'] = [
'#title' => t('Image style'),
'#type' => 'select',
'#default_value' => $this->getSetting('image_style'),
'#empty_option' => t('None (original image)'),
'#options' => $image_styles,
'#description' => [
'#markup' => $this->linkGenerator->generate($this->t('Configure Image Styles'), new Url('entity.image_style.collection')),
'#access' => $this->currentUser->hasPermission('administer image styles'),
],
];
return $element;
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = [];
$image_styles = image_style_options(FALSE);
// Unset possible 'No defined styles' option.
unset($image_styles['']);
// Styles could be lost because of enabled/disabled modules that defines
// their styles in code.
$image_style_setting = $this->getSetting('image_style');
if (isset($image_styles[$image_style_setting])) {
$summary[] = t('Image style: @style', ['@style' => $image_styles[$image_style_setting]]);
}
else {
$summary[] = t('Original image');
}
return $summary;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];
$files = $this->getEntitiesToView($items, $langcode);
// Early opt-out if the field is empty.
if (empty($files)) {
return $elements;
}
$url = NULL;
$image_link_setting = $this->getSetting('image_link');
// Check if the formatter involves a link.
if ($image_link_setting == 'content') {
$entity = $items->getEntity();
if (!$entity->isNew()) {
$url = $entity->toUrl();
}
}
elseif ($image_link_setting == 'file') {
$link_file = TRUE;
}
$image_style_setting = $this->getSetting('image_style');
// Collect cache tags to be added for each item in the field.
$cache_tags = [];
if (!empty($image_style_setting)) {
$image_style = $this->imageStyleStorage->load($image_style_setting);
$cache_tags = $image_style->getCacheTags();
}
foreach ($files as $delta => $file) {
if (isset($link_file)) {
$image_uri = $file->getFileUri();
$url = Url::fromUri(file_create_url($image_uri));
}
$cache_tags = Cache::mergeTags($cache_tags, $file->getCacheTags());
// Extract field item attributes for the theme function, and unset them
// from the $item so that the field template does not re-render them.
$item = $file->_referringItem;
$item_attributes = $item->_attributes;
unset($item->_attributes);
$elements[$delta] = [
'#theme' => 'image_formatter',
'#item' => $item,
'#item_attributes' => $item_attributes,
'#image_style' => $image_style_setting,
'#url' => $url,
'#cache' => [
'tags' => $cache_tags,
],
];
}
return $elements;
}
{% endblock %}

View File

@@ -0,0 +1,143 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Plugin\Field\FieldType\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Plugin\Field\FieldType;
{% endblock %}
{% block use_class %}
use Drupal\Component\Utility\Random;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\DataDefinition;
{% endblock %}
{% block class_declaration %}
/**
* Plugin implementation of the '{{ plugin_id }}' field type.
*
* @FieldType(
* id = "{{ plugin_id }}",
* label = @Translation("{{ label }}"),
* description = @Translation("{{ description }}"){% if default_widget or default_formatter %},
{% endif %}
{% if default_widget %}
* default_widget = "{{ default_widget }}"{% if default_widget and default_formatter %},
{% endif %}
{% else %}
{% endif %}
{% if default_formatter %}
* default_formatter = "{{ default_formatter }}"
{% else %}
{% endif %}
* )
*/
class {{ class_name }} extends FieldItemBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public static function defaultStorageSettings() {
return [
'max_length' => 255,
'is_ascii' => FALSE,
'case_sensitive' => FALSE,
] + parent::defaultStorageSettings();
}
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
// Prevent early t() calls by using the TranslatableMarkup.
$properties['value'] = DataDefinition::create('string')
->setLabel(new TranslatableMarkup('Text value'))
->setSetting('case_sensitive', $field_definition->getSetting('case_sensitive'))
->setRequired(TRUE);
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
$schema = [
'columns' => [
'value' => [
'type' => $field_definition->getSetting('is_ascii') === TRUE ? 'varchar_ascii' : 'varchar',
'length' => (int) $field_definition->getSetting('max_length'),
'binary' => $field_definition->getSetting('case_sensitive'),
],
],
];
return $schema;
}
/**
* {@inheritdoc}
*/
public function getConstraints() {
$constraints = parent::getConstraints();
if ($max_length = $this->getSetting('max_length')) {
$constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
$constraints[] = $constraint_manager->create('ComplexData', [
'value' => [
'Length' => [
'max' => $max_length,
'maxMessage' => t('%name: may not be longer than @max characters.', [
'%name' => $this->getFieldDefinition()->getLabel(),
'@max' => $max_length
]),
],
],
]);
}
return $constraints;
}
/**
* {@inheritdoc}
*/
public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
$random = new Random();
$values['value'] = $random->word(mt_rand(1, $field_definition->getSetting('max_length')));
return $values;
}
/**
* {@inheritdoc}
*/
public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
$elements = [];
$elements['max_length'] = [
'#type' => 'number',
'#title' => t('Maximum length'),
'#default_value' => $this->getSetting('max_length'),
'#required' => TRUE,
'#description' => t('The maximum length of the field in characters.'),
'#min' => 1,
'#disabled' => $has_data,
];
return $elements;
}
/**
* {@inheritdoc}
*/
public function isEmpty() {
$value = $this->get('value')->getValue();
return $value === NULL || $value === '';
}
{% endblock %}

View File

@@ -0,0 +1,98 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Plugin\Field\FieldWidget\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Plugin\Field\FieldWidget;
{% endblock %}
{% block use_class %}
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
{% endblock %}
{% block class_declaration %}
/**
* Plugin implementation of the '{{ plugin_id }}' widget.
*
* @FieldWidget(
* id = "{{ plugin_id }}",
* module = "{{ module }}",
* label = @Translation("{{ label }}"){% if field_type %},
* field_types = {
* "{{ field_type }}"
* }
{% else %}
* At least one field_types annotation array entry is necessary to display this formatter in the UI.
* ex. field_types = { "field_type" }
{% endif %}
* )
*/
class {{ class_name }} extends WidgetBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'size' => 60,
'placeholder' => '',
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$elements = [];
$elements['size'] = [
'#type' => 'number',
'#title' => t('Size of textfield'),
'#default_value' => $this->getSetting('size'),
'#required' => TRUE,
'#min' => 1,
];
$elements['placeholder'] = [
'#type' => 'textfield',
'#title' => t('Placeholder'),
'#default_value' => $this->getSetting('placeholder'),
'#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
];
return $elements;
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = [];
$summary[] = t('Textfield size: @size', ['@size' => $this->getSetting('size')]);
if (!empty($this->getSetting('placeholder'))) {
$summary[] = t('Placeholder: @placeholder', ['@placeholder' => $this->getSetting('placeholder')]);
}
return $summary;
}
/**
* {@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,
'#size' => $this->getSetting('size'),
'#placeholder' => $this->getSetting('placeholder'),
'#maxlength' => $this->getFieldSetting('max_length'),
];
return $element;
}
{% endblock %}

View File

@@ -0,0 +1,35 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\ImageEffect\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\ImageEffect;
{% endblock %}
{% block use_class %}
use Drupal\Core\Image\ImageInterface;
use Drupal\image\ImageEffectBase;
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{class_name}}' image effect.
*
* @ImageEffect(
* id = "{{plugin_id}}",
* label = @Translation("{{label}}"),
* description = @Translation("{{description}}")
* )
*/
class {{ class_name }} extends ImageEffectBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function applyEffect(ImageInterface $image) {
// Implement Image Effect.
return imagefilter($image->getToolkit()->getResource());
}
{% endblock %}

View File

@@ -0,0 +1,60 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\Mail\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\Mail;
{% endblock %}
{% block use_class %}
use Drupal\Core\Mail\Plugin\Mail\PhpMail;
{% if services is not empty %}
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endif %}
{% endblock %}
{% block use_class_services %}
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{class_name}}' mail plugin.
*
* @Mail(
* id = "{{plugin_id}}",
* label = @Translation("{{label}}")
* )
*/
class {{class_name}} extends PhpMail {% if services is not empty %}implements ContainerFactoryPluginInterface {% endif %}
{% endblock %}
{% block class_create %}
{% if services is not empty %}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = new static($configuration, $plugin_id, $plugin_definition);
{{ serviceClassInjectionNoOverride(services) }}
return $instance;
}
{% endif %}
{% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function format(array $message) {
}
/**
* {@inheritdoc}
*/
public function mail(array $message) {
}
{% endblock %}

View File

@@ -0,0 +1,29 @@
{% extends "base/class.php.twig" %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Plugin\QueueWorker;
{% endblock %}
{% block use_class %}
use Drupal\Core\Queue\QueueWorkerBase;
{% endblock %}
{% block class_declaration %}
/**
* Plugin implementation of the {{ plugin_id }} queueworker.
*
* @QueueWorker (
* id = "{{ plugin_id }}",
* title = @Translation("{{ label }}"),
* cron = {"time" = {{ cron_time }}}
* )
*/
class {{ class_name }} extends QueueWorkerBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function processItem($data) {
// Process item operations.
}
{% endblock %}

View File

@@ -0,0 +1,82 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module_name}}\Plugin\rest\resource\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module_name}}\Plugin\rest\resource;
{% endblock %}
{% block use_class %}
use Drupal\rest\ModifiedResourceResponse;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
{% endblock %}
{% block class_declaration %}
/**
* Provides a resource to get view modes by entity and bundle.
*
* @RestResource(
* id = "{{ plugin_id }}",
* label = @Translation("{{ plugin_label }}"),
* uri_paths = {
{% for state_settings in plugin_states %}
* "{{ state_settings.uri_paths }}" = "{{ plugin_url }}"
{% endfor %}
* }
* )
*/
class {{ class_name }} extends ResourceBase {% endblock %}
{% block class_variables %}
/**
* A current user instance.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
{% endblock %}
{% block class_create %}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->logger = $container->get('logger.factory')->get('{{module_name}}');
$instance->currentUser = $container->get('current_user');
return $instance;
}
{% endblock %}
{% block class_methods %}
{% for state, state_settings in plugin_states %}
/**
* Responds to {{ state }} requests.
*
* @param string $payload
*
* @return \Drupal\rest\{{ state_settings.response_class }}
* The HTTP response object.
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
public function {{ state|lower }}($payload) {
// You must to implement the logic of your REST Resource here.
// Use current user after pass authentication to validate access.
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
return new {{ state_settings.response_class }}({{ (state == 'DELETE') ? 'NULL' : '$payload' }}, {{ state_settings.http_code }});
}
{% endfor %}
{% endblock %}

View File

@@ -0,0 +1,51 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\RulesAction\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\RulesAction;
{% endblock %}
{% block use_class %}
use Drupal\rules\Core\RulesActionBase;
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{class_name}}' action.
*
* @RulesAction(
* id = "{{plugin_id}}",
* label = @Translation("{{label}}"),
* category = @Translation("{{category}}"),
{% if context %}
* context = {
{% for item in context %}
* "{{ item.name }}" = @ContextDefinition("{{ item.type }}",
* label = @Translation("{{ item.label }}"),
* description = @Translation("{{ item.description }}")
* ),
{% endfor %}
* }
{% endif %}
* )
*/
class {{class_name}} extends RulesActionBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function doExecute($object = NULL) {
// Insert code here.
}
/**
* {@inheritdoc}
*/
public function autoSaveContext() {
// Insert code here.
return [];
}
{% endblock %}

View File

@@ -0,0 +1,34 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
Drupal\{{module}}\Plugin\RulesDataProcessor\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\RulesDataProcessor;
{% endblock %}
{% block use_class %}
use Drupal\Core\Plugin\PluginBase;
use Drupal\rules\Context\DataProcessorInterface;
use Drupal\rules\Engine\ExecutionStateInterface;
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{class_name}}' action.
*
* @RulesDataProcessor(
* id = "{{plugin_id}}",
* label = @Translation("{{label}}")
* )
*/
class {{class_name}} extends PluginBase implements DataProcessorInterface {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function process($value, ExecutionStateInterface $rules_state) {
// Insert code here.
}
{% endblock %}

View File

@@ -0,0 +1,34 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Plugin\Validation\Constraint\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Plugin\Validation\Constraint;
{% endblock %}
{% block use_class %}
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
{% endblock %}
{% block class_declaration %}
/**
* Plugin implementation of the '{{ plugin_id }}'.
*
* @Constraint(
* id = "{{ plugin_id }}",
* label = @Translation("{{ label }}", context = "Validation"),
* )
*/
class {{ class_name }} extends Constraint
{% endblock %}
{% block class_properties %}
// The message that will be shown if the value is empty.
public $isEmpty = '%value is empty';
// The message that will be shown if the value is not unique.
public $notUnique = '%value is not unique';
{% endblock %}

View File

@@ -0,0 +1,47 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Plugin\Validation\Constraint\{{ class_name }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }}\Plugin\Validation\Constraint;
{% endblock %}
{% block use_class %}
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
{% endblock %}
{% block class_declaration %}
/**
* Validates the UniqueInteger constraint.
*/
class {{ class_name }}Validator extends ConstraintValidator
{% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function validate($items, Constraint $constraint) {
foreach ($items as $item) {
// First check if the value is not empty.
if (empty($item->value)) {
// The value is empty, so a violation, aka error, is applied.
// The type of violation applied comes from the constraint description
// in step 1.
$this->context->addViolation($constraint->isEmpty, ['%value' => $item->value]);
}
// Next check if the value is unique.
if (!$this->isUnique($item->value)) {
$this->context->addViolation($constraint->notUnique, ['%value' => $item->value]);
}
}
}
private function isUnique($value) {
// Here is where the check for a unique value would happen.
}
{% endblock %}

View File

@@ -0,0 +1,69 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\views\field\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\views\field;
{% endblock %}
{% block use_class %}
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\Random;
use Drupal\views\Plugin\views\field\FieldPluginBase;
use Drupal\views\ResultRow;
{% endblock %}
{% block class_declaration %}
/**
* A handler to provide a field that is completely custom by the administrator.
*
* @ingroup views_field_handlers
*
* @ViewsField("{{ class_machine_name }}")
*/
class {{ class_name }} extends FieldPluginBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function usesGroupBy() {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function query() {
// Do nothing -- to override the parent query.
}
/**
* {@inheritdoc}
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['hide_alter_empty'] = ['default' => FALSE];
return $options;
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function render(ResultRow $values) {
// Return a random text, here you can include your custom logic.
// Include any namespace required to call the method required to generate
// the desired output.
$random = new Random();
return $random->name();
}
{% endblock %}

View File

@@ -0,0 +1,33 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\migrate\process\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\migrate\process;
{% endblock %}
{% block use_class %}
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{class_name}}' migrate process plugin.
*
* @MigrateProcessPlugin(
* id = "{{plugin_id}}"
* )
*/
class {{class_name}} extends ProcessPluginBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
// Plugin logic goes here.
}
{% endblock %}

View File

@@ -0,0 +1,55 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\migrate\source\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\migrate\source;
{% endblock %}
{% block use_class %}
use Drupal\migrate\Plugin\migrate\source\SqlBase;
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{class_name}}' migrate source.
*
* @MigrateSource(
* id = "{{plugin_id}}",
* source_module = "{{module}}"
* )
*/
class {{class_name}} extends SqlBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function query() {
return $this->select('{{table}}', '{{alias}}')
->fields('{{alias}}')
{% if group_by %}
->groupBy('{{alias}}.{{group_by}}')
{% endif %};
}
/**
* {@inheritdoc}
*/
public function fields() {
$fields = [
{% for field in fields %}
'{{field.id}}' => $this->t('{{field.description}}'),
{% endfor %}
];
return $fields;
}
/**
* {@inheritdoc}
*/
public function getIds() {
return [];
}
{% endblock %}

View File

@@ -0,0 +1,39 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\migrate_plus\data_parser\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Plugin\migrate_plus\data_parser;
{% endblock %}
{% block use_class %}
use Drupal\migrate_plus\DataParserPluginBase;
{% endblock %}
{% block class_declaration %}
/**
* Provides a '{{class_name}}' data parser plugin.
*
* @DataParser(
* id = "{{plugin_id}}"
* title = @Translation("{{plugin_title}}")
* )
*/
class {{class_name}} extends DataParserPluginBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
protected function openSourceUrl($url) {
// Plugin logic goes here.
}
/**
* {@inheritdoc}
*/
protected function fetchNextRow() {
// Plugin logic goes here.
}
{% endblock %}

View File

@@ -0,0 +1,77 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Plugin\{{ plugin }}\{{class_name}}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\{{ namespace }};
{% endblock %}
{% block use_class %}
{% if pluginInterface is not empty %}
use {{ pluginInterface }};
{% endif %}
{% if services is not empty %}
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
{% endif %}
{% endblock %}
{% block use_class_services %}
{% endblock %}
{% block class_declaration %}
{% if pluginAnnotation is not empty %}
/**
* @{{ plugin_annotation }}(
{% for property in pluginAnnotationProperties %}
{% if property.name == 'id' %}
* id = "{{- id }}",
{% elseif property.type == "\\Drupal\\Core\\Annotation\\Translation" %}
* {{ property.name }} = @Translation("{{label}}"),
{% else %}
* {{ property.name }} = "{{ property.type }}",
{% endif %}
{% endfor %}
* )
*/
{% endif %}
class {{class_name}} implements {% if plugin_interface is not empty %}{{ plugin_interface }}{% endif %}{% if services is not empty %}, ContainerFactoryPluginInterface {% endif %}{% endblock %}
{% block class_create %}
{% if services is not empty %}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = new static($configuration, $plugin_id, $plugin_definition);
{{ serviceClassInjectionNoOverride(services) }}
return $instance;
}
{% endif %}
{% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function build() {
$build = [];
// Implement your logic
return $build;
}
{% for method in pluginInterfaceMethods %}
/**
* {@inheritdoc}
*/
{{ method.declaration }} {
}
{% endfor %}
{% endblock %}

View File

@@ -0,0 +1,28 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\Routing\{{ class }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\Routing;
{% endblock %}
{% block use_class %}
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
{% endblock %}
{% block class_declaration %}
/**
* Class {{ class }}.
*
* Listens to the dynamic route events.
*/
class {{ class }} extends RouteSubscriberBase {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
}{% endblock %}

View File

@@ -0,0 +1,56 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\Tests\{{ module }}\FunctionalJavascript\{{ class }}
{% endblock %}
{% block namespace_class %}
namespace Drupal\Tests\{{ module }}\FunctionalJavascript;
{% endblock %}
{% block use_class %}
use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
{% endblock %}
{% block class_declaration %}
/**
* JavaScript tests.
*
* @ingroup {{ module }}
*
* @group {{ module }}
*/
class {{ class }} extends JavaScriptTestBase {% endblock %}
{% block class_methods %}
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['{{ module }}'];
/**
* A user with permission to administer site configuration.
*
* @var \Drupal\user\UserInterface
*/
protected $user;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->user = $this->drupalCreateUser(['administer site configuration']);
$this->drupalLogin($this->user);
}
/**
* Tests that the home page loads with a 200 response.
*/
public function testFrontpage() {
$this->drupalGet(Url::fromRoute('<front>'));
$page = $this->getSession()->getPage();
$this->assertSession()->statusCodeEquals(200);
}
{% endblock %}

View File

@@ -0,0 +1,54 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\Tests\{{ machine_name }}\Functional\LoadTest
{% endblock %}
{% block namespace_class %}
namespace Drupal\Tests\{{ machine_name }}\Functional;
{% endblock %}
{% block use_class %}
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
{% endblock %}
{% block class_declaration %}
/**
* Simple test to ensure that main page loads with module enabled.
*
* @group {{ machine_name }}
*/
class LoadTest extends BrowserTestBase {% endblock %}
{% block class_methods %}
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['{{ machine_name }}'];
/**
* A user with permission to administer site configuration.
*
* @var \Drupal\user\UserInterface
*/
protected $user;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->user = $this->drupalCreateUser(['administer site configuration']);
$this->drupalLogin($this->user);
}
/**
* Tests that the home page loads with a 200 response.
*/
public function testLoad() {
$this->drupalGet(Url::fromRoute('<front>'));
$this->assertSession()->statusCodeEquals(200);
}
{% endblock %}

View File

@@ -0,0 +1,96 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\TwigExtension\{{ class }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\TwigExtension;
{% endblock %}
{% block use_class %}
{% endblock %}
{% block class_declaration %}
/**
* Class {{ class }}.
*/
class {{ class }} extends \Twig_Extension {% endblock %}
{% set properties = services[1:] %}
{% block class_properties %}
{% for service in properties %}
/**
* {{ service.class }} definition.
*
* @var {{ service.short }}
*/
protected ${{service.camel_case_name}};
{% endfor %}
{% endblock %}
{% block class_construct %}
{% if services|length > 1 %}
/**
* Constructs a new {{ class }} object.
*/
public function __construct({{ servicesAsParameters(services)|join(', ') }}) {
parent::__construct($renderer);
{{ serviceClassInitialization(properties) }}
}
{% endif %}
{% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function getTokenParsers() {
return [];
}
/**
* {@inheritdoc}
*/
public function getNodeVisitors() {
return [];
}
/**
* {@inheritdoc}
*/
public function getFilters() {
return [];
}
/**
* {@inheritdoc}
*/
public function getTests() {
return [];
}
/**
* {@inheritdoc}
*/
public function getFunctions() {
return [];
}
/**
* {@inheritdoc}
*/
public function getOperators() {
return [];
}
/**
* {@inheritdoc}
*/
public function getName() {
return '{{ name }}';
}
{% endblock %}

View File

@@ -0,0 +1,134 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\{{ entity_class }}AccessControlHandler.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}};
{% endblock %}
{% block use_class %}
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;
{% endblock %}
{% block class_declaration %}
/**
* Access controller for the {{ label }} entity.
*
* @see \Drupal\{{module}}\Entity\{{ entity_class }}.
*/
class {{ entity_class }}AccessControlHandler extends EntityAccessControlHandler {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** @var \Drupal\{{ module }}\Entity\{{ entity_class }}Interface $entity */
switch ($operation) {
case 'view':
if (!$entity->isPublished()) {
{% if has_bundle_permissions %}
$permission = $this->checkOwn($entity, 'view unpublished', $account);
if (!empty($permission)) {
return AccessResult::allowed();
}
{% endif %}
return AccessResult::allowedIfHasPermission($account, 'view unpublished {{ label|lower }} entities');
}
{% if has_bundle_permissions %}
$permission = $this->checkOwn($entity, $operation, $account);
if (!empty($permission)) {
return AccessResult::allowed();
}
{% endif %}
return AccessResult::allowedIfHasPermission($account, 'view published {{ label|lower }} entities');
case 'update':
{% if has_bundle_permissions %}
$permission = $this->checkOwn($entity, $operation, $account);
if (!empty($permission)) {
return AccessResult::allowed();
}
{% endif %}
return AccessResult::allowedIfHasPermission($account, 'edit {{ label|lower }} entities');
case 'delete':
{% if has_bundle_permissions %}
$permission = $this->checkOwn($entity, $operation, $account);
if (!empty($permission)) {
return AccessResult::allowed();
}
{% endif %}
return AccessResult::allowedIfHasPermission($account, 'delete {{ label|lower }} entities');
}
// Unknown operation, no opinion.
return AccessResult::neutral();
}
/**
* {@inheritdoc}
*/
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
return AccessResult::allowedIfHasPermission($account, 'add {{ label|lower }} entities');
}
{% if has_bundle_permissions %}
/**
* Test for given 'own' permission.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* @param $operation
* @param \Drupal\Core\Session\AccountInterface $account
*
* @return string|null
* The permission string indicating it's allowed.
*/
protected function checkOwn(EntityInterface $entity, $operation, AccountInterface $account) {
$status = $entity->isPublished();
$uid = $entity->getOwnerId();
$is_own = $account->isAuthenticated() && $account->id() == $uid;
if (!$is_own) {
return;
}
$bundle = $entity->bundle();
$ops = [
'create' => '%bundle add own %bundle entities',
'view unpublished' => '%bundle view own unpublished %bundle entities',
'view' => '%bundle view own entities',
'update' => '%bundle edit own entities',
'delete' => '%bundle delete own entities',
];
$permission = strtr($ops[$operation], ['%bundle' => $bundle]);
if ($operation === 'view unpublished') {
if (!$status && $account->hasPermission($permission)) {
return $permission;
}
else {
return NULL;
}
}
if ($account->hasPermission($permission)) {
return $permission;
}
return NULL;
}
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,54 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\{{ class }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}}\CacheContext;
{% endblock %}
{% block use_class %}
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\Context\CacheContextInterface;
{% endblock %}
{% block class_declaration %}
/**
* Class {{ class }}.
*/
class {{ class }} implements CacheContextInterface {% endblock %}
{% block class_construct %}
/**
* Constructs a new {{ class }} object.
*/
public function __construct({{ servicesAsParameters(services)|join(', ') }}) {
{{ serviceClassInitialization(services) }}
}
{% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public static function getLabel() {
\Drupal::messenger()->addMessage('Lable of cache context');
}
/**
* {@inheritdoc}
*/
public function getContext() {
// Actual logic of context variation will lie here.
}
/**
* {@inheritdoc}
*/
public function getCacheableMetadata() {
return new CacheableMetadata();
}
{% endblock %}

View File

@@ -0,0 +1,92 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\Entity\{{ entity_class }}.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }};
{% endblock %}
{% block use_class %}
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\{{ module }}\Entity\{{ entity_class }};
{% endblock %}
{% block class_declaration %}
/**
* Provides dynamic permissions for {{ label }} of different types.
*
* @ingroup {{ module }}
*
*/
class {{ entity_class }}Permissions{% endblock %}
{% block class_methods %}
use StringTranslationTrait;
/**
* Returns an array of node type permissions.
*
* @return array
* The {{ entity_class }} by bundle permissions.
* @see \Drupal\user\PermissionHandlerInterface::getPermissions()
*/
public function generatePermissions() {
$perms = [];
foreach ({{ entity_class }}::loadMultiple() as $type) {
$perms += $this->buildPermissions($type);
}
return $perms;
}
/**
* Returns a list of node permissions for a given node type.
*
* @param \Drupal\{{ module }}\Entity\{{ entity_class }} $type
* The {{ entity_class }} type.
*
* @return array
* An associative array of permission names and descriptions.
*/
protected function buildPermissions({{ entity_class}} $type) {
$type_id = $type->id();
$type_params = ['%type_name' => $type->label()];
return [
"$type_id create entities" => [
'title' => $this->t('Create new %type_name entities', $type_params),
],
"$type_id edit own entities" => [
'title' => $this->t('Edit own %type_name entities', $type_params),
],
"$type_id edit any entities" => [
'title' => $this->t('Edit any %type_name entities', $type_params),
],
"$type_id delete own entities" => [
'title' => $this->t('Delete own %type_name entities', $type_params),
],
"$type_id delete any entities" => [
'title' => $this->t('Delete any %type_name entities', $type_params),
],
{% if revisionable %}
"$type_id view revisions" => [
'title' => $this->t('View %type_name revisions', $type_params),
'description' => t('To view a revision, you also need permission to view the entity item.'),
],
"$type_id revert revisions" => [
'title' => $this->t('Revert %type_name revisions', $type_params),
'description' => t('To revert a revision, you also need permission to edit the entity item.'),
],
"$type_id delete revisions" => [
'title' => $this->t('Delete %type_name revisions', $type_params),
'description' => $this->t('To delete a revision, you also need permission to delete the entity item.'),
],
{% endif %}
];
}
{% endblock %}

View File

@@ -0,0 +1,212 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{ module }}\{{ entity_class }}HtmlRouteProvider.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{ module }};
{% endblock %}
{% block use_class %}
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
use Symfony\Component\Routing\Route;
{% endblock %}
{% block class_declaration %}
/**
* Provides routes for {{ label }} entities.
*
* @see \Drupal\Core\Entity\Routing\AdminHtmlRouteProvider
* @see \Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider
*/
class {{ entity_class }}HtmlRouteProvider extends AdminHtmlRouteProvider {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function getRoutes(EntityTypeInterface $entity_type) {
$collection = parent::getRoutes($entity_type);
$entity_type_id = $entity_type->id();
{% if revisionable %}
if ($history_route = $this->getHistoryRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.version_history", $history_route);
}
if ($revision_route = $this->getRevisionRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.revision", $revision_route);
}
if ($revert_route = $this->getRevisionRevertRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.revision_revert", $revert_route);
}
if ($delete_route = $this->getRevisionDeleteRoute($entity_type)) {
$collection->add("entity.{$entity_type_id}.revision_delete", $delete_route);
}
{% if is_translatable %}
if ($translation_route = $this->getRevisionTranslationRevertRoute($entity_type)) {
$collection->add("{$entity_type_id}.revision_revert_translation_confirm", $translation_route);
}
{% endif %}
{% endif %}
if ($settings_form_route = $this->getSettingsFormRoute($entity_type)) {
$collection->add("$entity_type_id.settings", $settings_form_route);
}
return $collection;
}
{% if revisionable %}
/**
* Gets the version history route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getHistoryRoute(EntityTypeInterface $entity_type) {
if ($entity_type->hasLinkTemplate('version-history')) {
$route = new Route($entity_type->getLinkTemplate('version-history'));
$route
->setDefaults([
'_title' => "{$entity_type->getLabel()} revisions",
'_controller' => '\Drupal\{{ module }}\Controller\{{ entity_class }}Controller::revisionOverview',
])
->setRequirement('_permission', 'view all {{ label|lower }} revisions')
->setOption('_admin_route', TRUE);
return $route;
}
}
/**
* Gets the revision route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getRevisionRoute(EntityTypeInterface $entity_type) {
if ($entity_type->hasLinkTemplate('revision')) {
$route = new Route($entity_type->getLinkTemplate('revision'));
$route
->setDefaults([
'_controller' => '\Drupal\{{ module }}\Controller\{{ entity_class }}Controller::revisionShow',
'_title_callback' => '\Drupal\{{ module }}\Controller\{{ entity_class }}Controller::revisionPageTitle',
])
->setRequirement('_permission', 'view all {{ label|lower }} revisions')
->setOption('_admin_route', TRUE);
return $route;
}
}
/**
* Gets the revision revert route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getRevisionRevertRoute(EntityTypeInterface $entity_type) {
if ($entity_type->hasLinkTemplate('revision_revert')) {
$route = new Route($entity_type->getLinkTemplate('revision_revert'));
$route
->setDefaults([
'_form' => '\Drupal\{{ module }}\Form\{{ entity_class }}RevisionRevertForm',
'_title' => 'Revert to earlier revision',
])
->setRequirement('_permission', 'revert all {{ label|lower }} revisions')
->setOption('_admin_route', TRUE);
return $route;
}
}
/**
* Gets the revision delete route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getRevisionDeleteRoute(EntityTypeInterface $entity_type) {
if ($entity_type->hasLinkTemplate('revision_delete')) {
$route = new Route($entity_type->getLinkTemplate('revision_delete'));
$route
->setDefaults([
'_form' => '\Drupal\{{ module }}\Form\{{ entity_class }}RevisionDeleteForm',
'_title' => 'Delete earlier revision',
])
->setRequirement('_permission', 'delete all {{ label|lower }} revisions')
->setOption('_admin_route', TRUE);
return $route;
}
}
{% if is_translatable %}
/**
* Gets the revision translation revert route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getRevisionTranslationRevertRoute(EntityTypeInterface $entity_type) {
if ($entity_type->hasLinkTemplate('translation_revert')) {
$route = new Route($entity_type->getLinkTemplate('translation_revert'));
$route
->setDefaults([
'_form' => '\Drupal\{{ module }}\Form\{{ entity_class }}RevisionRevertTranslationForm',
'_title' => 'Revert to earlier revision of a translation',
])
->setRequirement('_permission', 'revert all {{ label|lower }} revisions')
->setOption('_admin_route', TRUE);
return $route;
}
}
{% endif %}
{% endif %}
/**
* Gets the settings form route.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
* @return \Symfony\Component\Routing\Route|null
* The generated route, if available.
*/
protected function getSettingsFormRoute(EntityTypeInterface $entity_type) {
if (!$entity_type->getBundleEntityType()) {
$route = new Route("/admin/structure/{$entity_type->id()}/settings");
$route
->setDefaults([
'_form' => 'Drupal\{{ module }}\Form\{{ entity_class }}SettingsForm',
'_title' => "{$entity_type->getLabel()} settings",
])
->setRequirement('_permission', $entity_type->getAdminPermission())
->setOption('_admin_route', TRUE);
return $route;
}
}
{% endblock %}

View File

@@ -0,0 +1,40 @@
{% extends "base/class.php.twig" %}
{% block file_path %}
\Drupal\{{module}}\{{ entity_class }}ListBuilder.
{% endblock %}
{% block namespace_class %}
namespace Drupal\{{module}};
{% endblock %}
{% block use_class %}
use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
use Drupal\Core\Entity\EntityInterface;
{% endblock %}
{% block class_declaration %}
/**
* Provides a listing of {{ label }} entities.
*/
class {{ entity_class }}ListBuilder extends ConfigEntityListBuilder {% endblock %}
{% block class_methods %}
/**
* {@inheritdoc}
*/
public function buildHeader() {
$header['label'] = $this->t('{{ label }}');
$header['id'] = $this->t('Machine name');
return $header + parent::buildHeader();
}
/**
* {@inheritdoc}
*/
public function buildRow(EntityInterface $entity) {
$row['label'] = $entity->label();
$row['id'] = $entity->id();
// You probably want a few more properties here...
return $row + parent::buildRow($entity);
}
{% endblock %}

Some files were not shown because too many files have changed in this diff Show More