aac6598482
Since GitHub doesn’t apply these constraints to theirs wiki slug allowing characters like `,`, `:`, `*`, etc, we need to relax our constraints or some wiki pages will not be available after they were imported. For an example the Devise project have a wiki page with the following slug: “How To: Add sign_in, sign_out, and sign_up links to your layout template”
201 lines
4.7 KiB
Ruby
201 lines
4.7 KiB
Ruby
class WikiPage
|
|
include ActiveModel::Validations
|
|
include ActiveModel::Conversion
|
|
include StaticModel
|
|
extend ActiveModel::Naming
|
|
|
|
def self.primary_key
|
|
'slug'
|
|
end
|
|
|
|
def self.model_name
|
|
ActiveModel::Name.new(self, nil, 'wiki')
|
|
end
|
|
|
|
def to_key
|
|
[:slug]
|
|
end
|
|
|
|
validates :title, presence: true
|
|
validates :content, presence: true
|
|
|
|
# The Gitlab ProjectWiki instance.
|
|
attr_reader :wiki
|
|
|
|
# The raw Gollum::Page instance.
|
|
attr_reader :page
|
|
|
|
# The attributes Hash used for storing and validating
|
|
# new Page values before writing to the Gollum repository.
|
|
attr_accessor :attributes
|
|
|
|
def initialize(wiki, page = nil, persisted = false)
|
|
@wiki = wiki
|
|
@page = page
|
|
@persisted = persisted
|
|
@attributes = {}.with_indifferent_access
|
|
|
|
set_attributes if persisted?
|
|
end
|
|
|
|
# The escaped URL path of this page.
|
|
def slug
|
|
@attributes[:slug]
|
|
end
|
|
|
|
alias_method :to_param, :slug
|
|
|
|
# The formatted title of this page.
|
|
def title
|
|
if @attributes[:title]
|
|
@attributes[:title].gsub(/-+/, ' ')
|
|
else
|
|
""
|
|
end
|
|
end
|
|
|
|
# Sets the title of this page.
|
|
def title=(new_title)
|
|
@attributes[:title] = new_title
|
|
end
|
|
|
|
# The raw content of this page.
|
|
def content
|
|
@attributes[:content] ||= if @page
|
|
@page.raw_data
|
|
end
|
|
end
|
|
|
|
# The processed/formatted content of this page.
|
|
def formatted_content
|
|
@attributes[:formatted_content] ||= if @page
|
|
@page.formatted_data
|
|
end
|
|
end
|
|
|
|
# The markup format for the page.
|
|
def format
|
|
@attributes[:format] || :markdown
|
|
end
|
|
|
|
# The commit message for this page version.
|
|
def message
|
|
version.try(:message)
|
|
end
|
|
|
|
# The Gitlab Commit instance for this page.
|
|
def version
|
|
return nil unless persisted?
|
|
|
|
@version ||= @page.version
|
|
end
|
|
|
|
# Returns an array of Gitlab Commit instances.
|
|
def versions
|
|
return [] unless persisted?
|
|
|
|
@page.versions
|
|
end
|
|
|
|
def commit
|
|
versions.first
|
|
end
|
|
|
|
# Returns the Date that this latest version was
|
|
# created on.
|
|
def created_at
|
|
@page.version.date
|
|
end
|
|
|
|
# Returns boolean True or False if this instance
|
|
# is an old version of the page.
|
|
def historical?
|
|
@page.historical?
|
|
end
|
|
|
|
# Returns boolean True or False if this instance
|
|
# has been fully saved to disk or not.
|
|
def persisted?
|
|
@persisted == true
|
|
end
|
|
|
|
# Creates a new Wiki Page.
|
|
#
|
|
# attr - Hash of attributes to set on the new page.
|
|
# :title - The title for the new page.
|
|
# :content - The raw markup content.
|
|
# :format - Optional symbol representing the
|
|
# content format. Can be any type
|
|
# listed in the ProjectWiki::MARKUPS
|
|
# Hash.
|
|
# :message - Optional commit message to set on
|
|
# the new page.
|
|
#
|
|
# Returns the String SHA1 of the newly created page
|
|
# or False if the save was unsuccessful.
|
|
def create(attr = {})
|
|
@attributes.merge!(attr)
|
|
|
|
save :create_page, title, content, format, message
|
|
end
|
|
|
|
# Updates an existing Wiki Page, creating a new version.
|
|
#
|
|
# new_content - The raw markup content to replace the existing.
|
|
# format - Optional symbol representing the content format.
|
|
# See ProjectWiki::MARKUPS Hash for available formats.
|
|
# message - Optional commit message to set on the new version.
|
|
#
|
|
# Returns the String SHA1 of the newly created page
|
|
# or False if the save was unsuccessful.
|
|
def update(new_content = "", format = :markdown, message = nil)
|
|
@attributes[:content] = new_content
|
|
@attributes[:format] = format
|
|
|
|
save :update_page, @page, content, format, message
|
|
end
|
|
|
|
# Destroys the Wiki Page.
|
|
#
|
|
# Returns boolean True or False.
|
|
def delete
|
|
if wiki.delete_page(@page)
|
|
true
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def set_attributes
|
|
attributes[:slug] = @page.url_path
|
|
attributes[:title] = @page.title
|
|
attributes[:format] = @page.format
|
|
end
|
|
|
|
def save(method, *args)
|
|
project_wiki = wiki
|
|
if valid? && project_wiki.send(method, *args)
|
|
|
|
page_details = if method == :update_page
|
|
# Use url_path instead of path to omit format extension
|
|
@page.url_path
|
|
else
|
|
title
|
|
end
|
|
|
|
page_title, page_dir = project_wiki.page_title_and_dir(page_details)
|
|
gollum_wiki = project_wiki.wiki
|
|
@page = gollum_wiki.paged(page_title, page_dir)
|
|
|
|
set_attributes
|
|
|
|
@persisted = true
|
|
else
|
|
errors.add(:base, project_wiki.error_message) if project_wiki.error_message
|
|
@persisted = false
|
|
end
|
|
@persisted
|
|
end
|
|
end
|