Creating Searchable Documents
This helper provides a layout that will create a nested collection of documents like this one and which are searchable via the box on the top left.
The application must supply a hash to describe the page index that has been built on the the left of the page. Here is the index used for this page:
index = {} index[nil] = { intro: "Introduction", page2: "Page 2", } index["Topic 1"] = { topic1_item1: "First Item", topic1_item2: "Second Item", }
The sub-hash keys describe where each document lives and what its title is, for example
the document with title “Second Item” should live in _documents_root_/topic1/item2.md.erb
.
By default the root is "#{Origen.root}/templates/web/docs"
but this can be overridden
by supplying a :root
option which should describe the relative path from "#{Origen.root}/templates/web"
.
By default, the sub_hash key will be split by the ‘_’ character to find the _directory_/_file_
as shown above but this can be overridden by supplying the :path_separator
option. For example,
using path_separator: '__'
(double underscore) with the index used below would result in the
the document with title “Second Item” living now at _documents_root_/topic1/second_item.md.erb
index = {} index["Topic 1"] = { topic1__first_item: "First Item", topic1__second_item: "Second Item", }
An API is available to programatically define the document index, here is the first example above defined via the API rather than creating the hash explicitly:
index = OrigenDocHelpers::GuideIndex.new index.section nil do |section| section.page :intro, heading: "Introduction" section.page :page2, heading: "Page 2" end index.section :topic1, heading: "Topic 1" do |section| section.page :item1, heading: "First Item" section.page :item2, heading: "Second Item" end
On the face of it, this is just a slightly different way of writing the same thing and you may or may not prefer using the API vs. defining the hash directly.
However, the advantage of the API is that it allows the index to be defined out of order, allowing the user to insert entries at specific points in the index table. This can be useful to allow plugins to add pages to a parent application’s guide section.
This is achieved by adding :before
and :after
options, here for example to add a new section before “Topic 1”:
index.section :topic0, heading: "Topic 0", before: :topic1 do |section| section.page :my_topic end
or to add a new page within the “Topic 1” section:
index.section :topic1 do |section| section.page :my_topic, heading: "My Heading", after: :item1 end
Note that both the .section
and .page
methods support the use of :before
or :after
.
If neither option is given when referencing an existing GuideIndex
instance then the new section/page
will simply be appended onto the end.
A layout helper is provided to include a document in the search and wrap it with the indexed layout:
% render "doc_helpers/searchable.html", index: index do Blah blah blah % end
The :index
option is mandatory, but the following are optional:
:heading - Each wrapped document will have the heading (e.g. "First Item") inserted at the top of the page, to override it supply this option. A common example would be if the topic is long and so an abbreviated version has been used in the index. e.g. "First Item and Other Stuff" :topic - Each wrapped document will have the topic (e.g. "Topic 1") inserted at the top of the page, to override it supply this option. A common example would be if the topic is long and so an abbreviated version has been used in the index. e.g. "Topic 1 and Other Stuff" :root - override the top-level folder containing your documents, e.g. "tutorials/guides" :tab - the helper should automatically work out what tab to select for each document, however if it is struggling for some reason you can force it by supplying the hash key from the index that the given document should be associated with, e.g. :topic1_item1 :prompt - the search box prompt, by default is "Search these docs..." :path_separator - override how the sub-hash key in the index will be split (which character will be used) to generate the location of the document
Normally the searchable layout will be wrapped in your own application specific layout to insert your custom navigation bar, etc.
As an example here is the actual layout that has been used to generate this page:
--- title: Origen Documentation Helpers --- <%= render "partials/navbar.html", tab: :helpers %> % index = {} % index[nil] = { % intro: "Introduction", % page2: "Page 2", % } % index["Topic 1"] = { % topic1_item1: "First Item", % topic1_item2: "Second Item", % } % opts = options.merge(index: index, root: "helpers/searchable") % render "doc_helpers/searchable.html", options.merge(opts) do <%= yield %> % end
With the layout setup, writing documents is very simple; these should normally be regular markdown that is wrapped in your layout.
The top-level header size in your document should be h3
or ###
in markdown.
.html.erb
files will also work if you want to use them.
Here is the actual code used behind the Topic 1 - First Item page (where the layout being rendered is the one above):
% render "templates/web/layouts/doc.html" do Hello I'm item 1 % end