





<?php if (isset($block_html_id)): ?>
<div id="<?php print $block_html_id; ?>" <?php print $attributes; ?>>
<?php else: ?>
<div <?php print $attributes; ?>>
<?php endif; ?>
<?php print render($title_prefix); ?>
<?php if ($label): ?>
<h2<?php print $title_attributes; ?>><?php print $label; ?></h2>
<?php endif;?>
<?php print render($title_suffix); ?>
<div<?php print $content_attributes; ?>>
<?php print render($content) ?>
</div>
</div>
<div{{ attributes.addClass(classes) }}>
{{ title_prefix }}
{% if label %}
<h2{{ title_attributes }}>{{ label }}</h2>
{% endif %}
{{ title_suffix }}
<div{{ content_attributes.addClass('content') }}>
{% block content %}
{{ content }}
{% endblock %}
</div>
</div>
$items['admin/structure/types/manage/%node_type'] = array(
'title' => 'Edit content type',
'title callback' => 'node_type_page_title',
'title arguments' => array(4),
'page callback' => 'drupal_get_form',
'page arguments' => array('node_type_form', 4),
'access arguments' => array('administer content types'),
'file' => 'content_types.inc',
'type' => MENU_NORMAL,
);
entity.node_type.edit_form:
path: '/admin/structure/types/manage/{node_type}'
defaults:
_entity_form: 'node_type.edit'
requirements:
_permission: 'administer content types'
node.overview_types:
title: 'Content types'
parent: system.admin_structure
description: 'Manage content types'
route_name: node.overview_types
migrate.migration.d6_user_role.yml
id: d6_user_role
source:
plugin: d6_user_role
process:
id:
-
plugin: machine_name
source: name
-
plugin: dedupe_entity
entity_type: user_role
field: id
-
plugin: user_update_8002
label: name
(...)
destination:
plugin: entity:user_role
/**
* This plugin creates a machine name.
*
* @MigrateProcessPlugin(
* id = "machine_name"
* )
*/
class MachineName extends ProcessPluginBase {
(...)
public function transform($value, MigrateExecutable $migrate_executable, Row $row, $destination_property) {
$new_value = $this->getTransliteration()->transliterate($value, Language::LANGCODE_DEFAULT, '_');
$new_value = strtolower($new_value);
$new_value = preg_replace('/[^a-z0-9_]+/', '_', $new_value);
return preg_replace('/_+/', '_', $new_value);
}
Joe Shindelar, Thursday · 10:45-11:45
abstract class ConfigurableActionBase extends ActionBase
implements ConfigurablePluginInterface, PluginFormInterface {
//
interface ConfigurablePluginInterface {
public function getConfiguration();
public function setConfiguration(array $configuration);
public function defaultConfiguration();
}
//
interface PluginFormInterface {
public function buildConfigurationForm(array $form, array &$form_state);
public function validateConfigurationForm(array &$form, array &$form_state);
public function submitConfigurationForm(array &$form, array &$form_state);
}
$action = entity_create('action', array(
'id' => 'user_add_role_action.' . $role->id(),
'type' => 'user',
'label' => t('Add the @label role to the selected users',
array('@label' => $role->label())),
'configuration' => array(
'rid' => $role->id(),
),
'plugin' => 'user_add_role_action',
));
$action->save();
Simplified version of both email and telephone modules for Drupal 7
id: user.user_picture
status: true
langcode: en
name: user_picture
entity_type: user
type: image
settings:
uri_scheme: public
default_image:
fid: null
module: image
cardinality: 1
translatable: false
dependencies:
module:
- image
- user
id: user.user.user_picture
status: true
langcode: en
entity_type: user
bundle: user
field_name: user_picture
label: Picture
description: 'Your virtual face or picture.'
required: false
default_value: { }
default_value_function: ''
settings:
file_extensions: 'png gif jpg jpeg'
file_directory: pictures
max_filesize: '30 KB'
(..)
field_type: image
dependencies:
entity:
- field.storage.user.user_picture
id: user.user.user_picture status: true langcode: en entity_type: user bundle: userfield_name: user_picturename: user_picture label: Picture description: 'Your virtual face or picture.' required: false default_value: { } default_value_function: '' settings: file_extensions: 'png gif jpg jpeg' file_directory: pictures max_filesize: '30 KB' (..) field_type: image dependencies: entity: - field.storage.user.user_picture
Matt Cheney, David Strauss, Wednesday · 13:00-14:00
Drupal 7 has field_create_field(), field_create_instance(), update, delete and dozens of other field API crud functions and hooks.
$field_storage = entity_create('field_storage_config', array(
'entity_type' => 'node',
'name' => 'field_image',
'type' => 'image',
));
$field->save();
entity_create('field_config', array(
'field_name' => 'field_image',
'entity_type' => 'node',
'label' => 'Image',
'bundle' => 'article',
))->save();
$field = entity_load('field_config', 'node.article.field_image');
$field->cardinality = 3;
$field->settings['foo'] = 'bar';
$field->save();
$field->delete();
+
hook_entity_presave()
hook_entity_delete()
...
id: node.article.default
uuid: 4ac7c6b0-717e-43bd-8b04-4ad1e3f32429
targetEntityType: node
bundle: article
mode: default
content:
body:
label: hidden
type: text_default
settings: { }
field_image:
label: hidden
type: image
settings:
image_style: large
image_link: ''
weight: '-1'
$display = entity_get_display($entity_type, $bundle, $view_mode);
$display->setComponent('body', array(
'type' => 'text_default',
'weight' => 0,
))
-> save();
// During entity_view():
hook_entity_display_alter(EntityDisplay $display);
hook_entity_view(EntityInterface $entity,
EntityDisplay $display);
$options = $display->getComponent('field_image');
If you aren't happy
to see core adding form modes
then we can’t be friends
/**
* @FieldWidget(
* id = "mymodule_widget",
* label = @Translation("My awesome widget"),
* field_types = {
* "text"
* }
* )
*/
class MyWidget extends WidgetBase {
class MyWidget extends WidgetBase {
public function settingsForm(array $form, array &$form_state);
public function formElement(array $items, array &$form, array &$form_state);
public function errorElement(array $element, array $error,
array $form, array &$form_state);
public function massageFormValues(array $values, array $form, array &$form_state);
}
class MyFormatter extends FormatterBase {
public function settingsForm(array $form, array &$form_state);
public function settingsSummary();
public function prepareView(array $entities, $langcode,array &$items);
public function view(EntityInterface $entity, $langcode, array $items);
}
class TextItem extends TextItemBase {
(abstract class TextItemBase extends ConfigFieldItemBase)
public static function schema(Field $field);
public function settingsForm(array $form, array &$form_state);
public function instanceSettingsForm(array $form, array &$form_state);
public function validate() / presave() / delete() ...
Field values are objects
$node->field_tags instanceof FieldInterface
$node->field_tags[0] instanceof FieldItemInterface
Improved Developer experience
$node->body[LANGUAGE_NONE][0]['value']
is now
$node->body->value
// or
$node->body[0]->value
$translation = $node->getTranslation('de');
// Access and update translated fields as usual:
$german_title = $translation->title->value;
$translation->title->value = 'Drupal spricht viele Sprachen!';
$node instanceof NodeInterface
$translation instanceof NodeInterface
$entity->getFieldDefinitions();
foreach ($entity as $field) {
foreach ($field as $field_item) {
$field_item->getPropertyDefinitions();
foreach ($field_item as $item_value) {
$is_string = $item_value instanceof StringInterface;
}
}
}
"Data type" plugins, include
$properties['title'] = array(
'label' => t('Title'),
'description' => t('The title of this node, always treated as non-markup plain text.'),
'type' => 'string_field',
);
Multiple stars, Thursday · 14:15-15:15