Skip to content
Permalink
Browse files
This closes #20
  • Loading branch information
aledsage committed Mar 10, 2016
2 parents bf43bd0 + 8984334 commit ae8b0abb342505b2c008d14b0861a848c2324622
Show file tree
Hide file tree
Showing 19 changed files with 1,011 additions and 501 deletions.
@@ -14,15 +14,19 @@ familiarise yourself with the standard workflow for Apache Brooklyn:
[CONTRIB]: https://brooklyn.apache.org/community/how-to-contribute-docs.html
[COMMIT]: https://brooklyn.apache.org/developers/committers/index.html

The documents are written in [kramdown](http://kramdown.gettalong.org/syntax.html) a superset of Markdown
which is processed into HTML using [Jekyll](https://jekyllrb.com/). In addition to the standard set of options
and notation available with these platforms, a number of custom plug-ins have been implemented specifically
for the Brooklyn docs. These are detailed in the [contributing to docs](https://brooklyn.apache.org/contributing) doc.

Workstation Setup
-----------------

First, if you have not already done so, clone the `brooklyn` repository and subprojects
and set up the remotes as described in [Guide for committers][COMMIT].

The Brooklyn documentation uses Markdown notation (what this file is written in)
and the Jekyll process. This in turn requires Ruby and gems as described in the `Gemfile`:
The Brooklyn documentation uses [Jekyll](https://jekyllrb.com/) to process the site content into HTML.
This in turn requires Ruby and gems as described in the `Gemfile`:
install [RVM](http://rvm.io/) to manage Ruby installations and sets of Ruby gems.

\curl -sSL https://get.rvm.io | bash -s stable
@@ -0,0 +1,220 @@
#
# Adds a liquid tag to build a page on the contents of the folder it's in
#
# Pulls in files in the format <Number>_<title>.md in the order of version number. Ignores files not in this format.
#

require 'rubygems'
require 'yaml'
require "kramdown"

module PageStructureUtils

class ChildPage
def initialize(yaml, content)
@yaml=yaml
@content=content
end
attr_accessor :yaml
attr_accessor :content
def to_s # called with print / puts
"YAML : #{@yaml}" #, Content : #{@content}"
end

##
# Sort a list of children by their YAML containing section positions. Do this with Gem:Version
#
#
def self.sortBySectionPositions(yaml)

$major = "1"
$minor = 1
# first check all the child pages are numbered, if not, number them in the order they are
yaml.each do |i|
if i.yaml['section_position'] == nil
i.yaml['section_position'] = $major+"."+$minor.to_s
$minor += 1
else
# Store any major, start incrementing minor
$major = i.yaml['section_position'].to_s
$minor = 1
end
end

# return the comparison between the versions
yaml.sort{ |x,y| Gem::Version.new(x.yaml['section_position'].to_s) <=> Gem::Version.new(y.yaml['section_position'].to_s) }
end
##
# This goes through the hash looking for the keys for the different types of children
#
def self.getDefiningParameterFromHash(hash)
param_name = hash['path']
param_name = (param_name == nil ? hash['link'] : param_name)
(param_name == nil ? hash['section'] : param_name)
end
##
# Sorts a list of yaml children, if there's no numbering, use the YAML order to create a numbering
# NOTE: doesn't alter the returned object as that seemed to break things downstream
#
def self.sortYAMLSectionPositions(yaml)
position = Hash.new
$major = "1"
$minor = 1
# go through and generate a position for each
yaml.each do |i|
if i.instance_of? String
position[i] = $major+"."+$minor.to_s
$minor += 1
else
# get the key for this type of child
defining_param = getDefiningParameterFromHash(i)
if i['section_position'] == nil
position[defining_param] = $major+"."+$minor.to_s
$minor += 1
else
# Store any major, start incrementing minor
position[defining_param] = i['section_position'].to_s
$major = i['section_position'].to_s
$minor = 1
end
end
end
# sort on the position (NB: sort! for in-place sorting)
yaml.sort!{ |x,y|
$pos_x = nil
$pos_y = nil
if x.instance_of? String
$pos_x = position[x]
else
defining_param = getDefiningParameterFromHash(x)
$pos_x = position[defining_param]
end
if y.instance_of? String
$pos_y = position[y]
else
defining_param = getDefiningParameterFromHash(y)
$pos_y = position[defining_param]
end
Gem::Version.new($pos_x.to_s) <=> Gem::Version.new($pos_y.to_s)
}
end

##
# This function looks at all the *.md files at the YAML in the headers and produces a list of children ordered by section_position
#
#
def self.parseChildYAMLFromParent(page)
# get the base directory of the current file
$baseFile = Dir.pwd+page['dir']
# list all of the files in that directory
$listings = Dir[$baseFile+"/*.md"]
$allPages = []

for $listing in $listings

# read the file
$fileContent = IO.read($listing)
# try and split of any YAML
$partitionedFileContent = $fileContent.split('---');
# if there's potentially partitioned YAML try and parse it
if $partitionedFileContent.size > 2
# try and parse the YAML
yamlContent = YAML.load($partitionedFileContent[1])
# if we can, use it (section_type needs to be one of the allowed)
if yamlContent != nil && yamlContent != false && yamlContent['section_type'] != nil && yamlContent['section_type'] != "default"

if yamlContent['section_type'] == nil
# if no section position has been specified, put it at the end
yamlContent['section_position'] = Integer::MAX
end
# if there's YAML, check it has the section_position tag and put it into child pages
($allPages ||= []) << ChildPage.new(yamlContent, $partitionedFileContent[2..-1].join('---'))
end
end
end
$allPages = sortBySectionPositions($allPages)
# return the combined content
$allPages
end

##
# This function looks in a parent folder for all files in the format <Number>_<title>.md
#
#
def self.parseChildPagesFromParent(page)
# get the base directory of the current file
$baseFile = Dir.pwd+page['dir']
# list all of the files in that directory
$listings = Dir[$baseFile+"/*"]
# filter by the key pattern
$listings = $listings.select{ |i| i[/[\d\.]\_.*\.md/] }
# Sort the files based on the Gem::Version of the prefix
$listings = $listings.sort{ |x,y| Gem::Version.new((File.basename x).partition('_').first) <=> Gem::Version.new((File.basename y).partition('_').first) }
# loop through them and merge the content
$allPages = []

for $listing in $listings
$textContent = ""
yamlContent = nil

# read the file
$fileContent = IO.read($listing)
# try and split of any YAML
$partitionedFileContent = $fileContent.split('---');
# if there's potentially partitioned YAML try and parse it
if $partitionedFileContent.size > 2
# try and parse the YAML
yamlContent = YAML.load($partitionedFileContent[1])
# if we can, use it
if yamlContent != nil && yamlContent != false
$textContent = $partitionedFileContent[2..-1].join('---')
end
end

# if there's no text content set yet, just use the whole file
if $textContent == ""
# use the whole file content
$textContent = $fileContent
end
# append the current file to the content
($allPages ||= []) << ChildPage.new(yamlContent, $textContent)

end
# return the combined content
$allPages
end
end

class IncludePageContentTag < Liquid::Tag
def initialize(tag_name, text, tokens)
super
@text = text.strip
end
def render(context)
# $childPages = ChildPage.parseChildPagesFromParent(context['page'])
$childPages = ChildPage.parseChildYAMLFromParent(context['page'])
$content = ""
for $childPage in $childPages
#append the content
$content = $content+$childPage.content()
end
site = context.registers[:site]
pageHash = context.registers[:page]

# not sure how to get the page object so look through site.pages for the current URL
page = nil;
for currPage in site.pages
if currPage['url'] == pageHash['url']
page = currPage
break
end
end

# render the included content with the current page renderer
info = { :filters => [Jekyll::Filters], :registers => { :site => site, :page => page } }
page.render_liquid($content, site.site_payload, info)
end
end
end

Liquid::Template.register_tag('child_content', PageStructureUtils::IncludePageContentTag)
@@ -221,6 +221,34 @@ def self.gen_structure(site, item, parent, breadcrumb_pages_in, breadcrumb_paths
data['data'] = data
result = data
end

##
# This is added for inline seperate child files
# see: page_structure.rb
#
# require show_inline_children to be set to true to show in the menu
if page['check_directory_for_children'] == true
$childPages = PageStructureUtils::ChildPage.parseChildYAMLFromParent(page)
# add the child pages in before the site structure has been created
for $childPage in $childPages
if $childPage.yaml() != nil && $childPage.yaml() != false
# now add the YAML on as a child context to the page
if data['children'] == nil
data['children'] = []
end
data['children'] << $childPage.yaml()
end
end
end

##
# This sorts child pages by the YAML property section_position. This uses a versioning format so 1.1.0 > 1.0.4
# Any sections missing numbers will use their current position to determine their order
#
if data['children']
data['children'] = PageStructureUtils::ChildPage.sortYAMLSectionPositions(data['children'])
end

data['path'] = page.path
if item['href_path']
href_page = find_page_with_path_absolute_or_relative_to(site, render_liquid(site, page, item['href_path']), parent, structure_processed_pages)
@@ -309,6 +337,7 @@ def self.gen_structure(site, item, parent, breadcrumb_pages_in, breadcrumb_paths
end

if (data['children'])

data['menu'] = []
puts "children of #{data['path']} - #{data['children']}" if @@verbose
data['children'].each do |child|
@@ -0,0 +1,15 @@
---
layout: website-normal
title: Contributing to the Docs
check_directory_for_children: true
---

The Apache Brooklyn documentation is written in [kramdown](http://kramdown.gettalong.org/syntax.html){:target="_blank"} a superset of Markdown
which is processed into HTML using [Jekyll](https://jekyllrb.com/){:target="_blank"}. In addition to the standard set of options
and notation available with these platforms, a number of custom plug-ins have been implemented specifically
for the Apache Brooklyn docs. These are detailed below:

Jekyll plug-ins are written in ruby and kept in the `_plugins` folder. Note that if you're using `jekyll serve` to
display the site, changes to these plug-ins will not be reflected in the rendered site until jekyll is restarted.

{% child_content %}
@@ -0,0 +1,54 @@
---
section: Inline Children
section_position: 2
section_type: inline
---

### Inline Children

In addition to the `children` property defining lower pages in the site structure, they can also be used to define
inline sections within the current document. Inclusion in this way produces a menu link to an anchor in the current page.

Below is an example from [/guide/ops/persistence/index.md](https://github.com/apache/brooklyn-docs/blob/master/guide/ops/persistence/index.md){:target="_blank"}:

{% highlight yaml %}
children:
- { section: Command Line Options }
- { section: File-based Persistence }
- { section: Object Store Persistence }
- { section: Rebinding to State }
- { section: Writing Persistable Code }
- { section: Persisted State Backup }
{% endhighlight %}

Inline sections can also be detected from separate, child `.md` files. Including the tag `check_directory_for_children: true`
in the YAML front matter of a page causes the site structure plug-in to look through the current directory for any `.md` files
containing `section_type: inline` in the YAML front matter.

The content from these inline sections can then be included in the page content using the liquid tag `child_content`. This is shown below
in an example from [/guide/ops/locations/index.md](https://github.com/apache/brooklyn-docs/blob/master/guide/ops/locations/index.md){:target="_blank"}:

<pre>
---
title: Locations
layout: website-normal
check_directory_for_children: true
---

Locations are the environments to which Brooklyn deploys applications, including:

Brooklyn supports a wide range of locations:

* &lt;a href="#clouds"&gt;Clouds&lt;/a&gt;, where it will provision machines
* &lt;a href="#localhost"&gt;Localhost&lt;/a&gt; (e.g. your laptop),
where it will deploy via `ssh` to `localhost` for rapid testing
* &lt;a href="#byon"&gt;BYON&lt;/a&gt;, where you "bring your own nodes",
specifying already-existing hosts to use
* And many others, including object stores and online services

Configuration can be set in `~/.brooklyn/brooklyn.properties`
or directly in YAML when specifying a location.
On some entities, config keys determining maching selection and provisioning behavior
can also be set `in `provisioning.properties`.
{&#37; child_content &#37;}</pre>

0 comments on commit ae8b0ab

Please sign in to comment.