.../Field/FieldFormatter/AuthorFormatter.php | 47 ++++++++++ .../Field/FieldFormatter/TimestampFormatter.php | 40 +++++++++ .../Field/Plugin/Field/FieldType/BooleanItem.php | 3 +- .../Field/Plugin/Field/FieldType/CreatedItem.php | 4 +- .../Field/Plugin/Field/FieldType/LanguageItem.php | 1 + .../Field/Plugin/Field/FieldType/TimestampItem.php | 4 +- .../Field/FieldWidget/AuthorAutocompleteWidget.php | 68 ++++++++++++++ .../Plugin/Field/FieldWidget/BooleanWidget.php | 38 ++++++++ .../Plugin/Field/FieldWidget/LanguageWidget.php | 45 ++++++++++ .../FieldWidget/RouteBasedAutocompleteWidget.php | 42 +++++++++ .../Plugin/Field/FieldWidget/TimestampWidget.php | 73 +++++++++++++++ core/modules/datetime/datetime.module | 26 ++---- .../Field/FieldWidget/DateTimeTimestampWidget.php | 63 +++++++++++++ core/modules/node/lib/Drupal/node/Entity/Node.php | 93 +++++++++++++++++--- .../node/lib/Drupal/node/NodeFormController.php | 78 +++++----------- core/modules/node/node.module | 89 ++++++++++--------- core/modules/node/templates/node.html.twig | 6 +- core/modules/rdf/rdf.module | 3 +- .../Plugin/Field/FieldWidget/TextareaWidget.php | 7 +- core/themes/bartik/templates/node.html.twig | 6 +- 20 files changed, 591 insertions(+), 145 deletions(-) diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/AuthorFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/AuthorFormatter.php new file mode 100644 index 0000000..5b5be15 --- /dev/null +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/AuthorFormatter.php @@ -0,0 +1,47 @@ + $item) { + /** @var $referenced_user \Drupal\user\UserInterface */ + if ($referenced_user = $item->entity) { + $elements[$delta] = array( + '#theme' => 'username', + '#account' => $referenced_user, + '#link_options' => array('attributes' => array('rel' => 'author')), + ); + } + } + + return $elements; + } + +} diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php new file mode 100644 index 0000000..6861a00 --- /dev/null +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php @@ -0,0 +1,40 @@ + $item) { + $elements[$delta] = array('#markup' => format_date($item->value)); + } + + return $elements; + } + +} diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php index d674e75..4dc42e4 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/BooleanItem.php @@ -18,7 +18,8 @@ * id = "boolean", * label = @Translation("Boolean"), * description = @Translation("An entity field containing a boolean value."), - * no_ui = TRUE + * no_ui = TRUE, + * default_widget = "boolean", * ) */ class BooleanItem extends FieldItemBase { diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/CreatedItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/CreatedItem.php index 9b2e055..72c0ea9 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/CreatedItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/CreatedItem.php @@ -14,7 +14,9 @@ * id = "created", * label = @Translation("Created"), * description = @Translation("An entity field containing a UNIX timestamp of when the entity has been created."), - * no_ui = TRUE + * no_ui = TRUE, + * default_widget = "timestamp", + * default_formatter = "timestamp", * ) */ class CreatedItem extends TimestampItem { diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php index 9519b8d..838d060 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/LanguageItem.php @@ -21,6 +21,7 @@ * label = @Translation("Language"), * description = @Translation("An entity field referencing a language."), * no_ui = TRUE, + * default_widget = "language", * constraints = { * "ComplexData" = { * "value" = {"Length" = {"max" = 12}} diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php index a2d87a6..db15ea9 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php @@ -18,7 +18,9 @@ * id = "timestamp", * label = @Translation("Timestamp"), * description = @Translation("An entity field containing a UNIX timestamp value."), - * no_ui = TRUE + * no_ui = TRUE, + * default_widget = "timestamp", + * default_formatter = "timestamp", * ) */ class TimestampItem extends FieldItemBase { diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/AuthorAutocompleteWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/AuthorAutocompleteWidget.php new file mode 100644 index 0000000..a331fe6 --- /dev/null +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/AuthorAutocompleteWidget.php @@ -0,0 +1,68 @@ +getOwnerId()? $entity->getOwner()->getUsername() : ''; + + $user_config = \Drupal::config('user.settings'); + $element['value']['#description'] = $this->t('Leave blank for %anonymous.', array('%anonymous' => $user_config->get('anonymous'))); + + $element['value']['#element_validate'] = array(array($this, 'elementValidate')); + + return $element; + } + + /** + * Validates an element. + * + * @todo Convert to massageFormValues() override once that actually works. + */ + public function elementValidate($element, &$form_state, $form) { + $value = $element['#value']; + // The use of empty() is mandatory in the context of usernames + // as the empty string denotes the anonymous user. In case we + // are dealing with an anonymous user we set the user ID to 0. + if (empty($value)) { + $value = 0; + } + else { + $account = user_load_by_name($element['#value']); + if ($account !== FALSE) { + $value = $account->id(); + } + } + form_set_value($element, $value, $form_state); + } + +} diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/BooleanWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/BooleanWidget.php new file mode 100644 index 0000000..66f4d07 --- /dev/null +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/BooleanWidget.php @@ -0,0 +1,38 @@ + 'checkbox', + '#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL, + ); + + return $element; + } + +} diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/LanguageWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/LanguageWidget.php new file mode 100644 index 0000000..01de5a4 --- /dev/null +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/LanguageWidget.php @@ -0,0 +1,45 @@ +invoke('language', 'get_default_configuration', array($entity_type, $entity->getType())); + + $element['value'] = $element + array( + '#type' => 'language_select', + '#default_value' => $entity->getUntranslated()->language()->id, + '#languages' => Language::STATE_ALL, + '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'], + ); + + return $element; + } + +} diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/RouteBasedAutocompleteWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/RouteBasedAutocompleteWidget.php new file mode 100644 index 0000000..0b56e6e --- /dev/null +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/RouteBasedAutocompleteWidget.php @@ -0,0 +1,42 @@ + 'textfield', + '#default_value' => $items[$delta]->value, + '#autocomplete_route_name' => $this->getSetting('route_name'), + ); + + return $element; + } + +} diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/TimestampWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/TimestampWidget.php new file mode 100644 index 0000000..9856ca3 --- /dev/null +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/TimestampWidget.php @@ -0,0 +1,73 @@ +value) ? format_date($items[$delta]->value, 'custom', 'Y-m-d H:i:s O') : ''; + $element['value'] = $element + array( + '#type' => 'textfield', + '#default_value' => $default_value, + '#maxlength' => 25, + '#element_validate' => array( + array($this, 'elementValidate'), + ), + ); + + $timestamp = (int) $items[$delta]->value; + $created_timestamp = (int) $items->getEntity()->getCreatedTime(); + $element['value']['#description'] = $this->t('Format: %time. The date format is YYYY-MM-DD and %timezone is the time zone offset from UTC. Leave blank to use the time of form submission.', array('%time' => !empty($default_value) ? + date_format(date_create($default_value), 'Y-m-d H:i:s O') : format_date($created_timestamp, 'custom', 'Y-m-d H:i:s O'), '%timezone' => !empty($default_value) ? date_format(date_create($default_value), 'O') : format_date($created_timestamp, 'custom', 'O'))); + + return $element; + } + + /** + * Validates an element. + * + * @todo Convert to massageFormValues() override once that actually works. + */ + public function elementValidate($element, &$form_state, $form) { + $value = trim($element['#value']); + if (empty($value)) { + $value = 0; + } + else { + $date = new DrupalDateTime($value); + if ($date->hasErrors()) { + $value = -1; + // $this->setFormError('') + } + else { + $value = $date->getTimestamp(); + } + } + form_set_value($element, $value, $form_state); + } + +} diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module index 3a016b5..9980153 100644 --- a/core/modules/datetime/datetime.module +++ b/core/modules/datetime/datetime.module @@ -986,23 +986,13 @@ function datetime_range_years($string, $date = NULL) { } /** - * Implements hook_form_BASE_FORM_ID_alter() for node forms. + * Implements hook_entity_base_field_info_alter(). */ -function datetime_form_node_form_alter(&$form, &$form_state, $form_id) { - $format_type = datetime_default_format_type(); - - // Alter the 'Authored on' date to use datetime. - $form['created']['#type'] = 'datetime'; - $date_format = entity_load('date_format', 'html_date')->getPattern($format_type); - $time_format = entity_load('date_format', 'html_time')->getPattern($format_type); - $form['created']['#description'] = t('Format: %format. Leave blank to use the time of form submission.', array('%format' => datetime_format_example($date_format . ' ' . $time_format))); - unset($form['created']['#maxlength']); -} - -/** - * Implements hook_node_prepare_form(). - */ -function datetime_node_prepare_form(NodeInterface $node, $operation, array &$form_state) { - // Prepare the 'Authored on' date to use datetime. - $node->date = DrupalDateTime::createFromTimestamp($node->getCreatedTime()); +function datetime_entity_base_field_info_alter(&$fields, \Drupal\Core\Entity\EntityTypeInterface $entity_type) { + if ($entity_type->id() == 'node') { + $fields['created']->setDisplayOptions('form', array( + 'type' => 'datetime_timestamp', + 'weight' => 0, + )); + } } diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DateTimeTimestampWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DateTimeTimestampWidget.php new file mode 100644 index 0000000..a9310ef --- /dev/null +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/Field/FieldWidget/DateTimeTimestampWidget.php @@ -0,0 +1,63 @@ +getPattern($format_type); + $time_format = entity_load('date_format', 'html_time')->getPattern($format_type); + $default_value = isset($items[$delta]->value) ? DrupalDateTime::createFromTimestamp($items[$delta]->value) : ''; + $element['value'] = $element + array( + '#type' => 'datetime', + '#default_value' => $default_value, + '#element_validate' => array( + array($this, 'elementValidate'), + ), + ); + $element['value']['#description'] = $this->t('Format: %format. Leave blank to use the time of form submission.', array('%format' => datetime_format_example($date_format . ' ' . $time_format))); + + return $element; + } + + /** + * Validates an element. + * + * @todo Convert to massageFormValues() override once that actually works. + */ + public function elementValidate($element, &$form_state, $form) { + $date = $element['#value']['object']; + if ($date->hasErrors()) { + $value = -1; + } + else { + $value = $date->getTimestamp(); + } + form_set_value($element, $value, $form_state); + } + +} diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php index 4c971c6..17f55b1 100644 --- a/core/modules/node/lib/Drupal/node/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Entity/Node.php @@ -354,9 +354,15 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setReadOnly(TRUE); $fields['langcode'] = FieldDefinition::create('language') - ->setLabel(t('Language code')) + ->setLabel(t('Language')) ->setDescription(t('The node language code.')) - ->setRevisionable(TRUE); + ->setRevisionable(TRUE) + ->setCardinality(1) + ->setDisplayOptions('form', array( + 'type' => 'language', + 'weight' => 0, + )) + ->setDisplayConfigurable('form', TRUE); $fields['title'] = FieldDefinition::create('string') ->setLabel(t('Title')) @@ -380,23 +386,48 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setDisplayConfigurable('form', TRUE); $fields['uid'] = FieldDefinition::create('entity_reference') - ->setLabel(t('User ID')) + ->setLabel(t('Author')) ->setDescription(t('The user ID of the node author.')) ->setRevisionable(TRUE) + ->setCardinality(1) ->setSettings(array( 'target_type' => 'user', 'default_value' => 0, + )) + ->setDisplayOptions('view', array( + 'label' => 'hidden', + 'type' => 'author', + 'weight' => 0, + )) + ->setDisplayOptions('form', array( + 'type' => 'author_autocomplete', + 'weight' => -1, + 'settings' => array( + 'route_name' => 'user.autocomplete', + ), )); $fields['status'] = FieldDefinition::create('boolean') ->setLabel(t('Publishing status')) ->setDescription(t('A boolean indicating whether the node is published.')) - ->setRevisionable(TRUE); + ->setRevisionable(TRUE) + ->setCardinality(1); $fields['created'] = FieldDefinition::create('created') - ->setLabel(t('Created')) + ->setLabel(t('Publication date')) ->setDescription(t('The time that the node was created.')) - ->setRevisionable(TRUE); + ->setRevisionable(TRUE) + ->setCardinality(1) + ->setDisplayOptions('view', array( + 'label' => 'hidden', + 'type' => 'timestamp', + 'weight' => 0, + )) + ->setDisplayOptions('form', array( + 'type' => 'timestamp', + 'weight' => 0, + )) + ->setDisplayConfigurable('form', TRUE); $fields['changed'] = FieldDefinition::create('changed') ->setLabel(t('Changed')) @@ -404,14 +435,23 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setRevisionable(TRUE); $fields['promote'] = FieldDefinition::create('boolean') - ->setLabel(t('Promote')) - ->setDescription(t('A boolean indicating whether the node should be displayed on the front page.')) - ->setRevisionable(TRUE); + ->setLabel(t('Promoted to front page')) + ->setRevisionable(TRUE) + ->setDisplayOptions('form', array( + 'type' => 'boolean', + 'weight' => -1, + )) + ->setDisplayConfigurable('form', TRUE); $fields['sticky'] = FieldDefinition::create('boolean') - ->setLabel(t('Sticky')) - ->setDescription(t('A boolean indicating whether the node should be displayed at the top of lists in which it appears.')) - ->setRevisionable(TRUE); + ->setLabel(t('Sticky at top of lists')) + ->setRevisionable(TRUE) + ->setCardinality(1) + ->setDisplayOptions('form', array( + 'type' => 'boolean', + 'weight' => 0, + )) + ->setDisplayConfigurable('form', TRUE); $fields['revision_timestamp'] = FieldDefinition::create('timestamp') ->setLabel(t('Revision timestamp')) @@ -429,7 +469,18 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { $fields['log'] = FieldDefinition::create('string') ->setLabel(t('Log')) ->setDescription(t('The log entry explaining the changes in this revision.')) - ->setRevisionable(TRUE); + ->setLabel(t('Revision log message')) + ->setCardinality(1) + ->setDescription(t('Briefly describe the changes you have made.')) + ->setRevisionable(TRUE) + ->setDisplayOptions('form', array( + 'type' => 'text_textarea', + 'weight' => 0, + 'settings' => array( + 'rows' => 4, + ), + )) + ->setDisplayConfigurable('form', TRUE); return $fields; } @@ -444,6 +495,22 @@ public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $fields['title'] = clone $base_field_definitions['title']; $fields['title']->setLabel($node_type->title_label); } + + // Set a widget for the 'langcode' base field if Language module is enabled + // and the bundle has multilingual support. + if (\Drupal::moduleHandler()->moduleExists('language')) { + foreach (node_type_get_types() as $bundle) { + $configuration = language_get_default_configuration('node', $bundle->type); + if ($configuration['language_show']) { + $fields['langcode'] = clone $base_field_definitions['langcode']; + $fields['langcode']->setDisplayOptions('form', array( + 'type' => 'language', + 'weight' => 0, + )); + } + } + } + return $fields; } diff --git a/core/modules/node/lib/Drupal/node/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php index 672c8ef..fb05d6b 100644 --- a/core/modules/node/lib/Drupal/node/NodeFormController.php +++ b/core/modules/node/lib/Drupal/node/NodeFormController.php @@ -46,7 +46,6 @@ protected function prepareEntity() { } } else { - $node->date = format_date($node->getCreatedTime(), 'custom', 'Y-m-d H:i:s O'); // Remove the log message from the original node entity. $node->log = NULL; } @@ -61,6 +60,8 @@ public function form(array $form, array &$form_state) { /** @var \Drupal\node\NodeInterface $node */ $node = $this->entity; + $form = parent::form($form, $form_state, $node); + if ($this->operation == 'edit') { $form['#title'] = $this->t('Edit @type @title', array('@type' => node_get_type_label($node), '@title' => $node->label())); } @@ -87,15 +88,6 @@ public function form(array $form, array &$form_state) { '#default_value' => $node->getChangedTime(), ); - $language_configuration = \Drupal::moduleHandler()->invoke('language', 'get_default_configuration', array('node', $node->getType())); - $form['langcode'] = array( - '#title' => t('Language'), - '#type' => 'language_select', - '#default_value' => $node->getUntranslated()->language()->id, - '#languages' => Language::STATE_ALL, - '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'], - ); - $form['advanced'] = array( '#type' => 'vertical_tabs', '#attributes' => array('class' => array('entity-meta')), @@ -126,14 +118,12 @@ public function form(array $form, array &$form_state) { '#default_value' => $node->isNewRevision(), '#access' => $node->isNewRevision() || user_access('administer nodes'), '#group' => 'revision_information', + // Ensure the 'Create new revision' checkbox sits above the revision log + // message. + '#weight' => -1, ); - $form['log'] = array( - '#type' => 'textarea', - '#title' => t('Revision log message'), - '#rows' => 4, - '#default_value' => !empty($node->log->value) ? $node->log->value : '', - '#description' => t('Briefly describe the changes you have made.'), + $form['log'] += array( '#states' => array( 'visible' => array( ':input[name="revision"]' => array('checked' => TRUE), @@ -164,26 +154,17 @@ public function form(array $form, array &$form_state) { '#optional' => TRUE, ); - $form['uid'] = array( - '#type' => 'textfield', - '#title' => t('Authored by'), - '#maxlength' => 60, - '#autocomplete_route_name' => 'user.autocomplete', - '#default_value' => $node->getOwnerId()? $node->getOwner()->getUsername() : '', - '#weight' => -1, - '#description' => t('Leave blank for %anonymous.', array('%anonymous' => $user_config->get('anonymous'))), + $form['uid'] += array( '#group' => 'author', '#access' => user_access('administer nodes'), ); - $form['created'] = array( - '#type' => 'textfield', - '#title' => t('Authored on'), - '#maxlength' => 25, - '#description' => t('Format: %time. The date format is YYYY-MM-DD and %timezone is the time zone offset from UTC. Leave blank to use the time of form submission.', array('%time' => !empty($node->date) ? date_format(date_create($node->date), 'Y-m-d H:i:s O') : format_date($node->getCreatedTime(), 'custom', 'Y-m-d H:i:s O'), '%timezone' => !empty($node->date) ? date_format(date_create($node->date), 'O') : format_date($node->getCreatedTime(), 'custom', 'O'))), - '#default_value' => !empty($node->date) ? $node->date : '', + $form['uid']['widget'][0]['value']['#title'] = $this->t('Authored by'); + + $form['created'] += array( '#group' => 'author', '#access' => user_access('administer nodes'), ); + $form['created']['widget'][0]['value']['#title'] = $this->t('Authored on'); // Node options for administrators. $form['options'] = array( @@ -200,23 +181,17 @@ public function form(array $form, array &$form_state) { '#optional' => TRUE, ); - $form['promote'] = array( - '#type' => 'checkbox', - '#title' => t('Promoted to front page'), - '#default_value' => $node->isPromoted(), + $form['promote'] += array( '#group' => 'options', '#access' => user_access('administer nodes'), ); - $form['sticky'] = array( - '#type' => 'checkbox', - '#title' => t('Sticky at top of lists'), - '#default_value' => $node->isSticky(), + $form['sticky'] += array( '#group' => 'options', '#access' => user_access('administer nodes'), ); - return parent::form($form, $form_state, $node); + return $form; } /** @@ -310,17 +285,12 @@ public function validate(array $form, array &$form_state) { } // Validate the "authored by" field. - if (!empty($form_state['values']['uid']) && !($account = user_load_by_name($form_state['values']['uid']))) { - // The use of empty() is mandatory in the context of usernames - // as the empty string denotes the anonymous user. In case we - // are dealing with an anonymous user we set the user ID to 0. - $this->setFormError('uid', $form_state, $this->t('The username %name does not exist.', array('%name' => $form_state['values']['uid']))); + if (!is_numeric($form_state['values']['uid'][0]['value'])) { + $this->setFormError('uid', $form_state, $this->t('The username %name does not exist.', array('%name' => $form_state['values']['uid'][0]['value']))); } // Validate the "authored on" field. - // The date element contains the date object. - $date = $node->date instanceof DrupalDateTime ? $node->date : new DrupalDateTime($node->date); - if ($date->hasErrors()) { + if ($form_state['values']['created'][0]['value'] < 0) { $this->setFormError('date', $form_state, $this->t('You have to specify a valid date.')); } @@ -418,17 +388,11 @@ public function unpublish(array $form, array &$form_state) { public function buildEntity(array $form, array &$form_state) { /** @var \Drupal\node\NodeInterface $entity */ $entity = parent::buildEntity($form, $form_state); - // A user might assign the node author by entering a user name in the node - // form, which we then need to translate to a user ID. - if (!empty($form_state['values']['uid']) && $account = user_load_by_name($form_state['values']['uid'])) { - $entity->setOwnerId($account->id()); - } - else { - $entity->setOwnerId(0); - } - if (!empty($form_state['values']['created']) && $form_state['values']['created'] instanceOf DrupalDateTime) { - $entity->setCreatedTime($form_state['values']['created']->getTimestamp()); + $entity->setOwnerId($form_state['values']['uid'][0]['value']); + + if ($form_state['values']['created'][0]['value'] >= 0) { + $entity->setCreatedTime($form_state['values']['created'][0]['value']); } else { $entity->setCreatedTime(REQUEST_TIME); diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 0c0c99d..29c4797 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -172,6 +172,12 @@ function node_theme() { 'field__node__title' => array( 'base hook' => 'field', ), + 'field__node__uid' => array( + 'base hook' => 'field', + ), + 'field__node__created' => array( + 'base hook' => 'field', + ), ); } @@ -445,40 +451,6 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') { } /** - * Implements hook_field_extra_fields(). - */ -function node_field_extra_fields() { - $extra = array(); - $module_language_enabled = \Drupal::moduleHandler()->moduleExists('language'); - $description = t('Node module element'); - - foreach (node_type_get_types() as $bundle) { - // Add the 'language' select if Language module is enabled and the bundle - // has multilingual support. - // Visibility of the ordering of the language selector is the same as on the - // node/add form. - if ($module_language_enabled) { - $configuration = language_get_default_configuration('node', $bundle->type); - if ($configuration['language_show']) { - $extra['node'][$bundle->type]['form']['langcode'] = array( - 'label' => t('Language'), - 'description' => $description, - 'weight' => 0, - ); - } - } - $extra['node'][$bundle->type]['display']['langcode'] = array( - 'label' => t('Language'), - 'description' => $description, - 'weight' => 0, - 'visible' => FALSE, - ); - } - - return $extra; -} - -/** * Updates all nodes of one type to be of another type. * * @param string $old_id @@ -636,14 +608,9 @@ function template_preprocess_node(&$variables) { $variables['node'] = $variables['elements']['#node']; /** @var \Drupal\node\NodeInterface $node */ $node = $variables['node']; - - $variables['date'] = format_date($node->getCreatedTime()); - $username = array( - '#theme' => 'username', - '#account' => $node->getOwner(), - '#link_options' => array('attributes' => array('rel' => 'author')), - ); - $variables['name'] = drupal_render($username); + $variables['date'] = drupal_render($variables['elements']['created'], TRUE); + unset($variables['elements']['created']); + $variables['name'] = drupal_render($variables['elements']['uid'], TRUE); $variables['node_url'] = $node->url(); $variables['label'] = $variables['elements']['title']; @@ -703,9 +670,9 @@ function template_preprocess_node(&$variables) { } /** - * Returns HTML for the node title field. + * Returns HTML for the node 'title' field. * - * This is an override of theme_field() for the node title field. See that + * This is an override of theme_field() for the node 'title' field. See that * function for documentation about its details and overrides. * * @param array $variables @@ -720,6 +687,40 @@ function theme_field__node__title($variables) { } /** + * Returns HTML for the node 'uid' field. + * + * This is an override of theme_field() for the node 'uid' field. See that + * function for documentation about its details and overrides. + * + * @param array $variables + * An associative array. See theme_field() for details. + * + * @see theme_field() + * + * @ingroup themeable + */ +function theme_field__node__uid($variables) { + return '' . drupal_render($variables['items']) . ''; +} + +/** + * Returns HTML for the node 'created' field. + * + * This is an override of theme_field() for the node 'created' field. See that + * function for documentation about its details and overrides. + * + * @param array $variables + * An associative array. See theme_field() for details. + * + * @see theme_field() + * + * @ingroup themeable + */ +function theme_field__node__created($variables) { + return '' . drupal_render($variables['items']) . ''; +} + +/** * Implements hook_permission(). */ function node_permission() { diff --git a/core/modules/node/templates/node.html.twig b/core/modules/node/templates/node.html.twig index 5bf5ad9..720fae5 100644 --- a/core/modules/node/templates/node.html.twig +++ b/core/modules/node/templates/node.html.twig @@ -21,10 +21,8 @@ * {{ content|without('field_example') %} to temporarily suppress the printing * of a given child element. * - user_picture: The node author's picture from user-picture.html.twig. - * - date: Formatted creation date. Preprocess functions can reformat it by - * calling format_date() with the desired parameters on - * $variables['created']. - * - name: Themed username of node author output from theme_username(). + * - date: Themed creation date field. + * - name: Themed author date field. * - node_url: Direct URL of the current node. * - display_submitted: Whether submission information should be displayed. * - submitted: Submission information created from name and date during diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module index 6bf0e10..df76a9b 100644 --- a/core/modules/rdf/rdf.module +++ b/core/modules/rdf/rdf.module @@ -215,7 +215,8 @@ function rdf_entity_prepare_view($entity_type, array $entities, array $displays) $field_mapping = $mapping->getPreparedFieldMapping($name); if ($field_mapping['properties']) { foreach ($entity->get($name) as $item) { - $item->_attributes += rdf_rdfa_attributes($field_mapping, $item->getValue()); + $value = ($entity->getFieldDefinition($name)->isMultiple()) ? $item->getValue() : $entity->get($name)->value; + $item->_attributes += rdf_rdfa_attributes($field_mapping, $value); } } } diff --git a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWidget.php b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWidget.php index 3c57008..7785369 100644 --- a/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWidget.php +++ b/core/modules/text/lib/Drupal/text/Plugin/Field/FieldWidget/TextareaWidget.php @@ -18,7 +18,12 @@ * id = "text_textarea", * label = @Translation("Text area (multiple rows)"), * field_types = { - * "text_long" + * "text_long", + * "string", + * }, + * settings = { + * "rows" = "5", + * "placeholder" = "" * } * ) */ diff --git a/core/themes/bartik/templates/node.html.twig b/core/themes/bartik/templates/node.html.twig index e61bd9c..efd3245 100644 --- a/core/themes/bartik/templates/node.html.twig +++ b/core/themes/bartik/templates/node.html.twig @@ -21,10 +21,8 @@ * {{ content|without('field_example') }} to exclude the printing of a * given child element. * - user_picture: The node author's picture from user-picture.html.twig. - * - date: Formatted creation date. Preprocess functions can reformat it by - * calling format_date() with the desired parameters on - * $variables['created']. - * - name: Themed username of node author output from theme_username(). + * - date: Themed creation date field. + * - name: Themed author date field. * - node_url: Direct URL of the current node. * - display_submitted: Whether submission information should be displayed. * - submitted: Submission information created from name and date during