[WikiPages] Implement basic redirects (#683)

This commit is contained in:
Cinder 2024-07-26 12:43:45 -07:00
parent 852129269b
commit ba5b6b0fff
11 changed files with 99 additions and 22 deletions

View File

@ -55,6 +55,9 @@ class WikiPagesController < ApplicationController
end
if @wiki_page.present?
if @wiki_page.parent.present?
@wiki_redirect = WikiPage.titled(@wiki_page.parent)
end
respond_with(@wiki_page)
elsif request.format.html?
redirect_to show_or_new_wiki_pages_path(title: params[:id])
@ -121,6 +124,7 @@ class WikiPagesController < ApplicationController
def wiki_page_params(context)
permitted_params = %i[body skip_secondary_validations edit_reason]
permitted_params += %i[parent] if CurrentUser.is_privileged?
permitted_params += %i[is_locked is_deleted] if CurrentUser.is_janitor?
permitted_params += %i[title] if context == :create || CurrentUser.is_janitor?

View File

@ -77,6 +77,7 @@
@import "specific/user_feedback.scss";
@import "specific/user_warned.scss";
@import "specific/users.scss";
@import "specific/wiki_pages.scss";
@import "specific/wiki_page_versions.scss";
@import "common/z_responsive.scss";

View File

@ -0,0 +1,20 @@
#c-wiki-pages #a-show,
#c-wiki-page-versions {
.wiki-page-redirect {
margin-left: 1em;
color: var(--color-text-muted);
& > i {
display: inline-flex;
margin-right: 0.25em;
}
}
.wiki-redirect-history {
color: var(--color-text-muted);
margin-bottom: 1em;
}
#wiki-page-body {
margin-top: 0.25em;
}
}

View File

@ -5,15 +5,17 @@ class WikiPage < ApplicationRecord
before_validation :normalize_title
before_validation :normalize_other_names
before_validation :normalize_parent
after_save :create_version
validates :title, uniqueness: { :case_sensitive => false }
validates :title, presence: true
validates :title, tag_name: true, if: :title_changed?
validates :body, presence: { :unless => -> { is_deleted? || other_names.present? } }
validates :body, presence: { unless: -> { is_deleted? || other_names.present? || parent.present? } }
validates :title, length: { minimum: 1, maximum: 100 }
validates :body, length: { maximum: Danbooru.config.wiki_page_max_size }
validate :user_not_limited
validate :validate_rename
validate :validate_redirect
validate :validate_not_locked
before_destroy :validate_not_used_as_help_page
@ -94,6 +96,8 @@ class WikiPage < ApplicationRecord
q = q.where("is_deleted = false")
end
q = q.attribute_matches(:parent, params[:parent].try(:tr, " ", "_"))
if params[:other_names_present].to_s.truthy?
q = q.where("other_names is not null and other_names != '{}'")
elsif params[:other_names_present].to_s.falsy?
@ -169,6 +173,18 @@ class WikiPage < ApplicationRecord
end
end
def validate_redirect
return unless will_save_change_to_parent? && parent.present?
if WikiPage.find_by(title: parent).blank?
errors.add(:parent, "does not exist")
return
end
if HelpPage.find_by(wiki_page: title).present?
errors.add(:title, "is used as a help page and cannot be redirected")
end
end
def revert_to(version)
if id != version.wiki_page_id
raise RevertError.new("You cannot revert to a previous version of another wiki page.")
@ -176,6 +192,7 @@ class WikiPage < ApplicationRecord
self.title = version.title
self.body = version.body
self.parent = version.parent
self.other_names = version.other_names
end
@ -192,6 +209,10 @@ class WikiPage < ApplicationRecord
self.other_names = other_names.map { |name| WikiPage.normalize_other_name(name) }.uniq
end
def normalize_parent
self.parent = nil if parent == ""
end
def self.normalize_other_name(name)
name.unicode_normalize(:nfkc).gsub(/[[:space:]]+/, " ").strip.tr(" ", "_")
end
@ -214,19 +235,20 @@ class WikiPage < ApplicationRecord
end
def wiki_page_changed?
saved_change_to_title? || saved_change_to_body? || saved_change_to_is_locked? || saved_change_to_is_deleted? || saved_change_to_other_names?
saved_change_to_title? || saved_change_to_body? || saved_change_to_is_locked? || saved_change_to_is_deleted? || saved_change_to_other_names? || saved_change_to_parent?
end
def create_new_version
versions.create(
:updater_id => CurrentUser.user.id,
:updater_ip_addr => CurrentUser.ip_addr,
:title => title,
:body => body,
:is_locked => is_locked,
:is_deleted => is_deleted,
:other_names => other_names,
reason: edit_reason
updater_id: CurrentUser.user.id,
updater_ip_addr: CurrentUser.ip_addr,
title: title,
body: body,
is_locked: is_locked,
is_deleted: is_deleted,
other_names: other_names,
parent: parent,
reason: edit_reason,
)
end

View File

@ -5,6 +5,14 @@
<% if @thispage.visible? %>
<p>Showing differences between <%= compact_time @thispage.updated_at %> (<%= link_to_user @thispage.updater %>) and <%= compact_time @otherpage.updated_at %> (<%= link_to_user @otherpage.updater %>)</p>
<% if @thispage.parent != @otherpage.parent %>
<div class="wiki-redirect-history">
Page redirect changed
from <%= @thispage.parent.blank? ? "none" : link_to(@thispage.parent, show_or_new_wiki_pages_path(title: @thispage.parent)) %>
to <%= @otherpage.parent.blank? ? "none" : link_to(@otherpage.parent, show_or_new_wiki_pages_path(title: @otherpage.parent)) %>.
</div>
<% end %>
<div>
<%= text_diff(@thispage.body, @otherpage.body) %>
</div>

View File

@ -5,6 +5,10 @@
<section id="content">
<h1 id="wiki-page-title"><%= @wiki_page_version.pretty_title %> <span class="version">(<%= time_ago_in_words_tagged(@wiki_page_version.updated_at) %>)</span></h1>
<% if @wiki_page_version.parent.present? %>
<div class="wiki-page-redirect"><i class="fa-solid fa-turn-up fa-rotate-90"></i> Redirects to <%= link_to @wiki_page_version.parent, show_or_new_wiki_pages_path(title: @wiki_page_version.parent) %></div>
<% end %>
<div id="wiki-page-body" class="dtext dtext-container">
<% if @wiki_page_version.visible? %>
<%= format_text(@wiki_page_version.body) %>

View File

@ -12,6 +12,8 @@
<%= f.input :body, as: :dtext, limit: Danbooru.config.wiki_page_max_size, allow_color: true %>
<%= f.input :parent, label: "Redirects to", autocomplete: "wiki-page", input_html: { disabled: !CurrentUser.is_privileged? } %>
<% if CurrentUser.is_janitor? && @wiki_page.is_deleted? %>
<%= f.input :is_deleted, :label => "Deleted", :hint => "Uncheck to restore this wiki page" %>
<% end %>

View File

@ -2,6 +2,7 @@
<%= f.input :title, label: "Title", hint: "Use * for wildcard searches", autocomplete: "wiki-page" %>
<%= f.input :body_matches, label: "Body" %>
<%= f.user :creator %>
<%= f.input :parent, label: "Redirects to", autocomplete: "wiki-page" %>
<%= f.input :other_names_match, label: "Other names", hint: "Use * for wildcard searches" %>
<%= f.input :other_names_present, collection: %w[Yes No], include_blank: true %>
<%= f.input :hide_deleted, collection: %w[Yes No] %>

View File

@ -1,3 +1,4 @@
<% wiki_content = @wiki_redirect.presence || @wiki_page %>
<div id="c-wiki-pages">
<div id="a-show">
<%= render "sidebar" %>
@ -5,38 +6,41 @@
<section id="content">
<h1 id="wiki-page-title">
<%= link_to @wiki_page.pretty_title_with_category, posts_path(:tags => @wiki_page.title), :class => "tag-type-#{@wiki_page.category_id}" %>
<%= link_to wiki_content.pretty_title_with_category, posts_path(:tags => wiki_content.title), :class => "tag-type-#{wiki_content.category_id}" %>
<% if @wiki_page.is_locked? %>
<% if wiki_content.is_locked? %>
(locked)
<% end %>
<% if @wiki_page.is_deleted? %>
<% if wiki_content.is_deleted? %>
(deleted)
<% end %>
</h1>
<% if @wiki_redirect.present? %>
<div class="wiki-page-redirect"><i class="fa-solid fa-turn-up fa-rotate-90"></i> <%= @wiki_page.title %></div>
<% end %>
<div id="wiki-page-body" class="dtext-container">
<% if @wiki_page.visible? %>
<%= format_text(@wiki_page.body, allow_color: true, max_thumbs: 75) %>
<% if wiki_content.visible? %>
<%= format_text(wiki_content.body, allow_color: true, max_thumbs: 75) %>
<% if @wiki_page.artist %>
<p><%= link_to "View artist", @wiki_page.artist %></p>
<% if wiki_content.artist %>
<p><%= link_to "View artist", wiki_content.artist %></p>
<% end %>
<%= wiki_page_alias_and_implication_list(@wiki_page) %>
<%= wiki_page_alias_and_implication_list(wiki_content) %>
<% else %>
<p>This artist has requested removal of their information.</p>
<% end %>
</div>
<%= wiki_page_post_previews(@wiki_page) %>
<%= wiki_page_post_previews(wiki_content) %>
</section>
</div>
</div>
<% content_for(:page_title) do %>
Wiki - <%= @wiki_page.pretty_title %>
Wiki - <%= wiki_content.pretty_title %>
<% end %>
<%= render "secondary_links" %>

View File

@ -0,0 +1,8 @@
# frozen_string_literal: true
class AddWikiPageParentName < ActiveRecord::Migration[7.0]
def change
add_column :wiki_pages, :parent, :string
add_column :wiki_page_versions, :parent, :string
end
end

View File

@ -2316,7 +2316,8 @@ CREATE TABLE public.wiki_page_versions (
updated_at timestamp without time zone NOT NULL,
other_names text[] DEFAULT '{}'::text[] NOT NULL,
is_deleted boolean DEFAULT false NOT NULL,
reason character varying
reason character varying,
parent character varying
);
@ -2354,7 +2355,8 @@ CREATE TABLE public.wiki_pages (
updated_at timestamp without time zone NOT NULL,
updater_id integer,
other_names text[] DEFAULT '{}'::text[] NOT NULL,
is_deleted boolean DEFAULT false NOT NULL
is_deleted boolean DEFAULT false NOT NULL,
parent character varying
);
@ -4496,6 +4498,7 @@ ALTER TABLE ONLY public.favorites
SET search_path TO "$user", public;
INSERT INTO "schema_migrations" (version) VALUES
('20240726170041'),
('20240709134926'),
('20240706061122'),
('20240101042716'),