FEATURE: Permalinks for tags

FEATURE: Permalinks for tags

diff --git a/app/assets/javascripts/admin/components/permalink-form.js b/app/assets/javascripts/admin/components/permalink-form.js
index 0a15f51..81e9346 100644
--- a/app/assets/javascripts/admin/components/permalink-form.js
+++ b/app/assets/javascripts/admin/components/permalink-form.js
@@ -17,6 +17,7 @@ export default Component.extend({
       { id: "topic_id", name: I18n.t("admin.permalink.topic_id") },
       { id: "post_id", name: I18n.t("admin.permalink.post_id") },
       { id: "category_id", name: I18n.t("admin.permalink.category_id") },
+      { id: "tag_name", name: I18n.t("admin.permalink.tag_name") },
       { id: "external_url", name: I18n.t("admin.permalink.external_url") }
     ];
   },
diff --git a/app/assets/javascripts/admin/templates/permalinks.hbs b/app/assets/javascripts/admin/templates/permalinks.hbs
index dcfca2a..1424e53 100644
--- a/app/assets/javascripts/admin/templates/permalinks.hbs
+++ b/app/assets/javascripts/admin/templates/permalinks.hbs
@@ -32,6 +32,9 @@
               {{#if pl.category_id}}
                 {{category-link pl.category}}
               {{/if}}
+              {{#if pl.tag_id}}
+                <a href={{pl.tag_url}}>{{pl.tag_name}}</a>
+              {{/if}}
               {{#if pl.external_url}}
                 {{#if pl.linkIsExternal}}
                   {{d-icon "external-link-alt"}}
diff --git a/app/controllers/admin/permalinks_controller.rb b/app/controllers/admin/permalinks_controller.rb
index 4b04249..4e60a1a 100644
--- a/app/controllers/admin/permalinks_controller.rb
+++ b/app/controllers/admin/permalinks_controller.rb
@@ -15,6 +15,11 @@ class Admin::PermalinksController < Admin::AdminController
     params.require(:permalink_type)
     params.require(:permalink_type_value)
 
+    if params[:permalink_type] == "tag_name"
+      params[:permalink_type] = "tag_id"
+      params[:permalink_type_value] = Tag.find_by_name(params[:permalink_type_value])&.id
+    end
+
     permalink = Permalink.new(:url => params[:url], params[:permalink_type] => params[:permalink_type_value])
     if permalink.save
       render_serialized(permalink, PermalinkSerializer)
diff --git a/app/models/permalink.rb b/app/models/permalink.rb
index 925f640..9e1e2d1 100644
--- a/app/models/permalink.rb
+++ b/app/models/permalink.rb
@@ -4,6 +4,7 @@ class Permalink < ActiveRecord::Base
   belongs_to :topic
   belongs_to :post
   belongs_to :category
+  belongs_to :tag
 
   before_validation :normalize_url
 
@@ -80,12 +81,13 @@ class Permalink < ActiveRecord::Base
     return "#{Discourse::base_uri}#{post.url}" if post
     return topic.relative_url if topic
     return "#{category.url}/#{category.id}" if category
+    return tag.full_url if tag
     nil
   end
 
   def self.filter_by(url = nil)
     permalinks = Permalink
-      .includes(:topic, :post, :category)
+      .includes(:topic, :post, :category, :tag)
       .order('permalinks.created_at desc')
 
     permalinks.where!('url ILIKE :url OR external_url ILIKE :url', url: "%#{url}%") if url.present?
@@ -106,6 +108,7 @@ end
 #  created_at   :datetime         not null
 #  updated_at   :datetime         not null
 #  external_url :string(1000)
+#  tag_id       :integer
 #
 # Indexes
 #
diff --git a/app/serializers/permalink_serializer.rb b/app/serializers/permalink_serializer.rb
index 8918910..78b46fd 100644
--- a/app/serializers/permalink_serializer.rb
+++ b/app/serializers/permalink_serializer.rb
@@ -3,7 +3,8 @@
 class PermalinkSerializer < ApplicationSerializer
   attributes :id, :url, :topic_id, :topic_title, :topic_url,
              :post_id, :post_url, :post_number, :post_topic_title,
-             :category_id, :category_name, :category_url, :external_url
+             :category_id, :category_name, :category_url, :external_url,
+             :tag_id, :tag_name, :tag_url
 
   def topic_title
     object&.topic&.title
@@ -33,4 +34,12 @@ class PermalinkSerializer < ApplicationSerializer
   def category_url
     object&.category&.url
   end
+
+  def tag_name
+    object&.tag&.name
+  end
+
+  def tag_url
+    object&.tag&.full_url
+  end
 end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 673cb43..a8ff521 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -336,7 +336,7 @@ en:
         tomorrow_with_time: "tomorrow at %{time}"
         at_time: "at %{date_time}"
         existing_reminder: "You have a reminder set for this bookmark which will be sent"
-    
+
     copy_codeblock:
       copied: "copied!"
 
@@ -4715,6 +4715,7 @@ en:
         post_title: "Post"
         category_id: "Category ID"
         category_title: "Category"
+        tag_name: "Tag name"
         external_url: "External URL"
         destination: "Destination"
         delete_confirm: Are you sure you want to delete this permalink?
diff --git a/db/migrate/20200522204356_add_tag_to_permalink.rb b/db/migrate/20200522204356_add_tag_to_permalink.rb
new file mode 100644
index 0000000..d48a3d7
--- /dev/null
+++ b/db/migrate/20200522204356_add_tag_to_permalink.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddTagToPermalink < ActiveRecord::Migration[6.0]
+  def change
+    add_column :permalinks, :tag_id, :integer
+  end
+end
diff --git a/spec/models/permalink_spec.rb b/spec/models/permalink_spec.rb
index 8cd9d30..869d38f 100644
--- a/spec/models/permalink_spec.rb
+++ b/spec/models/permalink_spec.rb
@@ -32,6 +32,7 @@ describe Permalink do
     let(:topic)           { Fabricate(:topic) }
     let(:post)            { Fabricate(:post, topic: topic) }
     let(:category)        { Fabricate(:category) }
+    let(:tag)             { Fabricate(:tag) }
     subject(:target_url)  { permalink.target_url }
 
     it "returns a topic url when topic_id is set" do
@@ -77,6 +78,24 @@ describe Permalink do
       expect(target_url).to eq(post.url)
     end
 
+    it "returns a tag url when tag_id is set" do
+      permalink.tag_id = tag.id
+      expect(target_url).to eq(tag.full_url)
+    end
+
+    it "returns nil when tag_id is set but tag is not found" do
+      permalink.tag_id = 99999
+      expect(target_url).to eq(nil)
+    end
+
+    it "returns a post url when topic_id, post_id, category_id and tag_id are all set for some reason" do
+      permalink.post_id = post.id
+      permalink.topic_id = topic.id
+      permalink.category_id = category.id
+      permalink.tag_id = tag.id
+      expect(target_url).to eq(post.url)
+    end
+
     it "returns nil when nothing is set" do
       expect(target_url).to eq(nil)
     end
diff --git a/spec/requests/admin/permalinks_controller_spec.rb b/spec/requests/admin/permalinks_controller_spec.rb
index a84a0b2..ad3344b 100644
--- a/spec/requests/admin/permalinks_controller_spec.rb
+++ b/spec/requests/admin/permalinks_controller_spec.rb
@@ -54,4 +54,58 @@ describe Admin::PermalinksController do
       expect(result.length).to eq(3)
     end
   end
+
+  describe "#create" do
+    it "works for topics" do
+      topic = Fabricate(:topic)
+
+      post "/admin/permalinks.json", params: {
+        url: "/topics/771",
+        permalink_type: "topic_id",
+        permalink_type_value: topic.id
+      }
+
+      expect(response.status).to eq(200)
+      expect(Permalink.last).to have_attributes(url: "topics/771", topic_id: topic.id, post_id: nil, category_id: nil, tag_id: nil)
+    end
+
+    it "works for posts" do
+      some_post = Fabricate(:post)
+
+      post "/admin/permalinks.json", params: {
+        url: "/topics/771/8291",
+        permalink_type: "post_id",
+        permalink_type_value: some_post.id
+      }
+
+      expect(response.status).to eq(200)
+      expect(Permalink.last).to have_attributes(url: "topics/771/8291", topic_id: nil, post_id: some_post.id, category_id: nil, tag_id: nil)
+    end
+
+    it "works for categories" do
+      category = Fabricate(:category)
+
+      post "/admin/permalinks.json", params: {
+        url: "/forums/11",
+        permalink_type: "category_id",

[... diff too long, it was truncated ...]

GitHub sha: 631024ae

1 Like

This commit appears in #9863 which was merged by gschlager.