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
|  | 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) | 
| D7 | D8 | |
|---|---|---|
| total | 320,236 | 1’175,492 | 
| core | 320,236 | 807,409 (~68%) | 
| vendor | - | 368,083 (~32%) | 
|  | D7 en 7.29-17-g3310afe. | 
| D7 | D8 | |
|---|---|---|
| total | 652 | 6,127 | 
| core tests | 562 (~86%) | 1,376 (~22%) | 
| vendor | - | 2,465 (~40%) | 
| otras | 90 (~14%) | 2,286 (~37%) | 
| D7 | D8 | |
|---|---|---|
| total | 18 | 628 | 
| vendor | 0 | 269 (~43%) | 
| otras | 18 | 359 (~57%) | 
\o/
|  | hooks vs event listeners | 
ver estructura ej. syslog, telephone
|  | PSR-4 vs PSR-0/modules/my_module/lib/Drupal/my_module/Entity/MyEntity.php vs /modules/my_module/src/Entity/MyEntity.php | 
| Javascript | 
 | 
| CSS | 
 | 
<?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" * } * ) */
<?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; }
<?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 {
hook_entity_base_field_info{,_alter}(); hook_entity_bundle_field_info{,_alter}(); hook_entity_field_storage_info{,_alter}();
/**
 * 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',
    ),
  );
}<?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; } }
<?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'), ), ), ); } }
<?php drupal_add_css(drupal_get_path('module', 'example') . '/css/example.css');
<?php $example = array( '#attached' => array( 'css' => array( drupal_get_path('module', 'example') . '/css/example.css' => array(), ), ), );
<?php drupal_add_js(drupal_get_path('module', 'example') . '/example.js');
<?php $example = array( '#attached' => array( 'js' => array( drupal_get_path('module', 'example') . '/js/example.js' => array(), ), ), );
<?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'), ), );
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
<?php drupal_add_library('example', 'drag-and-drop');
<?php $example = array( '#attached' => array( 'library' => array( 'example/drag-and-drop', ), ), );
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