Soks 0.0.7 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +2 -0
- data/README.txt +3 -2
- data/TODO.txt +31 -0
- data/bin/soks-create-wiki.rb +0 -1
- data/lib/authenticators.rb +30 -4
- data/lib/helpers/counter-helpers.rb +132 -0
- data/lib/helpers/default-helpers.rb +170 -169
- data/lib/helpers/mail2wiki-helper.rb +18 -22
- data/lib/helpers/maintenance-helpers.rb +149 -0
- data/lib/helpers/rss2wiki-helper.rb +7 -8
- data/lib/soks-model.rb +82 -54
- data/lib/soks-servlet.rb +126 -108
- data/lib/soks-storage.rb +74 -11
- data/lib/soks-utils.rb +77 -3
- data/lib/soks-view.rb +169 -103
- data/lib/soks.rb +5 -23
- data/templates/default/attachment/newpage.js +4 -13
- data/templates/default/attachment/print_stylesheet.css +2 -7
- data/templates/default/caches/readme.txt +1 -0
- data/templates/default/content/Api%20for%20classes%20to%20modify%20the%20wiki.textile +2 -0
- data/templates/default/content/Author.textile +4 -1
- data/templates/default/content/Automatic%20Summaries.textile +16 -53
- data/templates/default/content/Automatic%20linking%20between%20pages.textile +3 -3
- data/templates/default/content/{bug%3A%20competing%20edits.textile → Bug%3A%20Competing%20edits.textile} +9 -0
- data/templates/default/content/Bug%3A%20Does%20not%20make%20use%20of%20if%2Dmodified%2Dsince%20r.textile +2 -0
- data/templates/default/content/Bug%3A%20E%2Dmail%20addresses%20with%20hyphens%20not%20recognised.textile +17 -0
- data/templates/default/content/Bug%3A%20Email%20adresses%20in%20page%20titles%20cause%20incorrec.textile +3 -0
- data/templates/default/content/Bug%3A%20GEM%20limits%20title%20lengths.textile +3 -1
- data/templates/default/content/Bug%3A%20Memory%20leak.textile +13 -0
- data/templates/default/content/Bug%3A%20Pages%20that%20link%20here%20may%20not%20appear%20on%20r.textile +13 -0
- data/templates/default/content/Bug%3A%20Textile%20mishandles%20paragraphs.textile +4 -0
- data/templates/default/content/Bug%3A%20Unanticipated%20Rollbacks.textile +2 -0
- data/templates/default/content/Bug%3A%20notextile%20does%20not%20prevent%20page%20inserts.textile +2 -0
- data/templates/default/content/Home%20Page.textile +3 -1
- data/templates/default/content/How%20to%20administrate%20this%20wiki.textile +23 -13
- data/templates/default/content/How%20to%20change%20the%20way%20this%20wiki%20looks.textile +3 -1
- data/templates/default/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +22 -0
- data/templates/default/content/How%20to%20get%20the%20latest%20Soks%20from%20cvs.textile +2 -0
- data/templates/default/content/How%20to%20hack%20soks.textile +2 -0
- data/templates/default/content/How%20to%20import%20a%20site%20from%20instiki.textile +2 -0
- data/templates/default/content/{How%20to%20import%20data%20to%20this%20wiki.textile → How%20to%20import%20data.textile} +3 -7
- data/templates/default/content/How%20to%20install%20Soks.textile +2 -0
- data/templates/default/content/How%20to%20password%20protect%20your%20wiki.textile +21 -11
- data/templates/default/content/How%20to%20report%20a%20bug.textile +2 -1
- data/templates/default/content/How%20to%20upgrade%20soks.textile +22 -0
- data/templates/default/content/How%20to%20use%20the%20keyboard%20shortcuts.textile +2 -2
- data/templates/default/content/How%20to%20use%20this%20wiki.textile +3 -1
- data/templates/default/content/List%20of%20changes.textile +84 -118
- data/templates/default/content/News%3A%20Version%201%2D0%2D0%20released.textile +19 -0
- data/templates/default/content/Pages%20to%20include%20in%20the%20distribution.textile +51 -0
- data/templates/default/content/Per%20Wiki%20Templates.textile +2 -0
- data/templates/default/content/Planned%20Features.textile +30 -9
- data/templates/default/content/README.textile +3 -2
- data/templates/default/content/RSS%20feed.textile +1 -1
- data/templates/default/content/Recent%20changes%20to%20this%20site.textile +283 -0
- data/templates/default/content/SOKS%20features.textile +3 -0
- data/templates/default/content/Site%20Index.textile +202 -0
- data/templates/default/content/Soks%20Licence.textile +2 -0
- data/templates/default/content/Tag%3A%20Include%20this%20page%20in%20the%20distribution.textile +6 -0
- data/templates/default/start.rb +67 -123
- data/templates/default/version.txt +1 -1
- data/templates/default/views/Page_edit.rhtml +7 -7
- data/templates/default/views/{Page_search_results.rhtml → Page_find.rhtml} +9 -3
- data/templates/default/views/Page_linksfromrss.rhtml +24 -0
- data/templates/default/views/Page_listrss.rhtml +46 -0
- data/templates/default/views/Page_meta.rhtml +1 -1
- data/templates/default/views/Page_revision.rhtml +39 -0
- data/templates/default/views/Page_revisions.rhtml +13 -5
- data/templates/default/views/Page_rss.rhtml +8 -8
- data/templates/default/views/Page_view.rhtml +3 -3
- data/templates/default/views/UploadPage_edit.rhtml +8 -8
- data/templates/default/views/frame.rhtml +8 -8
- data/templates/default/views/messages.yaml +1 -0
- data/test/html/2006Mar.html +66 -0
- data/test/html/poignant.html +36 -0
- data/test/html/poignant.textile +36 -0
- data/test/mock-objects.rb +69 -0
- data/test/stress_url_calls.rb +33 -0
- data/test/stress_urls.txt +68 -0
- data/test/test_counter-helper.rb +158 -0
- data/test/test_soks-helper-maintenance.rb +106 -0
- data/test/test_soks-helpers.rb +104 -0
- data/test/test_soks-model.rb +144 -0
- data/test/test_soks-servlet.rb +231 -0
- data/test/test_soks-storage.rb +70 -31
- data/test/test_soks-utils.rb +112 -13
- data/test/test_soks-view.rb +141 -3
- metadata +38 -27
- data/templates/default/content/A%20page%20with%20an%20umlaut%20%F6%20in%20its%20title.textile +0 -1
- data/templates/default/content/All%20News.textile +0 -26
- data/templates/default/content/Bil%20Kleb.textile +0 -1
- data/templates/default/content/Bil.textile +0 -1
- data/templates/default/content/Bill%20Wood.textile +0 -3
- data/templates/default/content/Bug%3A%20RSS%20feed%20does%20not%20validate.textile +0 -10
- data/templates/default/content/Bug%3A%20Type%20a%20title%20here.textile +0 -31
- data/templates/default/content/Instructions%20and%20Howtos.textile +0 -21
- data/templates/default/content/Latest%20News.textile +0 -26
- data/templates/default/content/New%20Recent%20Changes%20class.textile +0 -68
- data/templates/default/content/New%20page%20templates%20or%20categories%20code.textile +0 -68
- data/templates/default/content/News%3A%20Version%200%2E0%2E6%20Released.textile +0 -13
- data/templates/default/content/Recent%20Blog%20Entries.textile +0 -5
- data/templates/default/content/Recent%20Changes%20to%20This%20Site.textile +0 -286
- data/templates/default/content/Ruby.textile +0 -9
- data/templates/default/content/Skorgu.textile +0 -3
- data/templates/default/content/ctrl%2Dn.textile +0 -1
- data/templates/default/content/let%20me%20know.textile +0 -1
- data/templates/default/content/sandbox.textile +0 -20
- data/templates/default/content/tamc.textile +0 -1
- data/templates/default/content/tamc2.textile +0 -1
data/lib/soks-view.rb
CHANGED
@@ -1,17 +1,54 @@
|
|
1
|
+
# Extend the model classes to provide view functions
|
2
|
+
class Page
|
3
|
+
def textile( view = nil )
|
4
|
+
return "[[#{$MESSAGES[:Create]} #{name} => /edit/#{name} ]]" if empty?
|
5
|
+
content
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class ImagePage
|
10
|
+
def textile( view )
|
11
|
+
return "[[#{$MESSAGES[:Create]} #{name} => /edit/#{name} ]]" if empty?
|
12
|
+
return content if deleted?
|
13
|
+
"!#{view.file2(content)}!:#{view.url(name)}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class AttachmentPage
|
18
|
+
def textile( view )
|
19
|
+
return "[[#{$MESSAGES[:Create]} #{name} => /edit/#{name} ]]" if empty?
|
20
|
+
return content if deleted?
|
21
|
+
%Q{[[ #{name} => #{view.file2(content)} ]]\n}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
1
25
|
# This module is used to extend each erb page to provide helper methods
|
2
26
|
module ErbHelper
|
3
27
|
|
4
|
-
|
5
|
-
|
28
|
+
attr_accessor :name
|
29
|
+
attr_accessor :description
|
30
|
+
attr_accessor :author_to_email_conversion
|
31
|
+
|
32
|
+
def url( name, view = 'view', query = '' )
|
33
|
+
"#{root_url}/#{view}/#{url_name_for_page_name(name)}#{query}"
|
6
34
|
end
|
7
35
|
|
8
36
|
def file( name )
|
9
|
-
"#{
|
37
|
+
"#{root_url}/attachment/#{name}"
|
38
|
+
end
|
39
|
+
|
40
|
+
# Will refactor this out eventually and merge with above
|
41
|
+
def file2( name )
|
42
|
+
name = name[1..-1] if name[0,1] == '/'
|
43
|
+
"#{root_url}/#{name.strip}"
|
10
44
|
end
|
11
45
|
end
|
12
46
|
|
13
47
|
# This class records all the links between pages
|
14
48
|
class Links
|
49
|
+
|
50
|
+
attr_reader :links
|
51
|
+
|
15
52
|
def initialize
|
16
53
|
@links = Hash.new
|
17
54
|
end
|
@@ -48,7 +85,7 @@ end
|
|
48
85
|
class BruteMatch
|
49
86
|
|
50
87
|
IGNORE_CASE = true
|
51
|
-
|
88
|
+
|
52
89
|
def initialize
|
53
90
|
@matches = Hash.new
|
54
91
|
@titles = Array.new #sorted array for speed
|
@@ -70,18 +107,19 @@ class BruteMatch
|
|
70
107
|
end
|
71
108
|
|
72
109
|
def match( text )
|
73
|
-
@titles.each do |title|
|
74
|
-
regexp
|
75
|
-
page = @matches[ title ]
|
76
|
-
text.gsub!( regexp ) { |match| yield match, page }
|
110
|
+
@titles.each do |title,regexp,page|
|
111
|
+
text.gsub!( regexp ) { |match| "#{$1}#{yield $2, page}#{$3}" }
|
77
112
|
end
|
78
113
|
text
|
79
114
|
end
|
80
115
|
|
81
116
|
private
|
82
117
|
|
118
|
+
# The title, a regexp to match for the title, and the page are stored in a sorted array
|
83
119
|
def update_titles
|
84
|
-
@titles = @matches.keys.sort_by { |title| title.length }.reverse
|
120
|
+
@titles = @matches.keys.sort_by { |title| title.length }.reverse.map do |title|
|
121
|
+
[ title, /(^|\W)(#{Regexp.escape( title )})(\W|$)/i, @matches[ title ] ]
|
122
|
+
end
|
85
123
|
end
|
86
124
|
|
87
125
|
def lower_case( text )
|
@@ -98,17 +136,17 @@ end
|
|
98
136
|
# * Automatically links things that look like email addresses and urls
|
99
137
|
class WikiRedCloth < RedCloth
|
100
138
|
|
101
|
-
RULES = [:refs_soks_bracketed_link, :
|
139
|
+
RULES = [:refs_soks_bracketed_link, :refs_textile, :block_textile_table, :block_textile_lists,:block_textile_prefix, :inline_textile_image, :inline_textile_link, :inline_textile_code, :inline_soks, :inline_textile_glyphs, :inline_textile_span, :refs_markdown, :block_markdown_setext, :block_markdown_atx, :block_markdown_rule, :block_markdown_bq, :block_markdown_lists, :inline_markdown_reflink, :inline_markdown_link ]
|
102
140
|
|
103
|
-
def initialize( wiki, page, string )
|
104
|
-
@wiki, @page = wiki, page
|
141
|
+
def initialize( wiki, page, string, hard_breaks = false )
|
142
|
+
@wiki, @view, @page = wiki, wiki, page
|
105
143
|
@internal_links_from_page = []
|
106
|
-
super(insert_sub_strings( string.dup ),
|
107
|
-
self.hard_breaks =
|
144
|
+
super(insert_sub_strings( string.dup ),[:no_span_caps])
|
145
|
+
self.hard_breaks = hard_breaks
|
108
146
|
end
|
109
147
|
|
110
148
|
def to_html
|
111
|
-
super( *RULES )
|
149
|
+
super( *RULES ).to_s
|
112
150
|
end
|
113
151
|
|
114
152
|
def inline_soks( text )
|
@@ -149,16 +187,14 @@ class WikiRedCloth < RedCloth
|
|
149
187
|
|
150
188
|
def insert_sub_strings( text, count = 0 )
|
151
189
|
return text if count > 5 # Stops us getting locked into a cycle if people mess up the insert
|
152
|
-
text.gsub!(/\[\[\s*(insert (.+?))\s*\]\]/i) do |
|
153
|
-
|
154
|
-
|
155
|
-
if @wiki.exists? inserted_page.name
|
156
|
-
@internal_links_from_page << inserted_page
|
157
|
-
inserted_page.is_inserted_into( @page )
|
158
|
-
end
|
159
|
-
insert_sub_strings( "#{inserted_page.textile}\n", count + 1 )
|
190
|
+
text.gsub!(/\[\[\s*(insert (.+?))\s*\]\]/i) do |match|
|
191
|
+
if @wiki.exists? $1 # So we don't accidentlaly match a page whose name starts 'insert'
|
192
|
+
match
|
160
193
|
else
|
161
|
-
|
194
|
+
inserted_page = @wiki.page( $2 )
|
195
|
+
@internal_links_from_page << inserted_page if @wiki.exists? inserted_page.name
|
196
|
+
inserted_page.is_inserted_into( @page )
|
197
|
+
insert_sub_strings( "#{inserted_page.textile(@view)}\n", count + 1 )
|
162
198
|
end
|
163
199
|
end
|
164
200
|
text
|
@@ -176,107 +212,140 @@ class WikiRedCloth < RedCloth
|
|
176
212
|
title, pagename = $1, $3
|
177
213
|
pagename ||= title
|
178
214
|
case pagename
|
215
|
+
|
216
|
+
# http://soks.rubyforge.org/index
|
217
|
+
when /^http(s)?:\/\//i ; link(pagename,title)
|
218
|
+
|
219
|
+
# www.soks.org
|
179
220
|
when /^www\./i ; link("http://#{pagename}", title )
|
180
|
-
|
181
|
-
|
182
|
-
|
221
|
+
|
222
|
+
# tamc@soks.org
|
223
|
+
when /[A-Za-z0-9.]+?@[A-Za-z0-9.]+/ ; link("mailto:#{pagename}",title)
|
224
|
+
|
225
|
+
# /revision/Home page?revision=10
|
226
|
+
when %r{^/(\w+)/(.+?)(\?\w+=\w+)$}
|
227
|
+
@internal_links_from_page << @wiki.page($2) if @wiki.exists?($2)
|
228
|
+
link( @view.url($2,$1,$3), title, @wiki.exists?($2) ? '':'missing' )
|
229
|
+
|
230
|
+
# /edit/a new page
|
231
|
+
when %r{^/(\w+)/(.+)}
|
232
|
+
@internal_links_from_page << @wiki.page($2) if @wiki.exists?($2)
|
233
|
+
link( @view.url($2,$1), title, @wiki.exists?($2) ? '':'missing' )
|
234
|
+
|
235
|
+
# the name of a page
|
236
|
+
else
|
237
|
+
@internal_links_from_page << @wiki.page(pagename) if @wiki.exists? pagename
|
238
|
+
link( @view.url( pagename ), title, @wiki.exists?(pagename) ? '':'missing' )
|
183
239
|
end
|
184
240
|
end
|
185
241
|
end
|
186
242
|
|
187
|
-
def inline_soks_automatic_link( text )
|
188
|
-
@wiki.rollingmatch.match( text )
|
189
|
-
|
190
|
-
|
191
|
-
def wiki_link( pagename, title, css_class = nil )
|
192
|
-
if @wiki.exists? pagename
|
193
|
-
@internal_links_from_page << @wiki.page( pagename )
|
194
|
-
css_class ||= ''
|
243
|
+
def inline_soks_automatic_link( text )
|
244
|
+
@wiki.rollingmatch.match( text ) do |title, page|
|
245
|
+
@internal_links_from_page << page
|
246
|
+
link( @view.url(page.name), title, 'automatic' )
|
195
247
|
end
|
196
|
-
link( url_for(pagename), title, css_class || 'missing')
|
197
248
|
end
|
198
249
|
|
199
250
|
def link( url, title = url, css_class = '' )
|
200
251
|
shelve "<a href='#{url}' class='#{css_class}'>#{title}</a>"
|
201
252
|
end
|
202
253
|
|
203
|
-
|
204
|
-
|
205
|
-
|
254
|
+
end
|
255
|
+
|
256
|
+
module PageNameToUrlNameConversion
|
257
|
+
|
258
|
+
def setup_page_name_to_url_name_conversion
|
259
|
+
@urls_to_pages, @pages_to_urls = {}, {}
|
260
|
+
@wiki.each { |name,page| url_name_for_page_name( page.name ) }
|
261
|
+
@wiki.watch_attentively_for(:page_created) {|event,page,revision| url_name_for_page_name( page.name )}
|
262
|
+
@wiki.watch_attentively_for(:page_title_recapitalized) {|event,page| change_caps_for( page.name )}
|
263
|
+
end
|
264
|
+
|
265
|
+
# To allow punctuation in page titles and not mess up urls
|
266
|
+
def url_name_for_page_name( page_name )
|
267
|
+
@pages_to_urls[ page_name.downcase ] || add_url_name_for_page_name( page_name )
|
206
268
|
end
|
207
269
|
|
270
|
+
def page_name_for_url_name( url_name )
|
271
|
+
@urls_to_pages[ url_name.downcase ] || url_name
|
272
|
+
end
|
273
|
+
|
274
|
+
def add_url_name_for_page_name( page_name )
|
275
|
+
url_name = create_url_name( page_name )
|
276
|
+
@pages_to_urls[ page_name.downcase ] = url_name
|
277
|
+
@urls_to_pages[ url_name.downcase ] = page_name
|
278
|
+
url_name
|
279
|
+
end
|
280
|
+
|
281
|
+
def change_caps_for( page_name )
|
282
|
+
url_name = @pages_to_urls[ page_name.downcase ].downcase
|
283
|
+
@urls_to_pages[ url_name ] = page_name
|
284
|
+
end
|
285
|
+
|
286
|
+
# Turns text into a WikiWord by changing the capitalization and then dumping the punctuation
|
287
|
+
def create_url_name( page_name )
|
288
|
+
url_name = page_name.capitalize.gsub(/(\W+(\w))/) { |m| $1.upcase }.gsub(/\W+/,'')
|
289
|
+
url_name = "PunctuationOnlyInTitle" if url_name == ""
|
290
|
+
url_name = increment_url_name( url_name ) while @urls_to_pages.has_key? url_name.downcase
|
291
|
+
url_name
|
292
|
+
end
|
293
|
+
|
294
|
+
def increment_url_name( url_name )
|
295
|
+
if url_name =~ /(\w+)-(\d+)/
|
296
|
+
"#{$1}-#{$2.to_i.succ}"
|
297
|
+
else
|
298
|
+
url_name+"-2"
|
299
|
+
end
|
300
|
+
end
|
208
301
|
end
|
209
302
|
|
210
303
|
class View
|
211
|
-
|
212
304
|
include ErbHelper
|
305
|
+
include PageNameToUrlNameConversion
|
213
306
|
|
214
|
-
|
307
|
+
REDCLOTH_CACHE_NAME = 'redcloth'
|
215
308
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
309
|
+
attr_reader :rollingmatch, :links
|
310
|
+
attr_accessor :view_folder
|
311
|
+
attr_accessor :root_url
|
312
|
+
attr_accessor :reload_erb_each_request
|
313
|
+
attr_accessor :dont_frame_views
|
314
|
+
attr_accessor :redcloth_hard_breaks
|
315
|
+
|
316
|
+
def initialize( wiki, root_url, view_folder )
|
317
|
+
@wiki, @root_url, @view_folder = wiki, root_url, view_folder
|
318
|
+
@rollingmatch, @links = BruteMatch.new, Links.new
|
319
|
+
@redcloth_cache = wiki.load_cache(REDCLOTH_CACHE_NAME) || Hash.new
|
320
|
+
@erb_cache = Hash.new
|
321
|
+
@reload_erb_each_request = false
|
322
|
+
@dont_frame_views = []
|
323
|
+
@redcloth_hard_breaks = false
|
324
|
+
setup_page_name_to_url_name_conversion
|
220
325
|
wiki.watch_attentively_for( :page_revised ) { |event,page,revision| refresh_redcloth( page ) }
|
326
|
+
wiki.watch_for(:shutdown) { wiki.save_cache(REDCLOTH_CACHE_NAME,@redcloth_cache) }
|
221
327
|
end
|
222
328
|
|
223
|
-
def
|
224
|
-
page = @wiki.page pagename
|
329
|
+
def render( pagename, view = 'view', person = 'Anon.', query = {} )
|
330
|
+
page = @wiki.page( pagename )
|
225
331
|
renderedview = redcloth( page )
|
226
332
|
content_of_page = html( page.class, view, binding )
|
333
|
+
@wiki.notify(:page_viewed, page, view, person)
|
227
334
|
if should_frame? view
|
228
|
-
frame_erb.result
|
335
|
+
return frame_erb.result(binding)
|
229
336
|
else
|
230
|
-
content_of_page
|
337
|
+
return content_of_page
|
231
338
|
end
|
232
339
|
end
|
233
|
-
|
234
|
-
def find( pagename )
|
235
|
-
return view( pagename ) if @wiki.exists?( pagename )
|
236
|
-
view = 'find'
|
237
|
-
search_term = /#{pagename}/i
|
238
|
-
title_results = @wiki.select { |name,page| name=~ search_term }
|
239
|
-
text_results = @wiki.select { |name,page| page.content=~ search_term }
|
240
|
-
content_of_page = html( Page, 'search_results', binding )
|
241
|
-
page = nil
|
242
|
-
frame_erb.result binding
|
243
|
-
end
|
244
|
-
|
245
|
-
def revise( pagename, content, person, newpagename = pagename )
|
246
|
-
if @wiki.exists?( pagename ) && (newpagename != pagename)
|
247
|
-
@wiki.revise( pagename, "#{$MESSAGES[:content_moved_to]} [[#{newpagename}]]", person )
|
248
|
-
@wiki.revise( newpagename, "#{$MESSAGES[:content_moved_from]} [[#{pagename}]]", 'AutomaticPageMover' )
|
249
|
-
@wiki.revise( newpagename, content, person )
|
250
|
-
else
|
251
|
-
@wiki.revise( newpagename, content, person )
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
def move( oldpagename, person, newpagename )
|
256
|
-
unless newpagename == oldpagename
|
257
|
-
@wiki.revise( newpagename, "#{$MESSAGES[:content_moved_from]} [[#{oldpagename}]]", 'AutomaticPageMover')
|
258
|
-
@wiki.revise( newpagename, @wiki.page( oldpagename ).content, person)
|
259
|
-
@wiki.revise( oldpagename, "#{$MESSAGES[:content_moved_to]} [[#{newpagename}]]", person)
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
def rollback( pagename, revision, person )
|
264
|
-
@wiki.rollback( pagename, revision, person )
|
265
|
-
end
|
266
|
-
|
267
|
-
def delete( pagename, person )
|
268
|
-
@wiki.revise( pagename, $MESSAGES[:page_deleted], person )
|
269
|
-
end
|
270
340
|
|
271
341
|
def refresh_redcloth( page )
|
272
342
|
$LOG.info "Refreshing #{page}"
|
273
|
-
@redcloth_cache[page] =
|
274
|
-
@redcloth_cache[ page ] = WikiRedCloth.new( self, page, page.textile ).to_html
|
343
|
+
@redcloth_cache[ page.name ] = WikiRedCloth.new( self, page, page.textile(self), redcloth_hard_breaks).to_html
|
275
344
|
end
|
276
345
|
|
277
346
|
def redcloth( page )
|
278
|
-
|
279
|
-
@redcloth_cache[ page ]
|
347
|
+
textile = page.textile(self)
|
348
|
+
@redcloth_cache[ page.name ] || refresh_redcloth( page )
|
280
349
|
end
|
281
350
|
|
282
351
|
def clear_redcloth_cache( page = :all_pages )
|
@@ -284,7 +353,7 @@ class View
|
|
284
353
|
end
|
285
354
|
|
286
355
|
def html( klass, view, _binding )
|
287
|
-
@erb_cache.clear if
|
356
|
+
@erb_cache.clear if reload_erb_each_request
|
288
357
|
( @erb_cache[ path_for( klass, view ) ] ||= ERB.new( IO.readlines( erb_filename( klass, view ) ).join ) ).result( _binding )
|
289
358
|
end
|
290
359
|
|
@@ -294,37 +363,34 @@ class View
|
|
294
363
|
if klass.superclass
|
295
364
|
klass = klass.superclass
|
296
365
|
else
|
297
|
-
|
366
|
+
$LOG.warn "Not found #{path_for( klass, view)}"
|
367
|
+
raise WEBrick::HTTPStatus::NotFound
|
298
368
|
end
|
299
369
|
end
|
300
370
|
path_for( klass, view )
|
301
371
|
end
|
302
372
|
|
303
|
-
def path_for( klass, view ) "#{
|
373
|
+
def path_for( klass, view ) "#{view_folder}/#{klass}_#{view.downcase}.rhtml" end
|
304
374
|
|
305
375
|
def should_frame?( view )
|
306
|
-
|
376
|
+
not( dont_frame_views.include? view.downcase )
|
307
377
|
end
|
308
378
|
|
309
379
|
def frame_erb
|
310
|
-
@frame_erb = nil if
|
380
|
+
@frame_erb = nil if reload_erb_each_request
|
311
381
|
@frame_erb ||= load_frame_erb
|
312
382
|
end
|
313
383
|
|
314
384
|
def load_frame_erb
|
315
|
-
if File.exists? "#{
|
316
|
-
ERB.new( IO.readlines( "#{
|
385
|
+
if File.exists? "#{view_folder}/frame.rhtml"
|
386
|
+
ERB.new( IO.readlines( "#{view_folder}/frame.rhtml" ).join )
|
317
387
|
else
|
318
388
|
ERB.new( "<%= content_of_page %>" )
|
319
389
|
end
|
320
390
|
end
|
321
391
|
|
322
|
-
|
323
|
-
|
324
|
-
$SETTINGS
|
325
|
-
end
|
326
|
-
|
327
|
-
def method_missing( method, *args, &block )
|
392
|
+
def method_missing( method, *args, &block )
|
393
|
+
# $LOG.debug "View method missing called for #{method} with #{args.inspect}"
|
328
394
|
@wiki.send( method, *args, &block )
|
329
395
|
end
|
330
396
|
end
|
data/lib/soks.rb
CHANGED
@@ -9,35 +9,17 @@ require 'diff/lcs/array'
|
|
9
9
|
require 'fileutils'
|
10
10
|
require 'thread'
|
11
11
|
require 'yaml'
|
12
|
+
require 'logger'
|
12
13
|
|
13
14
|
require 'soks-utils'
|
14
15
|
require 'soks-storage'
|
15
16
|
require 'soks-model'
|
16
17
|
require 'soks-view'
|
17
18
|
require 'soks-servlet'
|
19
|
+
|
18
20
|
require 'helpers/default-helpers'
|
21
|
+
require 'helpers/maintenance-helpers'
|
22
|
+
require 'helpers/counter-helpers'
|
19
23
|
|
20
24
|
Thread.abort_on_exception = true
|
21
|
-
Socket.do_not_reverse_lookup = true
|
22
|
-
|
23
|
-
# These are the default settings. Can be overriden in the call to soks-servlet.rb#start_wiki
|
24
|
-
$SETTINGS = {
|
25
|
-
:name => 'A Soks Wiki',
|
26
|
-
:description => 'A Soks Wiki',
|
27
|
-
:root_directory => 'soks-wiki',
|
28
|
-
:check_files_every => 60, # Seconds
|
29
|
-
:url => 'http://localhost:8000',
|
30
|
-
:port => 8000,
|
31
|
-
:home_page => 'Home Page',
|
32
|
-
:dont_frame_templates => ['print','rss'],
|
33
|
-
:force_no_cache => false, # Adds headers to restrict the cacheing of pages
|
34
|
-
:redcloth_hard_breaks => false, # Set Redcloth to use hard breaks
|
35
|
-
:reload_erb_each_request => false, # False faster for production, true speeds development cycle
|
36
|
-
:server_type => WEBrick::SimpleServer, # Could be WEBrick::Daemon if you wish to fork
|
37
|
-
:authenticators => [ [ %r{/(view|rss|print|find|meta|attachment)/.*}, WEBrick::HTTPAuth::NoAuthenticationRequired.new ],
|
38
|
-
# [ %r{/upload/.*}, WEBrick::HTTPAuth::NotPermitted.new ],
|
39
|
-
# [ %r{/(edit|save)/home page}, WEBrick::HTTPAuth::SiteWidePassword.new('password','You need to enter the site wide password to edit the home page') ],
|
40
|
-
# [ %r{/(view|edit|save)/private.*},WEBrick::HTTPAuth::BasicAuth.new( :UserDB => htpasswd, :Realm => realm ) ], # See webrick documentation
|
41
|
-
[ %r{.*}, WEBrick::HTTPAuth::AskForUserName.new( 'No password, just enter a name') ]
|
42
|
-
]
|
43
|
-
}
|
25
|
+
Socket.do_not_reverse_lookup = true
|
@@ -3,7 +3,7 @@ function trim(str)
|
|
3
3
|
return str.replace(/^\s+/,'').replace(/\s+$/,'');
|
4
4
|
}
|
5
5
|
|
6
|
-
function editSelected()
|
6
|
+
function editSelected(web_root)
|
7
7
|
{
|
8
8
|
if (window.getSelection)
|
9
9
|
{
|
@@ -21,11 +21,11 @@ function editSelected()
|
|
21
21
|
void(txt=prompt('Please enter the title of the page you wish to create',''))
|
22
22
|
}
|
23
23
|
if(txt){
|
24
|
-
window.location =
|
24
|
+
window.location = web_root+escape(txt)
|
25
25
|
}
|
26
26
|
}
|
27
27
|
|
28
|
-
function hotkey( event )
|
28
|
+
function hotkey( event, web_root )
|
29
29
|
{
|
30
30
|
event = (event) ? event : ((window.event) ? event : null);
|
31
31
|
if (event)
|
@@ -34,17 +34,8 @@ function hotkey( event )
|
|
34
34
|
{
|
35
35
|
var charCode = (event.charCode) ? event.charCode : ((event.which) ? event.which : event.keyCode);
|
36
36
|
if (charCode == 14 ) {
|
37
|
-
editSelected();
|
37
|
+
editSelected(web_root);
|
38
38
|
}
|
39
39
|
}
|
40
40
|
}
|
41
|
-
}
|
42
|
-
|
43
|
-
function validateTitle( proposed_title )
|
44
|
-
{
|
45
|
-
var illegalcharacters = /[\\\[\]\?<>&\^\/]/;
|
46
|
-
if (illegalcharacters.test( proposed_title ) == true )
|
47
|
-
{
|
48
|
-
alert( 'Unfortunately the characters \ / [ ] ? < > & ^ in titles cause problems with Soks. Please try not to use them.');
|
49
|
-
}
|
50
41
|
}
|