diff --git a/app/assets/javascripts/moderator.js b/app/assets/javascripts/moderator.js
index ea6e95d50b44e39161f16adeded83eb984deeb15..3f92f61303a82955fc443bbb36d502e009865f39 100644
--- a/app/assets/javascripts/moderator.js
+++ b/app/assets/javascripts/moderator.js
@@ -1,5 +1,5 @@
 $(() => {
-  $('.js-convert-to-comment, .js-toggle-comments').on('ajax:success', ev => {
+  $('.js-convert-to-comment, .js-toggle-comments, .js-feature-post').on('ajax:success', ev => {
     location.reload();
   });
 });
\ No newline at end of file
diff --git a/app/assets/javascripts/pinned_links.coffee b/app/assets/javascripts/pinned_links.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..24f83d18bbd38c24c4f7c3c2fc360cd68e857a2a
--- /dev/null
+++ b/app/assets/javascripts/pinned_links.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index fe592dab45dde77b2483e2c92eca24a1b18c6ebb..48069d35470d677ea62d5352c7e6c5987f7f9a6f 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -182,4 +182,11 @@ img {
 
 .droppanel {
   z-index: 3;
+}
+
+.widget .widget--body + .widget--header {
+  border-top: 1px solid #d0d9dd;
+}
+.widget.is-tertiary .widget--body + .widget--header {
+  border-top: 1px solid #9daeb7;
 }
\ No newline at end of file
diff --git a/app/assets/stylesheets/pinned_links.scss b/app/assets/stylesheets/pinned_links.scss
new file mode 100644
index 0000000000000000000000000000000000000000..78805fa39484626dcffd98e19c94cc27c91d653f
--- /dev/null
+++ b/app/assets/stylesheets/pinned_links.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the PinnedLinks controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/controllers/advertisement_controller.rb b/app/controllers/advertisement_controller.rb
index 754d2fdf8e923faf2ee131bc3be2e9ff80351d26..579f9aaf3241492f88ec66353641469cf87c6437 100644
--- a/app/controllers/advertisement_controller.rb
+++ b/app/controllers/advertisement_controller.rb
@@ -1,6 +1,7 @@
 require 'rmagick'
 
 # Neccessary due to rmagick
+# rubocop:disable Metrics/ClassLength
 # rubocop:disable Metrics/MethodLength
 # rubocop:disable Metrics/AbcSize
 # rubocop:disable Metrics/BlockLength
@@ -146,10 +147,29 @@ class AdvertisementController < ApplicationController
     end
   end
 
+  def specific_category
+    @category = Category.find(params[:id])
+    @post = Rails.cache.fetch "community/#{RequestContext.community_id}/ca_random_category_post/#{params[:id]}",
+                              expires_in: 5.minutes do
+      select_random_post(@category)
+    end
+    if @post.question?
+      question_ad(@post)
+    elsif @post.article?
+      article_ad(@post)
+    else
+      not_found
+    end
+  end
+
   def random_question
-    @post = Rails.cache.fetch "community/#{RequestContext.community_id}/random_hot_post", expires_in: 5.minutes do
-      @hot_questions.sample
+    @post = Rails.cache.fetch "community/#{RequestContext.community_id}/ca_random_hot_post", expires_in: 5.minutes do
+      select_random_post
     end
+    if @post.nil?
+      return community
+    end
+
     if @post.question?
       question_ad(@post)
     elsif @post.article?
@@ -161,6 +181,17 @@ class AdvertisementController < ApplicationController
 
   private
 
+  def select_random_post(category = nil)
+    if category.nil?
+      category = Category.where(use_for_advertisement: true)
+    end
+    Post.undeleted.where(last_activity: (Rails.env.development? ? 365 : 7).days.ago..Time.now)
+        .where(post_type_id: Question.post_type_id)
+        .where(category: category)
+        .where('score > ?', SiteSetting['HotPostsScoreThreshold'])
+        .order('score DESC').limit(SiteSetting['HotQuestionsCount']).all.sample
+  end
+
   def wrap_text(text, width, font_size)
     columns = (width * 2.0 / font_size).to_i
     # Source: http://viseztrance.com/2011/03/texts-over-multiple-lines-with-rmagick.html
@@ -327,5 +358,6 @@ class AdvertisementController < ApplicationController
   end
 end
 # rubocop:enable Metrics/MethodLength
+# rubocop:enable Metrics/ClassLength
 # rubocop:enable Metrics/AbcSize
 # rubocop:enable Metrics/BlockLength
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index ad159bf37c2f6b0556456810697432cc49e0e2d0..67c1ca2dd9fc49b032df382b1b17e4c49d9f3a49 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -108,7 +108,7 @@ class ApplicationController < ActionController::Base
     setup_request_context || return
     setup_user
 
-    pull_hot_questions
+    pull_pinned_links_and_hot_questions
     pull_categories
 
     if user_signed_in? && (current_user.is_moderator || current_user.is_admin)
@@ -150,12 +150,19 @@ class ApplicationController < ActionController::Base
     end
   end
 
-  def pull_hot_questions
+  def pull_pinned_links_and_hot_questions
+    @pinned_links = Rails.cache.fetch("#{RequestContext.community_id}/pinned_links", expires_in: 2.hours) do
+      Rack::MiniProfiler.step 'pinned_links: cache miss' do
+        PinnedLink.where(active: true).where('shown_before IS NULL OR shown_before > NOW()').all
+      end
+    end
     @hot_questions = Rails.cache.fetch("#{RequestContext.community_id}/hot_questions", expires_in: 4.hours) do
       Rack::MiniProfiler.step 'hot_questions: cache miss' do
         Post.undeleted.where(last_activity: (Rails.env.development? ? 365 : 7).days.ago..Time.now)
-            .where(post_type_id: Question.post_type_id).includes(:category)
-            .order('score DESC').limit(SiteSetting['HotQuestionsCount'])
+            .where(post_type_id: Question.post_type_id)
+            .where(category: Category.where(use_for_hot_posts: true))
+            .where('score > ?', SiteSetting['HotPostsScoreThreshold'])
+            .order('score DESC').limit(SiteSetting['HotQuestionsCount']).all
       end
     end
   end
diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb
index c1b4f2a952cfa4aad7b4aa1bdca52cfeae5bf808..b9d0fa28f47dbce5cb1f0accdcc6fbbf8b24e594 100644
--- a/app/controllers/categories_controller.rb
+++ b/app/controllers/categories_controller.rb
@@ -92,6 +92,8 @@ class CategoriesController < ApplicationController
   def category_params
     params.require(:category).permit(:name, :short_wiki, :tag_set_id, :is_homepage, :min_trust_level, :button_text,
                                      :color_code, :min_view_trust_level, :license_id, :sequence,
+                                     :asking_guidance_override, :answering_guidance_override,
+                                     :use_for_hot_posts, :use_for_advertisement,
                                      display_post_types: [], post_type_ids: [], required_tag_ids: [],
                                      topic_tag_ids: [], moderator_tag_ids: [])
   end
diff --git a/app/controllers/moderator_controller.rb b/app/controllers/moderator_controller.rb
index 9affbebdf5291e87a6ed8431c5ffaf9c2324a914..d5d7fc8c898440dbb657064e16fb110277071d98 100644
--- a/app/controllers/moderator_controller.rb
+++ b/app/controllers/moderator_controller.rb
@@ -5,21 +5,8 @@ class ModeratorController < ApplicationController
 
   def index; end
 
-  def recently_deleted_questions
-    @questions = Question.unscoped.where(deleted: true).order('deleted_at DESC')
-                         .paginate(page: params[:page], per_page: 50)
-  end
-
-  def recently_deleted_answers
-    @answers = Answer.where(deleted: true).order('deleted_at DESC').paginate(page: params[:page], per_page: 50)
-  end
-
-  def recently_undeleted_questions
-    @questions = Question.unscoped.where(deleted: false).where.not(deleted_at: nil)
-                         .paginate(page: params[:page], per_page: 50)
-  end
-
-  def recently_undeleted_answers
-    @answers = Answer.where(deleted: false).where.not(deleted_at: nil).paginate(page: params[:page], per_page: 50)
+  def recently_deleted_posts
+    @posts = Post.unscoped.where(community: @community, deleted: true).order('deleted_at DESC')
+                 .paginate(page: params[:page], per_page: 50)
   end
 end
diff --git a/app/controllers/pinned_links_controller.rb b/app/controllers/pinned_links_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..64b7139fffee33c729f4fadf796f6e2031db2e79
--- /dev/null
+++ b/app/controllers/pinned_links_controller.rb
@@ -0,0 +1,79 @@
+class PinnedLinksController < ApplicationController
+  before_action :verify_moderator
+  before_action :set_pinned_link, only: [:edit, :update]
+
+  def index
+    links = if current_user.is_global_moderator && params[:global] == '2'
+              PinnedLink.unscoped
+            elsif current_user.is_global_moderator && params[:global] == '1'
+              PinnedLink.where(community: nil)
+            else
+              PinnedLink.where(community: @community)
+            end
+    @links = if params[:filter] == 'all'
+               links.all
+             elsif params[:filter] == 'inactive'
+               links.where(active: false).all
+             else
+               links.where(active: true).all
+             end
+    render layout: 'without_sidebar'
+  end
+
+  def new
+    @link = PinnedLink.new
+  end
+
+  def create
+    data = pinned_link_params
+    post = !data[:post_id].present? ? nil : Post.where(data[:post_id]).first
+    community = !data[:community].present? ? nil : Community.where(data[:community]).first
+
+    @link = PinnedLink.create data.merge(post: post, community: community)
+
+    attr = @link.attributes.map { |k, v| "#{k}: #{v}" }.join(' ')
+    AuditLog.moderator_audit(event_type: 'pinned_link_create', related: @link, user: current_user,
+                             comment: "<<PinnedLink #{attr}>>")
+
+    flash[:success] = 'Your pinned link has been created. Due to caching, it may take some time until it is shown.'
+    redirect_to pinned_links_path
+  end
+
+  def edit
+    unless current_user.is_global_moderator
+      return not_found if @link.community.id != @community.id
+    end
+  end
+
+  def update
+    unless current_user.is_global_moderator
+      return not_found if @link.community.id != @community.id
+    end
+
+    before = @link.attributes.map { |k, v| "#{k}: #{v}" }.join(' ')
+    data = pinned_link_params
+    post = !data[:post_id].present? ? nil : Post.where(data[:post_id]).first
+    community = !data[:community].present? ? nil : Community.where(data[:community]).first
+    @link.update data.merge(post: post, community: community)
+    after = @link.attributes.map { |k, v| "#{k}: #{v}" }.join(' ')
+    AuditLog.moderator_audit(event_type: 'pinned_link_update', related: @link, user: current_user,
+                             comment: "from <<PinnedLink #{before}>>\nto <<PinnedLink #{after}>>")
+
+    flash[:success] = 'The pinned link has been updated. Due to caching, it may take some time until it is shown.'
+    redirect_to pinned_links_path
+  end
+
+  private
+
+  def set_pinned_link
+    @link = PinnedLink.find params[:id]
+  end
+
+  def pinned_link_params
+    if current_user.is_global_moderator
+      params.require(:pinned_link).permit(:label, :link, :post, :active, :shown_before, :shown_after, :community)
+    else
+      params.require(:pinned_link).permit(:label, :link, :post, :active, :shown_before, :shown_after)
+    end
+  end
+end
diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index f8fac7e708d27a4bba723efa29a4a4890f5180e8..381789634f88254ee59e1029be8a65ad860f19f2 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -1,6 +1,6 @@
 class PostsController < ApplicationController
   before_action :authenticate_user!, except: [:document, :share_q, :share_a, :help_center]
-  before_action :set_post, only: [:edit_help, :update_help, :toggle_comments]
+  before_action :set_post, only: [:edit_help, :update_help, :toggle_comments, :feature]
   before_action :set_scoped_post, only: [:change_category]
   before_action :check_permissions, only: [:edit_help, :update_help]
   before_action :verify_moderator, only: [:new_help, :create_help, :toggle_comments]
@@ -166,6 +166,22 @@ class PostsController < ApplicationController
     render json: { success: true }
   end
 
+  def feature
+    data = {
+      label: @post.parent.nil? ? @post.title : @post.parent.title,
+      link: helpers.generic_show_link(@post),
+      post: @post,
+      active: true
+    }
+    @link = PinnedLink.create data
+
+    attr = @link.attributes.map { |k, v| "#{k}: #{v}" }.join(' ')
+    AuditLog.moderator_audit(event_type: 'pinned_link_create', related: @link, user: current_user,
+                            comment: "<<PinnedLink #{attr}>>\n(using moderator tools on post)")
+    flash[:success] = 'Post has been featured. Due to caching, it may take some time until the changes apply.'
+    render json: { success: true }
+  end
+
   def save_draft
     key = "saved_post.#{current_user.id}.#{params[:path]}"
     saved_at = "saved_post_at.#{current_user.id}.#{params[:path]}"
diff --git a/app/helpers/pinned_links_helper.rb b/app/helpers/pinned_links_helper.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4bae07f413c33b863345765386726352c2383e76
--- /dev/null
+++ b/app/helpers/pinned_links_helper.rb
@@ -0,0 +1,2 @@
+module PinnedLinksHelper
+end
diff --git a/app/models/pinned_link.rb b/app/models/pinned_link.rb
new file mode 100644
index 0000000000000000000000000000000000000000..03cd6abd79f2a70ebcef48d84cb5375075d09694
--- /dev/null
+++ b/app/models/pinned_link.rb
@@ -0,0 +1,4 @@
+class PinnedLink < ApplicationRecord
+  include MaybeCommunityRelated
+  belongs_to :post
+end
diff --git a/app/views/advertisement/index.html.erb b/app/views/advertisement/index.html.erb
index 4a52c7940603fb0a59500ba8a59184bf493c2fa1..6152f28bf560dde23b45afa276ae2514a9ac97a2 100644
--- a/app/views/advertisement/index.html.erb
+++ b/app/views/advertisement/index.html.erb
@@ -34,20 +34,42 @@
     <div class="grid--cell is-12 is-4-lg">
         <div class="widget">
             <div class="widget--header h-ta-center h-fw-bold">
-                Posts
+                Random Posts
             </div>
             <a href="<%= random_question_ads_url %>"><img src="<%= random_question_ads_url %>" alt="Random posts ad"></a>
             <div class="widget--body">
-                <p><strong>Random post</strong> (chosen from hot posts)</p>
                 <p>Image link</p>
                 <pre><code><%= random_question_ads_url %></code></pre>
                 <p>Image HTML:</p>
                 <pre><code><%= ('<img src="' + random_question_ads_url + '" alt="' + @community.name + ' questions">') %></code></pre>
-                <p><strong>Specific post</strong> (replace X with post ID)</p>
+            </div>
+        </div>
+    </div>
+    <div class="grid--cell is-12 is-4-lg">
+        <div class="widget">
+            <div class="widget--header h-ta-center h-fw-bold">
+                Specific Post
+            </div>
+            <div class="widget--body">
                 <p>Image link</p>
                 <pre><code><%= specific_question_ads_url('X') %></code></pre>
                 <p>Image HTML:</p>
                 <pre><code><%= ('<img src="' + specific_question_ads_url('X') + '" alt="(choose an alt text)">') %></code></pre>
+                <p><em>You need to replace X with the post ID</em></p>
+            </div>
+        </div>
+    </div>
+    <div class="grid--cell is-12 is-4-lg">
+        <div class="widget">
+            <div class="widget--header h-ta-center h-fw-bold">
+                Random from Category
+            </div>
+            <div class="widget--body">
+                <p>Image link</p>
+                <pre><code><%= specific_category_ads_url('X') %></code></pre>
+                <p>Image HTML:</p>
+                <pre><code><%= ('<img src="' + specific_category_ads_url('X') + '" alt="(choose an alt text)">') %></code></pre>
+                <p><em>You need to replace X with the category ID</em></p>
             </div>
         </div>
     </div>
diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb
index daf36e9451107c67bb35e60f9855ea50362b142f..097316ac3075309ced3c8427658f061da9ac5cc8 100644
--- a/app/views/categories/_form.html.erb
+++ b/app/views/categories/_form.html.erb
@@ -90,6 +90,40 @@
     <%= f.number_field :sequence, class: 'form-element' %>
   </div>
 
+  <div class="form-group">
+    <%= f.label :asking_guidance_override, class: 'form-element' %>
+    <span class="form-caption">
+      This field overrides the default asking guidance and is shown when a new post is created. Leave blank to use site-default.
+    </span>
+    <%= f.text_area :asking_guidance_override, class: 'form-element' %>
+  </div>
+
+  <div class="form-group">
+    <%= f.label :answering_guidance_override, class: 'form-element' %>
+    <span class="form-caption">
+      This field overrides the default answering guidance and is shown when a new answer is created. Leave blank to use site-default.
+    </span>
+    <%= f.text_area :answering_guidance_override, class: 'form-element' %>
+  </div>
+
+  <div class="form-group">
+    <%= f.label :use_for_hot_posts, class: 'form-element' %>
+    <span class="form-caption">
+      Whether the posts of this category are eligible to be selected as  hot posts.
+    </span>
+    <%= f.select :use_for_hot_posts, options_for_select([['yes', true], ['no', false]], selected: @category.use_for_hot_posts),
+                 {}, class: 'form-element' %>
+  </div>
+
+  <div class="form-group">
+    <%= f.label :use_for_advertisement, class: 'form-element' %>
+    <span class="form-caption">
+      Whether the posts of this category are eligible to be selected as random advertisement.
+    </span>
+    <%= f.select :use_for_advertisement, options_for_select([['yes', true], ['no', false]], selected: @category.use_for_advertisement),
+                 {}, class: 'form-element' %>
+  </div>
+
   <div class="form-group js-category-tags-group">
     <%= f.label :required_tag_ids, 'Required tags', class: 'form-element' %>
     <span class="form-caption js-tags-group-caption">
diff --git a/app/views/layouts/_sidebar.html.erb b/app/views/layouts/_sidebar.html.erb
index 9c990d439daab610e200c883e1a3601daca0340c..ab409b348e2d49b7fcc76509de758688de13ccd6 100644
--- a/app/views/layouts/_sidebar.html.erb
+++ b/app/views/layouts/_sidebar.html.erb
@@ -12,19 +12,48 @@
     <% end %>
   <% end %>
 
-  <% if Rails.env.development? || @hot_questions.to_a.size > 0 %>
-    <div class="widget has-margin-4">
-      <h4 class="widget--header has-margin-0">Hot Posts</h4>
+  <% if Rails.env.development? || @hot_questions.to_a.size > 0 || @pinned_links.to_a.size > 0 %>
+    <div class="widget has-margin-4 is-tertiary">
+    <% if Rails.env.development? || @pinned_links.to_a.size > 0 %>
+      <div class="widget--header">Featured</div>
+      <% @pinned_links.each do |pl| %>
+        <div class="widget--body">
+          <% pl_link = pl.post.nil? ? pl.link : generic_share_link(pl.post) %>
+          <% pl_label = pl.post.nil? ? pl.label : (pl.post.parent.nil? ? pl.post.title : pl.post.parent.title) %>
+          <%= link_to pl_link, class: 'h-fw-bold' do %>
+            <%= pl_label %>
+          <% end %>
+        <% unless pl.shown_before.nil? %>
+          <div>
+            &mdash;
+            <% if !pl.shown_after.nil? %>
+              <% if pl.shown_after < DateTime.now %>
+                ends in  <%= time_ago_in_words(pl.shown_before) %>
+              <% else %>
+                starts in <%= time_ago_in_words(pl.shown_after) %>
+              <% end %>
+            <% else %>
+              in <%= time_ago_in_words(pl.shown_before) %>
+            <% end %>
+          </div>
+          <% end %>
+        </div>
+      <% end %>
+    <% end %>
+    <% if Rails.env.development? || @hot_questions.to_a.size > 0 %>
+      <div class="widget--header">Hot Posts</div>
       <% @hot_questions.each do |hq| %>
         <div class="widget--body">
+          <% unless hq.category.nil? %>
+            <%= hq.category.name %>
+            &mdash;
+          <% end %>
           <%= link_to question_path(hq) do %>
-            <% unless hq.category.nil? %>
-              <span class="badge is-tag is-master-tag"><%= hq.category.name %></span>
-            <% end %>
             <%= hq.title %>
           <% end %>
         </div>
       <% end %>
+    <% end %>
     </div>
   <% end %>
 
@@ -64,27 +93,18 @@
       <img src="/assets/codidact.png" alt="Codidact logo" class="codidact-logo" />
     </div>
     <div class="widget--body">
+<% chat = SiteSetting['ChatLink'] %>
       <p>
         This site is part of the <a href="https://codidact.com">Codidact network</a>.
         We have other sites too &mdash; take a look!
       </p>
+      <% if chat.present? %>
+      <p>
+        You can also <%= link_to 'join us in chat', chat %>!
+      </p>
+      <% end %>
       <p>
         Want to advertise this site? <%= link_to 'Use our templates!', ads_path %>
       </p>
     </div>
-  </div>
-
-  <% chat = SiteSetting['ChatLink'] %>
-  <% if chat.present? %>
-    <div class="widget has-margin-4">
-      <div class="widget--header">
-        Chat
-      </div>
-      <div class="widget--body">
-        <p>
-          <%= link_to 'Join us in chat!', chat %>
-        </p>
-      </div>
-    </div>
-  <% end %>
-</div>
\ No newline at end of file
+  </div>
\ No newline at end of file
diff --git a/app/views/moderator/index.html.erb b/app/views/moderator/index.html.erb
index f731147068533592fab1a5f6f82fa293a2da333e..9538270cb3ce2effa8f97ea146ad91abf24ae54e 100644
--- a/app/views/moderator/index.html.erb
+++ b/app/views/moderator/index.html.erb
@@ -1,28 +1,67 @@
 <% content_for :title, "Moderator Dashboard" %>
 
 <h1>Moderator Dashboard</h1>
-<p>This page serves as a repository of links to the various tools you have access to as an administrative user. While
+<p>This page serves as a repository of links to the various tools you have access to as a moderator. While
   you use these, remember that the data in them is usually moderator-only, and should likely not be shared
   with anyone outside of that team unless you've ensured it's safe to share.</p>
-<ul>
-  <li><a href="/mod/flags">Flag queue</a></li>
-  <li>Recent deletions: <a href="/mod/deleted/questions">questions</a>, <a href="/mod/deleted/answers">answers</a></li>
-  <li>Recent undeletions: <a href="/mod/undeleted/questions">questions</a>, <a href="/mod/undeleted/answers">answers</a></li>
-  <li><%= link_to 'Create a help center page', new_help_post_path %></li>
-  <li><%= link_to 'Reports', users_report_path %></li>
-  <li><%= link_to 'Edit close reasons', close_reasons_path %></li>
-</ul>
-
-<h3>Safe to Share</h3>
-<p>Although for the most part, the information available under the /mod routes is sensitive or confidential, there are
-  cases where it's beneficial to share the information. If you're going to do this, make sure it's safe to share.
-  In general terms, this means that the information you share:</p>
-<ul>
-  <li>should not make it easier to circumvent the system - if you know details of systems that are generally not very
-    well-known, it's best to keep them secret so the system can't be circumvented</li>
-  <li>should not contain private details of <em>any</em> user</li>
-  <li>should not be discourteous to anyone - talk and speculation of bans and removals is inconsiderate to a user who
-    can't respond</li>
-</ul>
-<p>Apply common sense - think of what effect this information will have before you share it. If in doubt, check it with
-  another member of your team.</p>
+
+<div class="grid">
+  <div class="grid--cell is-4-lg is-6-md is-12-sm">
+    <div class="widget">
+      <div class="widget--body">
+        <i class="fa fa-flag"></i>
+        <a href="/mod/flags">Flag Queue</a>
+      </div>
+    </div>
+  </div>
+
+  <div class="grid--cell is-4-lg is-6-md is-12-sm">
+    <div class="widget">
+      <div class="widget--body">
+        <i class="fas fa-trash"></i>
+        <a href="/mod/deleted">Recent Deletions</a>
+      </div>
+    </div>
+  </div>
+
+  <div class="grid--cell is-4-lg is-6-md is-12-sm">
+    <div class="widget">
+      <div class="widget--body">
+        <i class="fas fa-file-alt"></i>
+        <a href="<%= new_help_post_path %>">Create Help Page</a>
+      </div>
+    </div>
+  </div>
+
+  <div class="grid--cell is-4-lg is-6-md is-12-sm">
+    <div class="widget">
+      <div class="widget--body">
+        <i class="fas fa-chart-line"></i>
+        <a href="<%= users_report_path %>">Reports</a>
+      </div>
+    </div>
+  </div>
+
+  <div class="grid--cell is-4-lg is-6-md is-12-sm">
+    <div class="widget">
+      <div class="widget--body">
+        <i class="fas fa-hand-paper"></i>
+        <a href="<%= close_reasons_path %>">Close Reasons</a>
+      </div>
+    </div>
+  </div>
+
+  <div class="grid--cell is-4-lg is-6-md is-12-sm">
+    <div class="widget">
+      <div class="widget--body">
+        <i class="fas fa-info"></i>
+        <a href="<%= pinned_links_path %>">Featured Links</a>
+      </div>
+    </div>
+  </div>
+</div>
+
+<% chat = SiteSetting['ChatLink'] %>
+<% if chat.present? %>
+<p>As a moderator, you should join our <a href="<%= chat %>">community chat server</a>. Ping a Codidact team member there and you'll receive access to a special moderator-only lounge, where you can discuss moderation questions with your fellow moderators.</p>
+<% end %>
\ No newline at end of file
diff --git a/app/views/moderator/recently_deleted_answers.html.erb b/app/views/moderator/recently_deleted_answers.html.erb
deleted file mode 100644
index 309158a07594475d2369a0c450a644add10c37f6..0000000000000000000000000000000000000000
--- a/app/views/moderator/recently_deleted_answers.html.erb
+++ /dev/null
@@ -1,10 +0,0 @@
-<% content_for :title, "Recently Deleted Answers" %>
-
-<h1>Recently Deleted Answers</h1>
-<div class="item-list">
-  <% @answers.each do |a| %>
-    <%= render 'answers/answer', answer: a %>
-  <% end %>
-</div>
-
-<%= will_paginate @answers, renderer: BootstrapPagination::Rails %>
diff --git a/app/views/moderator/recently_deleted_posts.html.erb b/app/views/moderator/recently_deleted_posts.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..f95bf2482a214b97aa2788f69178a395da5ecdb0
--- /dev/null
+++ b/app/views/moderator/recently_deleted_posts.html.erb
@@ -0,0 +1,10 @@
+<% content_for :title, "Recently Deleted Posts" %>
+
+<h1>Recently Deleted Posts</h1>
+<div class="item-list">
+  <% @posts.each do |post| %>
+    <%= render 'posts/type_agnostic', post: post %>
+  <% end %>
+</div>
+
+<%= will_paginate @posts, renderer: BootstrapPagination::Rails %>
diff --git a/app/views/moderator/recently_deleted_questions.html.erb b/app/views/moderator/recently_deleted_questions.html.erb
deleted file mode 100644
index 6eb638fdf8d7ad4cb3118a37ae2b97cc22d9f495..0000000000000000000000000000000000000000
--- a/app/views/moderator/recently_deleted_questions.html.erb
+++ /dev/null
@@ -1,10 +0,0 @@
-<% content_for :title, "Recently Deleted Questions" %>
-
-<h1>Recently Deleted Questions</h1>
-<div class="item-list">
-  <% @questions.each do |q| %>
-    <%= render 'posts/list', post: q %>
-  <% end %>
-</div>
-
-<%= will_paginate @questions, renderer: BootstrapPagination::Rails %>
diff --git a/app/views/moderator/recently_undeleted_answers.html.erb b/app/views/moderator/recently_undeleted_answers.html.erb
deleted file mode 100644
index 9045379d8f4adf5e5f4479e16649b8f7d30ae2c5..0000000000000000000000000000000000000000
--- a/app/views/moderator/recently_undeleted_answers.html.erb
+++ /dev/null
@@ -1,10 +0,0 @@
-<% content_for :title, "Recently Undeleted Answers" %>
-
-<h1>Recently Undeleted Answers</h1>
-<div class="item-list">
-  <% @answers.each do |a| %>
-    <%= render 'answers/answer', answer: a %>
-  <% end %>
-</div>
-
-<%= will_paginate @answers, renderer: BootstrapPagination::Rails %>
diff --git a/app/views/moderator/recently_undeleted_questions.html.erb b/app/views/moderator/recently_undeleted_questions.html.erb
deleted file mode 100644
index 387ff73e0b3c71a1c0d71b777e0678cf2b6be1e8..0000000000000000000000000000000000000000
--- a/app/views/moderator/recently_undeleted_questions.html.erb
+++ /dev/null
@@ -1,10 +0,0 @@
-<% content_for :title, "Recently Undeleted Questions" %>
-
-<h1>Recently Undeleted Questions</h1>
-<div class="item-list">
-  <% @questions.each do |q| %>
-    <%= render 'posts/list', post: q %>
-  <% end %>
-</div>
-
-<%= will_paginate @questions, renderer: BootstrapPagination::Rails %>
diff --git a/app/views/pinned_links/_form.html.erb b/app/views/pinned_links/_form.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..1452dde029e30d3a19b24098d9eba4418db3bc3f
--- /dev/null
+++ b/app/views/pinned_links/_form.html.erb
@@ -0,0 +1,52 @@
+<%= form_for @link, url: url do |f| %>
+  <div class="form-group has-padding-1">
+    <%= f.label :label, "Shown label", class: "form-element" %>
+    <div class="form-caption">What is shown in the sidebar. This will be ignored when a post is set.</div>
+    <%= f.text_area :label, class: "form-element" %>
+  </div>
+
+  <div class="form-group has-padding-1">
+    <%= f.label :link, "Target link", class: "form-element" %>
+    <div class="form-caption">What the label is linked to in the sidebar. This will be ignored when a post is set.</div>
+    <%= f.text_field :link, class: "form-element" %>
+  </div>
+
+  <% if current_user.is_global_moderator %>
+  <div class="form-group has-padding-1">
+    <%= f.label :community, "Community", class: "form-element" %>
+    <div class="form-caption">Which sidebar this is shown in the sidebar. Global if blank.</div>
+    <% communities = Community.all %>
+    <% ocs = communities.map { |c| [c.name, c.id] } %>
+    <%= f.select :community, options_for_select(ocs, selected: @link.community&.id),
+                { include_blank: true }, class: 'form-element' %>
+  </div>
+  <% end %>
+
+  <div class="form-group has-padding-1">
+    <%= f.label :post_id, "ID of target post", class: "form-element" %>
+    <div class="form-caption">You can link to a post within this community. Will override label and link.</div>
+    <%= f.number_field :post_id, class: "form-element" %>
+  </div>
+
+  <div class="form-group has-padding-1">
+    <%= f.label :active, "Active?", class: "form-element" %>
+    <%= f.select :active, options_for_select([['yes', true], ['no', false]], selected: @link.active),
+                 {}, class: 'form-element' %>
+  </div>
+
+  <div class="form-group has-padding-1">
+    <%= f.label :shown_before, "End date", class: "form-element" %>
+    <div class="form-caption">Link will show until this date. Will be shown in the sidebar.</div>
+    <%= f.date_field :shown_before, class: "form-element" %>
+  </div>
+
+  <div class="form-group has-padding-1">
+    <%= f.label :shown_after, "Start date", class: "form-element" %>
+    <div class="form-caption">Used to display in the sidebar when the event starts. Does not affect visibility - the event
+      will show immediately.</div>
+    <%= f.date_field :shown_after, class: "form-element" %>
+  </div>
+
+  <%= f.submit "Update", class: "button is-filled" %>
+  <%= link_to "Cancel", pinned_links_path(global: params[:global]), class: "button" %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/pinned_links/edit.html.erb b/app/views/pinned_links/edit.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..eafe82cc755ce626ca40c61d50a86b24ced75215
--- /dev/null
+++ b/app/views/pinned_links/edit.html.erb
@@ -0,0 +1,14 @@
+<h1>Edit featured link</h1>
+
+<% if @link.errors.any? %>
+  <div class="notice is-danger">
+    These errors prevented this link being saved:
+    <ul>
+      <% @link.errors.full_messages.each do |msg| %>
+        <li><%= msg %></li>
+      <% end %>
+    </ul>
+  </div>
+<% end %>
+
+<%= render 'form', url: update_pinned_link_path(global: params[:global]) %>
diff --git a/app/views/pinned_links/index.html.erb b/app/views/pinned_links/index.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..f95ebe133bf392335db55889f5e7f6ddad626614
--- /dev/null
+++ b/app/views/pinned_links/index.html.erb
@@ -0,0 +1,87 @@
+<h1>Featured Links</h1>
+<p class="is-lead">Featured links allow you as a moderator to draw attention to issues or posts of importance to the community. Use them sparingly and only when needed, because they tend to get ignored if used too often.</p>
+
+<div class="grid has-margin-bottom-4">
+    <% if current_user.is_global_moderator %>
+    <div class="grid--cell">
+        <div class="button-list is-gutterless">
+            <%= link_to "current community", query_url(global: '0', filter: params[:filter] || 'active'),
+                        class: "button is-muted is-outlined #{(params[:global] == '0' || params[:global].nil?) ? 'is-active' : ''}" %>
+            <%= link_to "global", query_url(global: '1', filter: params[:filter] || 'active'),
+                        class: "button is-muted is-outlined #{(params[:global] == '1') ? 'is-active' : ''}" %>
+            <%= link_to "everywhere", query_url(global: '2', filter: params[:filter] || 'active'),
+                        class: "button is-muted is-outlined #{(params[:global] == '2') ? 'is-active' : ''}" %>
+        </div>
+    </div>
+    <% end %>
+    <div class="grid--cell">
+        <div class="button-list is-gutterless">
+            <%= link_to "active", query_url(global: params[:global] || '0', filter: 'active'),
+                        class: "button is-muted is-outlined #{(params[:filter] == 'active' || params[:filter].nil?) ? 'is-active' : ''}" %>
+            <%= link_to "inactive", query_url(global: params[:global] || '0', filter: 'inactive'),
+                        class: "button is-muted is-outlined #{(params[:filter] == 'inactive') ? 'is-active' : ''}" %>
+            <%= link_to "all", query_url(global: params[:global] || '0', filter: 'all'),
+                        class: "button is-muted is-outlined #{(params[:filter] == 'all') ? 'is-active' : ''}" %>
+        </div>
+    </div>
+    <div class="grid--cell is-flexible">
+    </div>
+    <div class="grid--cell">
+        <div class="button-list is-gutterless">
+            <a href="<%= new_pinned_link_path %>" class="button is-filled"><i class="fa fa-plus"></i> New</a>
+        </div>
+    </div>
+</div>
+
+<table class="table is-with-hover">
+    <tr>
+        <th>type</th>
+        <th>shown label</th>
+        <th>links to</th>
+        <th>begins</th>
+        <th>ends</th>
+        <th>active?</th>
+        <% if current_user.is_global_moderator %>
+            <th>community</th>
+        <% end %>
+        <th>actions</th>
+    </tr>
+    <% @links.each do |pl| %>
+        <% pl_link = pl.post.nil? ? pl.link : ('Post #' + pl.post.id.to_s) %>
+        <% pl_label = pl.post.nil? ? pl.label : (pl.post.parent.nil? ? pl.post.title : pl.post.parent.title) %>
+        <tr>
+            <td>
+                <% if pl.shown_before.nil? %>
+                    <% if pl.post.nil? %>
+                        link
+                    <% else %>
+                        post
+                    <% end%>
+                <% else %>
+                    event
+                <% end%>
+            </td>
+            <td>
+                <%= pl_label %>
+            </td>
+            <td>
+                <%= pl_link %>
+            </td>
+            <td>
+                <%= pl.shown_after ? pl.shown_after : raw('&mdash;') %>
+            </td>
+            <td>
+                <%= pl.shown_before ? pl.shown_before : raw('&mdash;') %>
+            </td>
+            <td>
+                <%= pl.active ? raw('<strong>yes</strong>') : 'no' %>
+            </td>
+            <% if current_user.is_global_moderator %>
+                <td><%= pl.community.nil? ? 'global' : pl.community.name %></td>
+            <% end %>
+            <td>
+                <a href="<%= edit_pinned_link_path(pl.id) %>" class="button is-outlined">edit</a>
+            </td>
+        </tr>
+    <% end %>
+</table>
\ No newline at end of file
diff --git a/app/views/pinned_links/new.html.erb b/app/views/pinned_links/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..e719f8c89efe4496cf77e9d446676a4e1ef6279a
--- /dev/null
+++ b/app/views/pinned_links/new.html.erb
@@ -0,0 +1,14 @@
+<h1>New featured link</h1>
+
+<% if @link.errors.any? %>
+  <div class="notice is-danger">
+    These errors prevented this link being saved:
+    <ul>
+      <% @link.errors.full_messages.each do |msg| %>
+        <li><%= msg %></li>
+      <% end %>
+    </ul>
+  </div>
+<% end %>
+
+<%= render 'form', url: create_pinned_link_path %>
\ No newline at end of file
diff --git a/app/views/posts/_post_tools.html.erb b/app/views/posts/_post_tools.html.erb
index 3273a069cb1736afbf69fd0aeaf1dc1b753a310e..199e7291be1524697142da83049b69edebadbb9c 100644
--- a/app/views/posts/_post_tools.html.erb
+++ b/app/views/posts/_post_tools.html.erb
@@ -69,6 +69,17 @@
           <% end %>
         </details>
       <% end %>
+      <% if moderator? %>
+        <details>
+          <summary>Feature post</summary>
+          <p>
+            You can feature this post by linking it in the sidebar. You can edit the link options later in the moderator tools.
+          </p>
+          <%= form_tag post_feature_url(post), remote: true, class: 'js-feature-post' do %>
+            <%= submit_tag 'Feature post', class: 'button is-filled'  %>
+          <% end %>
+        </details>
+      <% end %>
     </div>
   </div>
 </div>
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 4d0ec2de22e79fe348167d2dfe3d8e280f2231c6..451a0cbe3167a822cf48c3d2d33f576be2e711a0 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -44,10 +44,7 @@ Rails.application.routes.draw do
   end
 
   get    'mod',                            to: 'moderator#index', as: :moderator
-  get    'mod/deleted/questions',          to: 'moderator#recently_deleted_questions', as: :recently_deleted_questions
-  get    'mod/deleted/answers',            to: 'moderator#recently_deleted_answers', as: :recently_deleted_answers
-  get    'mod/undeleted/questions',        to: 'moderator#recently_undeleted_questions', as: :recently_undeleted_questions
-  get    'mod/undeleted/answers',          to: 'moderator#recently_undeleted_answers', as: :recently_undeleted_answers
+  get    'mod/deleted',                    to: 'moderator#recently_deleted_posts', as: :recently_deleted_posts
   get    'mod/flags',                      to: 'flags#queue', as: :flag_queue
   post   'mod/flags/:id/resolve',          to: 'flags#resolve', as: :resolve_flag
   get    'mod/votes',                      to: 'suspicious_votes#index', as: :suspicious_votes
@@ -55,6 +52,14 @@ Rails.application.routes.draw do
   get    'mod/votes/user/:id',             to: 'suspicious_votes#user', as: :suspicious_votes_user
   delete 'mod/users/destroy/:id',          to: 'users#destroy', as: :destroy_user
 
+  scope 'mod/featured' do
+    root                                   to: 'pinned_links#index', as: :pinned_links
+    get   'new',                           to: 'pinned_links#new', as: :new_pinned_link
+    post  'new',                           to: 'pinned_links#create', as: :create_pinned_link
+    get   ':id/edit',                      to: 'pinned_links#edit', as: :edit_pinned_link
+    patch ':id/edit',                      to: 'pinned_links#update', as: :update_pinned_link
+  end
+
   get    'questions',                      to: 'questions#index', as: :questions
   get    'questions/lottery',              to: 'questions#lottery', as: :questions_lottery
   get    'meta',                           to: 'questions#meta', as: :meta
@@ -95,6 +100,7 @@ Rails.application.routes.draw do
 
   post   'posts/:id/category',             to: 'posts#change_category', as: :change_category
   post   'posts/:id/toggle_comments',      to: 'posts#toggle_comments', as: :post_comments_allowance_toggle
+  post   'posts/:id/feature',              to: 'posts#feature', as: :post_feature
   
 
   get  'posts/suggested-edit/:id',         to: 'suggested_edit#show', as: :suggested_edit
@@ -217,6 +223,7 @@ Rails.application.routes.draw do
     get 'community.png',                   to: 'advertisement#community', as: :community_ads
     get 'posts/random.png',                to: 'advertisement#random_question', as: :random_question_ads
     get 'posts/:id.png',                   to: 'advertisement#specific_question', as: :specific_question_ads
+    get 'category/:id.png',                to: 'advertisement#specific_category', as: :specific_category_ads
   end
 
   get   '403',                             to: 'errors#forbidden'
diff --git a/db/migrate/20200727183756_create_pinned_links.rb b/db/migrate/20200727183756_create_pinned_links.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a7d390475892ecccca9668cae7499e6f08c34494
--- /dev/null
+++ b/db/migrate/20200727183756_create_pinned_links.rb
@@ -0,0 +1,14 @@
+class CreatePinnedLinks < ActiveRecord::Migration[5.2]
+  def change
+    create_table :pinned_links do |t|
+      t.references :community, null: true, foreign_key: true
+      t.string :label, null: true
+      t.string :link, null: true
+      t.references :post, null: true, foreign_key: true
+      t.boolean :active
+      t.datetime :shown_after, null: true
+      t.datetime :shown_before, null: true
+      t.timestamps
+    end
+  end
+end
diff --git a/db/migrate/20200728093322_add_eligible_for_hot_post_to_category.rb b/db/migrate/20200728093322_add_eligible_for_hot_post_to_category.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9fadf7741f3c05aca7cd04dc428d9f4748951142
--- /dev/null
+++ b/db/migrate/20200728093322_add_eligible_for_hot_post_to_category.rb
@@ -0,0 +1,6 @@
+class AddEligibleForHotPostToCategory < ActiveRecord::Migration[5.2]
+  def change
+    add_column :categories, :use_for_hot_posts, :boolean, default: true
+    add_column :categories, :use_for_advertisement, :boolean, default: true
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 8182de617f09dc27edf077780215d865e7f1e3b0..ed909ff11df7ca5b7690c626271a416982283ae1 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2020_07_21_185230) do
+ActiveRecord::Schema.define(version: 2020_07_28_093322) do
 
   create_table "active_storage_attachments", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", force: :cascade do |t|
     t.string "name", null: false
@@ -77,6 +77,8 @@ ActiveRecord::Schema.define(version: 2020_07_21_185230) do
     t.integer "min_view_trust_level"
     t.bigint "license_id"
     t.integer "sequence"
+    t.boolean "use_for_hot_posts", default: true
+    t.boolean "use_for_advertisement", default: true
     t.index ["community_id"], name: "index_categories_on_community_id"
     t.index ["license_id"], name: "index_categories_on_license_id"
     t.index ["sequence"], name: "index_categories_on_sequence"
@@ -205,6 +207,20 @@ ActiveRecord::Schema.define(version: 2020_07_21_185230) do
     t.index ["user_id"], name: "index_notifications_on_user_id"
   end
 
+  create_table "pinned_links", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", force: :cascade do |t|
+    t.bigint "community_id"
+    t.string "label"
+    t.string "link"
+    t.bigint "post_id"
+    t.boolean "active"
+    t.datetime "shown_after"
+    t.datetime "shown_before"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["community_id"], name: "index_pinned_links_on_community_id"
+    t.index ["post_id"], name: "index_pinned_links_on_post_id"
+  end
+
   create_table "post_histories", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", force: :cascade do |t|
     t.integer "post_history_type_id"
     t.integer "user_id"
@@ -264,7 +280,7 @@ ActiveRecord::Schema.define(version: 2020_07_21_185230) do
     t.integer "post_type_id", null: false
     t.text "body_markdown"
     t.integer "answer_count", default: 0, null: false
-    t.datetime "last_activity", default: -> { "CURRENT_TIMESTAMP" }, null: false
+    t.datetime "last_activity", default: -> { "current_timestamp()" }, null: false
     t.string "att_source"
     t.string "att_license_name"
     t.string "att_license_link"
@@ -501,6 +517,8 @@ ActiveRecord::Schema.define(version: 2020_07_21_185230) do
   add_foreign_key "error_logs", "users"
   add_foreign_key "flags", "communities"
   add_foreign_key "notifications", "communities"
+  add_foreign_key "pinned_links", "communities"
+  add_foreign_key "pinned_links", "posts"
   add_foreign_key "post_histories", "communities"
   add_foreign_key "post_history_tags", "post_histories"
   add_foreign_key "post_history_tags", "tags"
diff --git a/db/seeds/categories.yml b/db/seeds/categories.yml
index 3f379f31d0b3a2ae0354d3a8851a0d0fea6d4d72..17727fdf0efc870f9c76841587f9b2c8dd18df52 100644
--- a/db/seeds/categories.yml
+++ b/db/seeds/categories.yml
@@ -7,6 +7,8 @@
     - <%= PostType['Answer'].id %>
   is_homepage: true
   tag_set_id: <%= TagSet.unscoped.where(name: 'Main').first %>
+  use_for_hot_posts: true
+  use_for_advertisement: true
 
 - name: Meta
   short_wiki: Discussions and feedback about the site itself in Q&A format.
@@ -15,4 +17,6 @@
   post_type_ids:
     - <%= PostType['Question'].id %>
     - <%= PostType['Answer'].id %>
-  tag_set_id: <%= TagSet.unscoped.where(name: 'Meta').first %>
\ No newline at end of file
+  tag_set_id: <%= TagSet.unscoped.where(name: 'Meta').first %>
+  use_for_hot_posts: true
+  use_for_advertisement: false
\ No newline at end of file
diff --git a/db/seeds/site_settings.yml b/db/seeds/site_settings.yml
index 93f3e3abbb5e1cc46736a99ea1c657983e61299e..0b2f716f9bbd684665a9a7048ae60d237d9ab3b3 100644
--- a/db/seeds/site_settings.yml
+++ b/db/seeds/site_settings.yml
@@ -291,3 +291,10 @@
   category: SiteDetails
   description: >
     A slogan to be shown on the /ads/community.png page.
+
+- name: HotPostsScoreThreshold
+  value: 1
+  value_type: integer
+  category: AdvancedSettings
+  description: >
+    The minimum score a question must have to qualify for selection for the Hot Posts sidebar and for being selected as random advertisement.
\ No newline at end of file
diff --git a/test/controllers/moderator_controller_test.rb b/test/controllers/moderator_controller_test.rb
index 8528ecc9605b2dcb4e8145ca02f546bab84e9c5e..c26c6381107aebeff989b5e6de40f072b3bfa24c 100644
--- a/test/controllers/moderator_controller_test.rb
+++ b/test/controllers/moderator_controller_test.rb
@@ -11,8 +11,7 @@ class ModeratorControllerTest < ActionController::TestCase
 
   test 'should require authentication to access pages' do
     sign_out :user
-    [:index, :recently_deleted_answers, :recently_deleted_questions, :recently_undeleted_answers,
-     :recently_undeleted_questions].each do |path|
+    [:index, :recently_deleted_posts].each do |path|
       get path
       assert_response(404)
     end
@@ -20,8 +19,7 @@ class ModeratorControllerTest < ActionController::TestCase
 
   test 'should require moderator status to access pages' do
     sign_in users(:standard_user)
-    [:index, :recently_deleted_answers, :recently_deleted_questions, :recently_undeleted_answers,
-     :recently_undeleted_questions].each do |path|
+    [:index, :recently_deleted_posts].each do |path|
       get path
       assert_response(404)
     end
diff --git a/test/controllers/pinned_links_controller_test.rb b/test/controllers/pinned_links_controller_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b7cb3d3d15993efc8ca563d798727df63861ccc7
--- /dev/null
+++ b/test/controllers/pinned_links_controller_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class PinnedLinksControllerTest < ActionDispatch::IntegrationTest
+  # test "the truth" do
+  #   assert true
+  # end
+end
diff --git a/test/fixtures/pinned_links.yml b/test/fixtures/pinned_links.yml
new file mode 100644
index 0000000000000000000000000000000000000000..80aed36e30b2598726b55a90c65850a8f9aeb609
--- /dev/null
+++ b/test/fixtures/pinned_links.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+# This model initially had no columns defined. If you add columns to the
+# model remove the '{}' from the fixture names and add the columns immediately
+# below each fixture, per the syntax in the comments below
+#
+one: {}
+# column: value
+#
+two: {}
+# column: value
diff --git a/test/models/pinned_link_test.rb b/test/models/pinned_link_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..66d150710199f79202dbbc2c268f97d8843c91b2
--- /dev/null
+++ b/test/models/pinned_link_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class PinnedLinkTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end