diff --git a/core/modules/block_content/src/BlockContentViewsData.php b/core/modules/block_content/src/BlockContentViewsData.php
index 3cd4a39..09d49b7 100644
--- a/core/modules/block_content/src/BlockContentViewsData.php
+++ b/core/modules/block_content/src/BlockContentViewsData.php
@@ -28,18 +28,6 @@ public function getViewsData() {
 
     $data['block_content_field_data']['type']['field']['id'] = 'field';
 
-    // @todo Figure out the way to integrate this automatic in
-    //   content_translation https://www.drupal.org/node/2410261.
-    if ($this->moduleHandler->moduleExists('content_translation')) {
-      $data['block_content']['translation_link'] = array(
-        'title' => $this->t('Translation link'),
-        'help' => $this->t('Provide a link to the translations overview for custom blocks.'),
-        'field' => array(
-          'id' => 'content_translation_link',
-        ),
-      );
-    }
-
     // Advertise this table as a possible base table.
     $data['block_content_revision']['table']['base']['help'] = $this->t('Block Content revision is a history of changes to block content.');
     $data['block_content_revision']['table']['base']['defaults']['title'] = 'info';
diff --git a/core/modules/comment/config/schema/comment.views.schema.yml b/core/modules/comment/config/schema/comment.views.schema.yml
index ed3f70b..606af82 100644
--- a/core/modules/comment/config/schema/comment.views.schema.yml
+++ b/core/modules/comment/config/schema/comment.views.schema.yml
@@ -20,33 +20,10 @@ views.field.comment_last_timestamp:
   type: views.field.date
   label: 'Last comment date'
 
-views.field.comment_link:
-  type: views_field
-  label: 'Comment link'
-  mapping:
-    text:
-      type: views_field
-      label: 'Text to display'
-    link_to_entity:
-      type: views_field
-      label: 'Link field to the entity if there is no comment'
-
 views.field.comment_link_approve:
   type: views.field.comment_link
   label: 'Comment approve link'
 
-views.field.comment_link_delete:
-  type: views.field.comment_link
-  label: 'Comment delete link'
-
-views.field.comment_link_edit:
-  type: views.field.comment_link
-  label: 'Comment edit link'
-  mapping:
-    destination:
-      type: boolean
-      label: 'Use destination'
-
 views.field.comment_link_reply:
   type: views.field.comment_link
   label: 'Comment reply link'
diff --git a/core/modules/comment/src/CommentViewsData.php b/core/modules/comment/src/CommentViewsData.php
index e853a58..c70f77f 100644
--- a/core/modules/comment/src/CommentViewsData.php
+++ b/core/modules/comment/src/CommentViewsData.php
@@ -102,30 +102,6 @@ public function getViewsData() {
     $data['comment_field_data']['status']['filter']['label'] = t('Approved comment status');
     $data['comment_field_data']['status']['filter']['type'] = 'yes-no';
 
-    $data['comment']['view_comment'] = array(
-      'field' => array(
-        'title' => t('Link to comment'),
-        'help' => t('Provide a simple link to view the comment.'),
-        'id' => 'comment_link',
-      ),
-    );
-
-    $data['comment']['edit_comment'] = array(
-      'field' => array(
-        'title' => t('Link to edit comment'),
-        'help' => t('Provide a simple link to edit the comment.'),
-        'id' => 'comment_link_edit',
-      ),
-    );
-
-    $data['comment']['delete_comment'] = array(
-      'field' => array(
-        'title' => t('Link to delete comment'),
-        'help' => t('Provide a simple link to delete the comment.'),
-        'id' => 'comment_link_delete',
-      ),
-    );
-
     $data['comment']['approve_comment'] = array(
       'field' => array(
         'title' => t('Link to approve comment'),
@@ -195,16 +171,6 @@ public function getViewsData() {
     $data['comment_field_data']['pid']['relationship']['help'] = t('The parent comment');
     $data['comment_field_data']['pid']['relationship']['label'] = t('parent');
 
-    if (\Drupal::moduleHandler()->moduleExists('content_translation')) {
-      $data['comment']['translation_link'] = array(
-        'title' => t('Translation link'),
-        'help' => t('Provide a link to the translations overview for comments.'),
-        'field' => array(
-          'id' => 'content_translation_link',
-        ),
-      );
-    }
-
     // Define the base group of this table. Fields that don't have a group defined
     // will go into this field by default.
     $data['comment_entity_statistics']['table']['group']  = t('Comment Statistics');
diff --git a/core/modules/comment/src/Plugin/views/field/Link.php b/core/modules/comment/src/Plugin/views/field/Link.php
deleted file mode 100644
index c2fc23d..0000000
--- a/core/modules/comment/src/Plugin/views/field/Link.php
+++ /dev/null
@@ -1,139 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\comment\Plugin\views\field\Link.
- */
-
-namespace Drupal\comment\Plugin\views\field;
-
-use Drupal\Core\Entity\EntityManagerInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\views\Plugin\views\field\FieldPluginBase;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Routing\RedirectDestinationTrait;
-use Drupal\Core\Url;
-use Drupal\views\ResultRow;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Base field handler to present a link.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("comment_link")
- */
-class Link extends FieldPluginBase {
-
-  use RedirectDestinationTrait;
-
-  /**
-   * Entity Manager service.
-   *
-   * @var \Drupal\Core\Entity\EntityManagerInterface
-   */
-  protected $entityManager;
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('entity.manager')
-    );
-  }
-
-  /**
-   * Constructs a Link field plugin.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
-   *   The entity manager service.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->entityManager = $entity_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function defineOptions() {
-    $options = parent::defineOptions();
-    $options['text'] = array('default' => '');
-    $options['link_to_entity'] = array('default' => FALSE);
-    return $options;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
-    $form['text'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Text to display'),
-      '#default_value' => $this->options['text'],
-    );
-    $form['link_to_entity'] = array(
-      '#title' => $this->t('Link field to the entity if there is no comment'),
-      '#type' => 'checkbox',
-      '#default_value' => $this->options['link_to_entity'],
-    );
-    parent::buildOptionsForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function query() {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function render(ResultRow $values) {
-    $comment = $this->getEntity($values);
-    return $this->renderLink($comment, $values);
-  }
-
-  /**
-   * Prepares the link pointing to the comment or its node.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $data
-   *   The comment entity.
-   * @param \Drupal\views\ResultRow $values
-   *   The values retrieved from a single row of a view's query result.
-   *
-   * @return string
-   *   Returns a string for the link text.
-   */
-  protected function renderLink($data, ResultRow $values) {
-    $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('View');
-    /** @var \Drupal\comment\CommentInterface $comment */
-    $comment = $data;
-    $cid = $comment->id();
-
-    $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['html'] = TRUE;
-
-    if (!empty($cid)) {
-      $this->options['alter']['url'] = Url::fromRoute('entity.comment.canonical', ['comment' => $cid]);
-      $this->options['alter']['fragment'] = "comment-" . $cid;
-    }
-    // If there is no comment link to the node.
-    elseif ($this->options['link_to_node']) {
-      $entity = $comment->getCommentedEntity();
-      $this->options['alter']['url'] = $entity->urlInfo();
-    }
-
-    return $text;
-  }
-
-}
diff --git a/core/modules/comment/src/Plugin/views/field/LinkApprove.php b/core/modules/comment/src/Plugin/views/field/LinkApprove.php
index 11e7812..88c6754 100644
--- a/core/modules/comment/src/Plugin/views/field/LinkApprove.php
+++ b/core/modules/comment/src/Plugin/views/field/LinkApprove.php
@@ -8,8 +8,10 @@
 namespace Drupal\comment\Plugin\views\field;
 
 use Drupal\comment\CommentInterface;
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
+use Drupal\views\Plugin\views\field\EntityLink;
 use Drupal\views\ResultRow;
 
 /**
@@ -19,7 +21,7 @@
  *
  * @ViewsField("comment_link_approve")
  */
-class LinkApprove extends Link {
+class LinkApprove extends EntityLink {
 
   /**
    * {@inheritdoc}
@@ -40,7 +42,7 @@ public function access(AccountInterface $account) {
    * @return string
    *   Returns a string for the link text.
    */
-  protected function renderLink($data, ResultRow $values) {
+  protected function renderLink(EntityInterface $data, ResultRow $values) {
     $status = $this->getValue($values, 'status');
 
     // Don't show an approve link on published comment.
diff --git a/core/modules/comment/src/Plugin/views/field/LinkDelete.php b/core/modules/comment/src/Plugin/views/field/LinkDelete.php
deleted file mode 100644
index 5ede03f..0000000
--- a/core/modules/comment/src/Plugin/views/field/LinkDelete.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\comment\Plugin\views\field\LinkDelete.
- */
-
-namespace Drupal\comment\Plugin\views\field;
-
-use Drupal\Core\Session\AccountInterface;
-use Drupal\views\ResultRow;
-
-/**
- * Field handler to present a link to delete a comment.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("comment_link_delete")
- */
-class LinkDelete extends Link {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function access(AccountInterface $account) {
-    //needs permission to administer comments in general
-    return $account->hasPermission('administer comments');
-  }
-
-  /**
-   * Prepares the link for deleting the comment.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $data
-   *   The comment entity.
-   * @param \Drupal\views\ResultRow $values
-   *   The values retrieved from a single row of a view's query result.
-   *
-   * @return string
-   *   Returns a string for the link text.
-   */
-  protected function renderLink($data, ResultRow $values) {
-    $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Delete');
-    $comment = $this->getEntity($values);
-
-    $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['url'] = $comment->urlInfo('delete-form');
-    $this->options['alter']['query'] = $this->getDestinationArray();
-
-    return $text;
-  }
-
-}
diff --git a/core/modules/comment/src/Plugin/views/field/LinkEdit.php b/core/modules/comment/src/Plugin/views/field/LinkEdit.php
deleted file mode 100644
index 7ae0693..0000000
--- a/core/modules/comment/src/Plugin/views/field/LinkEdit.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\comment\Plugin\views\field\LinkEdit.
- */
-
-namespace Drupal\comment\Plugin\views\field;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\views\ResultRow;
-
-/**
- * Field handler to present a link to edit a comment.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("comment_link_edit")
- */
-class LinkEdit extends Link {
-
-  protected function defineOptions() {
-    $options = parent::defineOptions();
-    $options['destination'] = array('default' => FALSE);
-
-    return $options;
-  }
-
-  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
-    parent::buildOptionsForm($form, $form_state);
-
-    $form['destination'] = array(
-      '#type' => 'checkbox',
-      '#title' => $this->t('Use destination'),
-      '#description' => $this->t('Add destination to the link'),
-      '#default_value' => $this->options['destination'],
-    );
-  }
-
-  /**
-   * Prepare the link for editing the comment.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $data
-   *   The comment entity.
-   * @param \Drupal\views\ResultRow $values
-   *   The values retrieved from a single row of a view's query result.
-   *
-   * @return string
-   *   Returns a string for the link text.
-   */
-  protected function renderLink($data, ResultRow $values) {
-    parent::renderLink($data, $values);
-    // Ensure user has access to edit this comment.
-    $comment = $this->getValue($values);
-    if (!$comment->access('update')) {
-      return;
-    }
-
-    $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Edit');
-    unset($this->options['alter']['fragment']);
-
-    if (!empty($this->options['destination'])) {
-      $this->options['alter']['query'] = $this->getDestinationArray();
-    }
-
-    $this->options['alter']['url'] = $comment->urlInfo('edit-form');
-
-    return $text;
-  }
-
-}
diff --git a/core/modules/comment/src/Plugin/views/field/LinkReply.php b/core/modules/comment/src/Plugin/views/field/LinkReply.php
index 65c7545..02d2066 100644
--- a/core/modules/comment/src/Plugin/views/field/LinkReply.php
+++ b/core/modules/comment/src/Plugin/views/field/LinkReply.php
@@ -7,8 +7,10 @@
 
 namespace Drupal\comment\Plugin\views\field;
 
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
+use Drupal\views\Plugin\views\field\EntityLink;
 use Drupal\views\ResultRow;
 
 /**
@@ -18,7 +20,7 @@
  *
  * @ViewsField("comment_link_reply")
  */
-class LinkReply extends Link {
+class LinkReply extends EntityLink {
 
   /**
    * {@inheritdoc}
@@ -39,7 +41,7 @@ public function access(AccountInterface $account) {
    * @return string
    *   Returns a string for the link text.
    */
-  protected function renderLink($data, ResultRow $values) {
+  protected function renderLink(EntityInterface $data, ResultRow $values) {
     $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Reply');
     $comment = $this->getEntity($values);
 
diff --git a/core/modules/contact/src/Plugin/views/field/ContactLink.php b/core/modules/contact/src/Plugin/views/field/ContactLink.php
index f746e00..e216ae7 100644
--- a/core/modules/contact/src/Plugin/views/field/ContactLink.php
+++ b/core/modules/contact/src/Plugin/views/field/ContactLink.php
@@ -12,7 +12,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
-use Drupal\user\Plugin\views\field\Link;
+use Drupal\views\Plugin\views\field\EntityLink;
 use Drupal\views\ResultRow;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -23,7 +23,7 @@
  *
  * @ViewsField("contact_link")
  */
-class ContactLink extends Link {
+class ContactLink extends EntityLink {
 
   /**
    * The access manager.
diff --git a/core/modules/content_translation/src/Plugin/views/field/TranslationLink.php b/core/modules/content_translation/src/Plugin/views/field/TranslationLink.php
index a084dfe..654520d 100644
--- a/core/modules/content_translation/src/Plugin/views/field/TranslationLink.php
+++ b/core/modules/content_translation/src/Plugin/views/field/TranslationLink.php
@@ -7,8 +7,7 @@
 
 namespace Drupal\content_translation\Plugin\views\field;
 
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\views\Plugin\views\field\FieldPluginBase;
+use Drupal\views\Plugin\views\field\EntityLink;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\views\ResultRow;
 
@@ -19,47 +18,11 @@
  *
  * @ViewsField("content_translation_link")
  */
-class TranslationLink extends FieldPluginBase {
+class TranslationLink extends EntityLink {
 
   /**
    * {@inheritdoc}
    */
-  protected function defineOptions() {
-    $options = parent::defineOptions();
-    $options['text'] = array('default' => '');
-    return $options;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
-    $form['text'] = array(
-      '#type' => 'textfield',
-      '#title' => $this->t('Text to display'),
-      '#default_value' => $this->options['text'],
-    );
-    parent::buildOptionsForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function render(ResultRow $values) {
-    return $this->renderLink($this->getEntity($values), $values);
-  }
-
-  /**
-   * Alters the field to render a link.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity being rendered.
-   * @param \Drupal\views\ResultRow $values
-   *   The current row of the views result.
-   *
-   * @return string
-   *   The actual rendered text (without the link) of this field.
-   */
   protected function renderLink(EntityInterface $entity, ResultRow $values) {
     if (content_translation_translate_access($entity)->isAllowed()) {
       $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Translate');
@@ -71,17 +34,4 @@ protected function renderLink(EntityInterface $entity, ResultRow $values) {
     }
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function query() {
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function clickSortable() {
-    return FALSE;
-  }
-
 }
diff --git a/core/modules/node/config/optional/views.view.content_recent.yml b/core/modules/node/config/optional/views.view.content_recent.yml
index 1ad0161..500e1fa 100644
--- a/core/modules/node/config/optional/views.view.content_recent.yml
+++ b/core/modules/node/config/optional/views.view.content_recent.yml
@@ -239,7 +239,7 @@ display:
           hide_alter_empty: true
           text: Edit
           entity_type: node
-          plugin_id: node_link_edit
+          plugin_id: entity_link_edit
         delete_node:
           id: delete_node
           table: node
@@ -290,7 +290,7 @@ display:
           hide_alter_empty: true
           text: Delete
           entity_type: node
-          plugin_id: node_link_delete
+          plugin_id: entity_link_delete
       filters:
         status_extra:
           id: status_extra
diff --git a/core/modules/node/config/schema/node.views.schema.yml b/core/modules/node/config/schema/node.views.schema.yml
index b1e8e73..70c5c23 100644
--- a/core/modules/node/config/schema/node.views.schema.yml
+++ b/core/modules/node/config/schema/node.views.schema.yml
@@ -101,30 +101,6 @@ views.field.node:
       type: boolean
       label: 'Link this field to the original piece of content'
 
-views.field.node_link:
-  type: views_field
-  label: 'Node link'
-  mapping:
-    text:
-      type: label
-      label: 'Text to display'
-
-views.field.node_link_delete:
-  type: views_field
-  label: 'Node delete link'
-  mapping:
-    text:
-      type: label
-      label: 'Text to display'
-
-views.field.node_link_edit:
-  type: views_field
-  label: 'Node edit link'
-  mapping:
-    text:
-      type: label
-      label: 'Text to display'
-
 views.field.node_bulk_form:
   type: views_field_bulk_form
   label: 'Node bulk form'
diff --git a/core/modules/node/src/NodeViewsData.php b/core/modules/node/src/NodeViewsData.php
index aecaec2..fb84daa 100644
--- a/core/modules/node/src/NodeViewsData.php
+++ b/core/modules/node/src/NodeViewsData.php
@@ -61,40 +61,6 @@ public function getViewsData() {
     $data['node_field_data']['sticky']['filter']['type'] = 'yes-no';
     $data['node_field_data']['sticky']['sort']['help'] = t('Whether or not the content is sticky. To list sticky content first, set this to descending.');
 
-    if (\Drupal::moduleHandler()->moduleExists('content_translation')) {
-      $data['node']['translation_link'] = array(
-        'title' => t('Translation link'),
-        'help' => t('Provide a link to the translations overview for nodes.'),
-        'field' => array(
-          'id' => 'content_translation_link',
-        ),
-      );
-    }
-
-    $data['node']['view_node'] = array(
-      'field' => array(
-        'title' => t('Link to content'),
-        'help' => t('Provide a simple link to the content.'),
-        'id' => 'node_link',
-      ),
-    );
-
-    $data['node']['edit_node'] = array(
-      'field' => array(
-        'title' => t('Link to edit content'),
-        'help' => t('Provide a simple link to edit the content.'),
-        'id' => 'node_link_edit',
-      ),
-    );
-
-    $data['node']['delete_node'] = array(
-      'field' => array(
-        'title' => t('Link to delete content'),
-        'help' => t('Provide a simple link to delete the content.'),
-        'id' => 'node_link_delete',
-      ),
-    );
-
     $data['node']['path'] = array(
       'field' => array(
         'title' => t('Path'),
diff --git a/core/modules/node/src/Plugin/views/field/Link.php b/core/modules/node/src/Plugin/views/field/Link.php
deleted file mode 100644
index a0d7ba7..0000000
--- a/core/modules/node/src/Plugin/views/field/Link.php
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\node\Plugin\views\field\Link.
- */
-
-namespace Drupal\node\Plugin\views\field;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Routing\RedirectDestinationTrait;
-use Drupal\views\Plugin\views\field\FieldPluginBase;
-use Drupal\views\ResultRow;
-
-/**
- * Field handler to present a link to the node.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("node_link")
- */
-class Link extends FieldPluginBase {
-
-  use RedirectDestinationTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function usesGroupBy() {
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function defineOptions() {
-    $options = parent::defineOptions();
-    $options['text'] = array('default' => '');
-    return $options;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
-    $form['text'] = array(
-      '#type' => 'textfield',
-      '#title' => $this->t('Text to display'),
-      '#default_value' => $this->options['text'],
-    );
-    parent::buildOptionsForm($form, $form_state);
-
-    // The path is set by renderLink function so don't allow to set it.
-    $form['alter']['path'] = array('#access' => FALSE);
-    $form['alter']['external'] = array('#access' => FALSE);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function query() {
-    $this->addAdditionalFields();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function render(ResultRow $values) {
-    if ($entity = $this->getEntity($values)) {
-      return $this->renderLink($entity, $values);
-    }
-  }
-
-  /**
-   * Prepares the link to the node.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $node
-   *   The node entity this field belongs to.
-   * @param ResultRow $values
-   *   The values retrieved from the view's result set.
-   *
-   * @return string
-   *   Returns a string for the link text.
-   */
-  protected function renderLink($node, ResultRow $values) {
-    if ($node->access('view')) {
-      $this->options['alter']['make_link'] = TRUE;
-      $this->options['alter']['url'] = $node->urlInfo();
-      $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('View');
-      return $text;
-    }
-  }
-
-}
diff --git a/core/modules/node/src/Plugin/views/field/LinkDelete.php b/core/modules/node/src/Plugin/views/field/LinkDelete.php
deleted file mode 100644
index 6dad5e0..0000000
--- a/core/modules/node/src/Plugin/views/field/LinkDelete.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\node\Plugin\views\field\LinkDelete.
- */
-
-namespace Drupal\node\Plugin\views\field;
-
-use Drupal\node\Plugin\views\field\Link;
-use Drupal\views\ResultRow;
-
-/**
- * Field handler to present a link to delete a node.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("node_link_delete")
- */
-class LinkDelete extends Link {
-
-  /**
-   * Prepares the link to delete a node.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $node
-   *   The node entity this field belongs to.
-   * @param \Drupal\views\ResultRow $values
-   *   The values retrieved from the view's result set.
-   *
-   * @return string
-   *   Returns a string for the link text.
-   */
-  protected function renderLink($node, ResultRow $values) {
-    // Ensure user has access to delete this node.
-    if (!$node->access('delete')) {
-      return;
-    }
-
-    $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['url'] = $node->urlInfo('delete-form');
-    $this->options['alter']['query'] = $this->getDestinationArray();
-
-    $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Delete');
-    return $text;
-  }
-
-}
diff --git a/core/modules/node/src/Plugin/views/field/LinkEdit.php b/core/modules/node/src/Plugin/views/field/LinkEdit.php
deleted file mode 100644
index 6d46642..0000000
--- a/core/modules/node/src/Plugin/views/field/LinkEdit.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of views_handler_field_node_link_edit.
- */
-
-namespace Drupal\node\Plugin\views\field;
-
-use Drupal\Core\Url;
-use Drupal\node\Plugin\views\field\Link;
-use Drupal\views\ResultRow;
-
-/**
- * Field handler to present a link node edit.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("node_link_edit")
- */
-class LinkEdit extends Link {
-
-  /**
-   * Prepares the link to the node.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $node
-   *   The node entity this field belongs to.
-   * @param ResultRow $values
-   *   The values retrieved from the view's result set.
-   *
-   * @return string
-   *   Returns a string for the link text.
-   */
-  protected function renderLink($node, ResultRow $values) {
-    // Ensure user has access to edit this node.
-    if (!$node->access('update')) {
-      return;
-    }
-
-    $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['url'] = $node->urlInfo('edit-form');
-    $this->options['alter']['query'] = $this->getDestinationArray();
-
-    $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Edit');
-    return $text;
-  }
-
-}
diff --git a/core/modules/node/src/Plugin/views/field/RevisionLink.php b/core/modules/node/src/Plugin/views/field/RevisionLink.php
index 8370170..8bccd90 100644
--- a/core/modules/node/src/Plugin/views/field/RevisionLink.php
+++ b/core/modules/node/src/Plugin/views/field/RevisionLink.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\node\Plugin\views\field;
 
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
 use Drupal\node\Plugin\views\field\Link;
@@ -50,7 +51,7 @@ public function access(AccountInterface $account) {
    * @return string
    *   Returns a string for the link text.
    */
-  protected function renderLink($data, ResultRow $values) {
+  protected function renderLink(EntityInterface $data, ResultRow $values) {
     list($node, $vid) = $this->get_revision_entity($values, 'view');
     if (!isset($vid)) {
       return;
diff --git a/core/modules/node/src/Plugin/views/field/RevisionLinkDelete.php b/core/modules/node/src/Plugin/views/field/RevisionLinkDelete.php
index c7519d0..1eb38fc 100644
--- a/core/modules/node/src/Plugin/views/field/RevisionLinkDelete.php
+++ b/core/modules/node/src/Plugin/views/field/RevisionLinkDelete.php
@@ -7,9 +7,9 @@
 
 namespace Drupal\node\Plugin\views\field;
 
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
-use Drupal\node\Plugin\views\field\RevisionLink;
 use Drupal\views\ResultRow;
 
 /**
@@ -39,7 +39,7 @@ public function access(AccountInterface $account) {
    * @return string
    *   Returns a string for the link text.
    */
-  protected function renderLink($data, ResultRow $values) {
+  protected function renderLink(EntityInterface $data, ResultRow $values) {
     list($node, $vid) = $this->get_revision_entity($values, 'delete');
     if (!isset($vid)) {
       return;
diff --git a/core/modules/node/src/Plugin/views/field/RevisionLinkRevert.php b/core/modules/node/src/Plugin/views/field/RevisionLinkRevert.php
index a5d1c97..7364f8e 100644
--- a/core/modules/node/src/Plugin/views/field/RevisionLinkRevert.php
+++ b/core/modules/node/src/Plugin/views/field/RevisionLinkRevert.php
@@ -7,9 +7,9 @@
 
 namespace Drupal\node\Plugin\views\field;
 
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
-use Drupal\node\Plugin\views\field\RevisionLink;
 use Drupal\views\ResultRow;
 
 /**
@@ -39,7 +39,7 @@ public function access(AccountInterface $account) {
    * @return string
    *   Returns a string for the link text.
    */
-  protected function renderLink($data, ResultRow $values) {
+  protected function renderLink(EntityInterface $data, ResultRow $values) {
     list($node, $vid) = $this->get_revision_entity($values, 'update');
     if (!isset($vid)) {
       return;
diff --git a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
index 40b226a..a4b6320 100644
--- a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
+++ b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml
@@ -83,14 +83,6 @@ views.argument_default.taxonomy_tid:
       type: string
       label: 'Multiple-value handling'
 
-views.field.term_link_edit:
-  type: views_field
-  label: 'Taxonomy language'
-  mapping:
-    text:
-      type: label
-      label: 'Text to display'
-
 views.field.term_name:
   type: views.field.field
   mapping:
diff --git a/core/modules/taxonomy/src/Plugin/views/field/LinkEdit.php b/core/modules/taxonomy/src/Plugin/views/field/LinkEdit.php
deleted file mode 100644
index 10f0337..0000000
--- a/core/modules/taxonomy/src/Plugin/views/field/LinkEdit.php
+++ /dev/null
@@ -1,89 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\taxonomy\Plugin\views\field\LinkEdit.
- */
-
-namespace Drupal\taxonomy\Plugin\views\field;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Routing\RedirectDestinationTrait;
-use Drupal\Core\Url;
-use Drupal\views\Plugin\views\field\FieldPluginBase;
-use Drupal\views\Plugin\views\display\DisplayPluginBase;
-use Drupal\views\ResultRow;
-use Drupal\views\ViewExecutable;
-
-/**
- * Field handler to present a term edit link.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("term_link_edit")
- */
-class LinkEdit extends FieldPluginBase {
-
-  use RedirectDestinationTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
-    parent::init($view, $display, $options);
-
-    $this->additional_fields['tid'] = 'tid';
-    $this->additional_fields['vid'] = 'vid';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function defineOptions() {
-    $options = parent::defineOptions();
-
-    $options['text'] = array('default' => '');
-
-    return $options;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
-    $form['text'] = array(
-      '#type' => 'textfield',
-      '#title' => $this->t('Text to display'),
-      '#default_value' => $this->options['text'],
-    );
-    parent::buildOptionsForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function query() {
-    $this->ensureMyTable();
-    $this->addAdditionalFields();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function render(ResultRow $values) {
-    // Check there is an actual value, as on a relationship there may not be.
-    if ($tid = $this->getValue($values, 'tid')) {
-      // Mock a term object for taxonomy_term_access(). Use machine name and
-      // vid to ensure compatibility with vid based and machine name based
-      // access checks. See http://drupal.org/node/995156
-      $term = entity_create('taxonomy_term', array(
-        'vid' => $values->{$this->aliases['vid']},
-      ));
-      if ($term->access('update')) {
-        $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Edit');
-        return \Drupal::l($text, new Url('entity.taxonomy.edit_form', ['taxonomy_term' => $tid], array('query' => $this->getDestinationArray())));
-      }
-    }
-  }
-
-}
diff --git a/core/modules/taxonomy/src/TermViewsData.php b/core/modules/taxonomy/src/TermViewsData.php
index 1d3ba6f..104a33b 100644
--- a/core/modules/taxonomy/src/TermViewsData.php
+++ b/core/modules/taxonomy/src/TermViewsData.php
@@ -75,25 +75,6 @@ public function getViewsData() {
     unset($data['taxonomy_term_field_data']['vid']['argument']);
     unset($data['taxonomy_term_field_data']['vid']['sort']);
 
-    $data['taxonomy_term_data']['edit_term'] = array(
-      'field' => array(
-        'title' => t('Term edit link'),
-        'help' => t('Provide a simple link to edit the term.'),
-        'id' => 'term_link_edit',
-        'click sortable' => FALSE,
-      ),
-    );
-
-    if (\Drupal::moduleHandler()->moduleExists('content_translation')) {
-      $data['taxonomy_term_data']['translation_link'] = array(
-        'title' => t('Translation link'),
-        'help' => t('Provide a link to the translations overview for taxonomy terms.'),
-        'field' => array(
-          'id' => 'content_translation_link',
-        ),
-      );
-    }
-
     $data['taxonomy_term_field_data']['name']['field']['id'] = 'term_name';
     $data['taxonomy_term_field_data']['name']['argument']['many to one'] = TRUE;
     $data['taxonomy_term_field_data']['name']['argument']['empty field name'] = t('Uncategorized');
diff --git a/core/modules/user/config/schema/user.views.schema.yml b/core/modules/user/config/schema/user.views.schema.yml
index 215bd41..d74140f 100644
--- a/core/modules/user/config/schema/user.views.schema.yml
+++ b/core/modules/user/config/schema/user.views.schema.yml
@@ -67,22 +67,6 @@ views_field_user:
       type: boolean
       label: 'Link this field to its user'
 
-views.field.user_link:
-  type: views_field
-  label: 'User link'
-  mapping:
-    text:
-      type: text
-      label: 'Text to display'
-
-views.field.user_link_cancel:
-  type: views.field.user_link
-  label: 'User cancel link'
-
-views.field.user_link_edit:
-  type: views.field.user_link
-  label: 'User edit link'
-
 views.field.user_permissions:
   type: views.field.prerender_list
   label: 'List of permission'
diff --git a/core/modules/user/src/Plugin/views/field/Link.php b/core/modules/user/src/Plugin/views/field/Link.php
deleted file mode 100644
index 78057cc..0000000
--- a/core/modules/user/src/Plugin/views/field/Link.php
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\user\Plugin\views\field\Link.
- */
-
-namespace Drupal\user\Plugin\views\field;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Routing\RedirectDestinationTrait;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\views\Plugin\views\field\FieldPluginBase;
-use Drupal\views\Plugin\views\display\DisplayPluginBase;
-use Drupal\views\ResultRow;
-use Drupal\views\ViewExecutable;
-use Drupal\Core\Entity\EntityInterface;
-
-/**
- * Field handler to present a link to the user.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("user_link")
- */
-class Link extends FieldPluginBase {
-
-  use RedirectDestinationTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function usesGroupBy() {
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
-    parent::init($view, $display, $options);
-
-    $this->additional_fields['uid'] = 'uid';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function defineOptions() {
-    $options = parent::defineOptions();
-    $options['text'] = array('default' => '');
-    return $options;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
-    $form['text'] = array(
-      '#type' => 'textfield',
-      '#title' => $this->t('Text to display'),
-      '#default_value' => $this->options['text'],
-    );
-    parent::buildOptionsForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function access(AccountInterface $account) {
-    return $account->hasPermission('administer users') || $account->hasPermission('access user profiles');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function query() {
-    $this->ensureMyTable();
-    $this->addAdditionalFields();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function render(ResultRow $values) {
-    if ($entity = $this->getEntity($values)) {
-      return $this->renderLink($entity, $values);
-    }
-  }
-
-  /**
-   * Alters the field to render a link.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   * @param \Drupal\views\ResultRow $values
-   *   The current row of the views result.
-   *
-   * @return string
-   *   The actual rendered text (without the link) of this field.
-   */
-  protected function renderLink(EntityInterface $entity, ResultRow $values) {
-    $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('View');
-
-    $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['url'] = $entity->urlInfo();
-
-    return $text;
-  }
-
-}
diff --git a/core/modules/user/src/Plugin/views/field/LinkCancel.php b/core/modules/user/src/Plugin/views/field/LinkCancel.php
deleted file mode 100644
index b29c426..0000000
--- a/core/modules/user/src/Plugin/views/field/LinkCancel.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\user\Plugin\views\field\LinkCancel.
- */
-
-namespace Drupal\user\Plugin\views\field;
-
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\views\ResultRow;
-
-/**
- * Field handler to present a link to user cancel.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("user_link_cancel")
- */
-class LinkCancel extends Link {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function renderLink(EntityInterface $entity, ResultRow $values) {
-    if ($entity && $entity->access('delete')) {
-      $this->options['alter']['make_link'] = TRUE;
-
-      $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Cancel account');
-
-      $this->options['alter']['url'] = $entity->urlInfo('cancel-form');
-      $this->options['alter']['query'] = $this->getDestinationArray();
-
-      return $text;
-    }
-  }
-
-}
diff --git a/core/modules/user/src/Plugin/views/field/LinkEdit.php b/core/modules/user/src/Plugin/views/field/LinkEdit.php
deleted file mode 100644
index 23a4f5a..0000000
--- a/core/modules/user/src/Plugin/views/field/LinkEdit.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\user\Plugin\views\field\LinkEdit.
- */
-
-namespace Drupal\user\Plugin\views\field;
-
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\views\ResultRow;
-
-/**
- * Field handler to present a link to user edit.
- *
- * @ingroup views_field_handlers
- *
- * @ViewsField("user_link_edit")
- */
-class LinkEdit extends Link {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function renderLink(EntityInterface $entity, ResultRow $values) {
-    if ($entity && $entity->access('update')) {
-      $this->options['alter']['make_link'] = TRUE;
-
-      $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('Edit');
-
-      $this->options['alter']['url'] = $entity->urlInfo('edit-form', ['query' => ['destination' => $this->getDestinationArray()]]);
-
-      return $text;
-    }
-  }
-
-}
diff --git a/core/modules/user/src/UserViewsData.php b/core/modules/user/src/UserViewsData.php
index edbdb99..cc24f2e 100644
--- a/core/modules/user/src/UserViewsData.php
+++ b/core/modules/user/src/UserViewsData.php
@@ -94,15 +94,6 @@ public function getViewsData() {
     $data['users_field_data']['preferred_admin_langcode']['title'] = t('Preferred admin language');
     $data['users_field_data']['preferred_admin_langcode']['help'] = t('Preferred administrative language of the user');
 
-    $data['users']['view_user'] = array(
-      'field' => array(
-        'title' => t('Link to user'),
-        'help' => t('Provide a simple link to the user.'),
-        'id' => 'user_link',
-        'click sortable' => FALSE,
-      ),
-    );
-
     $data['users_field_data']['created_fulldate'] = array(
       'title' => t('Created date'),
       'help' => t('Date in the form of CCYYMMDD.'),
@@ -216,34 +207,6 @@ public function getViewsData() {
       ),
     );
 
-    if (\Drupal::moduleHandler()->moduleExists('content_translation')) {
-      $data['users']['translation_link'] = array(
-        'title' => t('Translation link'),
-        'help' => t('Provide a link to the translations overview for users.'),
-        'field' => array(
-          'id' => 'content_translation_link',
-        ),
-      );
-    }
-
-    $data['users']['edit_node'] = array(
-      'field' => array(
-        'title' => t('Link to edit user'),
-        'help' => t('Provide a simple link to edit the user.'),
-        'id' => 'user_link_edit',
-        'click sortable' => FALSE,
-      ),
-    );
-
-    $data['users']['cancel_node'] = array(
-      'field' => array(
-        'title' => t('Link to cancel user'),
-        'help' => t('Provide a simple link to cancel the user.'),
-        'id' => 'user_link_cancel',
-        'click sortable' => FALSE,
-      ),
-    );
-
     $data['users']['data'] = array(
       'title' => t('Data'),
       'help' => t('Provides access to the user data service.'),
diff --git a/core/modules/views/config/schema/views.field.schema.yml b/core/modules/views/config/schema/views.field.schema.yml
index de8ffcb..6586d82 100644
--- a/core/modules/views/config/schema/views.field.schema.yml
+++ b/core/modules/views/config/schema/views.field.schema.yml
@@ -176,6 +176,31 @@ views.field.language:
       type: boolean
       label: 'Display in native language'
 
+
+views.field.entity_link:
+  type: views_field
+  label: 'Entity link'
+  mapping:
+    text:
+      type: label
+      label: 'Text to display'
+
+views.field.entity_link_delete:
+  type: views.field.entity_link
+  label: 'Entity delete link'
+  mapping:
+    text:
+      type: label
+      label: 'Text to display'
+
+views.field.entity_link_edit:
+   type: views.field.entity_link
+   label: 'Entity edit link'
+   mapping:
+     text:
+       type: label
+       label: 'Text to display'
+
 views.field.bulk_form:
   type: views_field_bulk_form
   label: 'Bulk form'
@@ -223,6 +248,7 @@ views.field.field:
     separator:
       type: label
       label: 'Separator'
+      label: 'Text to display'
     field_api_classes:
       type: boolean
       label: 'Use field template'
diff --git a/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php
index a22fd02..9cbb31c 100644
--- a/core/modules/views/src/EntityViewsData.php
+++ b/core/modules/views/src/EntityViewsData.php
@@ -203,6 +203,8 @@ public function getViewsData() {
       }
     }
 
+    $this->addEntityLinks($data[$base_table]);
+
     // Load all typed data definitions of all fields. This should cover each of
     // the entity base, revision, data tables.
     $field_definitions = $this->entityManager->getBaseFieldDefinitions($this->entityType->id());
@@ -230,6 +232,53 @@ public function getViewsData() {
   }
 
   /**
+   * Sets the entity links in case corresponding link templates exist.
+   *
+   * @param array $data
+   *   The views data of the base table.
+   */
+  protected function addEntityLinks(array &$data) {
+    $entity_type_id = $this->entityType->id();
+    $t_arguments = ['@entity_type_label' => $this->entityType->getLabel()];
+    if ($this->entityType->hasLinkTemplate('canonical')) {
+      $data['view_' . $entity_type_id] = [
+        'field' => [
+          'title' => $this->t('Link to @entity_type_label', $t_arguments),
+          'help' => $this->t('Provide a view link to the @entity_type_label.', $t_arguments),
+          'id' => 'entity_link',
+        ],
+      ];
+    }
+    if ($this->entityType->hasLinkTemplate('edit-form')) {
+      $data['edit_' . $entity_type_id] = [
+        'field' => [
+          'title' => $this->t('Link to edit @entity_type_label', $t_arguments),
+          'help' => $this->t('Provide an edit link to the @entity_type_label.', $t_arguments),
+          'id' => 'entity_link_edit',
+        ],
+      ];
+    }
+    if ($this->entityType->hasLinkTemplate('delete-form')) {
+      $data['delete_' . $entity_type_id] = [
+        'field' => [
+          'title' => $this->t('Link to delete @entity_type_label', $t_arguments),
+          'help' => $this->t('Provide a delete link to the @entity_type_label.', $t_arguments),
+          'id' => 'entity_link_delete',
+        ],
+      ];
+    }
+    if ($this->entityType->hasLinkTemplate('drupal:content-translation-overview')) {
+      $data['translate_' . $entity_type_id] = [
+        'field' => [
+          'title' => $this->t('Link to translate @entity_type_label', $t_arguments),
+          'help' => $this->t('Provide a translate link to the @entity_type_label.', $t_arguments),
+          'id' => 'content_translation_link',
+        ],
+      ];
+    }
+  }
+
+  /**
    * Puts the views data for a single field onto the views data.
    *
    * @param string $table
diff --git a/core/modules/views/src/Plugin/views/field/EntityLink.php b/core/modules/views/src/Plugin/views/field/EntityLink.php
new file mode 100644
index 0000000..cbc9cc4
--- /dev/null
+++ b/core/modules/views/src/Plugin/views/field/EntityLink.php
@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\field\EntityLink.
+ */
+
+namespace Drupal\views\Plugin\views\field;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\views\Plugin\views\display\DisplayPluginBase;
+use Drupal\views\ResultRow;
+use Drupal\views\ViewExecutable;
+
+/**
+ * Field handler to present a link to the entity_link.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("entity_link")
+ */
+class EntityLink extends FieldPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
+    parent::init($view, $display, $options);
+
+    // @FIXME
+    // $this->additional_fields['langcode'] = ['table' => 'node_field_data', 'field' => 'langcode'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function usesGroupBy() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineOptions() {
+    $options = parent::defineOptions();
+    $options['text'] = ['default' => '', 'translatable' => TRUE];
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
+    $form['text'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Text to display'),
+      '#default_value' => $this->options['text'],
+    ];
+    parent::buildOptionsForm($form, $form_state);
+
+    // The path is set by renderLink function so don't allow to set it.
+    $form['alter']['path'] = ['#access' => FALSE];
+    $form['alter']['external'] = ['#access' => FALSE];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    $this->addAdditionalFields();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render(ResultRow $values) {
+    if ($entity = $this->getEntity($values)) {
+      return $this->renderLink($entity, $values);
+    }
+  }
+
+  /**
+   * Prepares the link to view a entity.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The node entity this field belongs to.
+   * @param \Drupal\views\ResultRow $values
+   *   The values retrieved from the view's result set.
+   *
+   * @return string
+   *   Returns a string for the link text.
+   */
+  protected function renderLink(EntityInterface $entity, ResultRow $values) {
+    if ($entity->access('view')) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = $entity->getSystemPath();
+
+      $this->addLangcode($values);
+
+      $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('view');
+      return $text;
+    }
+  }
+
+  /**
+   * @param \Drupal\views\ResultRow $values
+   */
+  protected function addLangcode(ResultRow $values) {
+    if (isset($this->aliases['langcode'])) {
+      $languages = language_list();
+      $langcode = $this->getValue($values, 'langcode');
+      if (isset($languages[$langcode])) {
+        $this->options['alter']['language'] = $languages[$langcode];
+      }
+      else {
+        unset($this->options['alter']['language']);
+      }
+    }
+  }
+}
diff --git a/core/modules/views/src/Plugin/views/field/EntityLinkDelete.php b/core/modules/views/src/Plugin/views/field/EntityLinkDelete.php
new file mode 100644
index 0000000..8245714
--- /dev/null
+++ b/core/modules/views/src/Plugin/views/field/EntityLinkDelete.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\field\EntityLinkDelete.
+ */
+
+namespace Drupal\views\Plugin\views\field;
+
+use Drupal\views\ResultRow;
+
+/**
+ * Field handler to present a link to delete an entity.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("entity_link_delete")
+ */
+class EntityLinkDelete extends EntityLink {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function renderLink($entity, ResultRow $values) {
+    // Ensure user has access to delete this node.
+    if ($entity && $entity->access('delete')) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = $entity->getSystemPath('delete-form');
+      $this->options['alter']['query'] = drupal_get_destination();
+
+      $this->addLangcode($values);
+
+      $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('delete');
+      return $text;
+    }
+  }
+
+}
diff --git a/core/modules/views/src/Plugin/views/field/EntityLinkEdit.php b/core/modules/views/src/Plugin/views/field/EntityLinkEdit.php
new file mode 100644
index 0000000..d1f40ca
--- /dev/null
+++ b/core/modules/views/src/Plugin/views/field/EntityLinkEdit.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\views\Plugin\views\field\EntityLinkEdit.
+ */
+
+namespace Drupal\views\Plugin\views\field;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\views\ResultRow;
+
+/**
+ * Field handler to present a link to edit an entity.
+ *
+ * @ingroup views_field_handlers
+ *
+ * @ViewsField("entity_link_edit")
+ */
+class EntityLinkEdit extends EntityLink {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function renderLink(EntityInterface $entity, ResultRow $values) {
+    // Ensure user has access to delete this node.
+    if ($entity && $entity->access('update')) {
+      $this->options['alter']['make_link'] = TRUE;
+      $this->options['alter']['path'] = $entity->getSystemPath('edit-form');
+      $this->options['alter']['query'] = drupal_get_destination();
+
+      $this->addLangcode($values);
+
+      $text = !empty($this->options['text']) ? $this->options['text'] : $this->t('edit');
+      return $text;
+    }
+  }
+
+}
diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
index 56d1596..e8e49d6 100644
--- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
+++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
@@ -712,6 +712,35 @@ protected function assertField($data, $field_name) {
   }
 
   /**
+   * Tests add link types.
+   */
+  public function testEntityLinks() {
+    $this->baseEntityType->setLinkTemplate('canonical', '/entity_test/{entity_test}');
+    $this->baseEntityType->setLinkTemplate('edit-form', '/entity_test/{entity_test}/edit');
+    $this->baseEntityType->setLinkTemplate('delete-form', '/entity_test/{entity_test}/delete');
+    $this->baseEntityType->setLinkTemplate('drupal:content-translation-overview', '/entity_test/{entity_test}/translate');
+
+    $data = $this->viewsData->getViewsData();
+    $this->assertEquals('entity_link', $data['entity_test']['view_entity_test']['field']['id']);
+    $this->assertEquals('entity_link_edit', $data['entity_test']['edit_entity_test']['field']['id']);
+    $this->assertEquals('entity_link_delete', $data['entity_test']['delete_entity_test']['field']['id']);
+    $this->assertEquals('content_translation_link', $data['entity_test']['translate_entity_test']['field']['id']);
+  }
+
+  /**
+   * Tests additional edit links.
+   */
+  public function testEntityLinksJustEditForm() {
+    $this->baseEntityType->setLinkTemplate('edit-form', '/entity_test/{entity_test}/edit');
+
+    $data = $this->viewsData->getViewsData();
+    $this->assertFalse(isset($data['entity_test']['view_entity_test']));
+    $this->assertFalse(isset($data['entity_test']['delete_entity_test']));
+
+    $this->assertEquals('entity_link_edit', $data['entity_test']['edit_entity_test']['field']['id']);
+  }
+
+  /**
    * Tests views data for a string field.
    *
    * @param $data
