diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index 77ef530..514032f 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -727,19 +727,18 @@ function template_preprocess_forum_list(&$variables) {
 function template_preprocess_forum_topic_list(&$variables) {
   global $forum_topic_list_header;
 
-  $header = '';
+  $variables['table'] = array(
+    '#theme' => 'table',
+    '#attributes' => array('id' => 'forum-topic-' . $variables['tid']),
+    '#header' => array(),
+    '#rows' => array(),
+  );
+
   if (!empty($forum_topic_list_header)) {
-    // Create the tablesorting header.
-    $ts = tablesort_init($forum_topic_list_header);
-    foreach ($forum_topic_list_header as $cell) {
-      $cell = tablesort_header($cell, $forum_topic_list_header, $ts);
-      $header .= _theme_table_cell($cell, TRUE);
-    }
+    $variables['table']['#header'] = $forum_topic_list_header;
   }
-  $variables['header'] = $header;
 
   if (!empty($variables['topics'])) {
-    $row = 0;
     foreach ($variables['topics'] as $id => $topic) {
       $variables['topics'][$id]->icon = array(
         '#theme' => 'forum_icon',
@@ -749,8 +748,6 @@ function template_preprocess_forum_topic_list(&$variables) {
         '#sticky' => $topic->isSticky(),
         '#first_new' => $topic->first_new,
       );
-      $variables['topics'][$id]->zebra = $row % 2 == 0 ? 'odd' : 'even';
-      $row++;
 
       // We keep the actual tid in forum table, if it's different from the
       // current tid then it means the topic appears in two forums, one of
@@ -779,20 +776,50 @@ function template_preprocess_forum_topic_list(&$variables) {
 
       $variables['topics'][$id]->new_text = '';
       $variables['topics'][$id]->new_url = '';
+
       if ($topic->new_replies) {
         $variables['topics'][$id]->new_text = format_plural($topic->new_replies, '1 new post<span class="visually-hidden"> in topic %title</span>', '@count new posts<span class="visually-hidden"> in topic %title</span>', array('%title' => $variables['topics'][$id]->label()));
         $variables['topics'][$id]->new_url = url('node/' . $topic->id(), array('query' => comment_new_page_count($topic->comment_count, $topic->new_replies, $topic, 'comment_node_forum'), 'fragment' => 'new'));
       }
+    }
 
+    // Build table rows from topics.
+    foreach ($variables['topics'] as $topic) {
+      $row = array();
+      $row[] = array(
+        'data' => array(
+          $topic->icon,
+          array(
+            '#markup' => '<div class="title"><div>' . $topic->title_link . '</div><div>' . $topic->submitted . '</div></div>',
+          ),
+        ),
+        'class' => array('topic'),
+      );
+
+      if ($topic->moved) {
+        $row[] = array(
+          'data' => $topic->message,
+          'colspan' => '2',
+        );
+      }
+      else {
+        $new_replies = '';
+        if ($topic->new_replies) {
+          $new_replies = '<br /><a href="' . $topic->new_url . '">' . $topic->new_text . '</a>';
+        }
+
+        $row[] = array(
+          'data' => $topic->comment_count . $new_replies,
+          'class' => array('replies'),
+        );
+        $row[] = array(
+          'data' => $topic->last_reply,
+          'class' => array('last-reply'),
+        );
+      }
+      $variables['table']['#rows'][] = $row;
     }
   }
-  else {
-    // Make this safe for the template.
-    $variables['topics'] = array();
-  }
-  // Give meaning to $tid for themers. $tid actually stands for term id.
-  $variables['topic_id'] = $variables['tid'];
-  unset($variables['tid']);
 
   $variables['pager'] = array(
     '#theme' => 'pager',
diff --git a/core/modules/forum/templates/forum-topic-list.html.twig b/core/modules/forum/templates/forum-topic-list.html.twig
index 0e8cd16..8204daf 100644
--- a/core/modules/forum/templates/forum-topic-list.html.twig
+++ b/core/modules/forum/templates/forum-topic-list.html.twig
@@ -4,65 +4,13 @@
  * Default theme implementation to display a list of forum topics.
  *
  * Available variables:
- * - header: The table header. This is pre-generated with click-sorting
- *   information. If you need to change this, see
- *   template_preprocess_forum_topic_list().
+ * - table: The topic list table.
  * - pager: The pager to display beneath the table.
- * - topics: A collection of topics to be displayed. Each topic in topics
- *   contains:
- *   - icon: The icon to display.
- *   - moved: A flag to indicate whether the topic has been moved to another
- *     forum.
- *   - title_link: The title of the topic. Safe to output.
- *   - message: If the topic has been moved, this contains an explanation and a
- *     link.
- *   - zebra: 'even' or 'odd', used for row class.
- *   - comment_count: The number of replies on this topic.
- *   - new_replies: A flag to indicate whether there are unread comments.
- *   - new_url: If there are unread replies, this is a link to them.
- *   - new_text: Text containing the translated, properly pluralized count.
- *   - submitted: Text representing when the topic was posted. Safe to output.
- *   - last_reply: Text representing when the topic was last replied to.
- *   - timestamp: The raw timestamp this topic was posted.
- * - topic_id: Numeric ID for the current forum topic.
  *
  * @see template_preprocess_forum_topic_list()
  *
  * @ingroup themeable
  */
 #}
-<table id="forum-topic-{{ topic_id }}">
-  <thead>
-    <tr>{{ header }}</tr>
-  </thead>
-  <tbody>
-  {% for topic in topics %}
-    <tr class="{{ topic.zebra }}">
-      <td class="topic">
-        {{ topic.icon }}
-        <div class="title">
-          <div>
-            {{ topic.title_link }}
-          </div>
-          <div>
-            {{ topic.submitted }}
-          </div>
-        </div>
-      </td>
-    {% if topic.moved %}
-      <td colspan="3">{{ topic.message }}</td>
-    {% else %}
-      <td class="replies">
-        {{ topic.comment_count }}
-        {% if topic.new_replies %}
-          <br />
-          <a href="{{ topic.new_url }}">{{ topic.new_text }}</a>
-        {% endif %}
-      </td>
-      <td class="last-reply">{{ topic.last_reply }}</td>
-    {% endif %}
-    </tr>
-  {% endfor %}
-  </tbody>
-</table>
+{{ table }}
 {{ pager }}
