instiki 0.10.1 → 0.10.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.
- data/CHANGELOG +12 -0
- data/app/controllers/admin_controller.rb +13 -14
- data/app/controllers/application.rb +24 -3
- data/app/controllers/file_controller.rb +2 -2
- data/app/controllers/wiki_controller.rb +28 -30
- data/app/helpers/application_helper.rb +12 -5
- data/app/models/chunks/chunk.rb +1 -1
- data/app/models/chunks/include.rb +2 -2
- data/app/models/chunks/nowiki.rb +1 -1
- data/app/models/chunks/uri.rb +1 -1
- data/app/models/chunks/wiki.rb +1 -1
- data/app/models/file_yard.rb +7 -7
- data/app/models/page.rb +10 -2
- data/app/models/revision.rb +7 -3
- data/app/models/web.rb +6 -4
- data/app/models/wiki_content.rb +3 -5
- data/app/models/wiki_service.rb +32 -36
- data/app/views/admin/create_system.rhtml +4 -2
- data/app/views/admin/create_web.rhtml +4 -3
- data/app/views/admin/edit_web.rhtml +6 -5
- data/app/views/layouts/default.rhtml +8 -13
- data/app/views/navigation.rhtml +5 -3
- data/app/views/textile_help.rhtml +1 -1
- data/app/views/wiki/authors.rhtml +1 -1
- data/app/views/wiki/edit.rhtml +2 -4
- data/app/views/wiki/list.rhtml +1 -1
- data/app/views/wiki/new.rhtml +1 -1
- data/app/views/wiki/page.rhtml +23 -18
- data/app/views/wiki/revision.rhtml +7 -7
- data/app/views/wiki/search.rhtml +1 -1
- data/config/environment.rb +1 -1
- data/config/environments/development.rb +1 -1
- data/config/environments/test.rb +1 -1
- data/config/routes.rb +26 -12
- data/public/javascripts/edit_web.js +3 -0
- data/public/stylesheets/instiki.css +22 -3
- data/script/debug_storage +97 -0
- data/script/server +1 -1
- metadata +4 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
* 0.10.2:
|
2
|
+
Upgraded to Rails 0.13.1
|
3
|
+
Fixed HTML export
|
4
|
+
Added layout=no option to the export_html action (it exports page contents processed
|
5
|
+
by the markup engine, but without the default layout - so that they can be wrapped in
|
6
|
+
some other layout)
|
7
|
+
<nowiki> tag can span several lines (before it was applied when both opening and closing
|
8
|
+
tags were on the same line only)
|
9
|
+
Resolved the "endless redirection loop" condition and otherwise improved handling of
|
10
|
+
errors in the rendering engines
|
11
|
+
Fixed rendering of Markdown hyperlinks such as [Text](http://something.com/foo)
|
12
|
+
|
1
13
|
* 0.10.1:
|
2
14
|
Upgraded Rails to 0.12.0
|
3
15
|
Upgraded rubyzip to version 0.5.8
|
@@ -6,19 +6,17 @@ class AdminController < ApplicationController
|
|
6
6
|
|
7
7
|
def create_system
|
8
8
|
if @wiki.setup?
|
9
|
-
flash[:error] =
|
10
|
-
Wiki has already been created in '#{@wiki.storage_path}'.
|
11
|
-
this directory if you want to recreate it from scratch
|
12
|
-
|
13
|
-
|
9
|
+
flash[:error] =
|
10
|
+
"Wiki has already been created in '#{@wiki.storage_path}'. " +
|
11
|
+
"Shut down Instiki and delete this directory if you want to recreate it from scratch." +
|
12
|
+
"\n\n" +
|
13
|
+
"(WARNING: this will destroy content of your current wiki)."
|
14
14
|
redirect_home(@wiki.webs.keys.first)
|
15
15
|
elsif @params['web_name']
|
16
16
|
# form submitted -> create a wiki
|
17
17
|
@wiki.setup(@params['password'], @params['web_name'], @params['web_address'])
|
18
|
-
flash[:info] =
|
19
|
-
|
20
|
-
Please edit its home page and press Submit when finished.
|
21
|
-
EOL
|
18
|
+
flash[:info] = "Your new wiki '#{@params['web_name']}' is created!\n" +
|
19
|
+
"Please edit its home page and press Submit when finished."
|
22
20
|
redirect_to :web => @params['web_address'], :controller => 'wiki', :action => 'new',
|
23
21
|
:id => 'HomePage'
|
24
22
|
else
|
@@ -36,7 +34,7 @@ class AdminController < ApplicationController
|
|
36
34
|
redirect_to :web => @params['address'], :controller => 'wiki', :action => 'new',
|
37
35
|
:id => 'HomePage'
|
38
36
|
rescue Instiki::ValidationError => e
|
39
|
-
|
37
|
+
@error = e.message
|
40
38
|
# and re-render the form again
|
41
39
|
end
|
42
40
|
else
|
@@ -48,6 +46,7 @@ class AdminController < ApplicationController
|
|
48
46
|
end
|
49
47
|
|
50
48
|
def edit_web
|
49
|
+
|
51
50
|
system_password = @params['system_password']
|
52
51
|
if system_password
|
53
52
|
# form submitted
|
@@ -68,11 +67,11 @@ class AdminController < ApplicationController
|
|
68
67
|
flash[:info] = "Web '#{@params['address']}' was successfully updated"
|
69
68
|
redirect_home(@params['address'])
|
70
69
|
rescue Instiki::ValidationError => e
|
71
|
-
|
70
|
+
@error = e.message
|
72
71
|
# and re-render the same template again
|
73
72
|
end
|
74
73
|
else
|
75
|
-
|
74
|
+
@error = password_error(system_password)
|
76
75
|
# and re-render the same template again
|
77
76
|
end
|
78
77
|
else
|
@@ -86,8 +85,8 @@ class AdminController < ApplicationController
|
|
86
85
|
flash[:info] = 'Orphaned pages removed'
|
87
86
|
redirect_to :controller => 'wiki', :web => @web_name, :action => 'list'
|
88
87
|
else
|
89
|
-
flash[:error] = password_error(@params['
|
90
|
-
|
88
|
+
flash[:error] = password_error(@params['system_password_orphaned'])
|
89
|
+
redirect_to :controller => 'admin', :web => @web_name, :action => 'edit_web'
|
91
90
|
end
|
92
91
|
end
|
93
92
|
|
@@ -88,7 +88,11 @@ class ApplicationController < ActionController::Base
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def redirect_home(web = @web_name)
|
91
|
-
|
91
|
+
if web
|
92
|
+
redirect_to_page('HomePage', web)
|
93
|
+
else
|
94
|
+
redirect_to_url '/'
|
95
|
+
end
|
92
96
|
end
|
93
97
|
|
94
98
|
def redirect_to_page(page_name = @page_name, web = @web_name)
|
@@ -106,13 +110,30 @@ class ApplicationController < ActionController::Base
|
|
106
110
|
end
|
107
111
|
end
|
108
112
|
|
113
|
+
def rescue_action_in_public(exception)
|
114
|
+
message = <<-EOL
|
115
|
+
<html><body>
|
116
|
+
<h2>Internal Error 500</h2>
|
117
|
+
<p>An application error occurred while processing your request.</p>
|
118
|
+
<!-- \n#{exception}\n#{exception.backtrace.join("\n")}\n -->
|
119
|
+
</body></html>
|
120
|
+
EOL
|
121
|
+
render_text message, 'Internal Error 500'
|
122
|
+
end
|
123
|
+
|
109
124
|
def return_to_last_remembered
|
110
125
|
# Forget the redirect location
|
111
126
|
redirect_target, @session[:return_to] = @session[:return_to], nil
|
127
|
+
tried_home, @session[:tried_home] = @session[:tried_home], false
|
128
|
+
|
112
129
|
# then try to redirect to it
|
113
130
|
if redirect_target.nil?
|
114
|
-
|
115
|
-
|
131
|
+
if tried_home
|
132
|
+
raise 'Application could not render the index page'
|
133
|
+
else
|
134
|
+
logger.debug("Session ##{session.object_id}: no remembered redirect location, trying home")
|
135
|
+
redirect_home
|
136
|
+
end
|
116
137
|
else
|
117
138
|
logger.debug("Session ##{session.object_id}: " +
|
118
139
|
"redirect to the last remembered URL #{redirect_target}")
|
@@ -36,8 +36,8 @@ class FileController < ApplicationController
|
|
36
36
|
if @params['file']
|
37
37
|
# form supplied
|
38
38
|
file_yard.upload_file(@file_name, @params['file'])
|
39
|
-
flash[:info] = "Image '#{@file_name}' successfully uploaded"
|
40
39
|
@web.refresh_pages_with_references(@file_name)
|
40
|
+
flash[:info] = "Image '#{@file_name}' successfully uploaded"
|
41
41
|
return_to_last_remembered
|
42
42
|
elsif file_yard.has_file?(@file_name)
|
43
43
|
send_file(file_yard.file_path(@file_name))
|
@@ -59,7 +59,7 @@ class FileController < ApplicationController
|
|
59
59
|
if @problems.empty?
|
60
60
|
flash[:info] = 'Import successfully finished'
|
61
61
|
else
|
62
|
-
flash[:
|
62
|
+
flash[:error] = "Import finished, but some pages were not imported:<li>" +
|
63
63
|
@problems.join('</li><li>') + '</li>'
|
64
64
|
end
|
65
65
|
return_to_last_remembered
|
@@ -42,14 +42,14 @@ class WikiController < ApplicationController
|
|
42
42
|
# Within a single web ---------------------------------------------------------
|
43
43
|
|
44
44
|
def authors
|
45
|
-
@authors = @web.select.authors
|
45
|
+
@authors = @web.select.authors.sort
|
46
46
|
end
|
47
47
|
|
48
48
|
def export_html
|
49
49
|
export_pages_as_zip('html') do |page|
|
50
50
|
@page = page
|
51
51
|
@link_mode = :export
|
52
|
-
render_to_string('wiki/print', use_layout =
|
52
|
+
render_to_string('wiki/print', use_layout = (@params['layout'] != 'no'))
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -122,7 +122,7 @@ class WikiController < ApplicationController
|
|
122
122
|
|
123
123
|
def edit
|
124
124
|
if @page.nil?
|
125
|
-
|
125
|
+
redirect_home
|
126
126
|
elsif @page.locked?(Time.now) and not @params['break_lock']
|
127
127
|
redirect_to :web => @web_name, :action => 'locked', :id => @page_name
|
128
128
|
else
|
@@ -172,28 +172,28 @@ class WikiController < ApplicationController
|
|
172
172
|
end
|
173
173
|
|
174
174
|
def save
|
175
|
-
|
175
|
+
redirect_home if @page_name.nil?
|
176
176
|
cookies['author'] = @params['author']
|
177
177
|
|
178
178
|
begin
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
Author.new(@params['author'], remote_ip)
|
184
|
-
)
|
185
|
-
page.unlock
|
179
|
+
if @page
|
180
|
+
wiki.revise_page(@web_name, @page_name, @params['content'], Time.now,
|
181
|
+
Author.new(@params['author'], remote_ip))
|
182
|
+
@page.unlock
|
186
183
|
else
|
187
|
-
wiki.write_page(
|
188
|
-
@
|
189
|
-
Author.new(@params['author'], remote_ip)
|
190
|
-
)
|
184
|
+
wiki.write_page(@web_name, @page_name, @params['content'], Time.now,
|
185
|
+
Author.new(@params['author'], remote_ip))
|
191
186
|
end
|
192
187
|
redirect_to_page @page_name
|
193
|
-
rescue
|
194
|
-
page.unlock if defined? page
|
188
|
+
rescue => e
|
195
189
|
flash[:error] = e
|
196
|
-
|
190
|
+
flash[:content] = @params['content']
|
191
|
+
if @page
|
192
|
+
@page.unlock
|
193
|
+
redirect_to :action => 'edit', :web => @web_name, :id => @page_name
|
194
|
+
else
|
195
|
+
redirect_to :action => 'new', :web => @web_name, :id => @page_name
|
196
|
+
end
|
197
197
|
end
|
198
198
|
end
|
199
199
|
|
@@ -205,9 +205,9 @@ class WikiController < ApplicationController
|
|
205
205
|
# the application itself (for application errors, it's better not to rescue the error at all)
|
206
206
|
rescue => e
|
207
207
|
logger.error e
|
208
|
+
flash[:error] = e.message
|
208
209
|
if in_a_web?
|
209
|
-
redirect_to :web => @web_name, :
|
210
|
-
:action_suffix => "#{@page_name}?msg=#{e.message}"
|
210
|
+
redirect_to :action => 'edit', :web => @web_name, :id => @page_name
|
211
211
|
else
|
212
212
|
raise e
|
213
213
|
end
|
@@ -260,13 +260,8 @@ class WikiController < ApplicationController
|
|
260
260
|
# add an index file, if exporting to HTML
|
261
261
|
if file_type.to_s.downcase == 'html'
|
262
262
|
zip_out.put_next_entry 'index.html'
|
263
|
-
zip_out.puts
|
264
|
-
|
265
|
-
<head>
|
266
|
-
<META HTTP-EQUIV="Refresh" CONTENT="0;URL=HomePage.#{file_type}">
|
267
|
-
</head>
|
268
|
-
</html>
|
269
|
-
EOL
|
263
|
+
zip_out.puts "<html><head>" +
|
264
|
+
"<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;URL=HomePage.#{file_type}\"></head></html>"
|
270
265
|
end
|
271
266
|
end
|
272
267
|
FileUtils.rm_rf(Dir[File.join(@wiki.storage_path, file_prefix + '*.zip')])
|
@@ -338,9 +333,12 @@ class WikiController < ApplicationController
|
|
338
333
|
|
339
334
|
def render_to_string(template_name, with_layout = false)
|
340
335
|
add_variables_to_assigns
|
341
|
-
|
342
|
-
if with_layout
|
343
|
-
|
336
|
+
self.assigns['content_for_layout'] = @template.render_file(template_name)
|
337
|
+
if with_layout
|
338
|
+
@template.render_file('layouts/default')
|
339
|
+
else
|
340
|
+
self.assigns['content_for_layout']
|
341
|
+
end
|
344
342
|
end
|
345
343
|
|
346
344
|
def rss_with_content_allowed?
|
@@ -36,18 +36,20 @@ module ApplicationHelper
|
|
36
36
|
# Creates a hyperlink to a Wiki page, without checking if the page exists or not
|
37
37
|
def link_to_existing_page(page, text = nil, html_options = {})
|
38
38
|
link_to(
|
39
|
-
text || page.
|
39
|
+
text || page.plain_name,
|
40
40
|
{:web => @web.address, :action => 'show', :id => page.name, :only_path => true},
|
41
41
|
html_options)
|
42
42
|
end
|
43
43
|
|
44
|
-
|
45
44
|
# Creates a hyperlink to a Wiki page, or to a "new page" form if the page doesn't exist yet
|
46
45
|
def link_to_page(page_name, web = @web, text = nil, options = {})
|
47
46
|
raise 'Web not defined' if web.nil?
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
web.make_link(page_name, text, options.merge(:base_url => "#{base_url}/#{web.address}"))
|
48
|
+
end
|
49
|
+
|
50
|
+
def base_url
|
51
|
+
home_page_url = url_for :controller => 'admin', :action => 'create_system', :only_path => true
|
52
|
+
home_page_url.sub(%r-/create_system/?$-, '')
|
51
53
|
end
|
52
54
|
|
53
55
|
# Creates a menu of categories
|
@@ -65,4 +67,9 @@ module ApplicationHelper
|
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
70
|
+
# Performs HTML escaping on text, but keeps linefeeds intact (by replacing them with <br/>)
|
71
|
+
def escape_preserving_linefeeds(text)
|
72
|
+
h(text).gsub(/\n/, '<br/>')
|
73
|
+
end
|
74
|
+
|
68
75
|
end
|
data/app/models/chunks/chunk.rb
CHANGED
@@ -58,7 +58,7 @@ module Chunk
|
|
58
58
|
|
59
59
|
# We should not use object_id because object_id is not guarantied
|
60
60
|
# to be unique when we restart the wiki (new object ids can equal old ones
|
61
|
-
# that were restored
|
61
|
+
# that were restored from madeleine storage)
|
62
62
|
def id
|
63
63
|
@id ||= "#{@content.page_id}n#{@content.chunk_id}"
|
64
64
|
end
|
@@ -9,7 +9,7 @@ require 'chunks/wiki'
|
|
9
9
|
|
10
10
|
class Include < WikiChunk::WikiReference
|
11
11
|
|
12
|
-
INCLUDE_PATTERN = /\[\[!include(
|
12
|
+
INCLUDE_PATTERN = /\[\[!include\s+(.*?)\]\]\s*/i
|
13
13
|
def self.pattern() INCLUDE_PATTERN end
|
14
14
|
|
15
15
|
|
@@ -23,10 +23,10 @@ class Include < WikiChunk::WikiReference
|
|
23
23
|
|
24
24
|
def get_unmask_text_avoiding_recursion_loops
|
25
25
|
if refpage then
|
26
|
+
refpage.clear_display_cache
|
26
27
|
if refpage.wiki_includes.include?(@content.page_name)
|
27
28
|
# this will break the recursion
|
28
29
|
@content.delete_chunk(self)
|
29
|
-
refpage.clear_display_cache
|
30
30
|
return "<em>Recursive include detected; #{@page_name} --> #{@content.page_name} " +
|
31
31
|
"--> #{@page_name}</em>\n"
|
32
32
|
else
|
data/app/models/chunks/nowiki.rb
CHANGED
@@ -15,7 +15,7 @@ require 'chunks/chunk'
|
|
15
15
|
# Created: 8th June 2004
|
16
16
|
class NoWiki < Chunk::Abstract
|
17
17
|
|
18
|
-
NOWIKI_PATTERN = Regexp.new('<nowiki>(.*?)</nowiki>')
|
18
|
+
NOWIKI_PATTERN = Regexp.new('<nowiki>(.*?)</nowiki>', Regexp::MULTILINE)
|
19
19
|
def self.pattern() NOWIKI_PATTERN end
|
20
20
|
|
21
21
|
attr_reader :plain_text
|
data/app/models/chunks/uri.rb
CHANGED
@@ -71,7 +71,7 @@ class URIChunk < Chunk::Abstract
|
|
71
71
|
'(?=\.?(?:\s|\)|\z))' # ends only with optional dot + space or ")"
|
72
72
|
# or end of the string
|
73
73
|
|
74
|
-
SUSPICIOUS_PRECEDING_CHARACTER = '(!|\"\:|\"|\\\')?' # any of !, ":, ", '
|
74
|
+
SUSPICIOUS_PRECEDING_CHARACTER = '(!|\"\:|\"|\\\'|\]\()?' # any of !, ":, ", ', ](
|
75
75
|
|
76
76
|
INTERNET_URI_REGEXP =
|
77
77
|
Regexp.new(SUSPICIOUS_PRECEDING_CHARACTER + INTERNET_URI, Regexp::EXTENDED, 'N')
|
data/app/models/chunks/wiki.rb
CHANGED
@@ -99,7 +99,7 @@ module WikiChunk
|
|
99
99
|
class Link < WikiLink
|
100
100
|
|
101
101
|
unless defined? WIKI_LINK
|
102
|
-
WIKI_LINK = /(":)?\[\[([^\]]
|
102
|
+
WIKI_LINK = /(":)?\[\[\s*([^\]\s][^\]]+?)\s*\]\]/
|
103
103
|
LINK_TYPE_SEPARATION = Regexp.new('^(.+):((file)|(pic))$', 0, 'utf-8')
|
104
104
|
ALIAS_SEPARATION = Regexp.new('^(.+)\|(.+)$', 0, 'utf-8')
|
105
105
|
end
|
data/app/models/file_yard.rb
CHANGED
@@ -6,10 +6,9 @@ class FileYard
|
|
6
6
|
attr_reader :files_path
|
7
7
|
|
8
8
|
def initialize(files_path, max_upload_size)
|
9
|
-
@files_path = files_path
|
10
|
-
@
|
11
|
-
|
12
|
-
@files = Dir["#{files_path}/*"].collect{|path| File.basename(path) if File.file?(path) }.compact
|
9
|
+
@files_path, @max_upload_size = files_path, max_upload_size
|
10
|
+
FileUtils.mkdir_p(@files_path) unless File.exist?(@files_path)
|
11
|
+
@files = Dir["#{@files_path}/*"].collect{|path| File.basename(path) if File.file?(path) }.compact
|
13
12
|
end
|
14
13
|
|
15
14
|
def upload_file(name, io)
|
@@ -17,6 +16,7 @@ class FileYard
|
|
17
16
|
if io.kind_of?(Tempfile)
|
18
17
|
io.close
|
19
18
|
check_upload_size(io.size)
|
19
|
+
File.chmod(600, file_path(name)) if File.exists? file_path(name)
|
20
20
|
FileUtils.mv(io.path, file_path(name))
|
21
21
|
else
|
22
22
|
content = io.read
|
@@ -39,12 +39,12 @@ class FileYard
|
|
39
39
|
"#{files_path}/#{name}"
|
40
40
|
end
|
41
41
|
|
42
|
-
SANE_FILE_NAME = /[-
|
42
|
+
SANE_FILE_NAME = /[a-zA-Z0-9\-_\. ]{1,255}/
|
43
43
|
|
44
44
|
def sanitize_file_name(name)
|
45
|
-
unless name =~ SANE_FILE_NAME
|
45
|
+
unless name =~ SANE_FILE_NAME or name == '.' or name == '..'
|
46
46
|
raise Instiki::ValidationError.new("Invalid file name: '#{name}'.\n" +
|
47
|
-
"Only latin characters, digits, dots, underscores and
|
47
|
+
"Only latin characters, digits, dots, underscores, dashes and spaces are accepted.")
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
data/app/models/page.rb
CHANGED
@@ -10,9 +10,10 @@ class Page
|
|
10
10
|
attr_reader :name, :web
|
11
11
|
attr_accessor :revisions
|
12
12
|
|
13
|
-
def initialize(web, name
|
13
|
+
def initialize(web, name)
|
14
|
+
raise 'nil web' if web.nil?
|
15
|
+
raise 'nil name' if name.nil?
|
14
16
|
@web, @name, @revisions = web, name, []
|
15
|
-
revise(content, created_at, author)
|
16
17
|
end
|
17
18
|
|
18
19
|
def revise(content, created_at, author)
|
@@ -22,6 +23,10 @@ class Page
|
|
22
23
|
"You have tried to save page '#{name}' without changing its content")
|
23
24
|
end
|
24
25
|
|
26
|
+
# Try to render content to make sure that markup engine can take it,
|
27
|
+
# before addin a revision to the page
|
28
|
+
Revision.new(self, @revisions.length, content, created_at, author).force_rendering
|
29
|
+
|
25
30
|
# A user may change a page, look at it and make some more changes - several times.
|
26
31
|
# Not to record every such iteration as a new revision, if the previous revision was done
|
27
32
|
# by the same author, not more than 30 minutes ago, then update the last revision instead of
|
@@ -41,6 +46,9 @@ class Page
|
|
41
46
|
self.revisions.last.clear_display_cache
|
42
47
|
|
43
48
|
@web.refresh_pages_with_references(@name) if @revisions.length == 1
|
49
|
+
|
50
|
+
self
|
51
|
+
|
44
52
|
end
|
45
53
|
|
46
54
|
def rollback(revision_number, created_at, author_ip = nil)
|
data/app/models/revision.rb
CHANGED
@@ -26,6 +26,8 @@ class Revision
|
|
26
26
|
).strftime "%B %e, %Y %H:%M"
|
27
27
|
end
|
28
28
|
|
29
|
+
|
30
|
+
# todo: drop next_revision, previuous_revision and number from here - unused code
|
29
31
|
def next_revision
|
30
32
|
page.revisions[number + 1]
|
31
33
|
end
|
@@ -107,15 +109,17 @@ class Revision
|
|
107
109
|
def force_rendering
|
108
110
|
begin
|
109
111
|
display_content.render!
|
110
|
-
rescue
|
112
|
+
rescue => e
|
111
113
|
ApplicationController.logger.error "Failed rendering page #{@name}"
|
112
114
|
ApplicationController.logger.error e
|
113
|
-
message = e.message
|
115
|
+
message = e.message
|
114
116
|
# substitute content with an error message
|
115
|
-
content = <<-EOL
|
117
|
+
self.content = <<-EOL
|
116
118
|
<p>Markup engine has failed to render this page, raising the following error:</p>
|
117
119
|
<p>#{message}</p>
|
120
|
+
<pre>#{self.content}</pre>
|
118
121
|
EOL
|
122
|
+
clear_display_cache
|
119
123
|
raise e
|
120
124
|
end
|
121
125
|
end
|
data/app/models/web.rb
CHANGED
@@ -44,10 +44,12 @@ class Web
|
|
44
44
|
def max_upload_size() @max_upload_size || 100; end
|
45
45
|
def wiki() @wiki ||= WikiService.instance; end
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
def add_page(name, content, created_at, author)
|
48
|
+
page = Page.new(self, name)
|
49
|
+
page.revise(content, created_at, author)
|
50
|
+
@pages[page.name] = page
|
51
|
+
end
|
52
|
+
|
51
53
|
def address=(the_address)
|
52
54
|
if the_address != CGI.escape(the_address)
|
53
55
|
raise Instiki::ValidationError.new('Web name should contain only valid URI characters')
|
data/app/models/wiki_content.rb
CHANGED
@@ -33,10 +33,6 @@ require 'chunks/nowiki'
|
|
33
33
|
# * :mode
|
34
34
|
# => How should the content be rendered? For normal display (show),
|
35
35
|
# publishing (:publish) or export (:export)?
|
36
|
-
#
|
37
|
-
# AUTHOR: Mark Reid <mark @ threewordslong . com>
|
38
|
-
# CREATED: 15th May 2004
|
39
|
-
# UPDATED: 22nd May 2004
|
40
36
|
|
41
37
|
module ChunkManager
|
42
38
|
attr_reader :chunks_by_type, :chunks_by_id, :chunks, :chunk_id
|
@@ -141,7 +137,9 @@ class WikiContent < String
|
|
141
137
|
@options[:engine] = Engines::MAP[@web.markup]
|
142
138
|
@options[:engine_opts] = [:filter_html, :filter_styles] if @web.safe_mode
|
143
139
|
@options[:active_chunks] = (ACTIVE_CHUNKS - [WikiChunk::Word] ) if @web.brackets_only
|
144
|
-
|
140
|
+
|
141
|
+
@not_rendered = @pre_rendered = nil
|
142
|
+
|
145
143
|
super(@revision.content)
|
146
144
|
init_chunk_manager
|
147
145
|
build_chunks
|
data/app/models/wiki_service.rb
CHANGED
@@ -38,6 +38,34 @@ module AbstractWikiService
|
|
38
38
|
@system = {}
|
39
39
|
end
|
40
40
|
|
41
|
+
def edit_web(old_address, new_address, name, markup, color, additional_style, safe_mode = false,
|
42
|
+
password = nil, published = false, brackets_only = false, count_pages = false,
|
43
|
+
allow_uploads = true, max_upload_size = nil)
|
44
|
+
|
45
|
+
if not @webs.key? old_address
|
46
|
+
raise Instiki::ValidationError.new("Web with address '#{old_address}' does not exist")
|
47
|
+
end
|
48
|
+
|
49
|
+
if old_address != new_address
|
50
|
+
if @webs.key? new_address
|
51
|
+
raise Instiki::ValidationError.new("There is already a web with address '#{new_address}'")
|
52
|
+
end
|
53
|
+
@webs[new_address] = @webs[old_address]
|
54
|
+
@webs.delete(old_address)
|
55
|
+
@webs[new_address].address = new_address
|
56
|
+
end
|
57
|
+
|
58
|
+
web = @webs[new_address]
|
59
|
+
web.refresh_revisions if settings_changed?(web, markup, safe_mode, brackets_only)
|
60
|
+
|
61
|
+
web.name, web.markup, web.color, web.additional_style, web.safe_mode =
|
62
|
+
name, markup, color, additional_style, safe_mode
|
63
|
+
|
64
|
+
web.password, web.published, web.brackets_only, web.count_pages =
|
65
|
+
password, published, brackets_only, count_pages, allow_uploads
|
66
|
+
web.allow_uploads, web.max_upload_size = allow_uploads, max_upload_size.to_i
|
67
|
+
end
|
68
|
+
|
41
69
|
def read_page(web_address, page_name)
|
42
70
|
ApplicationController.logger.debug "Reading page '#{page_name}' from web '#{web_address}'"
|
43
71
|
web = @webs[web_address]
|
@@ -58,13 +86,11 @@ module AbstractWikiService
|
|
58
86
|
def revise_page(web_address, page_name, content, revised_on, author)
|
59
87
|
page = read_page(web_address, page_name)
|
60
88
|
page.revise(content, revised_on, author)
|
61
|
-
page
|
62
89
|
end
|
63
90
|
|
64
91
|
def rollback_page(web_address, page_name, revision_number, created_at, author_id = nil)
|
65
92
|
page = read_page(web_address, page_name)
|
66
93
|
page.rollback(revision_number, created_at, author_id)
|
67
|
-
page
|
68
94
|
end
|
69
95
|
|
70
96
|
def setup(password, web_name, web_address)
|
@@ -76,44 +102,14 @@ module AbstractWikiService
|
|
76
102
|
not (@webs.empty?)
|
77
103
|
end
|
78
104
|
|
79
|
-
def edit_web(old_address, new_address, name, markup, color, additional_style, safe_mode = false,
|
80
|
-
password = nil, published = false, brackets_only = false, count_pages = false,
|
81
|
-
allow_uploads = true, max_upload_size = nil)
|
82
|
-
|
83
|
-
if not @webs.key? old_address
|
84
|
-
raise Instiki::ValidationError.new("Web with address '#{old_address}' does not exist")
|
85
|
-
end
|
86
|
-
|
87
|
-
if old_address != new_address
|
88
|
-
if @webs.key? new_address
|
89
|
-
raise Instiki::ValidationError.new("There is already a web with address '#{new_address}'")
|
90
|
-
end
|
91
|
-
@webs[new_address] = @webs[old_address]
|
92
|
-
@webs.delete(old_address)
|
93
|
-
@webs[new_address].address = new_address
|
94
|
-
end
|
95
|
-
|
96
|
-
web = @webs[new_address]
|
97
|
-
web.refresh_revisions if settings_changed?(web, markup, safe_mode, brackets_only)
|
98
|
-
|
99
|
-
web.name, web.markup, web.color, web.additional_style, web.safe_mode =
|
100
|
-
name, markup, color, additional_style, safe_mode
|
101
|
-
|
102
|
-
web.password, web.published, web.brackets_only, web.count_pages =
|
103
|
-
password, published, brackets_only, count_pages, allow_uploads
|
104
|
-
web.allow_uploads, web.max_upload_size = allow_uploads, max_upload_size.to_i
|
105
|
-
end
|
106
|
-
|
107
|
-
def write_page(web_address, page_name, content, written_on, author)
|
108
|
-
page = Page.new(@webs[web_address], page_name, content, written_on, author)
|
109
|
-
@webs[web_address].add_page(page)
|
110
|
-
page
|
111
|
-
end
|
112
|
-
|
113
105
|
def storage_path
|
114
106
|
self.class.storage_path
|
115
107
|
end
|
116
108
|
|
109
|
+
def write_page(web_address, page_name, content, written_on, author)
|
110
|
+
@webs[web_address].add_page(page_name, content, written_on, author)
|
111
|
+
end
|
112
|
+
|
117
113
|
private
|
118
114
|
def settings_changed?(web, markup, safe_mode, brackets_only)
|
119
115
|
web.markup != markup ||
|
@@ -6,7 +6,9 @@
|
|
6
6
|
you'll need to do a brief one-time setup.
|
7
7
|
</p>
|
8
8
|
|
9
|
-
|
9
|
+
<%= form_tag({ :controller => 'admin', :action => 'create_system'},
|
10
|
+
{'id' => 'setup', 'method' => 'post', 'onSubmit' => 'return validateSetup()'})
|
11
|
+
%>
|
10
12
|
<ol class="setup">
|
11
13
|
<li>
|
12
14
|
|
@@ -43,7 +45,7 @@
|
|
43
45
|
<p align="right">
|
44
46
|
<input type="submit" value="Setup" style="margin-left: 40px" />
|
45
47
|
</p>
|
46
|
-
|
48
|
+
<%= end_form_tag %>
|
47
49
|
|
48
50
|
<script>
|
49
51
|
function proposeAddress() {
|
@@ -5,8 +5,9 @@
|
|
5
5
|
so different subjects or projects can write about different <i>MuppetShows</i>.
|
6
6
|
</p>
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
<%= form_tag({ :controller => 'admin', :action => 'create_web'},
|
9
|
+
{'id' => 'setup', 'method' => 'post', 'onSubmit' => 'cleanAddress(); return validateSetup()'})
|
10
|
+
%>
|
10
11
|
|
11
12
|
<ol class="setup">
|
12
13
|
<li>
|
@@ -35,7 +36,7 @@
|
|
35
36
|
</small>
|
36
37
|
</p>
|
37
38
|
|
38
|
-
|
39
|
+
<%= end_form_tag %>
|
39
40
|
|
40
41
|
<script>
|
41
42
|
function proposeAddress() {
|
@@ -1,7 +1,9 @@
|
|
1
1
|
<% @title = "Edit Web" %>
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
<%= form_tag({ :controller => 'admin', :action => 'edit_web', :web => @web.address },
|
4
|
+
{'id' => 'setup', 'method' => 'post', 'onSubmit' => 'cleanAddress(); return validateSetup()'})
|
5
|
+
%>
|
6
|
+
|
5
7
|
<h2 style="margin-bottom: 3px">Name and address</h2>
|
6
8
|
<div class="help">
|
7
9
|
The name of the web is included in the title on all pages.
|
@@ -113,7 +115,7 @@ TODO Enable these input elements again after release 0.10
|
|
113
115
|
</small>
|
114
116
|
</p>
|
115
117
|
|
116
|
-
|
118
|
+
<%= end_form_tag %>
|
117
119
|
|
118
120
|
<br/>
|
119
121
|
<h1>Other administrative tasks</h1>
|
@@ -133,5 +135,4 @@ TODO Enable these input elements again after release 0.10
|
|
133
135
|
</p>
|
134
136
|
<%= end_form_tag %>
|
135
137
|
|
136
|
-
|
137
|
-
<script type="text/javascript">overrideAutocomplete()</script>
|
138
|
+
<%= javascript_include_tag 'edit_web' %>
|
@@ -26,26 +26,21 @@ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
26
26
|
<%= File.read(RAILS_ROOT + '/public/stylesheets/instiki.css') if @inline_style %>
|
27
27
|
</style>
|
28
28
|
|
29
|
-
|
29
|
+
<%= stylesheet_link_tag 'instiki' unless @inline_style %>
|
30
30
|
|
31
31
|
<style type="text/css">
|
32
32
|
<%= @style_additions %>
|
33
33
|
<%= @web ? @web.additional_style : '' %>
|
34
34
|
</style>
|
35
|
-
|
35
|
+
|
36
36
|
<% if @web %>
|
37
|
-
|
38
|
-
|
39
|
-
:action => 'rss_with_headlines' %>"
|
40
|
-
/>
|
41
|
-
<link rel="alternate" type="application/rss+xml" title="<%= h @web.name %> - Full Pages RSS"
|
42
|
-
href="<%= url_for :controller => 'wiki', :web => @web.address,
|
43
|
-
:action => 'rss_with_content' %>"
|
44
|
-
/>
|
37
|
+
<%= auto_discovery_link_tag(:rss, :controller => 'wiki', :web => @web.address, :action => 'rss_with_headlines') %>
|
38
|
+
<%= auto_discovery_link_tag(:rss, :controller => 'wiki', :web => @web.address, :action => 'rss_with_content') %>
|
45
39
|
<% end %>
|
46
40
|
</head>
|
47
41
|
|
48
42
|
<body>
|
43
|
+
|
49
44
|
<div id="Container">
|
50
45
|
<div id="Content">
|
51
46
|
<h1 id="pageName">
|
@@ -59,12 +54,12 @@ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
59
54
|
<% end %>
|
60
55
|
</h1>
|
61
56
|
|
62
|
-
<% if @flash[:error] %> <div id="error">
|
63
|
-
<hr/><p><%= @flash[:error]
|
57
|
+
<% if @error or @flash[:error] %> <div id="error">
|
58
|
+
<hr/><p><%= escape_preserving_linefeeds(@error || @flash[:error]) %></p><hr/></div>
|
64
59
|
<% end %>
|
65
60
|
|
66
61
|
<% if @flash[:info] %> <div id="info">
|
67
|
-
<hr/><p><%= @flash[:info]
|
62
|
+
<hr/><p><%= escape_preserving_linefeeds @flash[:info] %></p><hr/></div>
|
68
63
|
<% end %>
|
69
64
|
|
70
65
|
<%= render 'navigation' unless @web.nil? || @hide_navigation %>
|
data/app/views/navigation.rhtml
CHANGED
@@ -8,8 +8,10 @@ def list_item(text, link_options, description, accesskey = nil)
|
|
8
8
|
end
|
9
9
|
%>
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
<%= form_tag({ :controller => 'wiki', :action => 'search', :web => @web.address},
|
12
|
+
{'id' => 'navigationForm', 'class' => 'navigation', 'method' => 'get'})
|
13
|
+
%>
|
14
|
+
|
13
15
|
<% if @action_name != 'published' then %>
|
14
16
|
<%= list_item 'Home Page', {:action => 'show', :id => 'HomePage'}, 'Home, Sweet Home', 'H' %> |
|
15
17
|
<%= list_item 'All Pages', {:action => 'list'}, 'Alphabetically sorted list of pages', 'A' %> |
|
@@ -27,4 +29,4 @@ end
|
|
27
29
|
<%= list_item 'Home Page', {:action => 'published', :id => 'HomePage'}, 'Home, Sweet Home', 'H' %> |
|
28
30
|
<% end%>
|
29
31
|
|
30
|
-
|
32
|
+
<%= end_form_tag %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<h3>Textile formatting tips (<a href="
|
1
|
+
<h3>Textile formatting tips (<a href="http://hobix.com/textile/quick.html" onClick="quickRedReference(); return false;">advanced</a>)</h3>
|
2
2
|
<table cellspacing="0" cellpadding="0">
|
3
3
|
<tr><td>_your text_</td><td class="arrow">→</td><td><em>your text</em></td></tr>
|
4
4
|
<tr><td>*your text*</td><td class="arrow">→</td><td><strong>your text</strong></td></tr>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<li>
|
6
6
|
<%= link_to_page author %>
|
7
7
|
co- or authored:
|
8
|
-
<%= @web.select.pages_authored_by(author).collect { |page| link_to_page(page.name) }.join ', ' %>
|
8
|
+
<%= @web.select.pages_authored_by(author).collect { |page| link_to_page(page.name) }.sort.join ', ' %>
|
9
9
|
</li>
|
10
10
|
<% end %>
|
11
11
|
</ul>
|
data/app/views/wiki/edit.rhtml
CHANGED
@@ -4,19 +4,17 @@
|
|
4
4
|
@hide_navigation = true
|
5
5
|
%>
|
6
6
|
|
7
|
-
<%= "<p style='color:red'>Please correct the error that caused this error in rendering:<br/><small>#{@params["msg"]}</small></p>" if @params["msg"] %>
|
8
|
-
|
9
7
|
<div id="MarkupHelp" style="float: right; width: 250px; margin-top: 5px">
|
10
8
|
<%= render("#{@web.markup}_help") %>
|
11
9
|
<%= render 'wiki_words_help' %>
|
12
10
|
</div>
|
13
11
|
|
14
12
|
<%= form_tag({ :action => 'save', :web => @web.address, :id => @page.name},
|
15
|
-
{'id' => 'editForm', 'method' => 'post', 'onSubmit' => 'cleanAuthorName()
|
13
|
+
{'id' => 'editForm', 'method' => 'post', 'onSubmit' => 'cleanAuthorName()'})
|
16
14
|
%>
|
17
15
|
|
18
16
|
<p>
|
19
|
-
<textarea name="content" style="width: 450px; height: 500px"><%= h @page.content %></textarea>
|
17
|
+
<textarea name="content" style="width: 450px; height: 500px"><%= h(@flash[:content] || @page.content) %></textarea>
|
20
18
|
</p>
|
21
19
|
<p>
|
22
20
|
<input type="submit" value="Submit" accesskey="s"/> as
|
data/app/views/wiki/list.rhtml
CHANGED
data/app/views/wiki/new.rhtml
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
%>
|
15
15
|
|
16
16
|
<p>
|
17
|
-
<textarea name="content" style="width: 450px; height: 500px"
|
17
|
+
<textarea name="content" style="width: 450px; height: 500px"><%= h(@flash[:content] || '') %></textarea>
|
18
18
|
</p>
|
19
19
|
<p>
|
20
20
|
<input type="submit" value="Submit" accesskey="s"/> as
|
data/app/views/wiki/page.rhtml
CHANGED
@@ -7,16 +7,19 @@
|
|
7
7
|
<%= @page.display_content %>
|
8
8
|
</div>
|
9
9
|
|
10
|
-
<div id="changes" style="display: none">
|
11
|
-
<p style="background: #eee; padding: 3px; border: 1px solid silver">
|
12
|
-
<small>
|
13
|
-
Showing changes from revision #<%= @page.number - 1 %> to #<%= @page.number %>:
|
14
|
-
<ins class="diffins">Added</ins> | <del class="diffdel">Removed</del>
|
15
|
-
</small>
|
16
|
-
</p>
|
17
10
|
|
18
|
-
|
19
|
-
|
11
|
+
<% if @page.revisions.length > 1 %>
|
12
|
+
<div id="changes" style="display: none">
|
13
|
+
<p style="background: #eee; padding: 3px; border: 1px solid silver">
|
14
|
+
<small>
|
15
|
+
Showing changes from revision #<%= @page.number - 1 %> to #<%= @page.number %>:
|
16
|
+
<ins class="diffins">Added</ins> | <del class="diffdel">Removed</del>
|
17
|
+
</small>
|
18
|
+
</p>
|
19
|
+
|
20
|
+
<%= @page.display_diff %>
|
21
|
+
</div>
|
22
|
+
<% end %>
|
20
23
|
|
21
24
|
<div class="byline">
|
22
25
|
<%= @page.revisions? ? "Revised" : "Created" %> on <%= @page.pretty_created_at %>
|
@@ -32,17 +35,17 @@
|
|
32
35
|
<% if @page.name == "HomePage" %>
|
33
36
|
<%= link_to('Edit Page',
|
34
37
|
{:web => @web.address, :action => 'edit', :id => @page.name},
|
35
|
-
{:class => 'navlink', :accesskey => 'E'})
|
38
|
+
{:class => 'navlink', :accesskey => 'E', :name => 'edit'})
|
36
39
|
%>
|
37
40
|
|
|
38
41
|
<%= link_to('Edit Web',
|
39
42
|
{:web => @web.address, :action => 'edit_web'},
|
40
|
-
{:class => 'navlink'})
|
43
|
+
{:class => 'navlink', :name => 'edit_web'})
|
41
44
|
%>
|
42
45
|
<% else %>
|
43
46
|
<%= link_to('Edit',
|
44
47
|
{:web => @web.address, :action => 'edit', :id => @page.name},
|
45
|
-
{:class => 'navlink', :accesskey => 'E'})
|
48
|
+
{:class => 'navlink', :accesskey => 'E', :name => 'edit'})
|
46
49
|
%>
|
47
50
|
<% end %>
|
48
51
|
|
@@ -51,16 +54,16 @@
|
|
51
54
|
<%= link_to('Back in time',
|
52
55
|
{:web => @web.address, :action => 'revision', :id => @page.name,
|
53
56
|
:rev => @page.revisions.length - 2},
|
54
|
-
{:class => 'navlink', :accesskey => 'R'})
|
57
|
+
{:class => 'navlink', :accesskey => 'R', :name => 'to_previous_revision'})
|
55
58
|
%>
|
56
59
|
<small>(<%= @page.revisions.length - 1 %> revisions)</small>
|
57
60
|
<% end %>
|
58
61
|
|
59
62
|
<% if @page.revisions.length > 1 %>
|
60
63
|
<span id="show_changes">
|
61
|
-
| <a href="#" onClick="toggleChanges(); return false;">See changes</a>
|
64
|
+
| <a href="#" name="see_changes" onClick="toggleChanges(); return false;">See changes</a>
|
62
65
|
</span>
|
63
|
-
<span id="hide_changes" style="display: none">
|
66
|
+
<span id="hide_changes" name="hide_changes" style="display: none">
|
64
67
|
| <a href="#" onClick="toggleChanges(); return false;">Hide changes</a>
|
65
68
|
</span>
|
66
69
|
<% end %>
|
@@ -69,12 +72,14 @@
|
|
69
72
|
| Views:
|
70
73
|
<%= link_to('Print',
|
71
74
|
{:web => @web.address, :action => 'print', :id => @page.name},
|
72
|
-
{:accesskey => 'p'}) %>
|
75
|
+
{:accesskey => 'p', :name => 'view_print'}) %>
|
73
76
|
<% if defined? RedClothForTex and RedClothForTex.available? and @web.markup == :textile %>
|
74
77
|
|
|
75
|
-
<%= link_to 'TeX', :web => @web.address, :action => 'tex', :id => @page.name
|
78
|
+
<%= link_to 'TeX', {:web => @web.address, :action => 'tex', :id => @page.name},
|
79
|
+
{:name => 'view_tex'} %>
|
76
80
|
|
|
77
|
-
<%= link_to 'PDF', :web => @web.address, :action => 'pdf', :id => @page.name
|
81
|
+
<%= link_to 'PDF', {:web => @web.address, :action => 'pdf', :id => @page.name},
|
82
|
+
{:name => 'view_pdf'} %>
|
78
83
|
<% end %>
|
79
84
|
</small>
|
80
85
|
|
@@ -28,15 +28,15 @@
|
|
28
28
|
<%= link_to('Forward in time',
|
29
29
|
{:web => @web.address, :action => 'revision', :id => @page.name,
|
30
30
|
:rev => @revision.next_revision.number},
|
31
|
-
{:class => 'navlink'})
|
31
|
+
{:class => 'navlink', :name => 'to_next_revision'})
|
32
32
|
%>
|
33
33
|
<% else %>
|
34
34
|
<%= link_to('Forward in time',
|
35
35
|
{:web => @web.address, :action => 'show', :id => @page.name},
|
36
|
-
{:class => 'navlink'})
|
36
|
+
{:class => 'navlink', :name => 'to_next_revision'})
|
37
37
|
%>
|
38
38
|
<% end %>
|
39
|
-
(<%= @revision.page.revisions.length - @revision.next_revision.number %> more)
|
39
|
+
<small>(<%= @revision.page.revisions.length - @revision.next_revision.number %> more)</small>
|
40
40
|
<% end %>
|
41
41
|
|
42
42
|
<% if @revision.next_revision && @revision.previous_revision %>
|
@@ -47,14 +47,14 @@
|
|
47
47
|
<%= link_to('Back in time',
|
48
48
|
{:web => @web.address, :action => 'revision', :id => @page.name,
|
49
49
|
:rev => @revision.previous_revision.number},
|
50
|
-
{:class => 'navlink'})
|
50
|
+
{:class => 'navlink', :name => 'to_previous_revision'})
|
51
51
|
%>
|
52
|
-
(<%= @revision.previous_revision.number + 1 %> more)
|
52
|
+
<small>(<%= @revision.previous_revision.number + 1 %> more)</small>
|
53
53
|
<% end %>
|
54
54
|
|
55
55
|
|
|
56
56
|
<%= link_to('See current', {:web => @web.address, :action => 'show', :id => @page.name},
|
57
|
-
{:class => 'navlink'})
|
57
|
+
{:class => 'navlink', :name => 'to_current_revision'})
|
58
58
|
%>
|
59
59
|
|
60
60
|
<% if @revision.previous_revision %>
|
@@ -70,7 +70,7 @@
|
|
70
70
|
|
71
71
|
<%= link_to('Rollback',
|
72
72
|
{:web => @web.address, :action => 'rollback', :id => @page.name, :rev => @revision.number},
|
73
|
-
{:class => 'navlink'})
|
73
|
+
{:class => 'navlink', :name => 'rollback'})
|
74
74
|
%>
|
75
75
|
|
76
76
|
<% if @page.references.length > 0 %>
|
data/app/views/wiki/search.rhtml
CHANGED
@@ -24,7 +24,7 @@
|
|
24
24
|
<% end %>
|
25
25
|
|
26
26
|
<% if (@results + @title_results).empty? %>
|
27
|
-
<h2>No pages
|
27
|
+
<h2>No pages contain "<%= @params["query"] %>" </h2>
|
28
28
|
<p>
|
29
29
|
Perhaps you should try expanding your query. Remember that Instiki searches for entire
|
30
30
|
phrases, so if you search for "all that jazz" it will not match pages that contain these
|
data/config/environment.rb
CHANGED
@@ -62,7 +62,7 @@ require_dependency "environments/#{RAILS_ENV}"
|
|
62
62
|
unless defined? RAILS_DEFAULT_LOGGER
|
63
63
|
RAILS_DEFAULT_LOGGER = Logger.new(STDERR)
|
64
64
|
ActionController::Base.logger ||= RAILS_DEFAULT_LOGGER
|
65
|
-
if
|
65
|
+
if $instiki_debug_logging
|
66
66
|
RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
|
67
67
|
ActionController::Base.logger.level = Logger::DEBUG
|
68
68
|
else
|
data/config/environments/test.rb
CHANGED
@@ -11,7 +11,7 @@ unless defined? TEST_LOGGER
|
|
11
11
|
$stderr.puts "To see the Rails log:\n less #{log_name}"
|
12
12
|
|
13
13
|
TEST_LOGGER = ActionController::Base.logger = Logger.new(log_name)
|
14
|
-
|
14
|
+
$instiki_debug_logging = true
|
15
15
|
|
16
16
|
WikiService.storage_path = RAILS_ROOT + '/storage/test/'
|
17
17
|
end
|
data/config/routes.rb
CHANGED
@@ -1,18 +1,32 @@
|
|
1
|
-
|
1
|
+
# Create a route to DEFAULT_WEB, if such is specified; also register a generic route
|
2
|
+
def connect_to_web(map, generic_path, generic_routing_options)
|
3
|
+
if defined? DEFAULT_WEB
|
4
|
+
explicit_path = generic_path.gsub(/:web\/?/, '')
|
5
|
+
explicit_routing_options = generic_routing_options.merge(:web => DEFAULT_WEB)
|
6
|
+
map.connect(explicit_path, explicit_routing_options)
|
7
|
+
end
|
8
|
+
map.connect(generic_path, generic_routing_options)
|
9
|
+
end
|
10
|
+
|
11
|
+
ActionController::Routing::Routes.draw do |map|
|
2
12
|
map.connect 'create_system', :controller => 'admin', :action => 'create_system'
|
3
13
|
map.connect 'create_web', :controller => 'admin', :action => 'create_web'
|
4
|
-
map.connect ':web/edit_web', :controller => 'admin', :action => 'edit_web'
|
5
14
|
map.connect 'remove_orphaned_pages', :controller => 'admin', :action => 'remove_orphaned_pages'
|
15
|
+
map.connect 'web_list', :controller => 'wiki', :action => 'web_list'
|
6
16
|
|
7
|
-
map
|
8
|
-
map
|
9
|
-
map
|
17
|
+
connect_to_web map, ':web/edit_web', :controller => 'admin', :action => 'edit_web'
|
18
|
+
connect_to_web map, ':web/file/:id', :controller => 'file', :action => 'file'
|
19
|
+
connect_to_web map, ':web/pic/:id', :controller => 'file', :action => 'pic'
|
20
|
+
connect_to_web map, ':web/import/:id', :controller => 'file', :action => 'import'
|
21
|
+
connect_to_web map, ':web/login', :controller => 'wiki', :action => 'login'
|
22
|
+
connect_to_web map, ':web/web_list', :controller => 'wiki', :action => 'web_list'
|
23
|
+
connect_to_web map, ':web/:action/:id', :controller => 'wiki'
|
24
|
+
connect_to_web map, ':web/:action', :controller => 'wiki'
|
25
|
+
connect_to_web map, ':web', :controller => 'wiki', :action => 'index'
|
10
26
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
map.connect ':web', :controller => 'wiki', :action => 'index'
|
17
|
-
map.connect '', :controller => 'wiki', :action => 'index'
|
27
|
+
if defined? DEFAULT_WEB
|
28
|
+
map.connect '', :controller => 'wiki', :web => DEFAULT_WEB, :action => 'index'
|
29
|
+
else
|
30
|
+
map.connect '', :controller => 'wiki', :action => 'index'
|
31
|
+
end
|
18
32
|
end
|
@@ -21,13 +21,15 @@ body, p, ol, ul, td {
|
|
21
21
|
}
|
22
22
|
|
23
23
|
a { color: #000; }
|
24
|
+
a:visited { color: #666; }
|
25
|
+
a:hover {
|
26
|
+
color: #fff;
|
27
|
+
background-color:#000;
|
28
|
+
}
|
24
29
|
|
25
30
|
.newWikiWord { background-color: #eee; }
|
26
31
|
.newWikiWord a:hover { background-color: white; }
|
27
32
|
|
28
|
-
a:visited { color: #666; }
|
29
|
-
a:hover { color: #fff; background-color:#000; }
|
30
|
-
|
31
33
|
h1, h2, h3 { color: #333; font-family: georgia, verdana, sans-serif; }
|
32
34
|
h1 { font-size: 28px }
|
33
35
|
h2 { font-size: 19px }
|
@@ -103,6 +105,7 @@ pre {
|
|
103
105
|
background-color: #eee;
|
104
106
|
padding: 10px;
|
105
107
|
font-size: 11px;
|
108
|
+
overflow: auto;
|
106
109
|
}
|
107
110
|
|
108
111
|
ol.setup {
|
@@ -220,3 +223,19 @@ ol.setup li {
|
|
220
223
|
.newsList p {
|
221
224
|
margin-bottom:30px
|
222
225
|
}
|
226
|
+
|
227
|
+
td {border:thin solid grey;}
|
228
|
+
table {
|
229
|
+
border: double black;
|
230
|
+
border-collapse: collapse;
|
231
|
+
}
|
232
|
+
|
233
|
+
.byline {
|
234
|
+
padding-top: 15px;
|
235
|
+
}
|
236
|
+
|
237
|
+
/* Affects the display of "category: ..." */
|
238
|
+
.property {
|
239
|
+
color: grey;
|
240
|
+
font-size: 10px;
|
241
|
+
}
|
@@ -0,0 +1,97 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
=begin
|
4
|
+
The purpose of this script is to help people poke around in the Madeleine storage.
|
5
|
+
|
6
|
+
Two caveats:
|
7
|
+
1. You MUST be a reasonably good Ruby programmer to use it successfully for anything non-trivial.
|
8
|
+
2. It's very easy to screw up something by poking in the storage internals. If you do, please
|
9
|
+
undo your changes by deleting the most recent snapshot(s) and don't ask for help.
|
10
|
+
|
11
|
+
Usage example:
|
12
|
+
|
13
|
+
E:\eclipse\workspace\instiki\script>irb
|
14
|
+
irb(main):001:0> load 'debug_storage'
|
15
|
+
Enter path to storage [E:/eclipse/workspace/instiki/storage/2500]:
|
16
|
+
Loading storage from the default storage path (E:/eclipse/workspace/instiki/storage/2500)
|
17
|
+
Instiki storage from E:/eclipse/workspace/instiki/storage/2500 is loaded.
|
18
|
+
Access it via global variable $wiki.
|
19
|
+
Happy poking!
|
20
|
+
=> true
|
21
|
+
irb(main):003:0> $wiki.system
|
22
|
+
=> {"password"=>"foo"}
|
23
|
+
irb(main):005:0> $wiki.system['password'] = 'bar'
|
24
|
+
=> "bar"
|
25
|
+
irb(main):006:0> $wiki.webs.keys
|
26
|
+
=> ["wiki1", "wiki2"]
|
27
|
+
irb(main):007:0> $wiki.webs['wiki1'].password = 'the_password'
|
28
|
+
=> "the_password"
|
29
|
+
irb(main):008:0> WikiService::snapshot
|
30
|
+
=> []
|
31
|
+
|
32
|
+
|
33
|
+
Things that are possible:
|
34
|
+
|
35
|
+
# cleaning old revisions
|
36
|
+
$wiki.webs['wiki'].pages['HomePage'].revisions = $wiki.webs['wiki'].pages['HomePage'].revisions[-1..-1]
|
37
|
+
|
38
|
+
# Changing contents of a revision
|
39
|
+
$wiki.webs['wiki'].pages['HomePage'].revisions[-1] = 'new content'
|
40
|
+
|
41
|
+
# Checking that all pages can be rendered by the markup engine
|
42
|
+
$wiki.webs['wiki'].pages.each_pair do |name, page|
|
43
|
+
page.revisions.each_with_index do |revision, i|
|
44
|
+
begin
|
45
|
+
revision.display_content
|
46
|
+
rescue =>
|
47
|
+
puts "Error when rendering revision ##{i} of page #{name.inspect}:"
|
48
|
+
puts e.message
|
49
|
+
puts e.backtrace.join("\n")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
=end
|
53
|
+
|
54
|
+
require 'fileutils'
|
55
|
+
require 'optparse'
|
56
|
+
require 'webrick'
|
57
|
+
|
58
|
+
default_storage_path = File.expand_path(File.dirname(__FILE__) + "/../storage/2500")
|
59
|
+
|
60
|
+
print "Enter path to storage [#{default_storage_path}]: "
|
61
|
+
storage_path = gets.chomp
|
62
|
+
if storage_path.empty?
|
63
|
+
storage_path = default_storage_path
|
64
|
+
puts "Loading storage from the default storage path (#{storage_path})"
|
65
|
+
else
|
66
|
+
puts "Loading storage from the path you entered (#{storage_path})"
|
67
|
+
end
|
68
|
+
|
69
|
+
unless File.directory?(storage_path) and not
|
70
|
+
(Dir["#{storage_path}/*.snapshot"] + Dir["#{storage_path}/*.command_log"]).empty?
|
71
|
+
raise "Found no storage at #{storage_path}"
|
72
|
+
end
|
73
|
+
|
74
|
+
RAILS_ROOT = File.expand_path(File.dirname(__FILE__) + '/../') unless defined? RAILS_ROOT
|
75
|
+
|
76
|
+
unless defined? ADDITIONAL_LOAD_PATHS
|
77
|
+
ADDITIONAL_LOAD_PATHS = %w(
|
78
|
+
app/models
|
79
|
+
lib
|
80
|
+
vendor/madeleine-0.7.1/lib
|
81
|
+
vendor/RedCloth-3.0.3/lib
|
82
|
+
vendor/rubyzip-0.5.8/lib
|
83
|
+
).map { |dir| "#{File.expand_path(File.join(RAILS_ROOT, dir))}"
|
84
|
+
}.delete_if { |dir| not File.exist?(dir) }
|
85
|
+
|
86
|
+
# Prepend to $LOAD_PATH
|
87
|
+
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) }
|
88
|
+
end
|
89
|
+
|
90
|
+
require 'wiki_service'
|
91
|
+
|
92
|
+
WikiService.storage_path = storage_path
|
93
|
+
$wiki = WikiService.instance
|
94
|
+
puts "Instiki storage from #{storage_path} is loaded."
|
95
|
+
puts 'Access it via global variable $wiki.'
|
96
|
+
puts 'Happy poking!'
|
97
|
+
nil
|
data/script/server
CHANGED
@@ -64,7 +64,7 @@ end
|
|
64
64
|
FileUtils.mkdir_p(storage_path)
|
65
65
|
|
66
66
|
ENV['RAILS_ENV'] = OPTIONS[:environment]
|
67
|
-
|
67
|
+
$instiki_debug_logging = OPTIONS[:verbose]
|
68
68
|
require File.expand_path(File.dirname(__FILE__) + '/../config/environment')
|
69
69
|
WikiService.storage_path = storage_path
|
70
70
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
|
|
3
3
|
specification_version: 1
|
4
4
|
name: instiki
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.10.
|
7
|
-
date: 2005-
|
6
|
+
version: 0.10.2
|
7
|
+
date: 2005-07-30
|
8
8
|
summary: Easy to install WikiClone running on WEBrick and Madeleine
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- config/environments/production.rb
|
119
119
|
- config/environments/test.rb
|
120
120
|
- script/breakpointer
|
121
|
+
- script/debug_storage
|
121
122
|
- script/server
|
122
123
|
test_files: []
|
123
124
|
rdoc_options: []
|
@@ -166,5 +167,5 @@ dependencies:
|
|
166
167
|
-
|
167
168
|
- "="
|
168
169
|
- !ruby/object:Gem::Version
|
169
|
-
version: 0.
|
170
|
+
version: 0.13.1
|
170
171
|
version:
|