From 8bf52a4ae3aebc8c58f51cff696e99ecafe9c7c8 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Fri, 16 Dec 2016 02:12:21 -0200 Subject: Show directory hierarchy when listing wiki pages --- app/controllers/projects/wikis_controller.rb | 3 ++- app/models/wiki_page.rb | 25 ++++++++++++++++++++++ app/views/projects/wikis/_sidebar.html.haml | 12 +++++++---- app/views/projects/wikis/pages.html.haml | 14 +++++++----- .../23535-folders-in-wiki-repository.yml | 4 ++++ spec/models/wiki_page_spec.rb | 17 +++++++++++++++ 6 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 changelogs/unreleased/23535-folders-in-wiki-repository.yml diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index c3353446fd1..45a42400b2a 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -8,6 +8,7 @@ class Projects::WikisController < Projects::ApplicationController def pages @wiki_pages = Kaminari.paginate_array(@project_wiki.pages).page(params[:page]) + @wiki_directories = WikiPage.group_by_directory(@wiki_pages) end def show @@ -116,7 +117,7 @@ class Projects::WikisController < Projects::ApplicationController # Call #wiki to make sure the Wiki Repo is initialized @project_wiki.wiki - @sidebar_wiki_pages = @project_wiki.pages.first(15) + @sidebar_wiki_directories = WikiPage.group_by_directory(@project_wiki.pages.first(15)) rescue ProjectWiki::CouldNotCreateWikiError flash[:notice] = "Could not create Wiki Repository at this time. Please try again later." redirect_to project_path(@project) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index c3de278f5b7..30db2b13dc0 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -12,6 +12,23 @@ class WikiPage ActiveModel::Name.new(self, nil, 'wiki') end + def self.group_by_directory(pages) + directories = {} + + pages.each do |page| + if page.slug.include?('/') + # Directory hierarchy is given by matching from the beginning up to + # the last forward slash. + directory = page.slug.match(/\A(.+)\//)[1] + directories[directory] = add_to_directory(directories[directory], page) + else + directories['root'] = add_to_directory(directories['root'], page) + end + end + + directories + end + def to_key [:slug] end @@ -176,6 +193,14 @@ class WikiPage private + def self.add_to_directory(directory, page) + if directory.present? + directory << page + else + [page] + end + end + def set_attributes attributes[:slug] = @page.url_path attributes[:title] = @page.title diff --git a/app/views/projects/wikis/_sidebar.html.haml b/app/views/projects/wikis/_sidebar.html.haml index cad9c15a49e..5aee1a136f5 100644 --- a/app/views/projects/wikis/_sidebar.html.haml +++ b/app/views/projects/wikis/_sidebar.html.haml @@ -12,10 +12,14 @@ .blocks-container .block.block-first %ul.wiki-pages - - @sidebar_wiki_pages.each do |wiki_page| - %li{ class: params[:id] == wiki_page.slug ? 'active' : '' } - = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_page) do - = wiki_page.title.capitalize + - @sidebar_wiki_directories.each do |wiki_directory, wiki_pages| + %li + = wiki_directory + %ul + - wiki_pages.each do |wiki_page| + %li{ class: params[:id] == wiki_page.slug ? 'active' : '' } + = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_page) do + = wiki_page.title.capitalize .block = link_to namespace_project_wikis_pages_path(@project.namespace, @project), class: 'btn btn-block' do More Pages diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index e1eaffc6884..274afb1bdea 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -14,10 +14,14 @@ Clone repository %ul.content-list - - @wiki_pages.each do |wiki_page| + - @wiki_directories.each do |wiki_directory, wiki_pages| %li - = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) - %small (#{wiki_page.format}) - .pull-right - %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} + = wiki_directory + %ul + - wiki_pages.each do |wiki_page| + %li + = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) + %small (#{wiki_page.format}) + .pull-right + %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} = paginate @wiki_pages, theme: 'gitlab' diff --git a/changelogs/unreleased/23535-folders-in-wiki-repository.yml b/changelogs/unreleased/23535-folders-in-wiki-repository.yml new file mode 100644 index 00000000000..7361b182a94 --- /dev/null +++ b/changelogs/unreleased/23535-folders-in-wiki-repository.yml @@ -0,0 +1,4 @@ +--- +title: Show directory hierarchy when listing wiki pages +merge_request: +author: Alex Braha Stoll diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 5c34b1b0a30..25e7b517fe6 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -7,6 +7,23 @@ describe WikiPage, models: true do subject { WikiPage.new(wiki) } + describe '::group_by_directory' do + context 'when there are no pages' do + it 'returns an empty hash' do + end + end + + context 'when there are pages' do + let!(:page_1) { create_page('page_1', 'content') } + let!(:page_2) { create_page('directory/page_2', 'content') } + let(:pages) { [page_1, page_2] } + + xit 'returns a hash in which keys are directories and values are their pages' do + expected_grouped_pages = { 'root' => [page_1], 'directory' => [page_2] } + end + end + end + describe "#initialize" do context "when initialized with an existing gollum page" do before do -- cgit v1.2.1 From 083442bc716d7e69cbb9e7852159b0f3ba9a4610 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sat, 17 Dec 2016 16:38:26 -0200 Subject: Add specs for WikiPage.group_by_directory --- spec/models/wiki_page_spec.rb | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 25e7b517fe6..595d4a621c1 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -7,19 +7,37 @@ describe WikiPage, models: true do subject { WikiPage.new(wiki) } - describe '::group_by_directory' do + describe '.group_by_directory' do context 'when there are no pages' do it 'returns an empty hash' do + expect(WikiPage.group_by_directory(nil)).to eq({}) + expect(WikiPage.group_by_directory([])).to eq({}) end end context 'when there are pages' do - let!(:page_1) { create_page('page_1', 'content') } - let!(:page_2) { create_page('directory/page_2', 'content') } - let(:pages) { [page_1, page_2] } + before do + create_page('page_1', 'content') + create_page('dir_1/page_2', 'content') + create_page('dir_1/dir_2/page_3', 'content') + end + + it 'returns a hash in which keys are directories and values are their pages' do + page_1 = wiki.find_page('page_1') + page_2 = wiki.find_page('dir_1/page_2') + page_3 = wiki.find_page('dir_1/dir_2/page_3') + expected_grouped_pages = { + '/' => [page_1], 'dir_1' => [page_2], 'dir_1/dir_2' => [page_3] + } - xit 'returns a hash in which keys are directories and values are their pages' do - expected_grouped_pages = { 'root' => [page_1], 'directory' => [page_2] } + grouped_pages = WikiPage.group_by_directory(wiki.pages) + + grouped_pages.each do |dir, pages| + expected_slugs = expected_grouped_pages.fetch(dir).map(&:slug) + slugs = pages.map(&:slug) + + expect(slugs).to match_array(expected_slugs) + end end end end -- cgit v1.2.1 From bebfba3e6de520f98d263ced2d2a17f6ddfc4a6f Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sat, 17 Dec 2016 16:38:55 -0200 Subject: Refactor WikiPage.group_by_directory --- app/models/wiki_page.rb | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 30db2b13dc0..425384d3df4 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -13,17 +13,14 @@ class WikiPage end def self.group_by_directory(pages) - directories = {} + return {} if pages.blank? + directories = { '/' => [] } pages.each do |page| - if page.slug.include?('/') - # Directory hierarchy is given by matching from the beginning up to - # the last forward slash. - directory = page.slug.match(/\A(.+)\//)[1] - directories[directory] = add_to_directory(directories[directory], page) - else - directories['root'] = add_to_directory(directories['root'], page) - end + directory = page.wiki.page_title_and_dir(page.slug).last + directory = '/' if directory.blank? + directories[directory] ||= [] + directories[directory] << page end directories -- cgit v1.2.1 From c7294dded2fc869d6431ac192649f11ca7e96375 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sat, 17 Dec 2016 16:39:55 -0200 Subject: Remove WikiPage.add_to_directory --- app/models/wiki_page.rb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 425384d3df4..aeacb6f8995 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -190,14 +190,6 @@ class WikiPage private - def self.add_to_directory(directory, page) - if directory.present? - directory << page - else - [page] - end - end - def set_attributes attributes[:slug] = @page.url_path attributes[:title] = @page.title -- cgit v1.2.1 From 91e1701b6abfb9a4b9ad50996bf4383d63b97e74 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sat, 17 Dec 2016 17:38:45 -0200 Subject: Remove root directory name from the sidebar of wikis --- app/views/projects/wikis/_sidebar.html.haml | 16 +++++++++------- app/views/projects/wikis/_sidebar_wiki_pages.html.haml | 4 ++++ 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 app/views/projects/wikis/_sidebar_wiki_pages.html.haml diff --git a/app/views/projects/wikis/_sidebar.html.haml b/app/views/projects/wikis/_sidebar.html.haml index 5aee1a136f5..b7464180a0c 100644 --- a/app/views/projects/wikis/_sidebar.html.haml +++ b/app/views/projects/wikis/_sidebar.html.haml @@ -13,13 +13,15 @@ .block.block-first %ul.wiki-pages - @sidebar_wiki_directories.each do |wiki_directory, wiki_pages| - %li - = wiki_directory - %ul - - wiki_pages.each do |wiki_page| - %li{ class: params[:id] == wiki_page.slug ? 'active' : '' } - = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_page) do - = wiki_page.title.capitalize + - if wiki_directory == '/' + = render 'sidebar_wiki_pages', wiki_pages: wiki_pages + - else + %li + = wiki_directory + %ul + = render 'sidebar_wiki_pages', wiki_pages: wiki_pages + + .block = link_to namespace_project_wikis_pages_path(@project.namespace, @project), class: 'btn btn-block' do More Pages diff --git a/app/views/projects/wikis/_sidebar_wiki_pages.html.haml b/app/views/projects/wikis/_sidebar_wiki_pages.html.haml new file mode 100644 index 00000000000..65453a384d2 --- /dev/null +++ b/app/views/projects/wikis/_sidebar_wiki_pages.html.haml @@ -0,0 +1,4 @@ +- wiki_pages.each do |wiki_page| + %li{ class: params[:id] == wiki_page.slug ? 'active' : '' } + = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_page) do + = wiki_page.title.capitalize -- cgit v1.2.1 From 294acf1c5cd2aea353081059c60b3951a2cf7c77 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sat, 17 Dec 2016 18:00:29 -0200 Subject: Remove root directory name from index of wikis --- app/views/projects/wikis/_wiki_pages.html.haml | 6 ++++++ app/views/projects/wikis/pages.html.haml | 17 ++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 app/views/projects/wikis/_wiki_pages.html.haml diff --git a/app/views/projects/wikis/_wiki_pages.html.haml b/app/views/projects/wikis/_wiki_pages.html.haml new file mode 100644 index 00000000000..ac98599d96b --- /dev/null +++ b/app/views/projects/wikis/_wiki_pages.html.haml @@ -0,0 +1,6 @@ +- wiki_pages.each do |wiki_page| + %li + = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) + %small (#{wiki_page.format}) + .pull-right + %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index 274afb1bdea..2813b3a1c81 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -15,13 +15,12 @@ %ul.content-list - @wiki_directories.each do |wiki_directory, wiki_pages| - %li - = wiki_directory - %ul - - wiki_pages.each do |wiki_page| - %li - = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) - %small (#{wiki_page.format}) - .pull-right - %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} + - if wiki_directory == '/' + = render 'wiki_pages', wiki_pages: wiki_pages + - else + %li + = wiki_directory + %ul + = render 'wiki_pages', wiki_pages: wiki_pages + = paginate @wiki_pages, theme: 'gitlab' -- cgit v1.2.1 From 5bbe6559917e1e64cdb047b6235715e2a7f002f2 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sun, 18 Dec 2016 21:22:20 -0200 Subject: Add component to show the full path of a wiki page when viewing its content --- app/assets/stylesheets/pages/wiki.scss | 3 ++- app/models/wiki_page.rb | 11 +++++++++ app/views/projects/wikis/show.html.haml | 2 +- spec/models/wiki_page_spec.rb | 40 +++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index b9f81533150..7afadb7364d 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -14,7 +14,8 @@ font-size: 22px; } - .wiki-last-edit-by { + .wiki-last-edit-by, .wiki-page-full-path { + display: block; color: $gl-gray-light; strong { diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index aeacb6f8995..e970cfbfff8 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -88,6 +88,12 @@ class WikiPage end end + # The hierarchy of the directory this page is contained in. + def directory + dir = wiki.page_title_and_dir(slug).last + dir.present? ? dir : '/' + end + # The processed/formatted content of this page. def formatted_content @attributes[:formatted_content] ||= if @page @@ -100,6 +106,11 @@ class WikiPage @attributes[:format] || :markdown end + # The full path for this page, including its filename and extension. + def full_path + "/#{directory}/#{page.filename}".gsub(/\/+/, '/') + end + # The commit message for this page version. def message version.try(:message) diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 1b6dceee241..25ae5c587ec 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -8,7 +8,7 @@ .nav-text %h2.wiki-page-title= @page.title.capitalize - + %span.wiki-page-full-path= "(#{@page.full_path})" %span.wiki-last-edit-by Last edited by %strong diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 595d4a621c1..c40a89b9dfb 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -224,6 +224,46 @@ describe WikiPage, models: true do end end + describe '#directory' do + context 'when the page is at the root directory' do + it 'returns /' do + create_page('file', 'content') + page = wiki.find_page('file') + + expect(page.directory).to eq('/') + end + end + + context 'when the page is inside an actual directory' do + it 'returns the full directory hierarchy' do + create_page('dir_1/dir_1_1/file', 'content') + page = wiki.find_page('dir_1/dir_1_1/file') + + expect(page.directory).to eq('dir_1/dir_1_1') + end + end + end + + describe '#full_path' do + context 'when the page is at the root directory' do + it 'returns /filename.fileextension' do + create_page('file', 'content') + page = wiki.find_page('file') + + expect(page.full_path).to eq('/file.md') + end + end + + context 'when the page is inside an actual directory' do + it 'returns /directory/filename.fileextension' do + create_page('dir/file', 'content') + page = wiki.find_page('dir/file') + + expect(page.full_path).to eq('/dir/file.md') + end + end + end + describe '#historical?' do before do create_page('Update', 'content') -- cgit v1.2.1 From 904aa039e5ccb4d9f653d254ea5818be130fb218 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sun, 18 Dec 2016 21:27:30 -0200 Subject: Change WikiPage.group_by_directory to use WikiPage#directory --- app/models/wiki_page.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index e970cfbfff8..1dbb3407623 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -17,10 +17,8 @@ class WikiPage directories = { '/' => [] } pages.each do |page| - directory = page.wiki.page_title_and_dir(page.slug).last - directory = '/' if directory.blank? - directories[directory] ||= [] - directories[directory] << page + directories[page.directory] ||= [] + directories[page.directory] << page end directories -- cgit v1.2.1 From 5607bb8f0921cbfa4586bb7b92acb6666a65b4e2 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sun, 18 Dec 2016 21:37:10 -0200 Subject: Change WikiPage#directory to always start a directory hierarchy with '/' --- app/models/wiki_page.rb | 4 ++-- spec/models/wiki_page_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 1dbb3407623..a563b0b7a72 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -89,7 +89,7 @@ class WikiPage # The hierarchy of the directory this page is contained in. def directory dir = wiki.page_title_and_dir(slug).last - dir.present? ? dir : '/' + "/#{dir}" end # The processed/formatted content of this page. @@ -106,7 +106,7 @@ class WikiPage # The full path for this page, including its filename and extension. def full_path - "/#{directory}/#{page.filename}".gsub(/\/+/, '/') + "#{directory}/#{page.filename}".gsub(/\/+/, '/') end # The commit message for this page version. diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index c40a89b9dfb..91d5fccce60 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -27,7 +27,7 @@ describe WikiPage, models: true do page_2 = wiki.find_page('dir_1/page_2') page_3 = wiki.find_page('dir_1/dir_2/page_3') expected_grouped_pages = { - '/' => [page_1], 'dir_1' => [page_2], 'dir_1/dir_2' => [page_3] + '/' => [page_1], '/dir_1' => [page_2], '/dir_1/dir_2' => [page_3] } grouped_pages = WikiPage.group_by_directory(wiki.pages) @@ -239,7 +239,7 @@ describe WikiPage, models: true do create_page('dir_1/dir_1_1/file', 'content') page = wiki.find_page('dir_1/dir_1_1/file') - expect(page.directory).to eq('dir_1/dir_1_1') + expect(page.directory).to eq('/dir_1/dir_1_1') end end end -- cgit v1.2.1 From 7f914ec73f9bdb3d2d4e51d48906a36186f496e3 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sun, 18 Dec 2016 22:30:07 -0200 Subject: Add tip about specifying the full path when creating new wiki pages --- app/assets/stylesheets/pages/wiki.scss | 8 ++++++++ app/views/projects/wikis/_new.html.haml | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index 7afadb7364d..6423c7d6302 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -1,3 +1,11 @@ +.new-wiki-page { + .new-wiki-page-slug-tip { + display: inline-block; + max-width: 100%; + margin-top: 5px; + } +} + .title .edit-wiki-header { width: 780px; margin-left: auto; diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml index c74f53b4c39..f9f8fc63288 100644 --- a/app/views/projects/wikis/_new.html.haml +++ b/app/views/projects/wikis/_new.html.haml @@ -13,5 +13,9 @@ = label_tag :new_wiki_path do %span Page slug = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => namespace_project_wikis_path(@project.namespace, @project), autofocus: true + %span.new-wiki-page-slug-tip + %i.fa.fa-lightbulb-o +  Tip: You can specify the full path for the new file. + We will automatically create any missing directories. .form-actions = button_tag 'Create Page', class: 'build-new-wiki btn btn-create' -- cgit v1.2.1 From f25344e36e9c1b0d0df2211b82b26c6515e96c31 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Mon, 19 Dec 2016 02:34:35 -0200 Subject: Change WikiPage.group_by_directory to order by directory and file alphabetical order --- app/models/wiki_page.rb | 29 ++++++++++++++++++++++++++++- spec/models/wiki_page_spec.rb | 30 ++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index a563b0b7a72..a84f84c67cd 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -12,10 +12,17 @@ class WikiPage ActiveModel::Name.new(self, nil, 'wiki') end + # Sorts and groups pages by directory. + # + # pages - an array of WikiPage objects. + # + # Returns a hash whose keys are directories and whose values are WikiPage + # arrays. See WikiPage.sort_by_directory for more info about the ordering. def self.group_by_directory(pages) return {} if pages.blank? - directories = { '/' => [] } + pages = sort_by_directory(pages) + directories = {} pages.each do |page| directories[page.directory] ||= [] directories[page.directory] << page @@ -199,6 +206,26 @@ class WikiPage private + # Sorts an array of pages by directory and file alphabetical order. + # Pages at the root directory will come first. The next pages will be + # sorted by their directories. Within directories, pages are sorted by + # filename alphabetical order. Pages are sorted in such a fashion that + # nested directories will always follow their parents (e.g. pages in + # dir_1/nested_dir_1 will follow pages inside dir_1). + # + # pages - an array of WikiPage objects. + # + # Returns a sorted array of WikiPage objects. + def self.sort_by_directory(pages) + pages.sort do |page, next_page| + if page.directory == next_page.directory + page.slug <=> next_page.slug + else + page.directory <=> next_page.directory + end + end + end + def set_attributes attributes[:slug] = @page.url_path attributes[:title] = @page.title diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 91d5fccce60..374849e1932 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -17,17 +17,22 @@ describe WikiPage, models: true do context 'when there are pages' do before do - create_page('page_1', 'content') + create_page('dir_1/dir_1_1/page_3', 'content') create_page('dir_1/page_2', 'content') - create_page('dir_1/dir_2/page_3', 'content') + create_page('dir_2/page_5', 'content') + create_page('dir_2/page_4', 'content') + create_page('page_1', 'content') end it 'returns a hash in which keys are directories and values are their pages' do page_1 = wiki.find_page('page_1') page_2 = wiki.find_page('dir_1/page_2') - page_3 = wiki.find_page('dir_1/dir_2/page_3') + page_3 = wiki.find_page('dir_1/dir_1_1/page_3') + page_4 = wiki.find_page('dir_2/page_4') + page_5 = wiki.find_page('dir_2/page_5') expected_grouped_pages = { - '/' => [page_1], '/dir_1' => [page_2], '/dir_1/dir_2' => [page_3] + '/' => [page_1], '/dir_1' => [page_2], '/dir_1/dir_1_1' => [page_3], + '/dir_2' => [page_4, page_5] } grouped_pages = WikiPage.group_by_directory(wiki.pages) @@ -39,6 +44,23 @@ describe WikiPage, models: true do expect(slugs).to match_array(expected_slugs) end end + + it 'returns a hash in which keys (directories) are sorted by alphabetical position' do + expected_ordered_directories = ['/', '/dir_1', '/dir_1/dir_1_1', '/dir_2'] + + grouped_pages = WikiPage.group_by_directory(wiki.pages) + + expect(grouped_pages.keys).to eq(expected_ordered_directories) + end + + it 'returns a hash in which values (pages) are sorted by alphabetical position' do + expected_ordered_page_slugs = ['dir_2/page_4', 'dir_2/page_5'] + + grouped_pages = WikiPage.group_by_directory(wiki.pages) + + dir_2_page_slugs = grouped_pages.fetch('/dir_2').map(&:slug) + expect(dir_2_page_slugs).to eq(expected_ordered_page_slugs) + end end end -- cgit v1.2.1 From e66fa4105b4ae275dc76a6594346367bd32b5ce9 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Mon, 19 Dec 2016 03:13:26 -0200 Subject: Improve style of wiki page lists --- app/assets/stylesheets/pages/wiki.scss | 16 ++++++++++++++++ app/views/projects/wikis/pages.html.haml | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index 6423c7d6302..819e4c3e3d8 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -130,6 +130,10 @@ margin: 5px 0 10px; } + ul.wiki-pages ul { + padding-left: 15px; + } + .wiki-sidebar-header { padding: 0 $gl-padding $gl-padding; @@ -138,3 +142,15 @@ } } } + +ul.wiki-pages-list.content-list { + & ul { + list-style: none; + margin-left: 0; + padding-left: 15px; + } + + & ul li { + padding: 5px 0; + } +} diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index 2813b3a1c81..28dd81e5c3f 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -13,7 +13,7 @@ = icon('cloud-download') Clone repository - %ul.content-list + %ul.wiki-pages-list.content-list - @wiki_directories.each do |wiki_directory, wiki_pages| - if wiki_directory == '/' = render 'wiki_pages', wiki_pages: wiki_pages -- cgit v1.2.1 From 50e3e796ea5ca12addbfb438feae606ca7067a22 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Tue, 20 Dec 2016 12:15:56 -0200 Subject: Fix scss style violation --- app/assets/stylesheets/pages/wiki.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index 819e4c3e3d8..1a22cd7d33f 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -22,7 +22,8 @@ font-size: 22px; } - .wiki-last-edit-by, .wiki-page-full-path { + .wiki-page-full-path, + .wiki-last-edit-by { display: block; color: $gl-gray-light; -- cgit v1.2.1 From 645aaf6e3d18007b56e5bbb33c6fda1526bdc716 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sun, 25 Dec 2016 22:13:20 -0200 Subject: Use the icon helper at wikis/_new.html.haml --- app/views/projects/wikis/_new.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml index f9f8fc63288..d91a7096701 100644 --- a/app/views/projects/wikis/_new.html.haml +++ b/app/views/projects/wikis/_new.html.haml @@ -14,8 +14,8 @@ %span Page slug = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => namespace_project_wikis_path(@project.namespace, @project), autofocus: true %span.new-wiki-page-slug-tip - %i.fa.fa-lightbulb-o -  Tip: You can specify the full path for the new file. + =icon('lightbulb-o') + Tip: You can specify the full path for the new file. We will automatically create any missing directories. .form-actions = button_tag 'Create Page', class: 'build-new-wiki btn btn-create' -- cgit v1.2.1 From 77fe503a1fd01eaa8b790d1aacc0cdab159f015e Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sun, 25 Dec 2016 22:50:36 -0200 Subject: Remove WikiPage.sort_by_directory --- app/models/wiki_page.rb | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index a84f84c67cd..efb6ff9bf2b 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -17,10 +17,10 @@ class WikiPage # pages - an array of WikiPage objects. # # Returns a hash whose keys are directories and whose values are WikiPage - # arrays. See WikiPage.sort_by_directory for more info about the ordering. + # arrays. def self.group_by_directory(pages) return {} if pages.blank? - pages = sort_by_directory(pages) + pages = pages.sort_by { |page| [page.directory, page.slug] } directories = {} pages.each do |page| @@ -206,26 +206,6 @@ class WikiPage private - # Sorts an array of pages by directory and file alphabetical order. - # Pages at the root directory will come first. The next pages will be - # sorted by their directories. Within directories, pages are sorted by - # filename alphabetical order. Pages are sorted in such a fashion that - # nested directories will always follow their parents (e.g. pages in - # dir_1/nested_dir_1 will follow pages inside dir_1). - # - # pages - an array of WikiPage objects. - # - # Returns a sorted array of WikiPage objects. - def self.sort_by_directory(pages) - pages.sort do |page, next_page| - if page.directory == next_page.directory - page.slug <=> next_page.slug - else - page.directory <=> next_page.directory - end - end - end - def set_attributes attributes[:slug] = @page.url_path attributes[:title] = @page.title -- cgit v1.2.1 From 8d8c5d9f61491c63e89d73a3f77244d3cd6406da Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sun, 25 Dec 2016 23:05:04 -0200 Subject: Simplify WikiPage.group_by_directory by using Enumerable#group_by --- app/models/wiki_page.rb | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index efb6ff9bf2b..0e905cb9a00 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -20,15 +20,8 @@ class WikiPage # arrays. def self.group_by_directory(pages) return {} if pages.blank? - pages = pages.sort_by { |page| [page.directory, page.slug] } - - directories = {} - pages.each do |page| - directories[page.directory] ||= [] - directories[page.directory] << page - end - - directories + pages.sort_by { |page| [page.directory, page.slug] }. + group_by { |page| page.directory } end def to_key -- cgit v1.2.1 From b361a67fb019e5c7f5361bbd3c43545da3ab0288 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Mon, 26 Dec 2016 13:07:40 -0200 Subject: Add model WikiDirectory --- app/models/wiki_directory.rb | 13 +++++++++++ spec/factories/wiki_directories.rb | 6 +++++ spec/models/wiki_directory_spec.rb | 45 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 app/models/wiki_directory.rb create mode 100644 spec/factories/wiki_directories.rb create mode 100644 spec/models/wiki_directory_spec.rb diff --git a/app/models/wiki_directory.rb b/app/models/wiki_directory.rb new file mode 100644 index 00000000000..c126a4d0421 --- /dev/null +++ b/app/models/wiki_directory.rb @@ -0,0 +1,13 @@ +class WikiDirectory + include ActiveModel::Validations + + attr_accessor :slug, :pages, :directories + + validates :slug, presence: true + + def initialize(slug, pages = [], directories = []) + @slug = slug + @pages = pages + @directories = directories + end +end diff --git a/spec/factories/wiki_directories.rb b/spec/factories/wiki_directories.rb new file mode 100644 index 00000000000..3f3c864ac2b --- /dev/null +++ b/spec/factories/wiki_directories.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :wiki_directory do + slug '/path_up_to/dir' + initialize_with { new(slug) } + end +end diff --git a/spec/models/wiki_directory_spec.rb b/spec/models/wiki_directory_spec.rb new file mode 100644 index 00000000000..8362a285c54 --- /dev/null +++ b/spec/models/wiki_directory_spec.rb @@ -0,0 +1,45 @@ +require 'spec_helper' + +RSpec.describe WikiDirectory, models: true do + describe 'validations' do + subject { build(:wiki_directory) } + + it { is_expected.to validate_presence_of(:slug) } + end + + describe '#initialize' do + context 'when there are pages and directories' do + let(:pages) { [build(:wiki_page)] } + let(:other_directories) { [build(:wiki_directory)] } + let(:directory) { WikiDirectory.new('/path_up_to/dir', pages, other_directories) } + + it 'sets the slug attribute' do + expect(directory.slug).to eq('/path_up_to/dir') + end + + it 'sets the pages attribute' do + expect(directory.pages).to eq(pages) + end + + it 'sets the directories attribute' do + expect(directory.directories).to eq(other_directories) + end + end + + context 'when there are no pages or directories' do + let(:directory) { WikiDirectory.new('/path_up_to/dir') } + + it 'sets the slug attribute' do + expect(directory.slug).to eq('/path_up_to/dir') + end + + it 'sets the pages attribute to an empty array' do + expect(directory.pages).to eq([]) + end + + it 'sets the directories attribute to an empty array' do + expect(directory.directories).to eq([]) + end + end + end +end -- cgit v1.2.1 From c8a1e9682656b6b3ec714e38459e089df2ee106c Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Mon, 26 Dec 2016 20:12:15 -0200 Subject: Change WikiPage.group_by_directory to use WikiDirectory --- app/models/wiki_page.rb | 18 ++++++++--- spec/models/wiki_page_spec.rb | 72 +++++++++++++++++++++++++------------------ 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 0e905cb9a00..63e5aa0e519 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -16,12 +16,22 @@ class WikiPage # # pages - an array of WikiPage objects. # - # Returns a hash whose keys are directories and whose values are WikiPage - # arrays. + # Returns an array of WikiPage and WikiDirectory objects. The entries are + # sorted by alphabetical order (directories and pages inside each directory). + # Pages at the root level come before everything. def self.group_by_directory(pages) - return {} if pages.blank? + return [] if pages.blank? + pages.sort_by { |page| [page.directory, page.slug] }. - group_by { |page| page.directory } + group_by { |page| page.directory }. + map do |dir, pages| + if dir == '/' + pages + else + WikiDirectory.new(dir, pages) + end + end. + flatten end def to_key diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 374849e1932..9eb94cb028d 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -9,9 +9,9 @@ describe WikiPage, models: true do describe '.group_by_directory' do context 'when there are no pages' do - it 'returns an empty hash' do - expect(WikiPage.group_by_directory(nil)).to eq({}) - expect(WikiPage.group_by_directory([])).to eq({}) + it 'returns an empty array' do + expect(WikiPage.group_by_directory(nil)).to eq([]) + expect(WikiPage.group_by_directory([])).to eq([]) end end @@ -23,43 +23,47 @@ describe WikiPage, models: true do create_page('dir_2/page_4', 'content') create_page('page_1', 'content') end + let(:page_1) { wiki.find_page('page_1') } + let(:dir_1) do + WikiDirectory.new('dir_1', [wiki.find_page('dir_1/page_2')]) + end + let(:dir_1_1) do + WikiDirectory.new('dir_1/dir_1_1', [wiki.find_page('dir_1/dir_1_1/page_3')]) + end + let(:dir_2) do + pages = [wiki.find_page('dir_2/page_5'), + wiki.find_page('dir_2/page_4')] + WikiDirectory.new('dir_2', pages) + end - it 'returns a hash in which keys are directories and values are their pages' do - page_1 = wiki.find_page('page_1') - page_2 = wiki.find_page('dir_1/page_2') - page_3 = wiki.find_page('dir_1/dir_1_1/page_3') - page_4 = wiki.find_page('dir_2/page_4') - page_5 = wiki.find_page('dir_2/page_5') - expected_grouped_pages = { - '/' => [page_1], '/dir_1' => [page_2], '/dir_1/dir_1_1' => [page_3], - '/dir_2' => [page_4, page_5] - } + it 'returns an array with pages and directories' do + expected_grouped_entries = [page_1, dir_1, dir_1_1, dir_2] - grouped_pages = WikiPage.group_by_directory(wiki.pages) + grouped_entries = WikiPage.group_by_directory(wiki.pages) - grouped_pages.each do |dir, pages| - expected_slugs = expected_grouped_pages.fetch(dir).map(&:slug) - slugs = pages.map(&:slug) + grouped_entries.each_with_index do |page_or_dir, i| + expected_page_or_dir = expected_grouped_entries[i] + expected_slugs = get_slugs(expected_page_or_dir) + slugs = get_slugs(page_or_dir) expect(slugs).to match_array(expected_slugs) end end - it 'returns a hash in which keys (directories) are sorted by alphabetical position' do - expected_ordered_directories = ['/', '/dir_1', '/dir_1/dir_1_1', '/dir_2'] - - grouped_pages = WikiPage.group_by_directory(wiki.pages) - - expect(grouped_pages.keys).to eq(expected_ordered_directories) - end - - it 'returns a hash in which values (pages) are sorted by alphabetical position' do - expected_ordered_page_slugs = ['dir_2/page_4', 'dir_2/page_5'] + it 'returns an array sorted by alphabetical position' do + # Directories and pages within directories are sorted alphabetically. + # Pages at root come before everything. + expected_order = ['page_1', 'dir_1/page_2', 'dir_1/dir_1_1/page_3', + 'dir_2/page_4', 'dir_2/page_5'] - grouped_pages = WikiPage.group_by_directory(wiki.pages) + grouped_entries = WikiPage.group_by_directory(wiki.pages) - dir_2_page_slugs = grouped_pages.fetch('/dir_2').map(&:slug) - expect(dir_2_page_slugs).to eq(expected_ordered_page_slugs) + actual_order = + grouped_entries.map do |page_or_dir| + get_slugs(page_or_dir) + end. + flatten + expect(actual_order).to eq(expected_order) end end end @@ -336,4 +340,12 @@ describe WikiPage, models: true do page = wiki.wiki.paged(title) wiki.wiki.delete_page(page, commit_details) end + + def get_slugs(page_or_dir) + if page_or_dir.is_a? WikiPage + [page_or_dir.slug] + else + page_or_dir.pages.present? ? page_or_dir.pages.map(&:slug) : [] + end + end end -- cgit v1.2.1 From 84735186a8ae73a722715f286653ccd71e7e48e8 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Mon, 26 Dec 2016 23:51:34 -0200 Subject: Add WikiPage#to_partial_path --- app/models/wiki_page.rb | 6 ++++++ spec/models/wiki_page_spec.rb | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 63e5aa0e519..96d03d510ff 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -207,6 +207,12 @@ class WikiPage end end + # Relative path to the partial to be used when rendering collections + # of this object. + def to_partial_path + 'projects/wikis/wiki_page' + end + private def set_attributes diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 9eb94cb028d..11efd0415d9 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -322,6 +322,14 @@ describe WikiPage, models: true do end end + describe '#to_partial_path' do + it 'returns the relative path to the partial to be used' do + page = build(:wiki_page) + + expect(page.to_partial_path).to eq('projects/wikis/wiki_page') + end + end + private def remove_temp_repo(path) -- cgit v1.2.1 From 7bd68ae0799a982a4113de3480bef0d51ecb2f1c Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Mon, 26 Dec 2016 23:52:26 -0200 Subject: Add WikiDirectory#to_partial_path --- app/models/wiki_directory.rb | 6 ++++++ spec/models/wiki_directory_spec.rb | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/app/models/wiki_directory.rb b/app/models/wiki_directory.rb index c126a4d0421..561e5a497bc 100644 --- a/app/models/wiki_directory.rb +++ b/app/models/wiki_directory.rb @@ -10,4 +10,10 @@ class WikiDirectory @pages = pages @directories = directories end + + # Relative path to the partial to be used when rendering collections + # of this object. + def to_partial_path + 'projects/wikis/wiki_directory' + end end diff --git a/spec/models/wiki_directory_spec.rb b/spec/models/wiki_directory_spec.rb index 8362a285c54..fac70f8d3c7 100644 --- a/spec/models/wiki_directory_spec.rb +++ b/spec/models/wiki_directory_spec.rb @@ -42,4 +42,12 @@ RSpec.describe WikiDirectory, models: true do end end end + + describe '#to_partial_path' do + it 'returns the relative path to the partial to be used' do + directory = build(:wiki_directory) + + expect(directory.to_partial_path).to eq('projects/wikis/wiki_directory') + end + end end -- cgit v1.2.1 From a5625c749b31760daf104241475a9b3527eb223c Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Mon, 26 Dec 2016 23:54:36 -0200 Subject: Render wiki entries using a collection of WikiPage and WikiDirectory objects --- app/controllers/projects/wikis_controller.rb | 4 ++-- app/views/projects/wikis/_sidebar.html.haml | 10 +--------- app/views/projects/wikis/_sidebar_wiki_pages.html.haml | 4 ---- app/views/projects/wikis/_wiki_directory.html.haml | 4 ++++ app/views/projects/wikis/_wiki_page.html.haml | 10 ++++++++++ app/views/projects/wikis/_wiki_pages.html.haml | 6 ------ app/views/projects/wikis/pages.html.haml | 9 +-------- 7 files changed, 18 insertions(+), 29 deletions(-) delete mode 100644 app/views/projects/wikis/_sidebar_wiki_pages.html.haml create mode 100644 app/views/projects/wikis/_wiki_directory.html.haml create mode 100644 app/views/projects/wikis/_wiki_page.html.haml delete mode 100644 app/views/projects/wikis/_wiki_pages.html.haml diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index 45a42400b2a..116c854b1ae 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -8,7 +8,7 @@ class Projects::WikisController < Projects::ApplicationController def pages @wiki_pages = Kaminari.paginate_array(@project_wiki.pages).page(params[:page]) - @wiki_directories = WikiPage.group_by_directory(@wiki_pages) + @wiki_entries = WikiPage.group_by_directory(@wiki_pages) end def show @@ -117,7 +117,7 @@ class Projects::WikisController < Projects::ApplicationController # Call #wiki to make sure the Wiki Repo is initialized @project_wiki.wiki - @sidebar_wiki_directories = WikiPage.group_by_directory(@project_wiki.pages.first(15)) + @sidebar_wiki_entries = WikiPage.group_by_directory(@project_wiki.pages.first(15)) rescue ProjectWiki::CouldNotCreateWikiError flash[:notice] = "Could not create Wiki Repository at this time. Please try again later." redirect_to project_path(@project) diff --git a/app/views/projects/wikis/_sidebar.html.haml b/app/views/projects/wikis/_sidebar.html.haml index b7464180a0c..e3fddfba689 100644 --- a/app/views/projects/wikis/_sidebar.html.haml +++ b/app/views/projects/wikis/_sidebar.html.haml @@ -12,15 +12,7 @@ .blocks-container .block.block-first %ul.wiki-pages - - @sidebar_wiki_directories.each do |wiki_directory, wiki_pages| - - if wiki_directory == '/' - = render 'sidebar_wiki_pages', wiki_pages: wiki_pages - - else - %li - = wiki_directory - %ul - = render 'sidebar_wiki_pages', wiki_pages: wiki_pages - + = render @sidebar_wiki_entries, context: 'sidebar' .block = link_to namespace_project_wikis_pages_path(@project.namespace, @project), class: 'btn btn-block' do diff --git a/app/views/projects/wikis/_sidebar_wiki_pages.html.haml b/app/views/projects/wikis/_sidebar_wiki_pages.html.haml deleted file mode 100644 index 65453a384d2..00000000000 --- a/app/views/projects/wikis/_sidebar_wiki_pages.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- wiki_pages.each do |wiki_page| - %li{ class: params[:id] == wiki_page.slug ? 'active' : '' } - = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_page) do - = wiki_page.title.capitalize diff --git a/app/views/projects/wikis/_wiki_directory.html.haml b/app/views/projects/wikis/_wiki_directory.html.haml new file mode 100644 index 00000000000..0e5f32ed859 --- /dev/null +++ b/app/views/projects/wikis/_wiki_directory.html.haml @@ -0,0 +1,4 @@ +%li + = wiki_directory.slug + %ul + = render wiki_directory.pages, context: context diff --git a/app/views/projects/wikis/_wiki_page.html.haml b/app/views/projects/wikis/_wiki_page.html.haml new file mode 100644 index 00000000000..cea27388a0d --- /dev/null +++ b/app/views/projects/wikis/_wiki_page.html.haml @@ -0,0 +1,10 @@ +- if context == 'sidebar' + %li{ class: params[:id] == wiki_page.slug ? 'active' : '' } + = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_page) do + = wiki_page.title.capitalize +- else + %li + = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) + %small (#{wiki_page.format}) + .pull-right + %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} diff --git a/app/views/projects/wikis/_wiki_pages.html.haml b/app/views/projects/wikis/_wiki_pages.html.haml deleted file mode 100644 index ac98599d96b..00000000000 --- a/app/views/projects/wikis/_wiki_pages.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -- wiki_pages.each do |wiki_page| - %li - = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) - %small (#{wiki_page.format}) - .pull-right - %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index 28dd81e5c3f..5fba2b1a5ae 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -14,13 +14,6 @@ Clone repository %ul.wiki-pages-list.content-list - - @wiki_directories.each do |wiki_directory, wiki_pages| - - if wiki_directory == '/' - = render 'wiki_pages', wiki_pages: wiki_pages - - else - %li - = wiki_directory - %ul - = render 'wiki_pages', wiki_pages: wiki_pages + = render @wiki_entries, context: 'pages' = paginate @wiki_pages, theme: 'gitlab' -- cgit v1.2.1 From 84cc7c3704cc0cc22a325572f35cd21d0e2a6cc7 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Tue, 27 Dec 2016 00:14:30 -0200 Subject: Stop rendering page full path at projects/wikis/show.html.haml --- app/assets/stylesheets/pages/wiki.scss | 1 - app/views/projects/wikis/show.html.haml | 1 - 2 files changed, 2 deletions(-) diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index 1a22cd7d33f..369fb44d818 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -22,7 +22,6 @@ font-size: 22px; } - .wiki-page-full-path, .wiki-last-edit-by { display: block; color: $gl-gray-light; diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 25ae5c587ec..87b9ff6e415 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -8,7 +8,6 @@ .nav-text %h2.wiki-page-title= @page.title.capitalize - %span.wiki-page-full-path= "(#{@page.full_path})" %span.wiki-last-edit-by Last edited by %strong -- cgit v1.2.1 From 94dcadd62ac66cc5c52579ae9c288314bbca0c20 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Tue, 27 Dec 2016 01:44:03 -0200 Subject: Add a breadcrumb at projects/wikis/show.html.haml --- app/assets/stylesheets/pages/wiki.scss | 5 +++++ app/helpers/wiki_helper.rb | 13 +++++++++++++ app/views/projects/wikis/show.html.haml | 3 +++ spec/helpers/wiki_helper_spec.rb | 21 +++++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 app/helpers/wiki_helper.rb create mode 100644 spec/helpers/wiki_helper_spec.rb diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index 369fb44d818..480cb2b9f0d 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -17,6 +17,11 @@ @extend .top-area; position: relative; + .wiki-breadcrumb { + border-bottom: 1px solid $white-normal; + padding: 11px 0; + } + .wiki-page-title { margin: 0; font-size: 22px; diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb new file mode 100644 index 00000000000..76ee632ab6d --- /dev/null +++ b/app/helpers/wiki_helper.rb @@ -0,0 +1,13 @@ +module WikiHelper + # Produces a pure text breadcrumb for a given page. + # + # page_slug - The slug of a WikiPage object. + # + # Returns a String composed of the capitalized name of each directory and the + # capitalized name of the page itself. + def breadcrumb(page_slug) + page_slug.split('/'). + map { |dir_or_page| dir_or_page.gsub(/-+/, ' ').capitalize }. + join(' / ') + end +end diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 87b9ff6e415..3609461b721 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -6,6 +6,9 @@ %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" } = icon('angle-double-left') + .wiki-breadcrumb + %span= breadcrumb(@page.slug) + .nav-text %h2.wiki-page-title= @page.title.capitalize %span.wiki-last-edit-by diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb new file mode 100644 index 00000000000..92c6f27a867 --- /dev/null +++ b/spec/helpers/wiki_helper_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe WikiHelper do + describe '#breadcrumb' do + context 'when the page is at the root level' do + it 'returns the capitalized page name' do + slug = 'page-name' + + expect(helper.breadcrumb(slug)).to eq('Page name') + end + end + + context 'when the page is inside a directory' do + it 'returns the capitalized name of each directory and of the page itself' do + slug = 'dir_1/page-name' + + expect(helper.breadcrumb(slug)).to eq('Dir_1 / Page name') + end + end + end +end -- cgit v1.2.1 From 104bfa2a3187aefebd4a53be1ad14600dc7781e9 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Tue, 27 Dec 2016 01:52:50 -0200 Subject: Remove WikiPage#full_path --- app/models/wiki_page.rb | 5 ----- spec/models/wiki_page_spec.rb | 20 -------------------- 2 files changed, 25 deletions(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 96d03d510ff..dec58681198 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -114,11 +114,6 @@ class WikiPage @attributes[:format] || :markdown end - # The full path for this page, including its filename and extension. - def full_path - "#{directory}/#{page.filename}".gsub(/\/+/, '/') - end - # The commit message for this page version. def message version.try(:message) diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 11efd0415d9..482f98e22f1 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -270,26 +270,6 @@ describe WikiPage, models: true do end end - describe '#full_path' do - context 'when the page is at the root directory' do - it 'returns /filename.fileextension' do - create_page('file', 'content') - page = wiki.find_page('file') - - expect(page.full_path).to eq('/file.md') - end - end - - context 'when the page is inside an actual directory' do - it 'returns /directory/filename.fileextension' do - create_page('dir/file', 'content') - page = wiki.find_page('dir/file') - - expect(page.full_path).to eq('/dir/file.md') - end - end - end - describe '#historical?' do before do create_page('Update', 'content') -- cgit v1.2.1 From d2b3fe45af8d458b935b3bbfc1558e21c1476d0a Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Tue, 27 Dec 2016 02:05:53 -0200 Subject: Change WikiPage#directory --- app/models/wiki_page.rb | 9 ++++----- spec/models/wiki_page_spec.rb | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index dec58681198..6c237306eff 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -25,10 +25,10 @@ class WikiPage pages.sort_by { |page| [page.directory, page.slug] }. group_by { |page| page.directory }. map do |dir, pages| - if dir == '/' - pages - else + if dir.present? WikiDirectory.new(dir, pages) + else + pages end end. flatten @@ -98,8 +98,7 @@ class WikiPage # The hierarchy of the directory this page is contained in. def directory - dir = wiki.page_title_and_dir(slug).last - "/#{dir}" + wiki.page_title_and_dir(slug).last end # The processed/formatted content of this page. diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 482f98e22f1..109a0499090 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -252,11 +252,11 @@ describe WikiPage, models: true do describe '#directory' do context 'when the page is at the root directory' do - it 'returns /' do + it 'returns an empty string' do create_page('file', 'content') page = wiki.find_page('file') - expect(page.directory).to eq('/') + expect(page.directory).to eq('') end end @@ -265,7 +265,7 @@ describe WikiPage, models: true do create_page('dir_1/dir_1_1/file', 'content') page = wiki.find_page('dir_1/dir_1_1/file') - expect(page.directory).to eq('/dir_1/dir_1_1') + expect(page.directory).to eq('dir_1/dir_1_1') end end end -- cgit v1.2.1 From 389bd6b7356e78668831e4628f9ca8dadb01fcf2 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sat, 31 Dec 2016 17:03:20 -0200 Subject: Improve WikiPage.group_by_directory --- app/models/wiki_page.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 6c237306eff..20bd9719b2f 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -23,7 +23,7 @@ class WikiPage return [] if pages.blank? pages.sort_by { |page| [page.directory, page.slug] }. - group_by { |page| page.directory }. + group_by(&:directory). map do |dir, pages| if dir.present? WikiDirectory.new(dir, pages) -- cgit v1.2.1 From b0ad4e0e87c642efefa840eeeea5824191e81405 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sat, 31 Dec 2016 17:14:45 -0200 Subject: Add new wiki related partials --- app/views/projects/wikis/_pages_wiki_page.html.haml | 5 +++++ app/views/projects/wikis/_sidebar_wiki_page.html.haml | 3 +++ app/views/projects/wikis/_wiki_page.html.haml | 11 +---------- 3 files changed, 9 insertions(+), 10 deletions(-) create mode 100644 app/views/projects/wikis/_pages_wiki_page.html.haml create mode 100644 app/views/projects/wikis/_sidebar_wiki_page.html.haml diff --git a/app/views/projects/wikis/_pages_wiki_page.html.haml b/app/views/projects/wikis/_pages_wiki_page.html.haml new file mode 100644 index 00000000000..6298cf6c8da --- /dev/null +++ b/app/views/projects/wikis/_pages_wiki_page.html.haml @@ -0,0 +1,5 @@ +%li + = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) + %small (#{wiki_page.format}) + .pull-right + %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} diff --git a/app/views/projects/wikis/_sidebar_wiki_page.html.haml b/app/views/projects/wikis/_sidebar_wiki_page.html.haml new file mode 100644 index 00000000000..eb9bd14920d --- /dev/null +++ b/app/views/projects/wikis/_sidebar_wiki_page.html.haml @@ -0,0 +1,3 @@ +%li{ class: params[:id] == wiki_page.slug ? 'active' : '' } + = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_page) do + = wiki_page.title.capitalize diff --git a/app/views/projects/wikis/_wiki_page.html.haml b/app/views/projects/wikis/_wiki_page.html.haml index cea27388a0d..c84d06dad02 100644 --- a/app/views/projects/wikis/_wiki_page.html.haml +++ b/app/views/projects/wikis/_wiki_page.html.haml @@ -1,10 +1 @@ -- if context == 'sidebar' - %li{ class: params[:id] == wiki_page.slug ? 'active' : '' } - = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_page) do - = wiki_page.title.capitalize -- else - %li - = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) - %small (#{wiki_page.format}) - .pull-right - %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} += render "#{context}_wiki_page", wiki_page: wiki_page -- cgit v1.2.1 From 48417893d7456dc0d46b0a514a2326cc8ce6076f Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Sat, 31 Dec 2016 17:27:03 -0200 Subject: Remove directories as one of the attributes of WikiDirectory --- app/models/wiki_directory.rb | 5 ++--- spec/models/wiki_directory_spec.rb | 15 +++------------ 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/app/models/wiki_directory.rb b/app/models/wiki_directory.rb index 561e5a497bc..9340fc2dbbe 100644 --- a/app/models/wiki_directory.rb +++ b/app/models/wiki_directory.rb @@ -1,14 +1,13 @@ class WikiDirectory include ActiveModel::Validations - attr_accessor :slug, :pages, :directories + attr_accessor :slug, :pages validates :slug, presence: true - def initialize(slug, pages = [], directories = []) + def initialize(slug, pages = []) @slug = slug @pages = pages - @directories = directories end # Relative path to the partial to be used when rendering collections diff --git a/spec/models/wiki_directory_spec.rb b/spec/models/wiki_directory_spec.rb index fac70f8d3c7..1caaa557085 100644 --- a/spec/models/wiki_directory_spec.rb +++ b/spec/models/wiki_directory_spec.rb @@ -8,10 +8,9 @@ RSpec.describe WikiDirectory, models: true do end describe '#initialize' do - context 'when there are pages and directories' do + context 'when there are pages' do let(:pages) { [build(:wiki_page)] } - let(:other_directories) { [build(:wiki_directory)] } - let(:directory) { WikiDirectory.new('/path_up_to/dir', pages, other_directories) } + let(:directory) { WikiDirectory.new('/path_up_to/dir', pages) } it 'sets the slug attribute' do expect(directory.slug).to eq('/path_up_to/dir') @@ -20,13 +19,9 @@ RSpec.describe WikiDirectory, models: true do it 'sets the pages attribute' do expect(directory.pages).to eq(pages) end - - it 'sets the directories attribute' do - expect(directory.directories).to eq(other_directories) - end end - context 'when there are no pages or directories' do + context 'when there are no pages' do let(:directory) { WikiDirectory.new('/path_up_to/dir') } it 'sets the slug attribute' do @@ -36,10 +31,6 @@ RSpec.describe WikiDirectory, models: true do it 'sets the pages attribute to an empty array' do expect(directory.pages).to eq([]) end - - it 'sets the directories attribute to an empty array' do - expect(directory.directories).to eq([]) - end end end -- cgit v1.2.1 From 683097666aa01ef6a5b490be67a4a0d9733152e3 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Mon, 30 Jan 2017 01:07:31 -0200 Subject: Add WikiPage.unhyphenize --- app/helpers/wiki_helper.rb | 2 +- app/models/wiki_page.rb | 6 +++++- spec/models/wiki_page_spec.rb | 8 ++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb index 76ee632ab6d..3e3f6246fc5 100644 --- a/app/helpers/wiki_helper.rb +++ b/app/helpers/wiki_helper.rb @@ -7,7 +7,7 @@ module WikiHelper # capitalized name of the page itself. def breadcrumb(page_slug) page_slug.split('/'). - map { |dir_or_page| dir_or_page.gsub(/-+/, ' ').capitalize }. + map { |dir_or_page| WikiPage.unhyphenize(dir_or_page).capitalize }. join(' / ') end end diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 20bd9719b2f..2f4f92846b4 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -34,6 +34,10 @@ class WikiPage flatten end + def self.unhyphenize(name) + name.gsub(/-+/, ' ') + end + def to_key [:slug] end @@ -78,7 +82,7 @@ class WikiPage # The formatted title of this page. def title if @attributes[:title] - @attributes[:title].gsub(/-+/, ' ') + self.class.unhyphenize(@attributes[:title]) else "" end diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 109a0499090..579ebac7afb 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -68,6 +68,14 @@ describe WikiPage, models: true do end end + describe '.unhyphenize' do + it 'removes hyphens from a name' do + name = 'a-name--with-hyphens' + + expect(WikiPage.unhyphenize(name)).to eq('a name with hyphens') + end + end + describe "#initialize" do context "when initialized with an existing gollum page" do before do -- cgit v1.2.1 From 89347fb688820667ce55089daa600277796871a5 Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Mon, 30 Jan 2017 01:08:36 -0200 Subject: Add merge request number --- changelogs/unreleased/23535-folders-in-wiki-repository.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/unreleased/23535-folders-in-wiki-repository.yml b/changelogs/unreleased/23535-folders-in-wiki-repository.yml index 7361b182a94..05212b608d4 100644 --- a/changelogs/unreleased/23535-folders-in-wiki-repository.yml +++ b/changelogs/unreleased/23535-folders-in-wiki-repository.yml @@ -1,4 +1,4 @@ --- title: Show directory hierarchy when listing wiki pages -merge_request: +merge_request: 8133 author: Alex Braha Stoll -- cgit v1.2.1 From fe5a753be903344a6cc1dc8f1e023b62887e920b Mon Sep 17 00:00:00 2001 From: Alex Braha Stoll Date: Mon, 13 Feb 2017 02:23:54 -0200 Subject: Fix haml-lint violation --- app/views/projects/wikis/_new.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml index d91a7096701..3d33679f07d 100644 --- a/app/views/projects/wikis/_new.html.haml +++ b/app/views/projects/wikis/_new.html.haml @@ -14,7 +14,7 @@ %span Page slug = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => namespace_project_wikis_path(@project.namespace, @project), autofocus: true %span.new-wiki-page-slug-tip - =icon('lightbulb-o') + = icon('lightbulb-o') Tip: You can specify the full path for the new file. We will automatically create any missing directories. .form-actions -- cgit v1.2.1