local_documentation 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/app/assets/images/documentation/link.svg +28 -0
  4. data/app/assets/images/documentation/logo-black.svg +23 -0
  5. data/app/assets/images/documentation/logo-white.svg +23 -0
  6. data/app/assets/images/documentation/page.svg +16 -0
  7. data/app/assets/images/documentation/pin.svg +15 -0
  8. data/app/assets/images/documentation/recommendation.svg +11 -0
  9. data/app/assets/images/documentation/search.svg +10 -0
  10. data/app/assets/images/documentation/unhappy.svg +15 -0
  11. data/app/assets/images/documentation/warning.svg +16 -0
  12. data/app/assets/javascripts/documentation/application.coffee +78 -0
  13. data/app/assets/javascripts/documentation/jquery-ui.js +4146 -0
  14. data/app/assets/javascripts/documentation/jquery.autosize.js +263 -0
  15. data/app/assets/stylesheets/documentation/application.scss +322 -0
  16. data/app/assets/stylesheets/documentation/markdown.scss +168 -0
  17. data/app/assets/stylesheets/documentation/page_form.scss +39 -0
  18. data/app/assets/stylesheets/documentation/reset.scss +101 -0
  19. data/app/controllers/documentation/application_controller.rb +27 -0
  20. data/app/controllers/documentation/pages_controller.rb +93 -0
  21. data/app/helpers/documentation/application_helper.rb +13 -0
  22. data/app/models/documentation/page.rb +214 -0
  23. data/app/models/documentation/screenshot.rb +15 -0
  24. data/app/views/documentation/pages/_admin_buttons.html.haml +18 -0
  25. data/app/views/documentation/pages/form.html.haml +16 -0
  26. data/app/views/documentation/pages/index.html.haml +13 -0
  27. data/app/views/documentation/pages/positioning.html.haml +22 -0
  28. data/app/views/documentation/pages/screenshot.html.haml +15 -0
  29. data/app/views/documentation/pages/search.html.haml +12 -0
  30. data/app/views/documentation/pages/show.html.haml +14 -0
  31. data/app/views/documentation/shared/access_denied.html.haml +10 -0
  32. data/app/views/documentation/shared/not_found.html.haml +10 -0
  33. data/app/views/layouts/documentation/_footer.html.haml +0 -0
  34. data/app/views/layouts/documentation/_head.html.haml +0 -0
  35. data/app/views/layouts/documentation/_header.html.haml +3 -0
  36. data/app/views/layouts/documentation/_search.html.haml +5 -0
  37. data/app/views/layouts/documentation/application.html.haml +22 -0
  38. data/config/locales/en.yml +62 -0
  39. data/config/routes.rb +11 -0
  40. data/db/migrate/20140711185212_create_documentation_pages.rb +10 -0
  41. data/db/migrate/20140724111844_create_nifty_attachments_table.rb +16 -0
  42. data/db/migrate/20140724114255_create_documentation_screenshots.rb +7 -0
  43. data/db/seeds.rb +15 -0
  44. data/doc/developers-guide/authorization.md +37 -0
  45. data/doc/developers-guide/building-views/accessing-pages.md +38 -0
  46. data/doc/developers-guide/building-views/helpers.md +105 -0
  47. data/doc/developers-guide/building-views/overview.md +3 -0
  48. data/doc/developers-guide/customization.md +9 -0
  49. data/doc/developers-guide/overview.md +20 -0
  50. data/doc/developers-guide/search-backends.md +17 -0
  51. data/doc/markdown/overview.md +37 -0
  52. data/lib/documentation.rb +20 -0
  53. data/lib/documentation/authorizer.rb +60 -0
  54. data/lib/documentation/config.rb +31 -0
  55. data/lib/documentation/engine.rb +29 -0
  56. data/lib/documentation/errors.rb +7 -0
  57. data/lib/documentation/generators/setup_generator.rb +17 -0
  58. data/lib/documentation/markdown_renderer.rb +62 -0
  59. data/lib/documentation/search_result.rb +84 -0
  60. data/lib/documentation/searchers/abstract.rb +47 -0
  61. data/lib/documentation/searchers/simple.rb +40 -0
  62. data/lib/documentation/version.rb +3 -0
  63. data/lib/documentation/view_helpers.rb +159 -0
  64. data/lib/tasks/documentation.rake +44 -0
  65. metadata +307 -0
@@ -0,0 +1,15 @@
1
+ module Documentation
2
+ class Screenshot < ActiveRecord::Base
3
+ establish_connection :documentation
4
+
5
+ attachment :upload
6
+
7
+ before_validation do
8
+ if self.upload_file && self.alt_text.blank?
9
+ self.alt_text = self.upload_file.original_filename
10
+ end
11
+ true
12
+ end
13
+
14
+ end
15
+ end
@@ -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,16 @@
1
+ - @page_title = @page.breadcrumb.reverse.map(&:title).join(" - ")
2
+
3
+ %section.content.edit-article
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
+
13
+ %p.submit
14
+ - if authorizer.can_upload?(@page)
15
+ = link_to t('.add_screenshot'), upload_screenshot_path, :class => 'button preview js-screenshot'
16
+ = 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,15 @@
1
+ = form_for @screenshot, :url => upload_screenshot_path, :html => {:class => 'pageForm'} do |f|
2
+ %dl
3
+ %dt= f.label :upload_file, "Upload File"
4
+ %dd.padded
5
+ - if params[:filename]
6
+ = params[:filename]
7
+ - else
8
+ = f.file_field :upload_file
9
+
10
+ %dl
11
+ %dt= f.label :alt_text, "Screenshot Title"
12
+ %dd= f.text_field :alt_text
13
+
14
+ %p.submit
15
+ = f.submit "Upload Screenshot", :class => 'button'
@@ -0,0 +1,12 @@
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= documentation_search_summary(@result)
10
+ = documentation_search_results(@result)
11
+ %p.pagination= documentation_search_pagination(@result, :link_class => 'button')
12
+
@@ -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,3 @@
1
+ %header
2
+ %h1= link_to t('.title'), root_path
3
+ %p.back= link_to "&larr; #{t('.back_to_site')}".html_safe, "/", :class => ''
@@ -0,0 +1,5 @@
1
+ - if authorizer.can_search?
2
+ = form_tag search_path, :method => :get do
3
+ %p.searchForm
4
+ = text_field_tag 'query', params[:query], :placeholder => t('.query_placeholder')
5
+
@@ -0,0 +1,22 @@
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
+ = render 'layouts/documentation/head'
9
+ = yield :head
10
+ %body
11
+ = render 'layouts/documentation/header'
12
+
13
+ %nav.pages
14
+ .inner
15
+ = render 'layouts/documentation/search'
16
+ = documentation_navigation_tree_for(@page)
17
+ %section.content
18
+ .inner
19
+ = flash_messages
20
+ = yield
21
+ = render 'layouts/documentation/footer'
22
+
@@ -0,0 +1,62 @@
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
+ documentation_search_summary:
18
+ text: "Found %{total_results} pages matching your query. Showing results %{start_result} to %{end_result}"
19
+ documentation_search_results:
20
+ in: in
21
+ documentation_search_pagination:
22
+ next: Next page
23
+ previous: Previous page
24
+
25
+ pages:
26
+ index:
27
+ welcome_title: Welcome to Documentation
28
+ welcome_text: Choose a page from the menu on the left of the screen to begin.
29
+ developer_tip:
30
+ You can override this page by adding a new view in <code>app/views/documentation/pages/index</code>.
31
+ Alternatively, you can disable this message by setting <code>developer_tips</code> to false in the
32
+ Documentation configuration.
33
+ create_root_page: Create new root page
34
+ reorder_root_pages: Re-order root pages
35
+
36
+ show:
37
+ view_in_website: View in website
38
+ last_updated: Last updated on %{timestamp}
39
+
40
+ admin_buttons:
41
+ new: New page
42
+ edit: Edit page
43
+ reorder: Re-order children
44
+ delete: Delete page
45
+
46
+ form:
47
+ title_placeholder: Enter a title for this page
48
+ content_placeholder: 'Use Markdown to enter page content'
49
+ permalink_placeholder: Automatically generated if left blank
50
+ add_screenshot: Add Screenshot
51
+ save: Save Page
52
+
53
+ positioning:
54
+ reorder_root_pages_title: Re-order root pages
55
+ back_to_page: Back to page
56
+ back_to_homepage: Back to homepage
57
+
58
+ search:
59
+ title: "Search results for '%{query}'"
60
+ no_results: "No pages were found matching '%{query}'"
61
+ next_page: Next page
62
+ previous_page: Previous page
@@ -0,0 +1,11 @@
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
+ match 'screenshot', :to => 'pages#screenshot', :as => 'upload_screenshot', :via => [:get, :post]
8
+ get 'search', :to => 'pages#search', :as => 'search'
9
+ get '*path' => 'pages#show', :as => 'page'
10
+ root :to => 'pages#index'
11
+ end
@@ -0,0 +1,10 @@
1
+ class CreateDocumentationPages < ActiveRecord::Migration
2
+ def up
3
+ create_table "documentation_pages" do |t|
4
+ t.string :title, :permalink
5
+ t.text :content, :compiled_content
6
+ t.integer :parent_id, :position
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ class CreateNiftyAttachmentsTable < ActiveRecord::Migration
2
+
3
+ def up
4
+ create_table :nifty_attachments do |t|
5
+ t.integer :parent_id
6
+ t.string :parent_type, :token, :digest, :role, :file_name, :file_type
7
+ t.binary :data, :limit => 10.megabytes
8
+ t.timestamps
9
+ end
10
+ end
11
+
12
+ def down
13
+ drop_table :nifty_attachments
14
+ end
15
+
16
+ end
@@ -0,0 +1,7 @@
1
+ class CreateDocumentationScreenshots < ActiveRecord::Migration
2
+ def change
3
+ create_table :documentation_screenshots do |t|
4
+ t.string :alt_text
5
+ end
6
+ end
7
+ end
@@ -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'))
@@ -0,0 +1,37 @@
1
+ By default, all pages you create will be visible & editable by anyone. In order to add a level of authorisation, you can define an **Authorizer** what level of access is given to each request.
2
+
3
+ ## Creating an authorizer class
4
+
5
+ To do this, begin by creating a new class which inherits from `Documentation::Authorizer`.
6
+
7
+ ```ruby
8
+ class MyDocsAuthorizer < Documentation::Authorizer
9
+ end
10
+ ```
11
+
12
+ Once you have created this class, you can define a number of methods. In all your methods you can access `controller` to access the controller which requested the page. This allows you to access sessions, params or other request information. The methods you can override are as follows:
13
+
14
+ * `can_use_ui?` - whether the built-in UI can be used
15
+ * `can_search?` - whether searching can take place
16
+ * `can_view_page?(page)` - whether the provided page can be viewed
17
+ * `can_add_page?(page)` - whether a page can be created within the provided page
18
+ * `can_reposition_page?(page)` - whether pages within the provided page can be repositioned
19
+ * `can_edit_page?(page)` - whether the provided page can be edited
20
+ * `can_delete_page?(page)` - whether the provided page can be deleted
21
+ * `can_upload?(page)` - whether a file can be uploaded to this page
22
+
23
+ The default for all these method if left un-defined, is `true`. Here's an example:
24
+
25
+ ```ruby
26
+ def can_edit_page?(page)
27
+ controller.request['rack.current_user'].admin?
28
+ end
29
+ ```
30
+
31
+ ## Using your authorizer class
32
+
33
+ Once you have created your class, you should tell Documentation that it should use it. Do this by adding the following to your `config/initializers/documentation.rb` file`.
34
+
35
+ ```ruby
36
+ Documentation.config.authorizer = MyDocsAuthorizer
37
+ ```
@@ -0,0 +1,38 @@
1
+ Everything you need to access the pages stored in the database can be found on the `Documentation::Page` model.
2
+
3
+ ## Finding pages
4
+
5
+ In most cases, you'll want to find a page based on its path from the root of the site, for example, `example/page/here` may be the string you want to use to find the `here` page.
6
+
7
+ ```ruby
8
+ page = Documentation::Page.find_from_path('example/page/here')
9
+ ```
10
+
11
+ ## Useful page methods
12
+
13
+ Once you've found a page, there are a number of methods & attribute which may be useful to you.
14
+
15
+ * `title` - the page's title
16
+ * `content` - the markdown content for a page
17
+ * `compiled_content` - the HTML content for a page
18
+ * `parents` - returns an array of all the parents for the page
19
+ * `breadcrumb` - returns the items which should be included in a breadcrumb trail
20
+ * `full_permalink` - the full permalink including all parents
21
+ * `children` - all child pages for the page
22
+ * `has_children?` - whether or not the page has children
23
+ * `navigation` - appropriate navigation pages for this page
24
+
25
+ ## Searching
26
+
27
+ If you wish to search pages, you should use the `Documentation::Page.search` method as shown below:
28
+
29
+ ```ruby
30
+ result = Documentation::Page.search('query here', :page => 1)
31
+ ```
32
+
33
+ Once you have a result object, you can use this to get information about the pages which matched the result. The following methods may be useful:
34
+
35
+ * `results` - the pages which have been found
36
+ * `excerpt_for(page)` - an excerpt to display for this page
37
+ * `empty?` - was the search empty?
38
+ * `total_pages` - the total number of pagination pages
@@ -0,0 +1,105 @@
1
+ All the helpers needed to do this are provided for you and are shown below. These are the same helpers which are used in the built-in interface.
2
+
3
+ -------------
4
+
5
+ ### `documentation_breadcrumb_for(page)`
6
+
7
+ This helper will return an unordered list containing a breadcrumb trail for the page you provide. The output will look something like this:
8
+
9
+ ```html
10
+ <nav class='breadcrumb'>
11
+ <ul>
12
+ <li><a href='/'>Home</a></li>
13
+ <li><a href='/example'>Example</a></li>
14
+ <li><a href='/example/page'>Page</a></li>
15
+ </ul>
16
+ </nav>
17
+ ```
18
+
19
+ #### Options for this helper
20
+
21
+ * `:class` - allows you to set the class for the outer nav element. Defaults to 'breadcrumb'.
22
+ * `:root_link` - sets the text for the first link in the breadcrumb. Defaults to 'Home' (taken from the i18n). Set to false to exclude this item.
23
+
24
+ -------------
25
+
26
+ ### `documentation_navigation_tree_for(page)`
27
+
28
+ Provides a single-level nested unordered list which contains the given page. If the given page has no children, its parents will be included. If it has children, they will be shown too. The active page will include the `active` class.
29
+
30
+ ```html
31
+ <ul>
32
+ <li><a href='/example'>Example Section</a></li>
33
+ <li>
34
+ <a href='/food'>Information about food</a>
35
+ <ul>
36
+ <li><a href='/foot/fruit'>Fruit</a></li>
37
+ <li><a href='/foot/vegetables' class='active'>Vegetables</a></li>
38
+ <li><a href='/foot/meat'>Meat</a></li>
39
+ </ul>
40
+ </li>
41
+ <li><a href='/drink'>Information about drink</a></li>
42
+ </ul>
43
+ ```
44
+
45
+ -------------
46
+
47
+ ### `documentation_content_for(page)`
48
+
49
+ Renders the content for a given page. This will deal with ensuring that the page is unescaped and that any formatting options are correctly parsed.
50
+
51
+ -------------
52
+
53
+ ### `documentation_authorizer`
54
+
55
+ Returns the documentation authorizer.
56
+
57
+ -------------
58
+
59
+ ### `documentation_edit_page_path(page)`
60
+
61
+ Returns the path to edit the given page in the provided UI.
62
+
63
+ -------------
64
+
65
+ ### `documentation_page_path(page)`
66
+
67
+ Returns the path to view the given page in the provided UI.
68
+
69
+ -------------
70
+
71
+ ### `documentation_search_summary(result)`
72
+
73
+ Returns information about your search result
74
+
75
+ -------------
76
+
77
+ ### `documentation_search_results(result, options)`
78
+
79
+ Return an unordered list containing your search results.
80
+
81
+ ```html
82
+ <ul class='searchResults'>
83
+ <li>
84
+ <h4><a href='path/to/page'>Title of page</a></h4>
85
+ <p class='in'><!--- Other pages if they exist --></p>
86
+ <p class='except'>An excerpt goes <mark>here</mark></p>
87
+ </li>
88
+ </ul>
89
+ ```
90
+
91
+ #### Options for this helper
92
+
93
+ * `:class` - the class for the outer list
94
+
95
+ -------------
96
+
97
+ ### `documentation_search_pagination(result, options)`
98
+
99
+ Return a next page and previous page link based on the results
100
+
101
+ #### Options for this helper
102
+
103
+ * `:link_class` - the class to apply to both links
104
+ * `:next_link_class` - the class for the next link
105
+ * `:previous_link_class` - the class for the previous link