diff --git a/config/schema/diff.schema.yml b/config/schema/diff.schema.yml
index 4a80385..1efc568 100644
--- a/config/schema/diff.schema.yml
+++ b/config/schema/diff.schema.yml
@@ -174,3 +174,26 @@ diff.plugin.settings.entity_reference_field_diff_builder:
     compare_entity_reference:
       type: integer
       label: 'Entity reference component to compare'
+
+diff.layout_plugins:
+  type: config_object
+  label: 'Plugin'
+  mapping:
+    type: sequence
+    sequence:
+      type: mapping
+      label: 'Diff configuration for a field type'
+      mapping:
+        type:
+          type: text
+          label: 'Plugin key'
+        settings:
+          type: diff.plugin.settings.[%parent.type]
+
+diff.layout_plugin.settings_base:
+  type: mapping
+  label: 'Settings for base diff layout plugin'
+  mapping:
+    markdown:
+      type: string
+      label: 'Mark-down function ID'
diff --git a/diff.routing.yml b/diff.routing.yml
index c858606..a493bbf 100644
--- a/diff.routing.yml
+++ b/diff.routing.yml
@@ -3,7 +3,7 @@ diff.revisions_diff:
   defaults:
     _controller: '\Drupal\diff\Controller\NodeRevisionController::compareNodeRevisions'
     _title: Diff General Settings
-    filter: 'raw'
+    filter: 'classic_layout'
   requirements:
     _access_node_revision: 'view'
   options:
diff --git a/diff.services.yml b/diff.services.yml
index e04e1dd..1615604 100755
--- a/diff.services.yml
+++ b/diff.services.yml
@@ -13,6 +13,11 @@ services:
     parent: default_plugin_manager
     arguments: ['@entity_type.manager', '@config.factory']
 
+  plugin.manager.diff.layout:
+    class: Drupal\diff\DiffLayoutManager
+    parent: default_plugin_manager
+    arguments: ['@entity_type.manager', '@config.factory']
+
   diff.entity_parser:
     class: Drupal\diff\DiffEntityParser
     arguments: ['@plugin.manager.diff.builder', '@config.factory']
diff --git a/src/Annotation/DiffLayoutBuilder.php b/src/Annotation/DiffLayoutBuilder.php
new file mode 100644
index 0000000..4240724
--- /dev/null
+++ b/src/Annotation/DiffLayoutBuilder.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\diff\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a DiffLayoutBuilder annotation object.
+ *
+ * Diff builders handle how fields are compared by the diff module.
+ *
+ * @Annotation
+ *
+ */
+class DiffLayoutBuilder extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The human-readable name of the diff layout builder.
+   *
+   * @ingroup plugin_translatable
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   */
+  public $label;
+
+}
diff --git a/src/Controller/NodeRevisionController.php b/src/Controller/NodeRevisionController.php
index 9e04643..f48c452 100644
--- a/src/Controller/NodeRevisionController.php
+++ b/src/Controller/NodeRevisionController.php
@@ -10,7 +10,7 @@ use Drupal\Component\Utility\Xss;
 /**
  * Returns responses for Node Revision routes.
  */
-class NodeRevisionController extends GenericRevisionController {
+class NodeRevisionController extends PluginRevisionController {
 
   /**
    * Returns a form for revision overview page.
diff --git a/src/Controller/PluginRevisionController.php b/src/Controller/PluginRevisionController.php
new file mode 100644
index 0000000..c47a807
--- /dev/null
+++ b/src/Controller/PluginRevisionController.php
@@ -0,0 +1,252 @@
+<?php
+
+namespace Drupal\diff\Controller;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Url;
+use Drupal\diff\DiffLayoutManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\diff\DiffEntityComparison;
+
+/**
+ * Base class for controllers that return responses on entity revision routes.
+ */
+class PluginRevisionController extends ControllerBase {
+
+  /**
+   * Wrapper object for writing/reading configuration from diff.plugins.yml
+   */
+  protected $config;
+
+  /**
+   * The diff entity comparison service.
+   */
+  protected $entityComparison;
+
+  /**
+   * The field diff layout plugin manager service.
+   *
+   * @var \Drupal\diff\DiffLayoutManager
+   */
+  protected $diffLayoutManager;
+
+  /**
+   * Constructs a PluginRevisionController object.
+   *
+   * @param DiffEntityComparison $entity_comparison
+   *   DiffEntityComparison service.
+   * @param DiffLayoutManager $diff_layout_manager
+   *   DiffLayoutManager service.
+   */
+  public function __construct(DiffEntityComparison $entity_comparison, DiffLayoutManager $diff_layout_manager) {
+    $this->config = $this->config('diff.settings');
+    $this->diffLayoutManager = $diff_layout_manager;
+    $this->entityComparison = $entity_comparison;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('diff.entity_comparison'),
+      $container->get('plugin.manager.diff.layout')
+    );
+  }
+
+  /**
+   * Get all the revision ids of given entity id.
+   *
+   * @param $storage
+   *   The entity storage manager.
+   * @param $entity_id
+   *   The entity to find revisions of.
+   *
+   * @return array
+   */
+  public function getVids(EntityStorageInterface $storage, $entity_id) {
+    $result = $storage->getQuery()
+      ->allRevisions()
+      ->condition($storage->getEntityType()->getKey('id'), $entity_id)
+      ->execute();
+    $result_array = array_keys($result);
+    sort($result_array);
+    return $result_array;
+  }
+
+  /**
+   * Returns a table which shows the differences between two entity revisions.
+   *
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
+   * @param \Drupal\Core\Entity\EntityInterface $left_revision
+   *   The left revision.
+   * @param \Drupal\Core\Entity\EntityInterface $right_revision
+   *   The right revision.
+   * @param string $filter
+   *   If $filter == 'raw' raw text is compared (including html tags)
+   *   If filter == 'raw-plain' markdown function is applied to the text before comparison.
+   *
+   * @return array
+   *   Table showing the diff between the two entity revisions.
+   */
+  public function compareEntityRevisions(RouteMatchInterface $route_match, EntityInterface $left_revision, EntityInterface $right_revision, $filter) {
+    $entity_type_id = $left_revision->getEntityTypeId();
+    $entity = $route_match->getParameter($entity_type_id);
+
+    $entity_type_id = $entity->getEntityTypeId();
+    $storage = $this->entityTypeManager()->getStorage($entity_type_id);
+    // Get language from the entity context.
+    $langcode = $entity->language()->getId();
+
+    // Get left and right revision in current language.
+    $left_revision = $left_revision->getTranslation($langcode);
+    $right_revision = $right_revision->getTranslation($langcode);
+
+    $vids = [];
+    // Filter revisions of current translation and where the translation is
+    // affected.
+    foreach ($this->getVids($storage, $entity->id()) as $vid) {
+      $revision = $storage->loadRevision($vid);
+      if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) {
+        $vids[] = $vid;
+      }
+    }
+
+    $build = array(
+      '#title' => $this->t('Changes to %title', ['%title' => $entity->label()]),
+    );
+
+    // Build the layout filter.
+    $build['diff_layout'] = [
+      '#type' => 'item',
+      '#title' => $this->t('Layout'),
+    ];
+    $build['diff_layout']['filter'] = $this->buildMarkdownNavigation($entity, $left_revision->getRevisionId(), $right_revision->getRevisionId(), $filter);
+
+    // Build the navigation links.
+    $build['diff_navigation'] = $this->buildRevisionsNavigation($entity, $vids, $left_revision->getRevisionId(), $right_revision->getRevisionId());
+
+    // Perform comparison only if both entity revisions loaded successfully.
+    if ($left_revision != FALSE && $right_revision != FALSE) {
+      // Build the diff comparison with the plugin.
+      $plugin = $this->diffLayoutManager->createInstance($filter);
+      $build = $plugin->build($build, $left_revision, $right_revision, $entity);
+    }
+
+    $build['#attached']['library'][] = 'diff/diff.general';
+    return $build;
+  }
+
+  /**
+   * Builds a table row with navigation between raw and raw-plain formats.
+   */
+  protected function buildMarkdownNavigation(EntityInterface $entity, $left_vid, $right_vid, $active_filter) {
+    $links = [];
+    foreach ($this->diffLayoutManager->getDefinitions() as $key => $value) {
+      $links[$key] = array(
+        'title' => $value['label'],
+        'url' => $this->diffRoute($entity, $left_vid, $right_vid, $key),
+      );
+    }
+
+    // Set as the first element the current filter.
+    $filter = $links[$active_filter];
+    unset($links[$active_filter]);
+    array_unshift($links, $filter);
+
+    $filter = [
+      '#type' => 'operations',
+      '#links' => $links,
+      '#prefix' => '<div class="diff-filter">',
+      '#suffix' => '</div>',
+    ];
+
+    return $filter;
+  }
+
+  protected function buildRevisionsNavigation(EntityInterface $entity, $vids, $left_vid, $right_vid) {
+    $revisions_count = count($vids);
+    // If there are only 2 revision return an empty row.
+    if ($revisions_count == 2) {
+      return [];
+    }
+    else {
+      $left_link = $right_link = '';
+      $element['diff_navigation'] = [
+        '#type' => 'item',
+        '#title' => $this->t('Navigation'),
+      ];
+      $i = 0;
+      // Find the previous revision.
+      while ($left_vid > $vids[$i]) {
+        $i += 1;
+      }
+      if ($i != 0) {
+        // build the left link.
+        $left_link = $this->l($this->t('< Previous difference'), $this->diffRoute($entity, $vids[$i - 1], $left_vid));
+      }
+      $element['diff_navigation']['left'] = [
+        '#type' => 'markup',
+        '#markup' => $left_link,
+        '#prefix' => '<span class="navigation-link">',
+        '#suffix' => '</span>',
+      ];
+      // Find the next revision.
+      $i = 0;
+      while ($i < $revisions_count && $right_vid >= $vids[$i]) {
+        $i += 1;
+      }
+      if ($revisions_count != $i && $vids[$i - 1] != $vids[$revisions_count - 1]) {
+        // Build the right link.
+        $right_link = $this->l($this->t('Next difference >'), $this->diffRoute($entity, $right_vid, $vids[$i]));
+      }
+      $element['diff_navigation']['right'] = [
+        '#type' => 'markup',
+        '#markup' => $right_link,
+        '#prefix' => '<span class="navigation-link">',
+        '#suffix' => '</span>',
+      ];
+      return $element;
+    }
+  }
+
+  /**
+   * Creates an url object for diff.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity to be compared.
+   * @param $left_vid
+   *   Vid of the left revision.
+   * @param $right_vid
+   *   Vid of the right revision.
+   * @param $filter
+   *   (optional) The filter added to the route.
+   *
+   * @return \Drupal\Core\Url
+   *   The URL object.
+   */
+  public function diffRoute(EntityInterface $entity, $left_vid, $right_vid, $filter = NULL) {
+    $entity_type_id = $entity->getEntityTypeId();
+    // @todo Remove the diff.revisions_diff route so we avoid adding extra cases.
+    if ($entity->getEntityTypeId() == 'node') {
+      $route_name = 'diff.revisions_diff';
+    }
+    else {
+      $route_name = "entity.$entity_type_id.revisions_diff";
+    }
+    $route_parameters = [
+      $entity_type_id => $entity->id(),
+      'left_revision' => $left_vid,
+      'right_revision' => $right_vid,
+    ];
+    if ($filter) {
+      $route_parameters['filter'] = $filter;
+    }
+    return Url::fromRoute($route_name, $route_parameters);
+  }
+
+}
\ No newline at end of file
diff --git a/src/DiffEntityComparison.php b/src/DiffEntityComparison.php
index 8184326..244e168 100644
--- a/src/DiffEntityComparison.php
+++ b/src/DiffEntityComparison.php
@@ -90,18 +90,19 @@ class DiffEntityComparison {
       $result[$left_key] = [
         '#name' => (isset($compare_settings['settings']['show_header']) && $compare_settings['settings']['show_header'] == 0) ? '' : $values['label'],
         '#settings' => $compare_settings,
+        '#data' => [],
       ];
 
       // Fields which exist on the right entity also.
       if (isset($right_values[$left_key])) {
-        $result[$left_key] += $this->combineFields($left_values[$left_key], $right_values[$left_key]);
+        $result[$left_key]['#data'] += $this->combineFields($left_values[$left_key], $right_values[$left_key]);
         // Unset the field from the right entity so that we know if the right
         // entity has any fields that left entity doesn't have.
         unset($right_values[$left_key]);
       }
       // This field exists only on the left entity.
       else {
-        $result[$left_key] += $this->combineFields($left_values[$left_key], []);
+        $result[$left_key]['#data'] += $this->combineFields($left_values[$left_key], []);
       }
     }
 
@@ -112,42 +113,24 @@ class DiffEntityComparison {
       $result[$right_key] = [
         '#name' => (isset($compare_settings['settings']['show_header']) && $compare_settings['settings']['show_header'] == 0) ? '' : $values['label'],
         '#settings' => $compare_settings,
+        '#data' => [],
       ];
-      $result[$right_key] += $this->combineFields([], $right_values[$right_key]);
+      $result[$right_key]['#data'] += $this->combineFields([], $right_values[$right_key]);
     }
 
     // Field rows. Recurse through all child elements.
     foreach (Element::children($result) as $key) {
-      $result[$key]['#states'] = array();
       // Ensure that the element follows the #states format.
-      if (isset($result[$key]['#left'])) {
+      if (isset($result[$key]['#data']['#left'])) {
         // We need to trim spaces and new lines from the end of the string
         // otherwise in some cases we have a blank not needed line.
-        $result[$key]['#states']['raw']['#left'] = trim($result[$key]['#left']);
-        unset($result[$key]['#left']);
+        $result[$key]['#data']['#left'] = trim($result[$key]['#data']['#left']);
       }
-      if (isset($result[$key]['#right'])) {
-        $result[$key]['#states']['raw']['#right'] = trim($result[$key]['#right']);
-        unset($result[$key]['#right']);
-      }
-      $field_settings = $result[$key]['#settings'];
-
-      if (!empty($field_settings['settings']['markdown'])) {
-        $result[$key]['#states']['raw_plain']['#left'] = $this->applyMarkdown($field_settings['settings']['markdown'], $result[$key]['#states']['raw']['#left']);
-        $result[$key]['#states']['raw_plain']['#right'] = $this->applyMarkdown($field_settings['settings']['markdown'], $result[$key]['#states']['raw']['#right']);
-      }
-      // In case the settings are not loaded correctly use drupal_html_to_text
-      // to avoid any possible notices when a user clicks on markdown.
-      else {
-        $result[$key]['#states']['raw_plain']['#left'] = $this->applyMarkdown('drupal_html_to_text', $result[$key]['#states']['raw']['#left']);
-        $result[$key]['#states']['raw_plain']['#right'] = $this->applyMarkdown('drupal_html_to_text', $result[$key]['#states']['raw']['#right']);
+      if (isset($result[$key]['#data']['#right'])) {
+        $result[$key]['#data']['#right'] = trim($result[$key]['#data']['#right']);
       }
     }
 
-    // Process the array (split the strings into single line strings)
-    // and get line counts per field.
-    array_walk($result, array($this, 'processStateLine'));
-
     return $result;
   }
 
@@ -231,57 +214,25 @@ class DiffEntityComparison {
    * @param $diff
    *   Array of strings.
    */
-  protected function processStateLine(&$diff) {
-    foreach ($diff['#states'] as $state => $data) {
-      if (isset($data['#left'])) {
-        if (is_string($data['#left'])) {
-          $diff['#states'][$state]['#left'] = explode("\n", $data['#left']);
-        }
-        $diff['#states'][$state]['#count_left'] = count($diff['#states'][$state]['#left']);
-      }
-      else {
-        $diff['#states'][$state]['#count_left'] = 0;
-      }
-      if (isset($data['#right'])) {
-        if (is_string($data['#right'])) {
-          $diff['#states'][$state]['#right'] = explode("\n", $data['#right']);
-        }
-        $diff['#states'][$state]['#count_right'] = count($diff['#states'][$state]['#right']);
-      }
-      else {
-        $diff['#states'][$state]['#count_right'] = 0;
+  public function processStateLine(&$diff) {
+    $data = $diff['#data'];
+    if (isset($data['#left'])) {
+      if (is_string($data['#left'])) {
+        $diff['#data']['#left'] = explode("\n", $data['#left']);
       }
+      $diff['#data']['#count_left'] = count($diff['#data']['#left']);
     }
-  }
-
-  /**
-   * Applies a markdown function to a string.
-   *
-   * @param $markdown
-   *   Key of the markdown function to be applied to the items.
-   *   One of drupal_html_to_text, filter_xss, filter_xss_all.
-   * @param $items
-   *   String to be processed.
-   *
-   * @return array|string
-   *   Result after markdown was applied on $items.
-   */
-  protected function applyMarkdown($markdown, $items) {
-    if (!$markdown) {
-      return $items;
-    }
-
-    if ($markdown == 'drupal_html_to_text') {
-      return trim(MailFormatHelper::htmlToText($items), "\n");
-    }
-    elseif ($markdown == 'filter_xss') {
-      return trim(Xss::filter($items), "\n");
+    else {
+      $diff['#data']['#count_left'] = 0;
     }
-    elseif ($markdown == 'filter_xss_all') {
-      return trim(Xss::filter($items, array()), "\n");
+    if (isset($data['#right'])) {
+      if (is_string($data['#right'])) {
+        $diff['#data']['#right'] = explode("\n", $data['#right']);
+      }
+      $diff['#data']['#count_right'] = count($diff['#data']['#right']);
     }
     else {
-      return $items;
+      $diff['#data']['#count_right'] = 0;
     }
   }
 
diff --git a/src/DiffLayoutBase.php b/src/DiffLayoutBase.php
new file mode 100644
index 0000000..8f67beb
--- /dev/null
+++ b/src/DiffLayoutBase.php
@@ -0,0 +1,124 @@
+<?php
+
+namespace Drupal\diff;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+abstract class DiffLayoutBase extends PluginBase implements DiffLayoutInterface, ContainerFactoryPluginInterface {
+
+  use StringTranslationTrait;
+
+  /**
+   * Contains the configuration object factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The entity parser.
+   *
+   * @var \Drupal\diff\DiffEntityParser
+   */
+  protected $entityParser;
+
+  /**
+   * Constructs a FieldDiffBuilderBase object.
+   *
+   * @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\Config\ConfigFactoryInterface $config
+   *   The configuration factory object.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity manager.
+   * @param \Drupal\diff\DiffEntityParser $entityParser
+   *   The entity manager.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config, EntityTypeManagerInterface $entity_type_manager, DiffEntityParser $entityParser) {
+    $this->configFactory = $config;
+    $this->entityTypeManager = $entity_type_manager;
+    $this->entityParser = $entityParser;
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+    $this->configuration += $this->defaultConfiguration();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('config.factory'),
+      $container->get('entity.manager'),
+      $container->get('diff.entity_parser')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    // @todo Implement buildConfigurationForm() method.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+    // @todo Implement validateConfigurationForm() method.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    // @todo Implement submitConfigurationForm() method.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfiguration() {
+    // @todo Implement getConfiguration() method.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setConfiguration(array $configuration) {
+    // @todo Implement setConfiguration() method.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function calculateDependencies() {
+    return [];
+  }
+}
diff --git a/src/DiffLayoutInterface.php b/src/DiffLayoutInterface.php
new file mode 100644
index 0000000..dcfccc5
--- /dev/null
+++ b/src/DiffLayoutInterface.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\diff;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Plugin\PluginFormInterface;
+use Drupal\Component\Plugin\ConfigurablePluginInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+
+interface DiffLayoutInterface extends PluginFormInterface, ConfigurablePluginInterface {
+
+  /**
+   * Builds a diff comparison between two revisions.
+   *
+   * This method is responsible for building the diff comparison between
+   * revisions of the same entity. It can build a table, navigation links and
+   * headers of a diff comparison.
+   *
+   * @see \Drupal\diff\Plugin\Layout\ClassicDiffLayout
+   *
+   * @param array $build
+   *   A renderable array of data.
+   * @param \Drupal\Core\Entity\EntityInterface $left_revision
+   *   The left revision.
+   * @param \Drupal\Core\Entity\EntityInterface $right_revision
+   *   The right revision.
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity.
+   *
+   * @return mixed
+   *   The modified build array that the plugin builds.
+   */
+  public function build(array $build, EntityInterface $left_revision, EntityInterface $right_revision, EntityInterface $entity);
+}
diff --git a/src/DiffLayoutManager.php b/src/DiffLayoutManager.php
new file mode 100644
index 0000000..9d3f781
--- /dev/null
+++ b/src/DiffLayoutManager.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Drupal\diff;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Plugin type manager for field diff builders.
+ *
+ * @ingroup diff_layout_builder
+ */
+class DiffLayoutManager extends DefaultPluginManager {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * Wrapper object for writing/reading simple configuration from diff.settings.yml
+   */
+  protected $config;
+
+  /**
+   * Wrapper object for writing/reading simple configuration from diff.plugins.yml
+   */
+  protected $layoutPluginsConfig;
+
+  /**
+   * Constructs a DiffLayoutManager object.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param EntityTypeManagerInterface $entity_type_manager
+   *   Entity Manager service.
+   * @param ConfigFactoryInterface $configFactory
+   *   The configuration factory.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $configFactory) {
+    parent::__construct('Plugin/Layout', $namespaces, $module_handler, '\Drupal\diff\DiffLayoutInterface', 'Drupal\diff\Annotation\DiffLayoutBuilder');
+
+    $this->entityTypeManager = $entity_type_manager;
+    $this->config = $configFactory->get('diff.settings');
+    $this->layoutPluginsConfig =  $configFactory->get('diff.layout_plugins');
+  }
+
+}
diff --git a/src/Plugin/Layout/ClassicDiffLayout.php b/src/Plugin/Layout/ClassicDiffLayout.php
new file mode 100644
index 0000000..9afeb2e
--- /dev/null
+++ b/src/Plugin/Layout/ClassicDiffLayout.php
@@ -0,0 +1,200 @@
+<?php
+
+namespace Drupal\diff\Plugin\Layout;
+
+use Drupal\Component\Utility\Xss;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Datetime\DateFormatter;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\Core\Url;
+use Drupal\diff\DiffEntityComparison;
+use Drupal\diff\DiffEntityParser;
+use Drupal\diff\DiffLayoutBase;
+use Drupal\node\NodeInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * @DiffLayoutBuilder(
+ *   id = "classic_layout",
+ *   label = @Translation("Standard"),
+ * )
+ */
+class ClassicDiffLayout extends DiffLayoutBase {
+
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * The diff entity comparison service.
+   */
+  protected $entityComparison;
+
+  /**
+   * The date service.
+   *
+   * @var \Drupal\Core\Datetime\DateFormatter
+   */
+  protected $date;
+
+  /**
+   * Constructs a FieldDiffBuilderBase object.
+   *
+   * @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\Config\ConfigFactoryInterface $config
+   *   The configuration factory object.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity manager.
+   * @param \Drupal\diff\DiffEntityParser $entityParser
+   *   The entity manager.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config, EntityTypeManagerInterface $entity_type_manager, DiffEntityParser $entityParser, RendererInterface $renderer, DiffEntityComparison $entityComparison, DateFormatter $date) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $config, $entity_type_manager, $entityParser);
+    $this->renderer = $renderer;
+    $this->entityComparison = $entityComparison;
+    $this->date = $date;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('config.factory'),
+      $container->get('entity.manager'),
+      $container->get('diff.entity_parser'),
+      $container->get('renderer'),
+      $container->get('diff.entity_comparison'),
+      $container->get('date.formatter')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build(array $build, EntityInterface $left_revision, EntityInterface $right_revision, EntityInterface $entity) {
+    $diff_header = $this->buildTableHeader($left_revision, $right_revision);
+    // Perform comparison only if both entity revisions loaded successfully.
+    $fields = $this->entityComparison->compareRevisions($left_revision, $right_revision);
+    // Build the diff rows for each field and append the field rows
+    // to the table rows.
+    $diff_rows = [];
+    foreach ($fields as $field) {
+      $field_label_row = '';
+      if (!empty($field['#name'])) {
+        $field_label_row = [
+          'data' => $this->t('%name', ['%name' => $field['#name']]),
+          'colspan' => 4,
+          'class' => ['field-name'],
+        ];
+      }
+
+      // Process the array (split the strings into single line strings)
+      // and get line counts per field.
+      $this->entityComparison->processStateLine($field);
+
+      $field_diff_rows = $this->entityComparison->getRows(
+        $field['#data']['#left'],
+        $field['#data']['#right']
+      );
+
+      // Add the field label to the table only if there are changes to that field.
+      if (!empty($field_diff_rows) && !empty($field_label_row)) {
+        $diff_rows[] = [$field_label_row];
+      }
+
+      // Add field diff rows to the table rows.
+      $diff_rows = array_merge($diff_rows, $field_diff_rows);
+    }
+
+    $build['diff'] = [
+      '#type' => 'table',
+      '#header' => $diff_header,
+      '#rows' => $diff_rows,
+      '#empty' => $this->t('No visible changes'),
+      '#attributes' => [
+        'class' => ['diff'],
+      ],
+    ];
+
+    $build['#attached']['library'][] = 'diff/diff.github';
+    return $build;
+  }
+
+
+  /**
+   * Build the header for the diff table.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $left_revision
+   *   Revision from the left hand side.
+   * @param \Drupal\Core\Entity\EntityInterface $right_revision
+   *   Revision from the right hand side.
+   *
+   * @return array
+   *   Header for Diff table.
+   */
+  protected function buildTableHeader(EntityInterface $left_revision, EntityInterface $right_revision) {
+    $header = [];
+    $header[] = [
+      'data' => ['#markup' => $this->buildRevisionLink($left_revision)],
+      'colspan' => 2,
+    ];
+    $header[] = [
+      'data' => ['#markup' => $this->buildRevisionLink($right_revision)],
+      'colspan' => 2,
+    ];
+
+    return $header;
+  }
+
+  /**
+   * Build the revision link for a revision.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $revision
+   *   A revision where to add a link.
+   *
+   * @return \Drupal\Core\GeneratedLink
+   *   Header link for a revision in the table.
+   */
+  protected function buildRevisionLink(EntityInterface $revision) {
+    $entity_type_id = $revision->getEntityTypeId();
+    if ($revision instanceof EntityRevisionLogInterface || $revision instanceof NodeInterface) {
+      $revision_log = '';
+
+      if ($revision instanceof EntityRevisionLogInterface) {
+        $revision_log = Xss::filter($revision->getRevisionLogMessage());
+      }
+      elseif ($revision instanceof NodeInterface) {
+        $revision_log = $revision->revision_log->value;
+      }
+      $revision_date = $this->date->format($revision->getRevisionCreationTime(), 'short');
+      $route_name = $entity_type_id != 'node' ? "entity.$entity_type_id.revisions_diff" : 'entity.node.revision';
+      $revision_link = $this->t($revision_log . '@date', [
+        '@date' => \Drupal::l($revision_date, Url::fromRoute($route_name, [
+          $entity_type_id => $revision->id(),
+          $entity_type_id . '_revision' => $revision->getRevisionId(),
+        ])),
+      ]);
+    }
+    else {
+      $revision_link = \Drupal::l($revision->label(), $revision->toUrl('revision'));
+    }
+    return $revision_link;
+  }
+
+}
diff --git a/src/Plugin/Layout/MarkdownDiffLayout.php b/src/Plugin/Layout/MarkdownDiffLayout.php
new file mode 100644
index 0000000..4d2d6a4
--- /dev/null
+++ b/src/Plugin/Layout/MarkdownDiffLayout.php
@@ -0,0 +1,244 @@
+<?php
+
+namespace Drupal\diff\Plugin\Layout;
+
+use Drupal\Component\Utility\Xss;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Datetime\DateFormatter;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Mail\MailFormatHelper;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\Core\Url;
+use Drupal\diff\DiffEntityComparison;
+use Drupal\diff\DiffEntityParser;
+use Drupal\diff\DiffLayoutBase;
+use Drupal\node\NodeInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * @DiffLayoutBuilder(
+ *   id = "markdown_layout",
+ *   label = @Translation("Markdown"),
+ * )
+ */
+class MarkdownDiffLayout extends DiffLayoutBase {
+
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * The diff entity comparison service.
+   */
+  protected $entityComparison;
+
+  /**
+   * The date service.
+   *
+   * @var \Drupal\Core\Datetime\DateFormatter
+   */
+  protected $date;
+
+  /**
+   * Constructs a FieldDiffBuilderBase object.
+   *
+   * @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\Config\ConfigFactoryInterface $config
+   *   The configuration factory object.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity manager.
+   * @param \Drupal\diff\DiffEntityParser $entityParser
+   *   The entity manager.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config, EntityTypeManagerInterface $entity_type_manager, DiffEntityParser $entityParser, RendererInterface $renderer, DiffEntityComparison $entityComparison, DateFormatter $date) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $config, $entity_type_manager, $entityParser);
+    $this->renderer = $renderer;
+    $this->entityComparison = $entityComparison;
+    $this->date = $date;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('config.factory'),
+      $container->get('entity.manager'),
+      $container->get('diff.entity_parser'),
+      $container->get('renderer'),
+      $container->get('diff.entity_comparison'),
+      $container->get('date.formatter')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build(array $build, EntityInterface $left_revision, EntityInterface $right_revision, EntityInterface $entity) {
+    $diff_header = $this->buildTableHeader($left_revision, $right_revision);
+    // Perform comparison only if both entity revisions loaded successfully.
+    $fields = $this->entityComparison->compareRevisions($left_revision, $right_revision);
+    // Build the diff rows for each field and append the field rows
+    // to the table rows.
+    $diff_rows = [];
+    foreach ($fields as $field) {
+      $field_label_row = '';
+      if (!empty($field['#name'])) {
+        $field_label_row = [
+          'data' => $this->t('%name', ['%name' => $field['#name']]),
+          'colspan' => 4,
+          'class' => ['field-name'],
+        ];
+      }
+      $field_settings = $field['#settings'];
+      if (!empty($field_settings['settings']['markdown'])) {
+        $field['#data']['#left'] = $this->applyMarkdown($field_settings['settings']['markdown'], $field['#data']['#left']);
+        $field['#data']['#right'] = $this->applyMarkdown($field_settings['settings']['markdown'], $field['#data']['#right']);
+      }
+      // In case the settings are not loaded correctly use drupal_html_to_text
+      // to avoid any possible notices when a user clicks on markdown.
+      else {
+        $field['#data']['#left'] = $this->applyMarkdown('drupal_html_to_text', $field['#data']['#left']);
+        $field['#data']['#right'] = $this->applyMarkdown('drupal_html_to_text', $field['#data']['#right']);
+      }
+
+      // Process the array (split the strings into single line strings)
+      // and get line counts per field.
+      $this->entityComparison->processStateLine($field);
+
+      $field_diff_rows = $this->entityComparison->getRows(
+        $field['#data']['#left'],
+        $field['#data']['#right']
+      );
+
+      // Add the field label to the table only if there are changes to that field.
+      if (!empty($field_diff_rows) && !empty($field_label_row)) {
+        $diff_rows[] = [$field_label_row];
+      }
+
+      // Add field diff rows to the table rows.
+      $diff_rows = array_merge($diff_rows, $field_diff_rows);
+    }
+
+    $build['diff'] = [
+      '#type' => 'table',
+      '#header' => $diff_header,
+      '#rows' => $diff_rows,
+      '#empty' => $this->t('No visible changes'),
+      '#attributes' => [
+        'class' => ['diff'],
+      ],
+    ];
+
+    $build['#attached']['library'][] = 'diff/diff.github';
+    return $build;
+  }
+
+
+  /**
+   * Build the header for the diff table.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $left_revision
+   *   Revision from the left hand side.
+   * @param \Drupal\Core\Entity\EntityInterface $right_revision
+   *   Revision from the right hand side.
+   *
+   * @return array
+   *   Header for Diff table.
+   */
+  protected function buildTableHeader(EntityInterface $left_revision, EntityInterface $right_revision) {
+    $header = [];
+    $header[] = [
+      'data' => ['#markup' => $this->buildRevisionLink($left_revision)],
+      'colspan' => 2,
+    ];
+    $header[] = [
+      'data' => ['#markup' => $this->buildRevisionLink($right_revision)],
+      'colspan' => 2,
+    ];
+
+    return $header;
+  }
+
+  /**
+   * Build the revision link for a revision.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $revision
+   *   A revision where to add a link.
+   *
+   * @return \Drupal\Core\GeneratedLink
+   *   Header link for a revision in the table.
+   */
+  protected function buildRevisionLink(EntityInterface $revision) {
+    $entity_type_id = $revision->getEntityTypeId();
+    if ($revision instanceof EntityRevisionLogInterface || $revision instanceof NodeInterface) {
+      $revision_log = '';
+
+      if ($revision instanceof EntityRevisionLogInterface) {
+        $revision_log = Xss::filter($revision->getRevisionLogMessage());
+      }
+      elseif ($revision instanceof NodeInterface) {
+        $revision_log = $revision->revision_log->value;
+      }
+      $revision_date = $this->date->format($revision->getRevisionCreationTime(), 'short');
+      $route_name = $entity_type_id != 'node' ? "entity.$entity_type_id.revisions_diff" : 'entity.node.revision';
+      $revision_link = $this->t($revision_log . '@date', [
+        '@date' => \Drupal::l($revision_date, Url::fromRoute($route_name, [
+          $entity_type_id => $revision->id(),
+          $entity_type_id . '_revision' => $revision->getRevisionId(),
+        ])),
+      ]);
+    }
+    else {
+      $revision_link = \Drupal::l($revision->label(), $revision->toUrl('revision'));
+    }
+    return $revision_link;
+  }
+
+
+  /**
+   * Applies a markdown function to a string.
+   *
+   * @param $markdown
+   *   Key of the markdown function to be applied to the items.
+   *   One of drupal_html_to_text, filter_xss, filter_xss_all.
+   * @param $items
+   *   String to be processed.
+   *
+   * @return array|string
+   *   Result after markdown was applied on $items.
+   */
+  protected function applyMarkdown($markdown, $items) {
+    if (!$markdown) {
+      return $items;
+    }
+
+    if ($markdown == 'drupal_html_to_text') {
+      return trim(MailFormatHelper::htmlToText($items), "\n");
+    }
+    elseif ($markdown == 'filter_xss') {
+      return trim(Xss::filter($items), "\n");
+    }
+    elseif ($markdown == 'filter_xss_all') {
+      return trim(Xss::filter($items, []), "\n");
+    }
+    else {
+      return $items;
+    }
+  }
+
+}
diff --git a/src/Routing/DiffRouteProvider.php b/src/Routing/DiffRouteProvider.php
index b825b54..0c0cd2e 100644
--- a/src/Routing/DiffRouteProvider.php
+++ b/src/Routing/DiffRouteProvider.php
@@ -36,8 +36,8 @@ class DiffRouteProvider implements EntityRouteProviderInterface {
     if ($entity_type->hasLinkTemplate('revisions-diff')) {
       $route = new Route($entity_type->getLinkTemplate('revisions-diff'));
       $route->addDefaults([
-        '_controller' => '\Drupal\diff\Controller\GenericRevisionController::compareEntityRevisions',
-        'filter' => 'raw',
+        '_controller' => '\Drupal\diff\Controller\PluginRevisionController::compareEntityRevisions',
+        'filter' => 'classic_layout',
       ]);
       $route->addRequirements([
         '_entity_access' => $entity_type->id() . '.view',
diff --git a/src/Tests/DiffPluginTest.php b/src/Tests/DiffPluginTest.php
index 405c0b6..cfeab4d 100644
--- a/src/Tests/DiffPluginTest.php
+++ b/src/Tests/DiffPluginTest.php
@@ -221,7 +221,6 @@ class DiffPluginTest extends DiffTestBase {
     // "changed" field is not displayed since there is no plugin for it. This
     // should not break the revisions comparison display.
     $this->assertResponse(200);
-    $this->assertLink(t('Back to Revision Overview'));
     $this->assertLink(t('Standard'));
   }
 
diff --git a/src/Tests/DiffRevisionTest.php b/src/Tests/DiffRevisionTest.php
index 97df3bf..310037c 100644
--- a/src/Tests/DiffRevisionTest.php
+++ b/src/Tests/DiffRevisionTest.php
@@ -95,8 +95,8 @@ class DiffRevisionTest extends DiffTestBase {
     $this->assertEqual((string) (($diff_row[3]->span)), '2');
     $this->assertEqual(htmlspecialchars_decode((strip_tags($diff_row[3]->asXML()))), 'Revision 2');
 
-    // Go back to revision overview.
-    $this->clickLink(t('Back to Revision Overview'));
+    $this->drupalGet('node/' . $node->id());
+    $this->clickLink(t('Revisions'));
     // Revert the revision, confirm.
     $this->clickLink(t('Revert'));
     $this->drupalPostForm(NULL, NULL, t('Revert'));
