Drupal 8 logo
Licencia

Esta presentación está bajo una Licencia Creative Commons Atribución 3.0 Unported.
Para ver una copia de la licencia, visite http://creativecommons.org/licenses/by/3.0/deed.es
Julio 2014

Important Drupal 8.x está aún en desarrollo.
Todo lo incluído en esta presentación podría cambiar/eliminarse antes de la versión estable.
(8.0-alpha13-344-g9b274e1)

Introducción (1/4)

Drupal 7 LOC
Figure 1. D7
Drupal 8 LOC
Figure 2. D8
Table 1. Líneas de código (LoC)
D7 D8

total

320,236

1’175,492

core

320,236

807,409 (~68%)

vendor

-

368,083 (~32%)

Note D7 en 7.29-17-g3310afe.

Introducción (2/4)

Drupal 7 classes
Figure 3. D7
Drupal 8 classes
Figure 4. D8
Table 2. Clases
D7 D8

total

652

6,127

core tests

562 (~86%)

1,376 (~22%)

vendor

-

2,465 (~40%)

otras

90 (~14%)

2,286 (~37%)

Introducción (3/4)

Drupal 7 interfaces
Figure 5. D7
Drupal 8 interfaces
Figure 6. D8
Table 3. Interfaces
D7 D8

total

18

628

vendor

0

269 (~43%)

otras

18

359 (~57%)

Introducción (3/4)

Cambio de paradigmas

Agrupando

Iniciativas

Iniciativas: Configuration Management (CMI)

Iniciativas: HTML5

Iniciativas: Layouts

Iniciativas: Mobile

Iniciativas: Multilingual

Iniciativas: Views in Core

\o/

Iniciativas: Web Services

Cambios en módulos

Cambios en módulos: reubicación

Cambios en módulos: nueva funcionalidad

Cambios en módulos: nuevos campos

Cambios en módulos: eliminados

Cambios en temas

Generales

Generales: Orientación a objetos

Generales: Términos

symfony
Note hooks vs event listeners

Generales: Estructura de ficheros

ver estructura ej. syslog, telephone

Note
PSR-4 vs PSR-0
/modules/my_module/lib/Drupal/my_module/Entity/MyEntity.php vs
/modules/my_module/src/Entity/MyEntity.php

Generales: Nuevas librerías php (1/2)

Adopted projects
Figure 7. Adopción

Generales: Nuevas librerías php (2/2)

Generales: Nuevas librerías assets

Javascript
  • foo
CSS
  • backbone
  • ckeditor
  • domready
  • farbtastic
  • html5shiv
  • jquery 2.0.3
  • jquery-bbq
  • jquery-form
  • jquery-once
  • jquery.ui 1.10.2
  • modernizr
  • normalize-css
  • underscore
  • libricons
  • joyride (tour)
  • js a11y: Drupal.announce()
  • jquery-ui-touch-punch

Generales: Symfony components

Generales: APIs, anotaciones

Anotación, ej. en plugins para definir entidades (no más hook_info's)
<?php
/**
 * Defines the file entity class.
 *
 * @ContentEntityType(
 *   id = "file",
 *   label = @Translation("File"),
 *   controllers = {
 *     "storage" = "Drupal\file\FileStorage",
 *     "access" = "Drupal\file\FileAccessController",
 *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder"
 *   },
 *   base_table = "file_managed",
 *   entity_keys = {
 *     "id" = "fid",
 *     "label" = "filename",
 *     "uuid" = "uuid"
 *   }
 * )
 */

Generales: APIs, EntityNG

Generales: APIS, EntityNG D7 node

D7
<?php
/**
 * Implements hook_entity_info().
 */
function user_entity_info() {
  $return = array(
    'user' => array(
      'label' => t('User'),
      'controller class' => 'UserController',
      'base table' => 'users',
      'uri callback' => 'user_uri',
      'label callback' => 'format_username',
      'fieldable' => TRUE,
      // $user->language is only the preferred user language for the user
      // interface textual elements. As it is not necessarily related to the
      // language assigned to fields, we do not define it as the entity language
      // key.
      'entity keys' => array(
        'id' => 'uid',
      ),
      'bundles' => array(
        'user' => array(
          'label' => t('User'),
          'admin' => array(
            'path' => 'admin/config/people/accounts',
            'access arguments' => array('administer users'),
          ),
        ),
      ),
      'view modes' => array(
        'full' => array(
          'label' => t('User account'),
          'custom settings' => FALSE,
        ),
      ),
    ),
  );
  return $return;
}

Generales: APIS, EntityNG D8 node

D8 entity definition: \Drupal\user\Entity\User
<?php
/**
 * Defines the user entity class.
 *
 * The base table name here is plural, despite Drupal table naming standards,
 * because "user" is a reserved word in many databases.
 *
 * @ContentEntityType(
 *   id = "user",
 *   label = @Translation("User"),
 *   controllers = {
 *     "storage" = "Drupal\user\UserStorage",
 *     "access" = "Drupal\user\UserAccessController",
 *     "list_builder" = "Drupal\user\UserListBuilder",
 *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
 *     "form" = {
 *       "default" = "Drupal\user\ProfileForm",
 *       "cancel" = "Drupal\user\Form\UserCancelForm",
 *       "register" = "Drupal\user\RegisterForm"
 *     },
 *     "translation" = "Drupal\user\ProfileTranslationHandler"
 *   },
 *   admin_permission = "administer user",
 *   base_table = "users",
 *   label_callback = "user_format_name",
 *   fieldable = TRUE,
 *   translatable = TRUE,
 *   entity_keys = {
 *     "id" = "uid",
 *     "uuid" = "uuid"
 *   },
 *   links = {
 *     "canonical" = "user.view",
 *     "edit-form" = "user.edit",
 *     "admin-form" = "user.account_settings",
 *     "cancel-form" = "user.cancel"
 *   }
 * )
 */
class User extends ContentEntityBase implements UserInterface {

Generales: APIs, campos

hook_entity_base_field_info{,_alter}(); hook_entity_bundle_field_info{,_alter}(); hook_entity_field_storage_info{,_alter}();

Generales: APIs, campos, number d7

D7 number
/**
 * Implements hook_field_schema().
 */
function number_field_schema($field) {
  switch ($field['type']) {
    case 'number_integer' :
      $columns = array(
        'value' => array(
          'type' => 'int',
          'not null' => FALSE
        ),
      );
      break;

    case 'number_float' :
      $columns = array(
        'value' => array(
          'type' => 'float',
          'not null' => FALSE
        ),
      );
      break;

    case 'number_decimal' :
      $columns = array(
        'value' => array(
          'type' => 'numeric',
          'precision' => $field['settings']['precision'],
          'scale' => $field['settings']['scale'],
          'not null' => FALSE
        ),
      );
      break;
  }
  return array(
    'columns' => $columns,
  );
}

/**
 * Implements hook_field_info().
 */
function number_field_info() {
  return array(
    'number_integer' => array(
      'label' => t('Integer'),
      'description' => t('This field stores a number in the database as an integer.'),
      'instance_settings' => array('min' => '', 'max' => '', 'prefix' => '', 'suffix' => ''),
      'default_widget' => 'number',
      'default_formatter' => 'number_integer',
    ),
    'number_decimal' => array(
      'label' => t('Decimal'),
      'description' => t('This field stores a number in the database in a fixed decimal format.'),
      'settings' => array('precision' => 10, 'scale' => 2, 'decimal_separator' => '.'),
      'instance_settings' => array('min' => '', 'max' => '', 'prefix' => '', 'suffix' => ''),
      'default_widget' => 'number',
      'default_formatter' => 'number_decimal',
    ),
    'number_float' => array(
      'label' => t('Float'),
      'description' => t('This field stores a number in the database in a floating point format.'),
      'settings' => array('decimal_separator' => '.'),
      'instance_settings' => array('min' => '', 'max' => '', 'prefix' => '', 'suffix' => ''),
      'default_widget' => 'number',
      'default_formatter' => 'number_decimal',
    ),
  );
}

Generales: APIs, campos, number d8

Typed data: \Drupal\Core\TypedData\Plugin\DataType\Integer
<?php
/**
 * The integer data type.
 *
 * The plain value of an integer is a regular PHP integer. For setting the value
 * any PHP variable that casts to an integer may be passed.
 *
 * @DataType(
 *   id = "integer",
 *   label = @Translation("Integer")
 * )
 */
class Integer extends PrimitiveBase implements IntegerInterface {

  /**
   * {@inheritdoc}
   */
  public function getCastedValue() {
    return (int) $this->value;
  }
}
Field definition \Drupal\Core\Field\Plugin\Field\FieldType\IntegerItem
<?php
/**
 * Defines the 'integer' field type.
 *
 * @FieldType(
 *   id = "integer",
 *   label = @Translation("Number (integer)"),
 *   description = @Translation("This field stores a number in the database as an integer."),
 *   default_widget = "number",
 *   default_formatter = "number_integer"
 * )
 */
class IntegerItem extends NumericItemBase {

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return array(
      'unsigned' => FALSE,
    ) + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultInstanceSettings() {
    return array(
      'min' => '',
      'max' => '',
      'prefix' => '',
      'suffix' => '',
      // Valid size property values include: 'tiny', 'small', 'medium', 'normal'
      // and 'big'.
      'size' => 'normal',
    ) + parent::defaultInstanceSettings();
  }

  /**
   * {@inheritdoc}
   */
  public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
    $properties['value'] = DataDefinition::create('integer')
      ->setLabel(t('Integer value'));

    return $properties;
  }

  /**
   * {@inheritdoc}
   */
  public function getConstraints() {
    $constraints = parent::getConstraints();

    // If this is an unsigned integer, add a validation constraint for the
    // integer to be positive.
    if ($this->getSetting('unsigned')) {
      $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
      $constraints[] = $constraint_manager->create('ComplexData', array(
        'value' => array(
          'Range' => array(
            'min' => 0,
            'minMessage' => t('%name: The integer must be larger or equal to %min.', array(
              '%name' => $this->getFieldDefinition()->getLabel(),
              '%min' => 0,
            )),
          ),
        ),
      ));
    }

    return $constraints;
  }

  /**
   * {@inheritdoc}
   */
  public static function schema(FieldStorageDefinitionInterface $field_definition) {
    return array(
      'columns' => array(
        'value' => array(
          'type' => 'int',
          'not null' => FALSE,
          // Expose the 'unsigned' setting in the field item schema.
          'unsigned' => $field_definition->getSetting('unsigned'),
          // Expose the 'size' setting in the field item schema. For instance,
          // supply 'big' as a value to produce a 'bigint' type.
          'size' => $field_definition->getSetting('size'),
        ),
      ),
    );
  }

}

Plugins

ejemplos:

Twig

Migrate

Assets: agregar css

Agregar css D7
<?php
drupal_add_css(drupal_get_path('module', 'example') . '/css/example.css');
Agregar css D8
<?php
$example = array(
  '#attached' => array(
    'css' => array(
      drupal_get_path('module', 'example') . '/css/example.css' => array(),
    ),
  ),
);

Assets: agregar js

Agregar js D7
<?php
drupal_add_js(drupal_get_path('module', 'example') . '/example.js');
Agregar js D8
<?php
$example = array(
  '#attached' => array(
    'js' => array(
      drupal_get_path('module', 'example') . '/js/example.js' => array(),
    ),
  ),
);

Assets: declarar js

Declarar librería D7
<?php
  // jQuery Form Plugin.
  $libraries['jquery.form'] = array(
    'title' => 'jQuery Form Plugin',
    'website' => 'http://malsup.com/jquery/form/',
    'version' => '3.39',
    'js' => array(
      'core/assets/vendor/jquery-form/jquery.form.js' => array(),
    ),
    'dependencies' => array(
      array('system', 'jquery'),
      array('system', 'jquery.cookie'),
    ),
  );
Declarar librería D8 (YAML), i.e. <module_name>.libraries.yml
jquery.form:
  remote: https://github.com/malsup/form
  version: 3.39
  js:
    assets/vendor/jquery-form/jquery.form.js: {}
  dependencies:
    - core/jquery
    - core/jquery.cookie
Agregar librería D7
<?php
drupal_add_library('example', 'drag-and-drop');
Agregar librería D8
<?php
$example = array(
  '#attached' => array(
    'library' => array(
      'example/drag-and-drop',
    ),
  ),
);

Otros

Generales: UI

Referencias

From Not-Invented-Here to Proudly-Found-Elsewhere: A Drupal 8 Story, por Alex Pott, alexpott.
DrupalCon Prague 2013
https://prague2013.drupal.org/session/not-invented-here-proudly-found-elsewhere-drupal-8-story

Upgrading your modules to Drupal 8, por Alex Bronstein, effulgentsia.
DrupalCon Portland 2013
https://portland2013.drupal.org/session/upgrading-your-modules-drupal-8

Upgrading your modules to Drupal 8, por Angie Byron, webchick.
DrupalCon Sydney 2013
http://sydney2013.drupal.org/program/core-conversations

Drupal 8 Entity API, por Wolfgang Ziegler, fago.
DrupalCon Austin 2014
https://austin2014.drupal.org/session/drupal-8-entity-api

30 Drupal 8 API Functions You Should Already Know, por Fredric Mitchell, fmitchell.
DrupalCon Austin 2014
https://austin2014.drupal.org/session/30-drupal-8-api-functions-you-should-already-know

Lista de cambios en drupal core
https://drupal.org/list-changes/drupal