diff --git a/lib/gollum.rb b/lib/gollum.rb
index 5cc1e40f..c2dd3d32 100644
--- a/lib/gollum.rb
+++ b/lib/gollum.rb
@@ -15,6 +15,7 @@ require File.expand_path('../gollum/blob_entry', __FILE__)
require File.expand_path('../gollum/wiki', __FILE__)
require File.expand_path('../gollum/page', __FILE__)
require File.expand_path('../gollum/file', __FILE__)
+require File.expand_path('../gollum/file_view', __FILE__)
require File.expand_path('../gollum/markup', __FILE__)
require File.expand_path('../gollum/sanitization', __FILE__)
require File.expand_path('../gollum/tex', __FILE__)
diff --git a/lib/gollum/file_view.rb b/lib/gollum/file_view.rb
new file mode 100644
index 00000000..4074334d
--- /dev/null
+++ b/lib/gollum/file_view.rb
@@ -0,0 +1,155 @@
+module Gollum
+=begin
+ FileView requires that:
+ - All files in root dir are processed first
+ - Then all the folders are sorted and processed
+=end
+ class FileView
+ def initialize pages
+ @pages = pages
+ end
+
+ def enclose_tree string
+ %Q(
\n) + string + %Q(\n )
+ end
+
+ def new_page page
+ '' + %Q( #{page.name2} \n)
+ end
+
+ def new_folder page
+ new_sub_folder ::File.dirname(page.path), page.name, page.name2
+ end
+
+ def new_sub_folder path, name, name2
+ <<-HTML
+
+
+ #{path}
+
+ #{name2}
+ HTML
+ end
+
+ def end_folder
+ <<-HTML
+
+
+
+ HTML
+ end
+
+ def render_files
+ html = ''
+ count = @pages.size
+ folder_start = -1
+
+ # Process all pages until folders start
+ count.times do | index |
+ page = @pages[ index ]
+ path = page.path
+
+ unless path.include? '/'
+ # Page processed (not contained in a folder)
+ html += new_page page
+ else
+ # Folders start at the next index
+ folder_start = index
+ break # Pages finished, move on to folders
+ end
+ end
+
+ # If there are no folders, then we're done.
+ return enclose_tree(html) if folder_start <= -1
+
+ # Handle special case of only one folder.
+ if (count - folder_start == 1)
+ path = @pages[ folder_start ]
+
+ html += <<-HTML
+
+ #{::File.dirname(path)}
+
+ #{page.name2}
+
+
+ HTML
+
+ return enclose_tree html
+ end
+
+ sorted_folders = []
+ (folder_start).upto count - 1 do | index |
+ sorted_folders += [[ @pages[ index ].path, index ]]
+ end
+
+ # http://stackoverflow.com/questions/3482814/sorting-list-of-string-paths-in-vb-net
+ sorted_folders.sort! do |first,second|
+ a = first[0]
+ b = second[0]
+
+ # use :: operator because gollum defines its own conflicting File class
+ dir_compare = ::File.dirname(a) <=> ::File.dirname(b)
+
+ # Sort based on directory name unless they're equal (0) in
+ # which case sort based on file name.
+ if dir_compare == 0
+ ::File.basename(a) <=> ::File.basename(b)
+ else
+ dir_compare
+ end
+ end
+
+ # Process first folder
+ page = @pages[ sorted_folders[ 0 ][1] ]
+ html += new_folder page
+
+ last_folder = ::File.dirname page.path # define last_folder
+
+ # keep track of folder depth, 0 = at root.
+ depth = 0
+
+ # process rest of folders
+ 1.upto(sorted_folders.size - 1) do | index |
+ page = @pages[ sorted_folders[ index ][1] ]
+ path = page.path
+ folder = ::File.dirname path
+
+ if last_folder == folder
+ # same folder
+ html += new_page page
+ elsif folder.include?('/')
+ # check if we're going up or down a depth level
+ if last_folder.scan('/').size > folder.scan('/').size
+ # end tag for 1 subfolder & 1 parent folder
+ # so emit 2 end tags
+ 2.times { html += end_folder; }
+ depth -= 1
+ else
+ depth += 1
+ end
+
+ # subfolder
+ html += new_sub_folder ::File.dirname(page.path).split('/').last, page.name, page.name2
+ else
+ # depth+1 because we need an additional end_folder
+ (depth+1).times { html += end_folder; }
+ depth = 0
+ # New root folder
+ html += new_folder page
+ end
+
+ last_folder = folder
+ end
+
+ # Process last folder's ending tags.
+ (depth+1).times {
+ depth.times { html += end_folder; }
+ depth = 0
+ }
+
+ # return the completed html
+ enclose_tree html
+ end # end render_files
+ end # end FileView class
+end # end Gollum module
diff --git a/lib/gollum/frontend/app.rb b/lib/gollum/frontend/app.rb
index c597d4ba..9549e335 100644
--- a/lib/gollum/frontend/app.rb
+++ b/lib/gollum/frontend/app.rb
@@ -200,6 +200,13 @@ module Precious
mustache :pages
end
+ get '/fileview' do
+ wiki = Gollum::Wiki.new(settings.gollum_path, settings.wiki_options)
+ @results = Gollum::FileView.new(wiki.pages).render_files
+ @ref = wiki.ref
+ mustache :fileview
+ end
+
get '/*' do
show_page_or_file(params[:splat].first)
end
diff --git a/lib/gollum/frontend/public/gollum/css/_styles.css b/lib/gollum/frontend/public/gollum/css/_styles.css
new file mode 100644
index 00000000..d70f29ed
--- /dev/null
+++ b/lib/gollum/frontend/public/gollum/css/_styles.css
@@ -0,0 +1,110 @@
+/* Just some base styles not needed for example to function */
+*, html { font-family: Verdana, Arial, Helvetica, sans-serif; }
+
+
+#results a:hover {
+ background-color: #4c4c4c;
+}
+
+#home_button {
+ position: absolute;
+ top: 10px;
+ left: 50%;
+}
+
+#home_button .minibutton {
+/* controls size of home btn */
+font-size: 1em;
+text-align: center;
+}
+
+#results {
+ position: absolute;
+ top: 60px;
+ left: 10px;
+}
+
+
+body, form, ul, li, p, h1, h2, h3, h4, h5
+{
+ margin: 0;
+ padding: 0;
+}
+body { background-color: #606061; color: #ffffff; margin: 0; }
+img { border: none; }
+p
+{
+ font-size: 1em;
+ margin: 0 0 1em 0;
+}
+
+html { font-size: 100%; /* IE hack */ }
+body { font-size: 1em; /* Sets base font size to 16px */ }
+table { font-size: 100%; /* IE hack */ }
+input, select, textarea, th, td { font-size: 1em; }
+
+/* CSS Tree menu styles */
+ol.tree
+{
+ padding: 0 0 0 30px;
+ width: 300px;
+}
+ li
+ {
+ position: relative;
+ margin-left: -15px;
+ list-style: none;
+ }
+ li.file
+ {
+ margin-left: -1px !important;
+ height: 1.5em;
+ }
+ li.file a
+ {
+ background: url(/images/fileview/document.png) 0 0 no-repeat;
+ color: #fff;
+ padding-left: 21px;
+ text-decoration: none;
+ display: block;
+ }
+ li.file a[href *= '.pdf'] { background: url(/images/fileview/document.png) 0 0 no-repeat; }
+ li.file a[href *= '.html'] { background: url(/images/fileview/document.png) 0 0 no-repeat; }
+ li.file a[href $= '.css'] { background: url(/images/fileview/document.png) 0 0 no-repeat; }
+ li.file a[href $= '.js'] { background: url(/images/fileview/document.png) 0 0 no-repeat; }
+ li input
+ {
+ position: absolute;
+ left: 0;
+ margin-left: 0;
+ opacity: 0;
+ z-index: 2;
+ cursor: pointer;
+ height: 1em;
+ width: 1em;
+ top: 0;
+ }
+ li input + ol
+ {
+ background: url(/images/fileview/toggle-small-expand.png) 40px 0 no-repeat;
+ margin: -1.188em 0 0 -44px; /* 15px */
+ height: 1.5em;
+ }
+ li input + ol > li { display: none; margin-left: -14px !important; padding-left: 1px; }
+ li label
+ {
+ background: url(/images/fileview/folder-horizontal.png) 15px 1px no-repeat;
+ cursor: pointer;
+ display: block;
+ padding-left: 37px;
+ }
+
+ li input:checked + ol
+ {
+ background: url(/images/fileview/toggle-small.png) 40px 5px no-repeat;
+ margin: -1.5em 0 0 -44px; /* 20px */
+ padding: 1.563em 0 0 80px;
+ height: auto;
+ }
+ li input:checked + ol > li { display: block; margin: 0 0 0.125em; /* 2px */}
+ li input:checked + ol > li:last-child { margin: 0 0 0.063em; /* 1px */ }
diff --git a/lib/gollum/frontend/public/gollum/images/fileview/document.png b/lib/gollum/frontend/public/gollum/images/fileview/document.png
new file mode 100644
index 00000000..f125928c
Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/document.png differ
diff --git a/lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png b/lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png
new file mode 100644
index 00000000..58e5cf7a
Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png differ
diff --git a/lib/gollum/frontend/public/gollum/images/fileview/toggle-small-expand.png b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small-expand.png
new file mode 100644
index 00000000..969f5e8a
Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small-expand.png differ
diff --git a/lib/gollum/frontend/public/gollum/images/fileview/toggle-small.png b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small.png
new file mode 100644
index 00000000..700af04c
Binary files /dev/null and b/lib/gollum/frontend/public/gollum/images/fileview/toggle-small.png differ
diff --git a/lib/gollum/frontend/templates/fileview.mustache b/lib/gollum/frontend/templates/fileview.mustache
new file mode 100644
index 00000000..4b62888c
--- /dev/null
+++ b/lib/gollum/frontend/templates/fileview.mustache
@@ -0,0 +1,29 @@
+
+
+
+
+
+ File View
+
+
+
+
+
+{{#has_results}}
+
+ {{{results}}}
+
+{{/has_results}}
+
+{{#no_results}}
+
+ There are no pages in {{ref}} .
+
+{{/no_results}}
+
+
diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb
index 6894ca2b..04b71974 100644
--- a/lib/gollum/page.rb
+++ b/lib/gollum/page.rb
@@ -116,14 +116,21 @@ module Gollum
self.class.strip_filename(filename)
end
- # Public: The canonical page name without extension, and dashes converted
- # to spaces.
+ # Public: The canonical page name without extension.
#
# Returns the String name.
def name
self.class.canonicalize_filename(filename)
end
+ # Public: The canonical page name without extension, and dashes
+ # really converted to spaces.
+ #
+ # Returns the String name.
+ def name2
+ self.class.canonicalize_filename(filename).gsub('-', ' ')
+ end
+
# Public: The title will be constructed from the
# filename by stripping the extension and replacing any dashes with
# spaces.