nestfans-wiki 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +34 -0
- data/Rakefile +37 -0
- data/app/assets/config/homeland_press_manifest.js +3 -0
- data/app/assets/javascripts/homeland/wiki/application.coffee +40 -0
- data/app/assets/stylesheets/homeland/wiki/application.scss +36 -0
- data/app/controllers/homeland/wiki/admin/page_versions_controller.rb +23 -0
- data/app/controllers/homeland/wiki/admin/pages_controller.rb +42 -0
- data/app/controllers/homeland/wiki/application_controller.rb +9 -0
- data/app/controllers/homeland/wiki/pages_controller.rb +92 -0
- data/app/helpers/homeland/wiki/application_helper.rb +10 -0
- data/app/models/homeland/wiki/ability.rb +32 -0
- data/app/models/page.rb +74 -0
- data/app/models/page_version.rb +7 -0
- data/app/views/homeland/wiki/admin/page_versions/index.html.erb +32 -0
- data/app/views/homeland/wiki/admin/page_versions/show.html.erb +20 -0
- data/app/views/homeland/wiki/admin/pages/_form.html.erb +29 -0
- data/app/views/homeland/wiki/admin/pages/edit.html.erb +6 -0
- data/app/views/homeland/wiki/admin/pages/index.html.erb +31 -0
- data/app/views/homeland/wiki/pages/_form.html.erb +41 -0
- data/app/views/homeland/wiki/pages/_sidebar.html.erb +14 -0
- data/app/views/homeland/wiki/pages/comments.html.erb +17 -0
- data/app/views/homeland/wiki/pages/edit.html.erb +8 -0
- data/app/views/homeland/wiki/pages/index.html.erb +13 -0
- data/app/views/homeland/wiki/pages/new.html.erb +8 -0
- data/app/views/homeland/wiki/pages/recent.html.erb +18 -0
- data/app/views/homeland/wiki/pages/show.html.erb +46 -0
- data/app/views/layouts/homeland/wiki/application.html.erb +15 -0
- data/config/locales/pages.en.yml +9 -0
- data/config/locales/pages.zh-CN.yml +9 -0
- data/config/locales/pages.zh-TW.yml +9 -0
- data/config/routes.rb +21 -0
- data/db/migrate/20170305220755_create_pages.rb +26 -0
- data/lib/homeland/wiki.rb +7 -0
- data/lib/homeland/wiki/engine.rb +30 -0
- data/lib/homeland/wiki/version.rb +7 -0
- metadata +95 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: b7cd5ea973751cfab3bc5e04592fe31339be6e97
|
|
4
|
+
data.tar.gz: b96a72412817867c29a1dcf20217a419e562e50a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d9d3ba3e863d2a8064b8ad4d3e56bcf5410bad6e8e5b7618e137039cd789fa5177946cd34ca3f6ba80b6124453519b788a0f376f8270d09aabce81396f4f9ac0
|
|
7
|
+
data.tar.gz: a2030d91feefde89ad5286c2353e5a4d5aa1ebbff433b62a9b7890ffb3f2fe9475a8422eab6626c8134cb338f2b2485143688f4229ab6be6c646a1102e698239
|
data/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Homeland::Wiki
|
|
2
|
+
--------------
|
|
3
|
+
|
|
4
|
+
Wiki 栏目插件 for [Homeland](https://gethomeland.com)
|
|
5
|
+
|
|
6
|
+
简单的实现 /wiki 栏目,并在导航栏显示。
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
在 Homeland 应用的 Gemfile 增加:
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
gem 'homeland-wiki'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
And then execute:
|
|
19
|
+
```bash
|
|
20
|
+
$ bundle
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Configuration
|
|
24
|
+
|
|
25
|
+
修改 Homeland 的 `modules` 配置,增加 `wiki` 以启用。
|
|
26
|
+
|
|
27
|
+
```yml
|
|
28
|
+
defaults: &defaults
|
|
29
|
+
# add "press" to modules
|
|
30
|
+
modules: 'topic,...,wiki'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'bundler/setup'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
require 'rdoc/task'
|
|
8
|
+
|
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
11
|
+
rdoc.title = 'Homeland::Wiki'
|
|
12
|
+
rdoc.options << '--line-numbers'
|
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
|
18
|
+
load 'rails/tasks/engine.rake'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
load 'rails/tasks/statistics.rake'
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
require 'bundler/gem_tasks'
|
|
26
|
+
|
|
27
|
+
require 'rake/testtask'
|
|
28
|
+
|
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
|
30
|
+
t.libs << 'test'
|
|
31
|
+
t.pattern = 'test/**/*_test.rb'
|
|
32
|
+
t.verbose = false
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
task default: :test
|
|
37
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Place all the behaviors and hooks related to the matching controller here.
|
|
2
|
+
# All this logic will automatically be available in application.js.
|
|
3
|
+
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
|
4
|
+
#
|
|
5
|
+
window.WikiView = Backbone.View.extend
|
|
6
|
+
el: "body"
|
|
7
|
+
events:
|
|
8
|
+
"click .editor-toolbar .preview": "togglePreviewView"
|
|
9
|
+
|
|
10
|
+
initialize: (opts) ->
|
|
11
|
+
@parentView = window._appView
|
|
12
|
+
$("<div id='preview' class='markdown form-control'></div>").insertAfter($("#page_body"))
|
|
13
|
+
$("#preview").hide()
|
|
14
|
+
window._editor = new Editor()
|
|
15
|
+
|
|
16
|
+
togglePreviewView: (e) ->
|
|
17
|
+
textarea = $("#page_body")
|
|
18
|
+
preview_box = $("#preview")
|
|
19
|
+
|
|
20
|
+
if $(e.target).hasClass("active")
|
|
21
|
+
$(e.target).removeClass("active")
|
|
22
|
+
preview_box.hide()
|
|
23
|
+
textarea.show()
|
|
24
|
+
else
|
|
25
|
+
$(e.target).addClass("active")
|
|
26
|
+
preview_box.show()
|
|
27
|
+
preview_box.css("height", textarea.height())
|
|
28
|
+
textarea.hide()
|
|
29
|
+
this.preview(preview_box, textarea.val())
|
|
30
|
+
return false
|
|
31
|
+
|
|
32
|
+
preview: (preview_box, val) ->
|
|
33
|
+
$.post '/wiki/preview', { body: val }, (data)->
|
|
34
|
+
preview_box.html(data)
|
|
35
|
+
false
|
|
36
|
+
false
|
|
37
|
+
|
|
38
|
+
document.addEventListener 'turbolinks:load', ->
|
|
39
|
+
if $('body').data('controller-name') in ['pages']
|
|
40
|
+
window._wikiView = new WikiView()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*= require_self
|
|
3
|
+
*/
|
|
4
|
+
.page-pages {
|
|
5
|
+
.sidebar {
|
|
6
|
+
strong { color: #999; }
|
|
7
|
+
ul {
|
|
8
|
+
padding: 10px 10px 10px 30px;
|
|
9
|
+
li { line-height: 180%; }
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.page-detail {
|
|
14
|
+
.card-header {
|
|
15
|
+
padding: 15px;
|
|
16
|
+
h1 { font-size: 20px; color: #111; margin: 0; margin-bottom: 6px;}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.info {
|
|
20
|
+
text-align:right;
|
|
21
|
+
padding:10px;
|
|
22
|
+
border-bottom:1px solid #eaeaea;
|
|
23
|
+
margin:-10px -10px 0;
|
|
24
|
+
background: #f5f5f5;
|
|
25
|
+
border-radius: 3px 3px 0 0;
|
|
26
|
+
margin-bottom:20px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.editors {
|
|
30
|
+
h3 { font-size:14px; color:#999;}
|
|
31
|
+
.media-object { display: inline; }
|
|
32
|
+
.buttons { margin-top: 10px; }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Homeland::Wiki::Admin
|
|
2
|
+
class PageVersionsController < ::Admin::ApplicationController
|
|
3
|
+
def index
|
|
4
|
+
@page = Page.find(params[:page_id])
|
|
5
|
+
@page_versions = @page.versions.order(version: :desc).page(params[:page])
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def show
|
|
9
|
+
@page = Page.find(params[:page_id])
|
|
10
|
+
@page_version = @page.versions.find(params[:id])
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def revert
|
|
14
|
+
@page = Page.find(params[:page_id])
|
|
15
|
+
@page_version = @page.versions.find(params[:id])
|
|
16
|
+
if @page.revert_version(@page_version.version)
|
|
17
|
+
redirect_to admin_page_versions_path(params[:page_id]), notice: "Wiki 内容已经撤销到了版本 #{@page_version.version}"
|
|
18
|
+
else
|
|
19
|
+
redirect_to admin_page_versions_path(params[:page_id]), alert: "版本撤销失败,原因: #{@page.errors.full_messages.join('<br />')}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Homeland::Wiki::Admin
|
|
2
|
+
class PagesController < ::Admin::ApplicationController
|
|
3
|
+
before_action :set_page, only: [:show, :edit, :update, :destroy]
|
|
4
|
+
|
|
5
|
+
def index
|
|
6
|
+
@pages = Page.unscoped.order(id: :desc).page(params[:page])
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def edit
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def update
|
|
13
|
+
@page.title = params[:page][:title]
|
|
14
|
+
@page.body = params[:page][:body]
|
|
15
|
+
@page.slug = params[:page][:slug]
|
|
16
|
+
@page.locked = params[:page][:locked]
|
|
17
|
+
@page.user_id = current_user.id
|
|
18
|
+
|
|
19
|
+
if @page.save
|
|
20
|
+
redirect_to(admin_pages_path, notice: 'Page was successfully updated.')
|
|
21
|
+
else
|
|
22
|
+
render action: 'edit'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def destroy
|
|
27
|
+
if @page.deleted_at.present?
|
|
28
|
+
@page.delete
|
|
29
|
+
else
|
|
30
|
+
@page.destroy
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
redirect_to(admin_pages_path)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def set_page
|
|
39
|
+
@page = Page.unscoped.find_by_slug(params[:id])
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module Homeland::Wiki
|
|
2
|
+
class PagesController < Homeland::Wiki::ApplicationController
|
|
3
|
+
require_module_enabled! :wiki
|
|
4
|
+
before_action :set_page, only: [:show, :edit, :update, :destroy, :comments]
|
|
5
|
+
|
|
6
|
+
etag { Setting.wiki_sidebar_html }
|
|
7
|
+
|
|
8
|
+
def index
|
|
9
|
+
fresh_when(Setting.wiki_index_html)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def recent
|
|
13
|
+
@pages = Page.recent.page(params[:page])
|
|
14
|
+
fresh_when(@pages)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def show
|
|
18
|
+
if @page.blank?
|
|
19
|
+
if current_user.blank?
|
|
20
|
+
render_404
|
|
21
|
+
return
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
redirect_to new_page_path(title: params[:id]), notice: 'Page not Found, Please create a new page'
|
|
25
|
+
return
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
@page.hits.incr(1)
|
|
29
|
+
fresh_when(@page)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def comments
|
|
33
|
+
render_404 if @page.blank?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def new
|
|
37
|
+
authorize! :create, Page
|
|
38
|
+
|
|
39
|
+
@page = Page.new
|
|
40
|
+
@page.slug = params[:title]
|
|
41
|
+
respond_to do |format|
|
|
42
|
+
format.html # new.html.erb
|
|
43
|
+
format.json { render json: @page }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def edit
|
|
48
|
+
authorize! :edit, @page
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def create
|
|
52
|
+
authorize! :create, Page
|
|
53
|
+
|
|
54
|
+
@page = Page.new(page_params)
|
|
55
|
+
@page.user_id = current_user.id
|
|
56
|
+
@page.version_enable = true
|
|
57
|
+
|
|
58
|
+
if @page.save
|
|
59
|
+
redirect_to page_path(@page.slug), notice: t('common.create_success')
|
|
60
|
+
else
|
|
61
|
+
render action: 'new'
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def update
|
|
66
|
+
authorize! :update, @page
|
|
67
|
+
|
|
68
|
+
@page.version_enable = true
|
|
69
|
+
@page.user_id = current_user.id
|
|
70
|
+
|
|
71
|
+
if @page.update(page_params)
|
|
72
|
+
redirect_to page_path(@page.slug), notice: t('common.update_success')
|
|
73
|
+
else
|
|
74
|
+
render action: 'edit'
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def preview
|
|
79
|
+
render plain: Homeland::Markdown.call(params[:body])
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
protected
|
|
83
|
+
|
|
84
|
+
def set_page
|
|
85
|
+
@page = Page.find_by_slug(params[:id])
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def page_params
|
|
89
|
+
params.require(:page).permit(:title, :body, :slug, :change_desc)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Homeland::Wiki
|
|
2
|
+
class Ability
|
|
3
|
+
include CanCan::Ability
|
|
4
|
+
|
|
5
|
+
attr_reader :user
|
|
6
|
+
|
|
7
|
+
def initialize(u)
|
|
8
|
+
@user = u
|
|
9
|
+
if @user.blank?
|
|
10
|
+
roles_for_anonymous
|
|
11
|
+
elsif @user.roles?(:admin)
|
|
12
|
+
can :manage, Page
|
|
13
|
+
elsif @user.roles?(:wiki_editor)
|
|
14
|
+
roles_for_wiki_editor
|
|
15
|
+
else
|
|
16
|
+
roles_for_anonymous
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
protected
|
|
21
|
+
|
|
22
|
+
def roles_for_wiki_editor
|
|
23
|
+
can :create, Page
|
|
24
|
+
can :update, Page, locked: false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def roles_for_anonymous
|
|
28
|
+
can [:read, :recent, :preview, :comments], Page
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
data/app/models/page.rb
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
class Page < ApplicationRecord
|
|
2
|
+
include MarkdownBody
|
|
3
|
+
include Searchable
|
|
4
|
+
|
|
5
|
+
counter :hits, default: 0
|
|
6
|
+
|
|
7
|
+
second_level_cache expires_in: 2.weeks
|
|
8
|
+
|
|
9
|
+
has_many :versions, class_name: 'PageVersion'
|
|
10
|
+
|
|
11
|
+
attr_accessor :user_id, :change_desc, :version_enable
|
|
12
|
+
|
|
13
|
+
validates :slug, :title, :body, presence: true
|
|
14
|
+
# 当需要记录版本时,如果是更新,那么要求填写 :change_desc
|
|
15
|
+
validates :user_id, if: proc { |p| p.version_enable == true }, presence: true
|
|
16
|
+
validates :change_desc, if: proc { |p| p.version_enable == true && !p.new_record? }, presence: true
|
|
17
|
+
validates :slug, format: /\A[a-z0-9\-_]+\z/
|
|
18
|
+
validates :slug, uniqueness: true
|
|
19
|
+
|
|
20
|
+
before_save :append_editor
|
|
21
|
+
def append_editor
|
|
22
|
+
unless editor_ids.include?(user_id.to_i)
|
|
23
|
+
editor_ids << user_id.to_i
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# 记录更新版本
|
|
28
|
+
after_save :create_version
|
|
29
|
+
def create_version
|
|
30
|
+
# 只有当 version_enable 为 true 的时候才记录版本
|
|
31
|
+
# 以免后台,以及其他的一些 update 时被误调用
|
|
32
|
+
return true unless version_enable
|
|
33
|
+
# 只有 body, title, slug 更改了才更新版本
|
|
34
|
+
if self.body_changed? || self.title_changed? || self.slug_changed?
|
|
35
|
+
update_column(:version, self.version + 1)
|
|
36
|
+
PageVersion.create(user_id: user_id,
|
|
37
|
+
page_id: id,
|
|
38
|
+
desc: change_desc || '',
|
|
39
|
+
version: version,
|
|
40
|
+
body: body,
|
|
41
|
+
title: title,
|
|
42
|
+
slug: slug)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def as_indexed_json(_options = {})
|
|
47
|
+
as_json(only: [:slug, :title, :body])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def indexed_changed?
|
|
51
|
+
slug_changed? || title_changed? || body_changed?
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def to_param
|
|
55
|
+
slug
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# 撤掉到指定版本
|
|
59
|
+
def revert_version(version)
|
|
60
|
+
page_version = PageVersion.where(page_id: id, version: version).first
|
|
61
|
+
return false if page_version.blank?
|
|
62
|
+
update(body: page_version.body,
|
|
63
|
+
title: page_version.title,
|
|
64
|
+
slug: page_version.slug)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def editors
|
|
68
|
+
User.where(id: editor_ids)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.find_by_slug(slug)
|
|
72
|
+
fetch_by_uniq_keys(slug: slug)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<% content_for :sitemap do %>
|
|
2
|
+
<a href="<%= admin_pages_path %>">Wiki</a> <i class="fa fa-angle-right"></i>
|
|
3
|
+
<a href="<%= admin_page_path(params[:page_id]) %>">Page:<%= params[:page_id] %></a> <i class="fa fa-angle-right"></i>
|
|
4
|
+
<span class="current">版本历史</span>
|
|
5
|
+
<% end %>
|
|
6
|
+
<h1>Wiki 列表</h1>
|
|
7
|
+
|
|
8
|
+
<table class="table table-bordered table-striped table-condensed">
|
|
9
|
+
<tr class="head">
|
|
10
|
+
<td class="first">Version</td>
|
|
11
|
+
<td style="width:200px">Slug</td>
|
|
12
|
+
<td>Title</td>
|
|
13
|
+
<td>Desc</td>
|
|
14
|
+
<td>Creator</td>
|
|
15
|
+
<td>At</td>
|
|
16
|
+
<td></td>
|
|
17
|
+
</tr>
|
|
18
|
+
|
|
19
|
+
<% @page_versions.each do |item| %>
|
|
20
|
+
<tr>
|
|
21
|
+
<td class="first"><%= item.version %></td>
|
|
22
|
+
<td><%= item.slug %></td>
|
|
23
|
+
<td><%= item.title %></td>
|
|
24
|
+
<td><%= item.desc %></td>
|
|
25
|
+
<td><%= user_name_tag(item.user) %></td>
|
|
26
|
+
<td><%= l item.created_at, format: :long %></td>
|
|
27
|
+
<td><%= link_to 'View', admin_page_version_path(item.page_id, item.id) %>
|
|
28
|
+
<%= link_to 'Revert', revert_admin_page_version_path(item.page_id, item.id), 'data-confirm' => 'Are you sure?', method: :post %></td>
|
|
29
|
+
</tr>
|
|
30
|
+
<% end %>
|
|
31
|
+
</table>
|
|
32
|
+
<%= paginate @page_versions %>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<% content_for :sitemap do %>
|
|
2
|
+
<a href="<%= admin_pages_path %>">Wiki</a> <i class="fa fa-angle-right"></i>
|
|
3
|
+
<a href="<%= edit_admin_page_path(params[:page_id]) %>">Page:<%= params[:page_id] %></a> <i class="fa fa-angle-right"></i>
|
|
4
|
+
<a href="<%= admin_page_versions_path(params[:page_id]) %>">版本历史</a> <i class="fa fa-angle-right"></i>
|
|
5
|
+
<span class="current">明细</span>
|
|
6
|
+
<% end %>
|
|
7
|
+
<div class="pull-right">
|
|
8
|
+
<%= link_to 'Revert', revert_admin_page_version_path(@page_version.page_id, @page_version.id), 'data-confirm' => 'Are you sure?', method: :post, class: "btn btn-danger" %>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="field">
|
|
11
|
+
<%= user_name_tag @page_version.user %> 修改与 <%= l @page_version.created_at, format: :long %>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="field">
|
|
14
|
+
Slug: <%= @page_version.slug %>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="field">
|
|
17
|
+
Title: <%= @page_version.title %>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<%= @page_version.body_html %>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<%= form_for [:admin, @page] do |f| %>
|
|
2
|
+
<%= render "shared/error_messages", target: @page %>
|
|
3
|
+
|
|
4
|
+
<div class="form-group form-check">
|
|
5
|
+
<%= f.check_box :locked, class: "form-check-input" %>
|
|
6
|
+
<%= f.label :locked, class: "form-check-label" %>
|
|
7
|
+
<div class="form-text">锁定后,前台非管理员将无法修改。</div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="form-group">
|
|
11
|
+
<%= f.label :slug %>
|
|
12
|
+
<%= f.text_field :slug, class: "form-control" %>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div class="form-group">
|
|
16
|
+
<%= f.label :title %>
|
|
17
|
+
<%= f.text_field :title, class: "form-control" %>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div class="form-group">
|
|
21
|
+
<%= f.label :body %>
|
|
22
|
+
<%= f.text_area :body, class: "form-control", rows: 30 %>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="form-actions">
|
|
26
|
+
<%= f.submit t("common.save"), class: "btn btn-primary", 'data-disable-with' => t("common.saving") %>
|
|
27
|
+
<%= link_to "取消", admin_pages_path, class: "btn btn-outline-primary" %>
|
|
28
|
+
</div>
|
|
29
|
+
<% end %>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<% content_for :sitemap do %>
|
|
2
|
+
<span class="current">Wiki</span>
|
|
3
|
+
<% end %>
|
|
4
|
+
|
|
5
|
+
<table class="table table-bordered table-striped table-condensed">
|
|
6
|
+
<tr class="head">
|
|
7
|
+
<td class="first">ID</td>
|
|
8
|
+
<td style="width:200px">Slug</td>
|
|
9
|
+
<td>Title</td>
|
|
10
|
+
<td>at</td>
|
|
11
|
+
<td>lock</td>
|
|
12
|
+
<td>Version</td>
|
|
13
|
+
<td style="width:80px;"></td>
|
|
14
|
+
</tr>
|
|
15
|
+
|
|
16
|
+
<% @pages.each do |page| %>
|
|
17
|
+
<tr class="<%= 'deleted' if !page.deleted_at.blank? %>">
|
|
18
|
+
<td class="first"><%= page.id %></td>
|
|
19
|
+
<td><%= page.slug %></td>
|
|
20
|
+
<td><%= truncate(page.title, length: 30) %></td>
|
|
21
|
+
<td><%= l page.created_at, format: :short %></td>
|
|
22
|
+
<td><%= page.locked %></td>
|
|
23
|
+
<td><%= page.version %></td>
|
|
24
|
+
<td>
|
|
25
|
+
<%= link_to '', admin_page_versions_path(page.id), class: "fa fa-clock-o", title: "修改记录" %>
|
|
26
|
+
<%= link_to '', edit_admin_page_path(page), class: "fa fa-pencil" %>
|
|
27
|
+
<%= link_to '', admin_page_path(page), 'data-confirm' => 'Are you sure?', method: :delete, class: "fa fa-trash" %></td>
|
|
28
|
+
</tr>
|
|
29
|
+
<% end %>
|
|
30
|
+
</table>
|
|
31
|
+
<%= paginate @pages %>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<%= form_for @page do |f| %>
|
|
2
|
+
<%= render "shared/error_messages", target: @page %>
|
|
3
|
+
|
|
4
|
+
<div class="form-group">
|
|
5
|
+
<%= f.label :slug %>
|
|
6
|
+
<%= f.text_field :slug, class: "form-control" %>
|
|
7
|
+
<div class="form-text">
|
|
8
|
+
<%= Setting.base_url %>/wiki/:slug
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<div class="form-group">
|
|
13
|
+
<%= f.label :title %>
|
|
14
|
+
<%= f.text_field :title, class: "form-control" %>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div class="edit-tools">
|
|
18
|
+
<%= render "/shared/editor_toolbar" %>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<div class="form-group">
|
|
22
|
+
<%= f.text_area :body, rows: 30, class: "form-control topic-editor" %>
|
|
23
|
+
|
|
24
|
+
<div class="form-text">
|
|
25
|
+
请使用 Markdown 格式编写,可以试试用 <a href="https://www.typora.io" target="_blank">Typora</a> 这个 App 来编写。
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<% if !@page.new_record? %>
|
|
30
|
+
<div class="form-group">
|
|
31
|
+
<%= f.label :change_desc %>
|
|
32
|
+
<%= f.text_area :change_desc, class: "form-control", rows: 2 %>
|
|
33
|
+
<div class="form-text"><%= t("pages.describe_this_time_change") %></div>
|
|
34
|
+
</div>
|
|
35
|
+
<% end %>
|
|
36
|
+
|
|
37
|
+
<div class="form-actions">
|
|
38
|
+
<%= f.submit t("common.save"), class: "btn btn-primary", 'data-disable-with' => t("common.saving") %>
|
|
39
|
+
<%= link_to t("common.cancel"), pages_path, class: "btn btn-outline-primary" %>
|
|
40
|
+
</div>
|
|
41
|
+
<% end %>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<div class="sidebar wiki-sidebar col-sm-3 <%= "hide-ios" if action_name != "index" %>">
|
|
2
|
+
<div class="card">
|
|
3
|
+
<div class="card-body">
|
|
4
|
+
<strong>导航</strong>
|
|
5
|
+
<ul>
|
|
6
|
+
<li><a href="/wiki">首页</a></li>
|
|
7
|
+
<li><%= link_to(t("pages.wiki_index"), recent_pages_path) %></li>
|
|
8
|
+
<li class="hide-ios"><%= link_to(t("pages.new_page"), new_page_path)%></li>
|
|
9
|
+
</ul>
|
|
10
|
+
|
|
11
|
+
<%= raw Setting.wiki_sidebar_html %>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<% title_tag [t('pages.comments'), @page.title].join(' · ') %>
|
|
2
|
+
|
|
3
|
+
<div class="row">
|
|
4
|
+
<%= render 'sidebar' %>
|
|
5
|
+
|
|
6
|
+
<div class="col-md-9">
|
|
7
|
+
<div class="card">
|
|
8
|
+
<div id="comments" class="card-body">
|
|
9
|
+
《<%= link_to @page.title, page_path(@page.slug) %>》 - <%= t('pages.comments') %>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div class="hide-ios">
|
|
14
|
+
<%= render "/shared/comments", commentable: @page %>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<% title_tag t('pages.wiki_index') %>
|
|
2
|
+
|
|
3
|
+
<div class="row">
|
|
4
|
+
<%= render "sidebar" %>
|
|
5
|
+
|
|
6
|
+
<div class="col-md-9">
|
|
7
|
+
<div class="card">
|
|
8
|
+
<div class="card-header hide-ios"><%= t("pages.wiki_index") %></div>
|
|
9
|
+
<div class="card-body">
|
|
10
|
+
<ul>
|
|
11
|
+
<% @pages.each do |item| %>
|
|
12
|
+
<li><%= page_title_tag(item) %></li>
|
|
13
|
+
<% end %>
|
|
14
|
+
</ul>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<% title_tag @page.title %>
|
|
2
|
+
|
|
3
|
+
<div class="row">
|
|
4
|
+
<%= render 'sidebar' %>
|
|
5
|
+
|
|
6
|
+
<div class="col-md-9 page-detail">
|
|
7
|
+
<div class="card">
|
|
8
|
+
<% if !@page.locked or admin? %>
|
|
9
|
+
<div class="card-header">
|
|
10
|
+
<h1><%= @page.title %></h1>
|
|
11
|
+
<div class="infos">
|
|
12
|
+
<%= link_to comments_page_path(@page.slug) do %>
|
|
13
|
+
<%= @page.comments_count %> 条评论
|
|
14
|
+
<% end %>,
|
|
15
|
+
<%= @page.version %> 次修正,<%= @page.hits %> 次阅读, <%= t("common.last_modified_at")%> <%= timeago(@page.updated_at) %>
|
|
16
|
+
<span class="pull-right opts hide-ios">
|
|
17
|
+
<%= link_to(icon_tag('pencil'), edit_page_path(@page)) if can? :edit, @page %>
|
|
18
|
+
</span>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<% end %>
|
|
23
|
+
|
|
24
|
+
<div class="card-body markdown markdown-toc">
|
|
25
|
+
<article>
|
|
26
|
+
<%= @page.body_html %>
|
|
27
|
+
</article>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div class="card-footer editors clearfix">
|
|
31
|
+
<div class="heading">
|
|
32
|
+
<%= t("pages.wiki_page_contributors")%>
|
|
33
|
+
<span class="pull-right"><%= social_share_button_tag h("#{@page.title} via: @#{Setting.twitter_id} ") %></span>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="avatars">
|
|
36
|
+
<% @page.editors.each do |item| %>
|
|
37
|
+
<%= user_avatar_tag(item, :xs) %>
|
|
38
|
+
<% end %>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="buttons hide-ios">
|
|
41
|
+
<%= link_to "发表评论", comments_page_path(@page.slug, anchor: "new_comment"), class: "btn btn-success" %>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<% content_for :stylesheets do %>
|
|
2
|
+
<%= stylesheet_link_tag "homeland/wiki/application", media: "all" %>
|
|
3
|
+
<% end %>
|
|
4
|
+
|
|
5
|
+
<% content_for :javascripts do %>
|
|
6
|
+
<%= javascript_include_tag "homeland/wiki/application" %>
|
|
7
|
+
<% end %>
|
|
8
|
+
|
|
9
|
+
<% content_for :main do %>
|
|
10
|
+
<div id="homeland-wiki">
|
|
11
|
+
<%= yield %>
|
|
12
|
+
</div>
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
<%= render template: "/layouts/application" %>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"en":
|
|
2
|
+
pages:
|
|
3
|
+
describe_this_time_change: "Please describe the purpose of this modification."
|
|
4
|
+
edit_page: "Edit Page"
|
|
5
|
+
new_page: "New Page"
|
|
6
|
+
wiki_index: "Wiki Index"
|
|
7
|
+
wiki_page_contributors: "Contributors:"
|
|
8
|
+
wiki_page_lock_warning: "This page is locked and only Adminstrators are authorised to modify."
|
|
9
|
+
comments: 'Comments'
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Homeland::Wiki::Engine.routes.draw do
|
|
2
|
+
resources :pages, path: 'wiki' do
|
|
3
|
+
collection do
|
|
4
|
+
get :recent
|
|
5
|
+
post :preview
|
|
6
|
+
end
|
|
7
|
+
member do
|
|
8
|
+
get :comments
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
namespace :admin do
|
|
13
|
+
resources :pages, path: 'wiki' do
|
|
14
|
+
resources :versions, controller: :page_versions do
|
|
15
|
+
member do
|
|
16
|
+
post :revert
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class CreatePages < ActiveRecord::Migration[5.0]
|
|
2
|
+
def up
|
|
3
|
+
return if ActiveRecord::Base.connection.table_exists? :pages
|
|
4
|
+
|
|
5
|
+
create_table :pages do |t|
|
|
6
|
+
t.string :slug, null: false
|
|
7
|
+
t.string :title, null: false
|
|
8
|
+
t.text :body, null: false
|
|
9
|
+
t.boolean :locked, default: false
|
|
10
|
+
t.integer :version, default: 0, null: false
|
|
11
|
+
t.integer :editor_ids, default: [], null: false, array: true
|
|
12
|
+
t.integer :word_count, default: 0, null: false
|
|
13
|
+
t.integer :changes_cout, default: 1, null: false
|
|
14
|
+
t.integer :comments_count, default: 0, null: false
|
|
15
|
+
t.datetime :deleted_at
|
|
16
|
+
|
|
17
|
+
t.timestamps
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
add_index :pages, :slug, unique: true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def down
|
|
24
|
+
drop_table :pages, if_exists: true
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Homeland
|
|
2
|
+
module Wiki
|
|
3
|
+
class Engine < ::Rails::Engine
|
|
4
|
+
isolate_namespace Homeland::Wiki
|
|
5
|
+
|
|
6
|
+
initializer 'homeland.wiki.init' do |app|
|
|
7
|
+
if Setting.has_module?(:wiki)
|
|
8
|
+
Homeland.register_plugin do |plugin|
|
|
9
|
+
plugin.name = 'wiki'
|
|
10
|
+
plugin.display_name = '知识库'
|
|
11
|
+
plugin.description = Homeland::Wiki::DESCRIPTION
|
|
12
|
+
plugin.version = Homeland::Wiki::VERSION
|
|
13
|
+
plugin.navbar_link = true
|
|
14
|
+
plugin.user_menu_link = false
|
|
15
|
+
plugin.root_path = "/wiki"
|
|
16
|
+
plugin.admin_path = "/admin/wiki"
|
|
17
|
+
plugin.admin_navbar_link = true
|
|
18
|
+
plugin.spec_path = config.root.join('spec')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
app.routes.prepend do
|
|
22
|
+
mount Homeland::Wiki::Engine, at: '/'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
app.config.paths["db/migrate"].concat(config.paths["db/migrate"].expanded)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: nestfans-wiki
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.4.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Griffin Qiu
|
|
8
|
+
- Jason Lee
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2019-07-08 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: rails
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
requirements:
|
|
18
|
+
- - "~>"
|
|
19
|
+
- !ruby/object:Gem::Version
|
|
20
|
+
version: '5'
|
|
21
|
+
type: :runtime
|
|
22
|
+
prerelease: false
|
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - "~>"
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
version: '5'
|
|
28
|
+
description: Display Wiki channel in navbar for wike pages.
|
|
29
|
+
email:
|
|
30
|
+
- griffinqiu@gmail.com
|
|
31
|
+
- huacnlee@gmail.com
|
|
32
|
+
executables: []
|
|
33
|
+
extensions: []
|
|
34
|
+
extra_rdoc_files: []
|
|
35
|
+
files:
|
|
36
|
+
- README.md
|
|
37
|
+
- Rakefile
|
|
38
|
+
- app/assets/config/homeland_press_manifest.js
|
|
39
|
+
- app/assets/javascripts/homeland/wiki/application.coffee
|
|
40
|
+
- app/assets/stylesheets/homeland/wiki/application.scss
|
|
41
|
+
- app/controllers/homeland/wiki/admin/page_versions_controller.rb
|
|
42
|
+
- app/controllers/homeland/wiki/admin/pages_controller.rb
|
|
43
|
+
- app/controllers/homeland/wiki/application_controller.rb
|
|
44
|
+
- app/controllers/homeland/wiki/pages_controller.rb
|
|
45
|
+
- app/helpers/homeland/wiki/application_helper.rb
|
|
46
|
+
- app/models/homeland/wiki/ability.rb
|
|
47
|
+
- app/models/page.rb
|
|
48
|
+
- app/models/page_version.rb
|
|
49
|
+
- app/views/homeland/wiki/admin/page_versions/index.html.erb
|
|
50
|
+
- app/views/homeland/wiki/admin/page_versions/show.html.erb
|
|
51
|
+
- app/views/homeland/wiki/admin/pages/_form.html.erb
|
|
52
|
+
- app/views/homeland/wiki/admin/pages/edit.html.erb
|
|
53
|
+
- app/views/homeland/wiki/admin/pages/index.html.erb
|
|
54
|
+
- app/views/homeland/wiki/pages/_form.html.erb
|
|
55
|
+
- app/views/homeland/wiki/pages/_sidebar.html.erb
|
|
56
|
+
- app/views/homeland/wiki/pages/comments.html.erb
|
|
57
|
+
- app/views/homeland/wiki/pages/edit.html.erb
|
|
58
|
+
- app/views/homeland/wiki/pages/index.html.erb
|
|
59
|
+
- app/views/homeland/wiki/pages/new.html.erb
|
|
60
|
+
- app/views/homeland/wiki/pages/recent.html.erb
|
|
61
|
+
- app/views/homeland/wiki/pages/show.html.erb
|
|
62
|
+
- app/views/layouts/homeland/wiki/application.html.erb
|
|
63
|
+
- config/locales/pages.en.yml
|
|
64
|
+
- config/locales/pages.zh-CN.yml
|
|
65
|
+
- config/locales/pages.zh-TW.yml
|
|
66
|
+
- config/routes.rb
|
|
67
|
+
- db/migrate/20170305220755_create_pages.rb
|
|
68
|
+
- lib/homeland/wiki.rb
|
|
69
|
+
- lib/homeland/wiki/engine.rb
|
|
70
|
+
- lib/homeland/wiki/version.rb
|
|
71
|
+
homepage: https://github.com/ruby-china/homeland-wiki
|
|
72
|
+
licenses:
|
|
73
|
+
- MIT
|
|
74
|
+
metadata: {}
|
|
75
|
+
post_install_message:
|
|
76
|
+
rdoc_options: []
|
|
77
|
+
require_paths:
|
|
78
|
+
- lib
|
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - ">="
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '0'
|
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
requirements: []
|
|
90
|
+
rubyforge_project:
|
|
91
|
+
rubygems_version: 2.6.14
|
|
92
|
+
signing_key:
|
|
93
|
+
specification_version: 4
|
|
94
|
+
summary: Display Wiki channel in navbar for wike pages.
|
|
95
|
+
test_files: []
|