wiki pages: use names instead of ids in urls.
Switching to using wiki names in URLs instead of IDs: * https://danbooru.donami.us/wiki_pages/vocaloid * https://danbooru.donami.us/wiki_pages/hatsune_miku ID numbers can still be used, but they redirect to the name instead: * https://danbooru.donami.us/wiki_pages/11 (redirects to /wiki_pages/touhou). Numeric tags are prefixed with '~' to distinguish them from IDs: * https://danbooru.donami.us/wiki_pages/2019 (the wiki with id 2019) * https://danbooru.donami.us/wiki_pages/~2019 (the wiki for the tag named 2019) The tag names 'new' and 'search' are disallowed to prevent conflicts with existing routes: * https://danbooru.donami.us/wiki_pages/new * https://danbooru.donami.us/wiki_pages/search
This commit is contained in:
@@ -11,7 +11,7 @@ class WikiPagesController < ApplicationController
|
||||
end
|
||||
|
||||
def edit
|
||||
@wiki_page = WikiPage.find(params[:id])
|
||||
@wiki_page, _ = WikiPage.find_by_id_or_title(params[:id])
|
||||
respond_with(@wiki_page)
|
||||
end
|
||||
|
||||
@@ -30,18 +30,16 @@ class WikiPagesController < ApplicationController
|
||||
end
|
||||
|
||||
def show
|
||||
if params[:id] =~ /\A\d+\z/
|
||||
@wiki_page = WikiPage.find(params[:id])
|
||||
else
|
||||
@wiki_page = WikiPage.titled(params[:id]).first
|
||||
end
|
||||
@wiki_page, found_by = WikiPage.find_by_id_or_title(params[:id])
|
||||
|
||||
if @wiki_page.present?
|
||||
respond_with(@wiki_page)
|
||||
elsif request.format.html?
|
||||
if request.format.html? && @wiki_page.blank? && found_by == :title
|
||||
redirect_to show_or_new_wiki_pages_path(title: params[:id])
|
||||
else
|
||||
elsif request.format.html? && @wiki_page.present? && found_by == :id
|
||||
redirect_to @wiki_page
|
||||
elsif @wiki_page.blank?
|
||||
raise ActiveRecord::RecordNotFound
|
||||
else
|
||||
respond_with(@wiki_page)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -51,19 +49,19 @@ class WikiPagesController < ApplicationController
|
||||
end
|
||||
|
||||
def update
|
||||
@wiki_page = WikiPage.find(params[:id])
|
||||
@wiki_page, _ = WikiPage.find_by_id_or_title(params[:id])
|
||||
@wiki_page.update(wiki_page_params(:update))
|
||||
respond_with(@wiki_page)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@wiki_page = WikiPage.find(params[:id])
|
||||
@wiki_page, _ = WikiPage.find_by_id_or_title(params[:id])
|
||||
@wiki_page.update(is_deleted: true)
|
||||
respond_with(@wiki_page)
|
||||
end
|
||||
|
||||
def revert
|
||||
@wiki_page = WikiPage.find(params[:id])
|
||||
@wiki_page, _ = WikiPage.find_by_id_or_title(params[:id])
|
||||
@version = @wiki_page.versions.find(params[:version_id])
|
||||
@wiki_page.revert_to!(@version)
|
||||
flash[:notice] = "Page was reverted"
|
||||
|
||||
@@ -103,13 +103,14 @@ module ApplicationHelper
|
||||
link_to search, posts_path(tags: search)
|
||||
end
|
||||
|
||||
def link_to_wiki(text, title)
|
||||
link_to text, wiki_page_path(title)
|
||||
def link_to_wiki(text, title = text, **options)
|
||||
title = "~#{title}" if title =~ /\A\d+\z/
|
||||
link_to text, wiki_page_path(title), class: "wiki-link", **options
|
||||
end
|
||||
|
||||
def link_to_wikis(*wiki_titles, last_word_connector: ", or", **options)
|
||||
links = wiki_titles.map do |title|
|
||||
link_to title.tr("_", " "), wiki_page_path(title)
|
||||
link_to_wiki title.tr("_", " "), title
|
||||
end
|
||||
|
||||
to_sentence(links, **options)
|
||||
|
||||
@@ -6,32 +6,32 @@ module TagsHelper
|
||||
|
||||
if tag.antecedent_alias
|
||||
html << "<p class='fineprint'>This tag has been aliased to "
|
||||
html << link_to(tag.antecedent_alias.consequent_name, show_or_new_wiki_pages_path(:title => tag.antecedent_alias.consequent_name))
|
||||
html << link_to_wiki(tag.antecedent_alias.consequent_name)
|
||||
html << " (#{link_to_wiki "learn more", "help:tag_aliases"}).</p>"
|
||||
end
|
||||
|
||||
if tag.consequent_aliases.present?
|
||||
html << "<p class='fineprint'>The following tags are aliased to this tag: "
|
||||
html << raw(tag.consequent_aliases.map {|x| link_to(x.antecedent_name, show_or_new_wiki_pages_path(:title => x.antecedent_name))}.join(", "))
|
||||
html << raw(tag.consequent_aliases.map {|x| link_to_wiki x.antecedent_name }.join(", "))
|
||||
html << " (#{link_to_wiki "learn more", "help:tag_aliases"}).</p>"
|
||||
end
|
||||
|
||||
automatic_tags = TagImplication.automatic_tags_for([tag.name])
|
||||
if automatic_tags.present?
|
||||
html << "<p class='fineprint'>This tag automatically adds "
|
||||
html << raw(automatic_tags.map {|x| link_to(x, show_or_new_wiki_pages_path(:title => x))}.join(", "))
|
||||
html << raw(automatic_tags.map {|x| link_to_wiki x, x }.join(", "))
|
||||
html << " (#{link_to_wiki "learn more", "help:autotags"}).</p>"
|
||||
end
|
||||
|
||||
if tag.antecedent_implications.present?
|
||||
html << "<p class='fineprint'>This tag implicates "
|
||||
html << raw(tag.antecedent_implications.map {|x| link_to(x.consequent_name, show_or_new_wiki_pages_path(:title => x.consequent_name))}.join(", "))
|
||||
html << raw(tag.antecedent_implications.map {|x| link_to_wiki x.consequent_name }.join(", "))
|
||||
html << " (#{link_to_wiki "learn more", "help:tag_implications"}).</p>"
|
||||
end
|
||||
|
||||
if tag.consequent_implications.present?
|
||||
html << "<p class='fineprint'>The following tags implicate this tag: "
|
||||
html << raw(tag.consequent_implications.map {|x| link_to(x.antecedent_name, show_or_new_wiki_pages_path(:title => x.antecedent_name))}.join(", "))
|
||||
html << raw(tag.consequent_implications.map {|x| link_to_wiki x.antecedent_name }.join(", "))
|
||||
html << " (#{link_to_wiki "learn more", "help:tag_implications"}).</p>"
|
||||
end
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@ a.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a.wiki-link {
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
|
||||
a[rel*="external"] {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
@@ -275,6 +275,10 @@ div#c-posts {
|
||||
|
||||
aside#sidebar > section > ul {
|
||||
margin-bottom: 1em;
|
||||
|
||||
a.wiki-link {
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
}
|
||||
|
||||
aside#sidebar > section > ul ul li {
|
||||
|
||||
@@ -25,6 +25,8 @@ class TagNameValidator < ActiveModel::EachValidator
|
||||
record.errors[attribute] << "'#{value}' cannot begin with '#{$1}:'"
|
||||
when /\A(#{Tag.categories.regexp}):(.+)\z/i
|
||||
record.errors[attribute] << "'#{value}' cannot begin with '#{$1}:'"
|
||||
when "new", "search"
|
||||
record.errors[attribute] << "'#{value}' is a reserved name and cannot be used"
|
||||
when /\A(.+)_\(cosplay\)\z/i
|
||||
tag_name = TagAlias.to_aliased([$1]).first
|
||||
tag = Tag.find_by_name(tag_name)
|
||||
|
||||
@@ -23,6 +23,14 @@ class WikiPage < ApplicationRecord
|
||||
api_attributes including: [:category_name]
|
||||
|
||||
module SearchMethods
|
||||
def find_by_id_or_title(id)
|
||||
if id =~ /\A\d+\z/
|
||||
[find_by_id(id), :id]
|
||||
else
|
||||
[find_by_title(normalize_title(id)), :title]
|
||||
end
|
||||
end
|
||||
|
||||
def titled(title)
|
||||
where(title: normalize_title(title))
|
||||
end
|
||||
@@ -138,7 +146,7 @@ class WikiPage < ApplicationRecord
|
||||
end
|
||||
|
||||
def self.normalize_title(title)
|
||||
title.downcase.gsub(/[[:space:]]+/, "_").gsub(/__/, "_").gsub(/\A_|_\z/, "")
|
||||
title.downcase.delete_prefix("~").gsub(/[[:space:]]+/, "_").gsub(/__/, "_").gsub(/\A_|_\z/, "")
|
||||
end
|
||||
|
||||
def normalize_title
|
||||
@@ -235,4 +243,12 @@ class WikiPage < ApplicationRecord
|
||||
def visible?
|
||||
artist.blank? || !artist.is_banned? || CurrentUser.is_builder?
|
||||
end
|
||||
|
||||
def to_param
|
||||
if title =~ /\A\d+\z/
|
||||
"~#{title}"
|
||||
else
|
||||
title
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -113,8 +113,10 @@ class TagSetPresenter < Presenter
|
||||
unless name_only
|
||||
if category == Tag.categories.artist
|
||||
html << %{<a class="wiki-link" href="/artists/show_or_new?name=#{u(name)}">?</a> }
|
||||
elsif name =~ /\A\d+\z/
|
||||
html << %{<a class="wiki-link" href="/wiki_pages/~#{u(name)}">?</a> }
|
||||
else
|
||||
html << %{<a class="wiki-link" href="/wiki_pages/show_or_new?title=#{u(name)}">?</a> }
|
||||
html << %{<a class="wiki-link" href="/wiki_pages/#{u(name)}">?</a> }
|
||||
end
|
||||
|
||||
if show_extra_links && current_query.present?
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<% if dtext_link.external_link? %>
|
||||
<%= external_link_to(dtext_link.link_target) %>
|
||||
<% elsif dtext_link.wiki_link? %>
|
||||
<%= link_to(dtext_link.link_target, show_or_new_wiki_pages_path(title: dtext_link.link_target), class: "tag-type-#{Tag.category_for(dtext_link.link_target)}") %>
|
||||
<%= link_to_wiki dtext_link.link_target, class: "tag-type-#{Tag.category_for(dtext_link.link_target)}" %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to("»", dtext_links_path(search: { link_target: dtext_link.link_target })) %>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<div class="current-related-tags-columns">
|
||||
<% if related_tags.present? %>
|
||||
<%= render "related_tags/tag_column", tags: related_tags.tags, class: "general-related-tags-column", title: related_tags.pretty_name %>
|
||||
<%= render "related_tags/tag_column", tags: related_tags.wiki_page_tags, class: "wiki-related-tags-column", title: link_to("wiki:#{related_tags.pretty_name}", show_or_new_wiki_pages_path(title: related_tags.query)) %>
|
||||
<%= render "related_tags/tag_column", tags: related_tags.wiki_page_tags, class: "wiki-related-tags-column", title: link_to_wiki("wiki:#{related_tags.pretty_name}", related_tags.query) %>
|
||||
|
||||
<% related_tags.other_wiki_pages.each do |wiki| %>
|
||||
<%= render "related_tags/tag_column", tags: wiki.tags, class: "other-wiki-related-tags-column", title: link_to("wiki:#{wiki.pretty_title}", show_or_new_wiki_pages_path(title: wiki.title)) %>
|
||||
<%= render "related_tags/tag_column", tags: wiki.tags, class: "other-wiki-related-tags-column", title: link_to_wiki("wiki:#{wiki.pretty_title}", wiki.title) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<% @query.tags_for_html.each do |tag, category| %>
|
||||
<tr>
|
||||
<td class="category-<%= category %>">
|
||||
<%= link_to("?", show_or_new_wiki_pages_path(:title => tag)) %>
|
||||
<%= link_to_wiki "?", tag %>
|
||||
<%= link_to(tag, posts_path(:tags => tag)) %>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<tr>
|
||||
<td><%= tag.post_count %></td>
|
||||
<td class="category-<%= tag.category %> col-expand">
|
||||
<%= link_to("?", show_or_new_wiki_pages_path(:title => tag.name)) %>
|
||||
<%= link_to_wiki "?", tag.name %>
|
||||
<%= link_to(tag.name, posts_path(:tags => tag.name)) %>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -40,13 +40,29 @@ class WikiPagesControllerTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
should "render" do
|
||||
get wiki_page_path(@wiki_page)
|
||||
should "redirect to the title for an id" do
|
||||
get wiki_page_path(@wiki_page.id)
|
||||
assert_redirected_to wiki_page_path(@wiki_page.title)
|
||||
|
||||
get wiki_page_path(@wiki_page.id), as: :json
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
should "distinguish between an id and a title" do
|
||||
as(@user) { @wiki_page.update(title: "2019") }
|
||||
|
||||
get wiki_page_path("~2019")
|
||||
assert_response :success
|
||||
|
||||
get wiki_page_path(@wiki_page.id)
|
||||
assert_redirected_to wiki_page_path("~2019")
|
||||
|
||||
get wiki_page_path("2019")
|
||||
assert_response 404
|
||||
end
|
||||
|
||||
should "render for a title" do
|
||||
get wiki_page_path(:id => @wiki_page.title)
|
||||
get wiki_page_path(@wiki_page.title)
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
@@ -64,8 +80,9 @@ class WikiPagesControllerTest < ActionDispatch::IntegrationTest
|
||||
as_user do
|
||||
@wiki_page.update(title: "-aaa")
|
||||
end
|
||||
get wiki_page_path(:id => @wiki_page.id)
|
||||
assert_response :success
|
||||
|
||||
get wiki_page_path(@wiki_page.id)
|
||||
assert_redirected_to wiki_page_path(@wiki_page.title)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -695,7 +695,7 @@ class PostTest < ActiveSupport::TestCase
|
||||
|
||||
context "that already exists" do
|
||||
setup do
|
||||
%W(___ ~foo _foo foo_ foo__bar foo*bar foo,bar foo\abar café 東方).each do |tag|
|
||||
%W(___ ~foo _foo foo_ foo__bar foo*bar foo,bar foo\abar café 東方 new search).each do |tag|
|
||||
build(:tag, name: tag).save(validate: false)
|
||||
end
|
||||
end
|
||||
@@ -710,6 +710,8 @@ class PostTest < ActiveSupport::TestCase
|
||||
assert_invalid_tag("foo\abar")
|
||||
assert_invalid_tag("café")
|
||||
assert_invalid_tag("東方")
|
||||
assert_invalid_tag("new")
|
||||
assert_invalid_tag("search")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user