local_documentation 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- 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 +78 -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 +322 -0
- data/app/assets/stylesheets/documentation/markdown.scss +168 -0
- data/app/assets/stylesheets/documentation/page_form.scss +39 -0
- data/app/assets/stylesheets/documentation/reset.scss +101 -0
- data/app/controllers/documentation/application_controller.rb +27 -0
- data/app/controllers/documentation/pages_controller.rb +93 -0
- data/app/helpers/documentation/application_helper.rb +13 -0
- data/app/models/documentation/page.rb +214 -0
- data/app/models/documentation/screenshot.rb +15 -0
- data/app/views/documentation/pages/_admin_buttons.html.haml +18 -0
- data/app/views/documentation/pages/form.html.haml +16 -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/screenshot.html.haml +15 -0
- data/app/views/documentation/pages/search.html.haml +12 -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/_footer.html.haml +0 -0
- data/app/views/layouts/documentation/_head.html.haml +0 -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 +22 -0
- data/config/locales/en.yml +62 -0
- data/config/routes.rb +11 -0
- data/db/migrate/20140711185212_create_documentation_pages.rb +10 -0
- data/db/migrate/20140724111844_create_nifty_attachments_table.rb +16 -0
- data/db/migrate/20140724114255_create_documentation_screenshots.rb +7 -0
- data/db/seeds.rb +15 -0
- data/doc/developers-guide/authorization.md +37 -0
- data/doc/developers-guide/building-views/accessing-pages.md +38 -0
- data/doc/developers-guide/building-views/helpers.md +105 -0
- data/doc/developers-guide/building-views/overview.md +3 -0
- data/doc/developers-guide/customization.md +9 -0
- data/doc/developers-guide/overview.md +20 -0
- data/doc/developers-guide/search-backends.md +17 -0
- data/doc/markdown/overview.md +37 -0
- data/lib/documentation.rb +20 -0
- data/lib/documentation/authorizer.rb +60 -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 +17 -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 +3 -0
- data/lib/documentation/view_helpers.rb +159 -0
- data/lib/tasks/documentation.rake +44 -0
- metadata +307 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
As with all Rails engines, you can customize every aspect of the engine within your Rails application.
|
2
|
+
|
3
|
+
## Overriding views
|
4
|
+
|
5
|
+
You can override views by simply placing new view files in your `app/views` folder. You can see the files which exist and can be overridden in [our views directory](https://github.com/qbraksa/documentation/tree/master/app/views). We use Haml for our views but you can use whatever you want when overriding.
|
6
|
+
|
7
|
+
## Internationalization
|
8
|
+
|
9
|
+
The interface pulls all its wording from the Rails i18n system. This means you can simply override any wording in your own locale files. The keys available can be found in [our en.yml file](https://github.com/qbraksa/documentation/blob/master/config/locales/en.yml).
|
@@ -0,0 +1,20 @@
|
|
1
|
+
**Welcome to Documentation.** You can go ahead and delete this page whenever you're ready. It contains some information as well as being a good reference point for how things will be styled. Every page in Documentation is formatted with Markdown (although there are a couple of additions which are demonstrated here).
|
2
|
+
|
3
|
+
## Features
|
4
|
+
|
5
|
+
* A simple & attractive interface for viewing & editing your pages
|
6
|
+
* Store pages in a hierarchy
|
7
|
+
* Modular authorisation architecture
|
8
|
+
* Modular search backend architecture
|
9
|
+
* Full i18n support
|
10
|
+
* Override any views as necessary within your Rails application
|
11
|
+
|
12
|
+
Recommendation: Take a look through all the pages in this guide while developing your application. If you delete this section, you can always re-add it by running `rake documentation:install_guides` from the root of your Rails application.
|
13
|
+
|
14
|
+
## Useful links
|
15
|
+
|
16
|
+
The links below provide you with easy access to key resources which will help you.
|
17
|
+
|
18
|
+
* [Browse source code on GitHub](https://github.com/qbraksa/documentation)
|
19
|
+
* [View issues](https://github.com/qbraksa/documentation/issues)
|
20
|
+
* [Check out the installation guide](https://github.com/qbraksa/documentation/blob/master/README.md)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
By default, Documentation uses a very very simple search which uses a LIKE query on your database. As this method is far from ideal, Documentation allows additional search backends to be created.
|
2
|
+
|
3
|
+
## Elasticsearch
|
4
|
+
|
5
|
+
The recommended method of indexing & searching data is to use Elasticsearch. A module is provided for this [on GitHub](https://github.com/adamcooke/documentation-elasticsearch) and can be installed by following the instructions on the repo's README page.
|
6
|
+
|
7
|
+
## Creating your own search backend
|
8
|
+
|
9
|
+
To create your own backend, create a new class which inherits from `Documentation::Searchers::Abstract`. This class must confirm to the protocol outlined in this [abstract.rb](https://github.com/qbraksa/documentation/blob/master/lib/documentation/searchers/abstract.rb) file.
|
10
|
+
|
11
|
+
## Using your custom backend
|
12
|
+
|
13
|
+
Once you have created a backend, you should tell Documentation to use it. Just add the following to your `config/initializers/documentation.rb` file.
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
Documentation.config.searcher = MyCustomSearcher.new
|
17
|
+
```
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Pages all use standard Markdown markup to format them. There are some additional options though which you may find useful:
|
2
|
+
|
3
|
+
## Linking to other pages
|
4
|
+
|
5
|
+
If you need to link to other documentation pages, it is important to use the following syntax to ensure the link is maintain regardless of how the page is rendered.
|
6
|
+
|
7
|
+
* `[Page](^permalink)` - links from a child of the page where the link is shown
|
8
|
+
* `[Page](^./permalink)` - links from a sibling of the page where the link is shown
|
9
|
+
* `[Page](^/permalink) `- links from the root page
|
10
|
+
|
11
|
+
It is important to ensure the `^` character is maintained.
|
12
|
+
|
13
|
+
## Code Highlighting
|
14
|
+
|
15
|
+
Code highlighting is handled by [Pygments](http://pygments.org/). This is a Python library and you may need to install it. Fortunately, installing it is usually as simple as running:
|
16
|
+
|
17
|
+
```text
|
18
|
+
easy_install pygments
|
19
|
+
```
|
20
|
+
|
21
|
+
## Recommendations & Warnings
|
22
|
+
|
23
|
+
Any paragraph which is prefixed with `Recommendation:` or `Warning:` will be styled as appropriate. Recommendations are displayed with an information icon and a blue background and warnings are displayed with a warning icon and a yellow background. As shown below:
|
24
|
+
|
25
|
+
Recommendation: This is an example recommendation
|
26
|
+
|
27
|
+
Warning: This is an example warning.
|
28
|
+
|
29
|
+
## Images
|
30
|
+
|
31
|
+
If you are embedding images, it is usually best to embed them in the centre of the page. To do to this, simply use the following Markdown:
|
32
|
+
|
33
|
+
```text
|
34
|
+
![My image*center](path/to/image.png)
|
35
|
+
```
|
36
|
+
|
37
|
+
This will embed the image in a `imgcontainer` element with the `center` class. The stylesheet will then take care of the rest.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'haml'
|
2
|
+
require 'coffee-rails'
|
3
|
+
require 'sass-rails'
|
4
|
+
require 'jquery-rails'
|
5
|
+
require 'dynamic_form'
|
6
|
+
require 'ostruct'
|
7
|
+
require 'nifty/attachments'
|
8
|
+
require 'nifty/dialog'
|
9
|
+
|
10
|
+
require 'documentation/version'
|
11
|
+
require 'documentation/errors'
|
12
|
+
require 'documentation/engine'
|
13
|
+
require 'documentation/markdown_renderer'
|
14
|
+
require 'documentation/view_helpers'
|
15
|
+
require 'documentation/searchers/abstract'
|
16
|
+
require 'documentation/search_result'
|
17
|
+
require 'documentation/config'
|
18
|
+
|
19
|
+
module Documentation
|
20
|
+
end
|
@@ -0,0 +1,60 @@
|
|
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_upload?(page)
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def can_search?
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
def can_use_ui?
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
def check!(action, object = :none)
|
41
|
+
action_method_name = "can_#{action}?"
|
42
|
+
if self.respond_to?(action_method_name)
|
43
|
+
result = object == :none ? self.send(action_method_name) : self.send(action_method_name, object)
|
44
|
+
if result != true
|
45
|
+
raise Documentation::AccessDeniedError, "You are not permitted to perform this action."
|
46
|
+
end
|
47
|
+
else
|
48
|
+
raise Documentation::Error, "Invalid authorizer check (#{action})"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def request
|
55
|
+
controller.request
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
end
|
60
|
+
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,17 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module Documentation
|
4
|
+
module Generators
|
5
|
+
class SetupGenerator < Rails::Generators::Base
|
6
|
+
|
7
|
+
def create_route
|
8
|
+
route 'mount Documentation::Engine => "/docs"'
|
9
|
+
end
|
10
|
+
|
11
|
+
def migrate_database
|
12
|
+
rake("documentation:db:migrate")
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
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
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Documentation
|
2
|
+
class SearchResult
|
3
|
+
|
4
|
+
attr_accessor :query
|
5
|
+
attr_accessor :time
|
6
|
+
attr_accessor :raw_results
|
7
|
+
attr_accessor :results
|
8
|
+
attr_accessor :page
|
9
|
+
attr_accessor :per_page
|
10
|
+
attr_accessor :total_results
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@time = nil
|
14
|
+
@raw_results = {}
|
15
|
+
@page = 1
|
16
|
+
@total_pages = 1
|
17
|
+
@per_page = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Return the pages
|
22
|
+
#
|
23
|
+
def results
|
24
|
+
@results ||= begin
|
25
|
+
results = Documentation::Page.where(:id => raw_results.keys).includes(:parent).to_a
|
26
|
+
results.sort_by { |p| raw_results.keys.index(p.id) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Return the highlight string for a given page
|
32
|
+
#
|
33
|
+
def excerpt_for(page)
|
34
|
+
if @raw_results[page.id] && hl = @raw_results[page.id][:highlights]
|
35
|
+
ERB::Util.html_escape((hl.join("..."))).gsub('{{{', "<mark>").gsub("}}}", "</mark>").html_safe
|
36
|
+
else
|
37
|
+
page.content[0,255].gsub(/[\n\r]/, '') + "..."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Is the result set empty?
|
43
|
+
#
|
44
|
+
def empty?
|
45
|
+
self.results.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# The total number of pages in the result set
|
50
|
+
#
|
51
|
+
def total_pages
|
52
|
+
(total_results / per_page.to_f).ceil
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# The number of the first result on the current page
|
57
|
+
#
|
58
|
+
def start_result_number
|
59
|
+
((page - 1) * per_page) + 1
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# The number of the last result on the current page
|
64
|
+
#
|
65
|
+
def end_result_number
|
66
|
+
start_result_number + (results.size) - 1
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Is this the first page of the result set?
|
71
|
+
#
|
72
|
+
def first_page?
|
73
|
+
page == 1
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Is this the last page of the result set?
|
78
|
+
#
|
79
|
+
def last_page?
|
80
|
+
page == total_pages
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Documentation
|
2
|
+
module Searchers
|
3
|
+
class Abstract
|
4
|
+
|
5
|
+
attr_reader :options
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@options = options
|
9
|
+
setup
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# Run whatever initial set up is needed
|
14
|
+
#
|
15
|
+
def setup
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Search for a page from the index
|
20
|
+
#
|
21
|
+
def search(query, options = {})
|
22
|
+
[]
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Delete a page from the index
|
27
|
+
#
|
28
|
+
def delete(page)
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Reset an index to have no data within it
|
34
|
+
#
|
35
|
+
def reset
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Add or update an page in the index
|
41
|
+
#
|
42
|
+
def index(page)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|