documentation 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/images/documentation/link.svg +28 -0
- data/app/assets/images/documentation/logo-black.svg +23 -0
- data/app/assets/images/documentation/logo-white.svg +23 -0
- data/app/assets/images/documentation/page.svg +16 -0
- data/app/assets/images/documentation/pin.svg +15 -0
- data/app/assets/images/documentation/recommendation.svg +11 -0
- data/app/assets/images/documentation/search.svg +10 -0
- data/app/assets/images/documentation/unhappy.svg +15 -0
- data/app/assets/images/documentation/warning.svg +16 -0
- data/app/assets/javascripts/documentation/application.coffee +14 -0
- data/app/assets/javascripts/documentation/jquery-ui.js +4146 -0
- data/app/assets/javascripts/documentation/jquery.autosize.js +263 -0
- data/app/assets/stylesheets/documentation/application.scss +320 -0
- data/app/assets/stylesheets/documentation/markdown.scss +168 -0
- data/app/assets/stylesheets/documentation/page_form.scss +38 -0
- data/app/assets/stylesheets/documentation/reset.scss +101 -0
- data/app/controllers/documentation/application_controller.rb +21 -0
- data/app/controllers/documentation/pages_controller.rb +74 -0
- data/app/helpers/documentation/application_helper.rb +13 -0
- data/app/models/documentation/page.rb +213 -0
- data/app/views/documentation/pages/_admin_buttons.html.haml +18 -0
- data/app/views/documentation/pages/form.html.haml +12 -0
- data/app/views/documentation/pages/index.html.haml +13 -0
- data/app/views/documentation/pages/positioning.html.haml +22 -0
- data/app/views/documentation/pages/search.html.haml +26 -0
- data/app/views/documentation/pages/show.html.haml +14 -0
- data/app/views/documentation/shared/access_denied.html.haml +10 -0
- data/app/views/documentation/shared/not_found.html.haml +10 -0
- data/app/views/layouts/documentation/_header.html.haml +3 -0
- data/app/views/layouts/documentation/_search.html.haml +5 -0
- data/app/views/layouts/documentation/application.html.haml +18 -0
- data/config/locales/en.yml +56 -0
- data/config/routes.rb +10 -0
- data/db/migrate/20140711185212_create_documentation_pages.rb +10 -0
- data/db/seeds.rb +15 -0
- data/lib/documentation.rb +16 -0
- data/lib/documentation/authorizer.rb +52 -0
- data/lib/documentation/config.rb +31 -0
- data/lib/documentation/engine.rb +29 -0
- data/lib/documentation/errors.rb +7 -0
- data/lib/documentation/generators/setup_generator.rb +13 -0
- data/lib/documentation/markdown_renderer.rb +62 -0
- data/lib/documentation/search_result.rb +84 -0
- data/lib/documentation/searchers/abstract.rb +47 -0
- data/lib/documentation/searchers/simple.rb +40 -0
- data/lib/documentation/version.rb +1 -1
- data/lib/documentation/view_helpers.rb +113 -0
- data/lib/tasks/documentation.rake +6 -0
- metadata +219 -3
@@ -0,0 +1,18 @@
|
|
1
|
+
- canAdd = authorizer.can_add_page?(@page)
|
2
|
+
- canEdit = authorizer.can_edit_page?(@page)
|
3
|
+
- canReposition = authorizer.can_reposition_page?(@page)
|
4
|
+
- canDelete = authorizer.can_delete_page?(@page)
|
5
|
+
|
6
|
+
- if canAdd || canEdit || canReposition || canDelete
|
7
|
+
%p.adminButtons
|
8
|
+
- if canAdd
|
9
|
+
= link_to t('.new'), new_page_path(@page.full_permalink), :class => 'button new'
|
10
|
+
|
11
|
+
- if canEdit
|
12
|
+
= link_to t('.edit'), edit_page_path(@page.full_permalink), :class => 'button edit'
|
13
|
+
|
14
|
+
- if canReposition
|
15
|
+
= link_to t('.reorder'), page_positioning_path(@page.parents[-1].try(:full_permalink)), :class => 'button edit'
|
16
|
+
|
17
|
+
- if canDelete
|
18
|
+
= link_to t('.delete'), delete_page_path(@page.full_permalink), :class => 'button delete', :method => :delete, :data => {:confirm => "Are you sure you wish to remove this page?"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
- @page_title = @page.breadcrumb.reverse.map(&:title).join(" - ")
|
2
|
+
|
3
|
+
%section.content
|
4
|
+
= documentation_breadcrumb_for @page
|
5
|
+
= form_for @page, :url => @page.new_record? ? new_page_path(@page.parent ? @page.parent.full_permalink : nil) : edit_page_path(@page.full_permalink), :html => {:class => 'pageForm'} do |f|
|
6
|
+
= error_messages_for @page
|
7
|
+
%p.title= f.text_field :title, :placeholder => t('.title_placeholder')
|
8
|
+
%p.content= f.text_area :content, :placeholder => t('.content_placeholder')
|
9
|
+
%dl
|
10
|
+
%dt= f.label :permalink
|
11
|
+
%dd= f.text_field :permalink, :placeholder => t('.permalink_placeholder')
|
12
|
+
%p.submit= f.submit t('.save'), :class => 'button'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
%section.welcome
|
2
|
+
%h1= t('.welcome_title')
|
3
|
+
%h2= t('.welcome_text')
|
4
|
+
|
5
|
+
- if Documentation.config.developer_tips
|
6
|
+
.override
|
7
|
+
%p= t('.developer_tip').html_safe
|
8
|
+
|
9
|
+
%p.new
|
10
|
+
- if authorizer.can_add_page?(nil)
|
11
|
+
= link_to t('.create_root_page'), new_page_path, :class => 'button new'
|
12
|
+
- if authorizer.can_reposition_page?(nil)
|
13
|
+
= link_to t('.reorder_root_pages'), page_positioning_path, :class => 'button'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
- if @page
|
2
|
+
- @page_title = @page.breadcrumb.reverse.map(&:title).join(" - ")
|
3
|
+
= documentation_breadcrumb_for @page
|
4
|
+
- else
|
5
|
+
- @page_title = t('.reorder_root_pages_title')
|
6
|
+
= documentation_breadcrumb_for nil
|
7
|
+
|
8
|
+
%section.page
|
9
|
+
%h1= @page ? @page.title : t('.reorder_root_pages_title')
|
10
|
+
|
11
|
+
= form_tag page_positioning_path(@page.try(:full_permalink)), :class => 'reordering' do
|
12
|
+
%ul
|
13
|
+
- for child in @pages
|
14
|
+
%li
|
15
|
+
= child.title
|
16
|
+
= hidden_field_tag 'order[]', child.id
|
17
|
+
|
18
|
+
%p.adminButtons
|
19
|
+
- if @page
|
20
|
+
= link_to t('.back_to_page'), page_path(@page.full_permalink), :class => 'button edit'
|
21
|
+
- else
|
22
|
+
= link_to t('.back_to_homepage'), root_path, :class => 'button edit'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
- @page_title = t('.title', :query => params[:query])
|
2
|
+
|
3
|
+
%section.page
|
4
|
+
|
5
|
+
- if @result.empty?
|
6
|
+
%p.noSearchResults= t('.no_results', :query => params[:query])
|
7
|
+
- else
|
8
|
+
%h1= t('.title', :query => params[:query])
|
9
|
+
%p.searchSummary= t('.summary', :total_results => @result.total_results, :start_result => @result.start_result_number, :end_result => @result.end_result_number)
|
10
|
+
|
11
|
+
%ul.searchResults
|
12
|
+
- for page in @result.results
|
13
|
+
%li
|
14
|
+
%h4= link_to page.title, page_path(page.full_permalink)
|
15
|
+
- unless page.parents.empty?
|
16
|
+
%p.in
|
17
|
+
= t('.in')
|
18
|
+
= page.parents.map { |c| link_to(h(c.title), page_path(c.full_permalink))}.join(" ⇒ ").html_safe
|
19
|
+
%p.excerpt= @result.excerpt_for(page)
|
20
|
+
|
21
|
+
|
22
|
+
%p.pagination
|
23
|
+
- unless @result.first_page?
|
24
|
+
= link_to t('.previous_page'), search_path(:query => params[:query], :page => @result.page - 1), :class => 'button'
|
25
|
+
- unless @result.last_page?
|
26
|
+
= link_to t('.next_page'), search_path(:query => params[:query], :page => @result.page + 1), :class => 'button'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
- @page_title = @page.breadcrumb.reverse.map(&:title).join(" - ")
|
2
|
+
|
3
|
+
= documentation_breadcrumb_for @page
|
4
|
+
|
5
|
+
%section.page
|
6
|
+
- if @page.preview_path
|
7
|
+
%p.previewLink= link_to t('.view_in_website'), @page.preview_path, :class => 'button preview'
|
8
|
+
|
9
|
+
%h1= @page.title
|
10
|
+
%p.updated= t('.last_updated', :timestamp => @page.updated_at.to_s(:long))
|
11
|
+
.documentationMarkdown
|
12
|
+
~ preserve(documentation_content_for(@page))
|
13
|
+
|
14
|
+
= render 'admin_buttons'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
!!!
|
2
|
+
%html.errorPage
|
3
|
+
%head
|
4
|
+
%title= @page_title
|
5
|
+
= stylesheet_link_tag 'documentation/application'
|
6
|
+
= csrf_meta_tags
|
7
|
+
%body
|
8
|
+
%section.errorMessage
|
9
|
+
%h2 Access Denied
|
10
|
+
%p You are not permitted to view this page. If you believe you have received this message in error, please contact the site admin.
|
@@ -0,0 +1,10 @@
|
|
1
|
+
!!!
|
2
|
+
%html.errorPage
|
3
|
+
%head
|
4
|
+
%title= @page_title
|
5
|
+
= stylesheet_link_tag 'documentation/application'
|
6
|
+
= csrf_meta_tags
|
7
|
+
%body
|
8
|
+
%section.errorMessage
|
9
|
+
%h2 Page Not Found
|
10
|
+
%p No page was found at the path you have entered. Please ensure you have entered the correct URL otherwise contact the site admin.
|
@@ -0,0 +1,18 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title #{@page_title} - #{t('.title')}
|
5
|
+
= stylesheet_link_tag 'documentation/application'
|
6
|
+
= javascript_include_tag 'documentation/application'
|
7
|
+
= csrf_meta_tags
|
8
|
+
%body
|
9
|
+
= render 'layouts/documentation/header'
|
10
|
+
%nav.pages
|
11
|
+
.inner
|
12
|
+
= render 'layouts/documentation/search'
|
13
|
+
= documentation_navigation_tree_for(@page)
|
14
|
+
%section.content
|
15
|
+
.inner
|
16
|
+
= flash_messages
|
17
|
+
= yield
|
18
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
en:
|
2
|
+
layouts:
|
3
|
+
documentation:
|
4
|
+
application:
|
5
|
+
title: Documentation
|
6
|
+
header:
|
7
|
+
title: Documentation
|
8
|
+
back_to_site: Back to site
|
9
|
+
search:
|
10
|
+
query_placeholder: Search Documentation...
|
11
|
+
|
12
|
+
documentation:
|
13
|
+
|
14
|
+
helpers:
|
15
|
+
documentation_breadcrumb_for:
|
16
|
+
default_root_link: Home
|
17
|
+
|
18
|
+
pages:
|
19
|
+
index:
|
20
|
+
welcome_title: Welcome to Documentation
|
21
|
+
welcome_text: Choose a page from the menu on the left of the screen to begin.
|
22
|
+
developer_tip:
|
23
|
+
You can override this page by adding a new view in <code>app/views/documentation/pages/index</code>.
|
24
|
+
Alternatively, you can disable this message by setting <code>developer_tips</code> to false in the
|
25
|
+
Documentation configuration.
|
26
|
+
create_root_page: Create new root page
|
27
|
+
reorder_root_pages: Re-order root pages
|
28
|
+
|
29
|
+
show:
|
30
|
+
view_in_website: View in website
|
31
|
+
last_updated: Last updated on %{timestamp}
|
32
|
+
|
33
|
+
admin_buttons:
|
34
|
+
new: New page
|
35
|
+
edit: Edit page
|
36
|
+
reorder: Re-order children
|
37
|
+
delete: Delete page
|
38
|
+
|
39
|
+
form:
|
40
|
+
title_placeholder: Enter a title for this page
|
41
|
+
content_placeholder: 'Use Markdown to enter page content'
|
42
|
+
permalink_placeholder: Automatically generated if left blank
|
43
|
+
save: Save Page
|
44
|
+
|
45
|
+
positioning:
|
46
|
+
reorder_root_pages_title: Re-order root pages
|
47
|
+
back_to_page: Back to page
|
48
|
+
back_to_homepage: Back to homepage
|
49
|
+
|
50
|
+
search:
|
51
|
+
title: "Search results for '%{query}'"
|
52
|
+
no_results: "No pages were found matching '%{query}'"
|
53
|
+
summary: "Found %{total_results} pages matching your query. Showing results %{start_result} to %{end_result}"
|
54
|
+
in: in
|
55
|
+
next_page: Next page
|
56
|
+
previous_page: Previous page
|
data/config/routes.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Documentation::Engine.routes.draw do
|
2
|
+
|
3
|
+
match 'new(/*path)', :to => 'pages#new', :as => 'new_page', :via => [:get, :post]
|
4
|
+
match 'positioning(/*path)', :to => 'pages#positioning', :as => 'page_positioning', :via => [:get, :post]
|
5
|
+
match 'edit(/*path)', :to => 'pages#edit', :as => 'edit_page', :via => [:get, :patch]
|
6
|
+
match 'delete(/*path)', :to => 'pages#destroy', :as => 'delete_page', :via => [:delete]
|
7
|
+
get 'search', :to => 'pages#search', :as => 'search'
|
8
|
+
get '*path' => 'pages#show', :as => 'page'
|
9
|
+
root :to => 'pages#index'
|
10
|
+
end
|
data/db/seeds.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$doc_root = File.join(File.expand_path(File.join('..', '..'), __FILE__), 'doc')
|
2
|
+
|
3
|
+
def doc(*path)
|
4
|
+
File.read(File.join($doc_root, *path))
|
5
|
+
end
|
6
|
+
|
7
|
+
guide = Documentation::Page.create(:title => "Developers' Guide", :content => doc('developers-guide', 'overview.md'))
|
8
|
+
guide.children.create(:title => 'Authorization', :content => doc('developers-guide', 'authorization.md'))
|
9
|
+
guide.children.create(:title => 'Search Backends', :content => doc('developers-guide', 'search-backends.md'))
|
10
|
+
guide.children.create(:title => 'Customization', :content => doc('developers-guide', 'customization.md'))
|
11
|
+
views = guide.children.create(:title => 'Building your own views', :content => doc('developers-guide', 'building-views', 'overview.md'))
|
12
|
+
views.children.create(:title => 'Accessing Pages', :content => doc('developers-guide', 'building-views', 'accessing-pages.md'))
|
13
|
+
views.children.create(:title => 'Helpers', :content => doc('developers-guide', 'building-views', 'helpers.md'))
|
14
|
+
|
15
|
+
markdown = Documentation::Page.create(:title => "Using Markdown", :content => doc('markdown', 'overview.md'))
|
data/lib/documentation.rb
CHANGED
@@ -1,2 +1,18 @@
|
|
1
|
+
require 'haml'
|
2
|
+
require 'coffee-rails'
|
3
|
+
require 'sass-rails'
|
4
|
+
require 'jquery-rails'
|
5
|
+
require 'dynamic_form'
|
6
|
+
require 'ostruct'
|
7
|
+
|
8
|
+
require 'documentation/version'
|
9
|
+
require 'documentation/errors'
|
10
|
+
require 'documentation/engine'
|
11
|
+
require 'documentation/markdown_renderer'
|
12
|
+
require 'documentation/view_helpers'
|
13
|
+
require 'documentation/searchers/abstract'
|
14
|
+
require 'documentation/search_result'
|
15
|
+
require 'documentation/config'
|
16
|
+
|
1
17
|
module Documentation
|
2
18
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Documentation
|
2
|
+
class Authorizer
|
3
|
+
|
4
|
+
def initialize(controller)
|
5
|
+
@controller = controller
|
6
|
+
end
|
7
|
+
|
8
|
+
def can_view_page?(page)
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
def can_add_page?(page)
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
def can_reposition_page?(page)
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def can_delete_page?(page)
|
21
|
+
true
|
22
|
+
end
|
23
|
+
|
24
|
+
def can_edit_page?(page)
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def can_search?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def check!(action, object = :none)
|
33
|
+
action_method_name = "can_#{action}?"
|
34
|
+
if self.respond_to?(action_method_name)
|
35
|
+
result = object == :none ? self.send(action_method_name) : self.send(action_method_name, object)
|
36
|
+
if result != true
|
37
|
+
raise Documentation::AccessDeniedError, "You are not permitted to perform this action."
|
38
|
+
end
|
39
|
+
else
|
40
|
+
raise Documentation::Error, "Invalid authorizer check (#{action})"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def request
|
47
|
+
controller.request
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'documentation/authorizer'
|
2
|
+
require 'documentation/searchers/simple'
|
3
|
+
|
4
|
+
module Documentation
|
5
|
+
|
6
|
+
#
|
7
|
+
# Sets the default configuration
|
8
|
+
#
|
9
|
+
DEFAULT_CONFIGURATION = {
|
10
|
+
# This defines the at path where a page can be viewed in
|
11
|
+
# the source website. For example, /docs/
|
12
|
+
:preview_path_prefix => nil,
|
13
|
+
|
14
|
+
# Should we display developer tips in the UI?
|
15
|
+
:developer_tips => true,
|
16
|
+
|
17
|
+
# The authorizer to use
|
18
|
+
:authorizer => Documentation::Authorizer,
|
19
|
+
|
20
|
+
# The searcher to use
|
21
|
+
:searcher => Documentation::Searchers::Simple.new
|
22
|
+
}
|
23
|
+
|
24
|
+
#
|
25
|
+
# Return configuration options
|
26
|
+
#
|
27
|
+
def self.config
|
28
|
+
@config ||= OpenStruct.new(DEFAULT_CONFIGURATION)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Documentation
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
|
4
|
+
isolate_namespace Documentation
|
5
|
+
|
6
|
+
initializer 'shoppe.initialize' do |app|
|
7
|
+
|
8
|
+
config.paths["db/migrate"].expanded.each do |expanded_path|
|
9
|
+
app.config.paths["db/migrate"] << expanded_path
|
10
|
+
end
|
11
|
+
|
12
|
+
# Load view helpers for the base application
|
13
|
+
ActiveSupport.on_load(:action_view) do
|
14
|
+
ActionView::Base.send :include, Documentation::ViewHelpers
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
generators do
|
19
|
+
require 'documentation/generators/setup_generator'
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.mounted_path
|
23
|
+
if route = Rails.application.routes.routes.select { |r| r.app == self }.first
|
24
|
+
route.path.spec.to_s
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'redcarpet'
|
2
|
+
require 'pygments'
|
3
|
+
|
4
|
+
module Documentation
|
5
|
+
class MarkdownRenderer < Redcarpet::Render::HTML
|
6
|
+
|
7
|
+
attr_accessor :page
|
8
|
+
|
9
|
+
include ActionView::Helpers::TagHelper
|
10
|
+
|
11
|
+
def block_code(code, language)
|
12
|
+
title = nil
|
13
|
+
code.gsub!(/\A\:\:(.*)$/) { title = $1 ; nil }
|
14
|
+
String.new.tap do |s|
|
15
|
+
s << "<p class='codeTitle'>#{title}</p>" if title
|
16
|
+
s << Pygments.highlight(code, :lexer => language)
|
17
|
+
end
|
18
|
+
rescue
|
19
|
+
"<div class='highlight'><pre>#{code}</pre></div>"
|
20
|
+
end
|
21
|
+
|
22
|
+
def link(link, title, content)
|
23
|
+
if link =~ /\A\^/
|
24
|
+
case link
|
25
|
+
when /\A\^\.\/(.*)/
|
26
|
+
# ^./pagename
|
27
|
+
# Links to pages on the same level as the current page
|
28
|
+
link = "{{docRoot}}/#{page.parents.map(&:permalink).join('/')}/#{$1}"
|
29
|
+
when /\A\^\/(.*)/
|
30
|
+
# ^/full/path
|
31
|
+
# Links to a page frmo the root of the docs
|
32
|
+
link = "{{docRoot}}/#{$1}"
|
33
|
+
when /\A\^(.*)/
|
34
|
+
# ^child/item
|
35
|
+
# Links to a child of the current page
|
36
|
+
link = "{{docRoot}}/#{page.full_permalink}/#{$1}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
"<a href='#{link}' title='#{title}'>#{content}</a>"
|
40
|
+
end
|
41
|
+
|
42
|
+
def image(src, title, alt)
|
43
|
+
if alt.gsub!(/\*([\w\-\s]+)\z/, '')
|
44
|
+
klass = "imgcontainer #{$1}"
|
45
|
+
else
|
46
|
+
klass = nil
|
47
|
+
end
|
48
|
+
content_tag :span, tag(:img, :src => src, :title => title, :alt => alt), :class => klass
|
49
|
+
end
|
50
|
+
|
51
|
+
def paragraph(text)
|
52
|
+
klass = ''
|
53
|
+
text.gsub!(/\A(\w+)\:/) do
|
54
|
+
klass = $1
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
text.sub!(/ ([^ ]+)$/, ' \1')
|
58
|
+
"<p class='#{klass.downcase}'>#{text}</p>"
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|