...probably
http://rocketeerbkw.github.io/slides/austin-drupal-users-group/developing-for-d8-isnt-hard/
These are my opinions and I may not be right.
I apologize if I get ranty.
Example code here is not complete.
Stop calling Drupal 8 hard!
This "marketing" is turning away people before they get a chance to see to see for themselves.
Everything... and nothing. Major Drupal concepts haven't changed, they've just moved around or have a different interface.
There are some new things to get familiar with too.
function MODULE_block_info() {
$blocks = array();
$blocks['MODULE_block_1'] = array(
'info' => 'Module Block 1',
);
return $blocks;
}
function MODULE_block_view($delta) {
$block = array();
switch ($delta) {
case 'MODULE_block_1';
$block['subject'] = t('Block 1');
$block['content'] = t('Content!');
}
return $block;
}
function MODULE_block_configure() {}
function MODULE_block_save() {}
namespace Drupal\MODULE\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* @Block(
* id = "MODULE_block_1",
* admin_label = @Translation("Module Block 1")
* )
*/
class Block1 extends BlockBase {
public function build() {
return array(
'#markup' => t('Content!');
);
}
}
function blockForm() {}
function blockSubmit() {}
function blockAccess() {}
function defaultConfiguration() {}
... are small pieces of functionality that are swappable.
namespace Drupal\user\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
/**
* @FieldFormatter(
* id = "author",
* label = @Translation("Author"),
* description = @Translation("Display the referenced author user entity."),
* field_types = {
* "entity_reference"
* }
* )
*/
class AuthorFormatter extends FormatterBase {
public function viewElements(FieldItemListInterface $items) {}
public static function isApplicable(FieldDefinitionInterface $field_definition) {}
}
namespace Drupal\user\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* Checks if a user's email address is unique on the site.
*
* @Plugin(
* id = "UserMailUnique",
* label = @Translation("User email unique", context = "Validation")
* )
*/
class UserMailUnique extends Constraint {
public $message = 'The email address %value is already taken.';
public function validatedBy() {}
}
function hook_boot() {
// Do stuff on every page load
}
function hook_init() {
// Do stuff on every non-cached page load
}
services:
MODULE.MODULE_subscriber:
class: Drupal\MODULE\MODULESubscriber
tags:
- { name: 'event_subscriber' }
namespace Drupal\MODULE;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MODULESubscriber implements EventSubscriberInterface {
public function onLoad(GetResponseEvent $event) {
// Do stuff on each page load
}
static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = array('onLoad');
return $events;
}
}
A human friendly data serialization standard for all programming languages.
Replacement for Drupal Arrays of Doom ™. Safer(ish) than moving PHP around.
$view = new view();
$view->name = 'test';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Test';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Test';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '10';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'node';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'test';
uuid: 557e1a08-e34c-488a-8600-c77c496509fb
langcode: en
status: true
dependencies:
module:
- node
- user
id: test
label: Test
module: views
description: ''
tag: ''
base_table: node
base_field: nid
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: perm
options:
perm: 'access content'
cache:
type: none
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: false
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: full
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: '‹ previous'
next: 'next ›'
first: '« first'
last: 'last »'
quantity: 9
style:
type: default
row:
type: 'entity:node'
options:
build_mode: teaser
links: true
view_mode: teaser
rendering_language: translation_language_renderer
fields:
title:
id: title
table: node_field_data
field: title
label: ''
alter:
alter_text: false
make_link: false
absolute: false
trim: false
word_boundary: false
ellipsis: false
strip_tags: false
html: false
hide_empty: false
empty_zero: false
link_to_node: 1
relationship: none
group_type: group
admin_label: ''
exclude: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_alter_empty: true
filters:
status:
value: true
table: node_field_data
field: status
provider: node
id: status
expose:
operator: ''
group: 1
sorts:
created:
id: created
table: node_field_data
field: created
order: DESC
relationship: none
group_type: group
admin_label: ''
exposed: false
expose:
label: ''
granularity: second
title: Test
header: { }
footer: { }
empty: { }
relationships: { }
arguments: { }
field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null
page_1:
display_plugin: page
id: page_1
display_title: Page
position: 1
display_options:
field_langcode: '***LANGUAGE_language_content***'
field_langcode_add_to_query: null
path: test
MODULE.routing.yml
MODULE.dashboard
path: '/MODULE/dashboard'
defaults:
_content: '\Drupal\MODULE\Controller\DashboardController::dashboard'
_title: 'Dashboard'
requirements:
_permission: 'view MODULE dashboard'
namespace Drupal\MODULE\Controller;
Class DashboardController {
public function dashboard() {}
}
books.links.tasks.yml
book.admin:
route_name: book.admin
title: 'Books'
base_route: system.admin_content
book.admin.list:
route_name: book.admin
title: 'List'
parent_id: book.admin
book.settings:
route_name: book.settings
title: 'Settings'
parent_id: book.admin
weight: 8
menu.links.action.yml
menu.menu_add:
route_name: menu.menu_add
title: 'Add menu'
appears_on:
- menu.overview_page
menu.links.contextual.yml
menu.edit:
title: 'Edit menu'
route_name: 'menu.menu_edit'
group: menu
book.links.menu.yml
book.render:
title: 'Books'
route_name: book.render
hidden: 1
function MODULE_settings_form($form, &$form_state) {
$form['MODULE_name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return system_settings_form($form);
}
namespace Drupal\MODULE\Form;
use Drupal\Core\Form\ConfigFormBase;
class MODULESettingsForm extends ConfigFormBase {
public function getFormID() {
return 'MODULE.settings';
}
public function buildForm(array $form, array &$form_state) {
$form['MODULE_name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
);
return parent::buildForm($form, $form_state);
}
public function submitForm(array &$form, &$form_state) {
// Set CMI stuff here
parent::submitForm($form, $form_state);
}
}
@rocketeerbkw
rocketeerbkw@gmail.com
rocketeerbkw.com