amber 0.2.6
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.
- data/LICENSE +661 -0
- data/README.md +114 -0
- data/bin/amber +71 -0
- data/lib/amber.rb +76 -0
- data/lib/amber/cli.rb +98 -0
- data/lib/amber/logger.rb +21 -0
- data/lib/amber/menu.rb +141 -0
- data/lib/amber/page_array.rb +61 -0
- data/lib/amber/render/asset.rb +55 -0
- data/lib/amber/render/autolink.rb +78 -0
- data/lib/amber/render/bracketlink.rb +33 -0
- data/lib/amber/render/helpers/haml_helper.rb +54 -0
- data/lib/amber/render/helpers/html_helper.rb +75 -0
- data/lib/amber/render/helpers/language_helper.rb +25 -0
- data/lib/amber/render/helpers/navigation_helper.rb +203 -0
- data/lib/amber/render/layout.rb +66 -0
- data/lib/amber/render/table_of_contents.rb +383 -0
- data/lib/amber/render/template.rb +158 -0
- data/lib/amber/render/view.rb +189 -0
- data/lib/amber/server.rb +113 -0
- data/lib/amber/site.rb +154 -0
- data/lib/amber/site_configuration.rb +132 -0
- data/lib/amber/static_page.rb +151 -0
- data/lib/amber/static_page/filesystem.rb +270 -0
- data/lib/amber/static_page/page_properties.rb +124 -0
- data/lib/amber/static_page/property_set.rb +78 -0
- data/lib/amber/static_page/render.rb +122 -0
- metadata +203 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
#
|
2
|
+
# Array of StaticPages
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'bigdecimal'
|
6
|
+
|
7
|
+
module Amber
|
8
|
+
class PageArray < Array
|
9
|
+
|
10
|
+
def limit(num)
|
11
|
+
PageArray.new(self[0..(num-1)])
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# available options:
|
16
|
+
#
|
17
|
+
# :locale -- the locale to use when comparing attributes
|
18
|
+
# :direction -- either :asc or :desc
|
19
|
+
# :numeric -- if true, attributes are cast as numbers before comparison
|
20
|
+
#
|
21
|
+
def order_by(attr, options={})
|
22
|
+
locale = options[:locale] || I18n.locale
|
23
|
+
direction = options[:direction] || :asc
|
24
|
+
array = sort do |a,b|
|
25
|
+
if direction == :desc
|
26
|
+
a, b = b, a
|
27
|
+
end
|
28
|
+
a_prop = a.prop(locale, attr)
|
29
|
+
b_prop = b.prop(locale, attr)
|
30
|
+
if options[:numeric]
|
31
|
+
a_prop = to_numeric(a_prop)
|
32
|
+
b_prop = to_numeric(b_prop)
|
33
|
+
end
|
34
|
+
if a_prop.nil? && b_prop.nil?
|
35
|
+
0
|
36
|
+
elsif a_prop.nil?
|
37
|
+
1
|
38
|
+
elsif b_prop.nil?
|
39
|
+
-1
|
40
|
+
else
|
41
|
+
a_prop <=> b_prop
|
42
|
+
end
|
43
|
+
end
|
44
|
+
# remove pages from the results that have no value set for the attr
|
45
|
+
array.delete_if do |page|
|
46
|
+
page.prop(locale, attr).nil?
|
47
|
+
end
|
48
|
+
return PageArray.new.replace array
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_numeric(anything)
|
52
|
+
num = BigDecimal.new(anything.to_s)
|
53
|
+
if num.frac == 0
|
54
|
+
num.to_i
|
55
|
+
else
|
56
|
+
num.to_f
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#
|
2
|
+
# For rendering things that are assets, like sass files.
|
3
|
+
# Maybe images too?
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'sass'
|
7
|
+
|
8
|
+
module Amber
|
9
|
+
module Render
|
10
|
+
class Asset
|
11
|
+
|
12
|
+
RENDER_MAP = {
|
13
|
+
'.sass' => {:method => 'render_sass', :new_suffix => '.css', :args => [:sass]},
|
14
|
+
'.scss' => {:method => 'render_sass', :new_suffix => '.css', :args => [:scss]}
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.render(src_file, dst_file)
|
18
|
+
unless Dir.exists?(File.dirname(dst_file))
|
19
|
+
FileUtils.mkdir_p(File.dirname(dst_file))
|
20
|
+
end
|
21
|
+
File.unlink(dst_file) if File.exists?(dst_file)
|
22
|
+
src_ext = File.extname(src_file)
|
23
|
+
renderer = RENDER_MAP[src_ext]
|
24
|
+
if renderer
|
25
|
+
content = self.send(renderer[:method], *([src_file] + renderer[:args]))
|
26
|
+
new_dst_file = dst_file.sub(/#{Regexp.escape(src_ext)}$/, renderer[:new_suffix])
|
27
|
+
File.open(new_dst_file,'w') do |w|
|
28
|
+
w.write(content)
|
29
|
+
end
|
30
|
+
else
|
31
|
+
File.link(src_file, dst_file)
|
32
|
+
end
|
33
|
+
rescue SystemCallError => exc
|
34
|
+
Amber.log_exception(exc)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.render_dir(src_dir, dst_dir)
|
38
|
+
Dir.chdir(src_dir) do
|
39
|
+
Dir.glob('*').each do |file|
|
40
|
+
next if File.directory?(file) || file =~ /^\./
|
41
|
+
src_file = File.join(src_dir, file)
|
42
|
+
dst_file = File.join(dst_dir, file)
|
43
|
+
render(src_file, dst_file)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.render_sass(src_file, syntax)
|
49
|
+
engine = Sass::Engine.new(File.read(src_file), :syntax => syntax)
|
50
|
+
engine.render
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# adapted from https://github.com/tenderlove/rails_autolink
|
3
|
+
# MIT license
|
4
|
+
|
5
|
+
module Amber::Render::Autolink
|
6
|
+
|
7
|
+
def self.auto_link(text)
|
8
|
+
auto_link_email_addresses(auto_link_urls(text))
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
AUTO_LINK_RE = %r{
|
14
|
+
(?: ((?:ed2k|ftp|http|https|irc|mailto|news|gopher|nntp|telnet|webcal|xmpp|callto|feed|svn|urn|aim|rsync|tag|ssh|sftp|rtsp|afs|file):)// | www\. )
|
15
|
+
[^\s<\u00A0]+
|
16
|
+
}ix
|
17
|
+
|
18
|
+
# regexps for determining context, used high-volume
|
19
|
+
AUTO_LINK_CRE = [/<[^>]+$/, /^[^>]*>/, /<a\b.*?>/i, /<\/a>/i]
|
20
|
+
|
21
|
+
AUTO_EMAIL_LOCAL_RE = /[\w.!#\$%&'*\/=?^`{|}~+-]/
|
22
|
+
AUTO_EMAIL_RE = /[\w.!#\$%+-]\.?#{AUTO_EMAIL_LOCAL_RE}*@[\w-]+(?:\.[\w-]+)+/
|
23
|
+
|
24
|
+
BRACKETS = { ']' => '[', ')' => '(', '}' => '{' }
|
25
|
+
|
26
|
+
WORD_PATTERN = RUBY_VERSION < '1.9' ? '\w' : '\p{Word}'
|
27
|
+
|
28
|
+
# Turns all urls into clickable links. If a block is given, each url
|
29
|
+
# is yielded and the result is used as the link text.
|
30
|
+
def self.auto_link_urls(text)
|
31
|
+
text.gsub(AUTO_LINK_RE) do
|
32
|
+
scheme, href = $1, $&
|
33
|
+
punctuation = []
|
34
|
+
|
35
|
+
if auto_linked?($`, $')
|
36
|
+
# do not change string; URL is already linked
|
37
|
+
href
|
38
|
+
else
|
39
|
+
# don't include trailing punctuation character as part of the URL
|
40
|
+
while href.sub!(/[^#{WORD_PATTERN}\/-]$/, '')
|
41
|
+
punctuation.push $&
|
42
|
+
if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size
|
43
|
+
href << punctuation.pop
|
44
|
+
break
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
#link_text = block_given?? yield(href) : href
|
49
|
+
link_text = href.sub(/^#{scheme}\/\//,'')
|
50
|
+
href = 'http://' + href unless scheme
|
51
|
+
%(<a href="#{href}">#{link_text}</a>) + punctuation.reverse.join('')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Turns all email addresses into clickable links.
|
57
|
+
def self.auto_link_email_addresses(text)
|
58
|
+
text.gsub(AUTO_EMAIL_RE) do
|
59
|
+
text = $&
|
60
|
+
|
61
|
+
if auto_linked?($`, $')
|
62
|
+
text
|
63
|
+
else
|
64
|
+
#display_text = (block_given?) ? yield(text) : text
|
65
|
+
#display_text = text
|
66
|
+
text.gsub!('@', '@').gsub!('.', '.')
|
67
|
+
%(<a href="mailto:#{text}">#{text}</a>)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Detects already linked context or position in the middle of a tag
|
73
|
+
def self.auto_linked?(left, right)
|
74
|
+
(left =~ AUTO_LINK_CRE[0] and right =~ AUTO_LINK_CRE[1]) or
|
75
|
+
(left.rindex(AUTO_LINK_CRE[2]) and $' !~ AUTO_LINK_CRE[3])
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# bracket links are links in the form [[label => target]] or [[page-name]]
|
5
|
+
#
|
6
|
+
|
7
|
+
module Amber::Render::Bracketlink
|
8
|
+
|
9
|
+
# linking using double square brackets
|
10
|
+
BRACKET_LINK_RE = /
|
11
|
+
\[\[ # start [[
|
12
|
+
([^\[\]]+) # $text : one or more characters that are not [ or ] ($1)
|
13
|
+
\]\] # end ]]
|
14
|
+
/x
|
15
|
+
|
16
|
+
def self.bracket_link(text, &block)
|
17
|
+
text.gsub(BRACKET_LINK_RE) do |m|
|
18
|
+
link_text = $~[1].strip
|
19
|
+
if link_text =~ /^.+\s*[-=]>\s*.+$/
|
20
|
+
# link_text == "from -> to"
|
21
|
+
from, to = link_text.split(/\s*[-=]>\s*/)[0..1]
|
22
|
+
from = "" unless from.instance_of? String # \ sanity check for
|
23
|
+
to = "" unless from.instance_of? String # / badly formed links
|
24
|
+
else
|
25
|
+
# link_text == "to" (ie, no link label)
|
26
|
+
from = nil
|
27
|
+
to = link_text
|
28
|
+
end
|
29
|
+
yield(from, to)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module HamlHelper
|
4
|
+
|
5
|
+
#
|
6
|
+
# acts like haml_tag, capture_haml, or haml_concat, depending on how it is called.
|
7
|
+
#
|
8
|
+
# two or more args --> like haml_tag
|
9
|
+
# one arg and a block --> like haml_tag
|
10
|
+
# zero args and a block --> like capture_haml
|
11
|
+
# one arg and no block --> like haml_concat
|
12
|
+
#
|
13
|
+
# additionally, we allow the use of more than one class.
|
14
|
+
#
|
15
|
+
# some examples of these usages:
|
16
|
+
#
|
17
|
+
# def display_robot(robot)
|
18
|
+
# haml do # like capture_haml
|
19
|
+
# haml '.head', robot.head_html # like haml_tag
|
20
|
+
# haml '.head' do # same
|
21
|
+
# haml robot.head_html
|
22
|
+
# end
|
23
|
+
# haml '.body.metal', robot.body_html # like haml_tag, but with multiple classes
|
24
|
+
# haml '<a href="/x">link</a>' # like haml_concat
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# wrapping the helper in a capture_haml call is very useful, because then
|
29
|
+
# the helper can be used wherever a normal helper would be.
|
30
|
+
#
|
31
|
+
def haml(name=nil, *args, &block)
|
32
|
+
if name
|
33
|
+
if args.empty? and block.nil?
|
34
|
+
haml_concat name
|
35
|
+
else
|
36
|
+
if name =~ /^(.*?\.[^\.]*)(\..*)$/
|
37
|
+
# allow chaining of classes if there are multiple '.' in the first arg
|
38
|
+
name = $1
|
39
|
+
classes = $2.gsub('.',' ')
|
40
|
+
hsh = args.detect{|i| i.is_a?(Hash)}
|
41
|
+
unless hsh
|
42
|
+
hsh = {}
|
43
|
+
args << hsh
|
44
|
+
end
|
45
|
+
hsh[:class] = classes
|
46
|
+
end
|
47
|
+
haml_tag(name, *args, &block)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
capture_haml(&block)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Amber
|
2
|
+
module Render
|
3
|
+
module HtmlHelper
|
4
|
+
|
5
|
+
def html_head_base
|
6
|
+
href = (['..'] * @page.path.count).join('/')
|
7
|
+
"<base href=\"#{href}\" />"
|
8
|
+
end
|
9
|
+
|
10
|
+
#
|
11
|
+
# three forms:
|
12
|
+
#
|
13
|
+
# (1) link('page-name')
|
14
|
+
# (2) link('label' => 'page-name')
|
15
|
+
# (3) link('label' => 'https://url')
|
16
|
+
#
|
17
|
+
# both accept optional options hash:
|
18
|
+
#
|
19
|
+
# (1) link('page-name', :class => 'x')
|
20
|
+
# (2) link('label' => 'page-name', :class => 'x')
|
21
|
+
#
|
22
|
+
def link(name, options=nil)
|
23
|
+
options = nil if options && !options.is_a?(Hash)
|
24
|
+
if name.is_a? Hash
|
25
|
+
klass = name.delete(:class)
|
26
|
+
label, name = name.to_a.first
|
27
|
+
if label.is_a? Symbol
|
28
|
+
label = I18n.t label
|
29
|
+
end
|
30
|
+
else
|
31
|
+
klass = options[:class] if options
|
32
|
+
end
|
33
|
+
if name =~ /^#/ || name =~ /^http/ || name =~ /\./
|
34
|
+
path = name
|
35
|
+
label ||= name
|
36
|
+
else
|
37
|
+
if index = name.index('#')
|
38
|
+
anchor = name[index..-1]
|
39
|
+
name_without_anchor = name[0..(index-1)]
|
40
|
+
else
|
41
|
+
anchor = ''
|
42
|
+
name_without_anchor = name
|
43
|
+
end
|
44
|
+
page = @site.find_page(name_without_anchor)
|
45
|
+
if page
|
46
|
+
label ||= page.nav_title
|
47
|
+
path = page_path(page) + anchor
|
48
|
+
else
|
49
|
+
puts "warning: dead link to `#{name_without_anchor}` from page `/#{I18n.locale}/#{@page.path.join('/')}`"
|
50
|
+
label ||= name_without_anchor
|
51
|
+
label += ' [dead link]'
|
52
|
+
path = name_without_anchor
|
53
|
+
end
|
54
|
+
end
|
55
|
+
if klass
|
56
|
+
%(<a href="#{path}" class="#{klass}">#{label}</a>)
|
57
|
+
else
|
58
|
+
%(<a href="#{path}">#{label}</a>)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# returns the shortest possible path. this would be nice to support some day, but more difficult with statically rendered sites.
|
64
|
+
#
|
65
|
+
def page_path(page, locale=I18n.locale)
|
66
|
+
if page.prop(locale, :alias)
|
67
|
+
"/#{locale}/#{page.prop(locale, :alias).first}/#{page.name}"
|
68
|
+
else
|
69
|
+
"/#{locale}/#{page.path.join('/')}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Amber
|
2
|
+
module Render
|
3
|
+
module LanguageHelper
|
4
|
+
|
5
|
+
def t(*args)
|
6
|
+
I18n.t(*args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def translation_missing?
|
10
|
+
!@page.content_file_exists?(I18n.locale)
|
11
|
+
end
|
12
|
+
|
13
|
+
# return array of arrays, each array with: language_name, language_code, current_url_with_locale_switch
|
14
|
+
#
|
15
|
+
# [ ['English', :en, 'en/about-us'] ]
|
16
|
+
#
|
17
|
+
def available_languages
|
18
|
+
@site.locales.collect { |locale|
|
19
|
+
[Amber::POSSIBLE_LANGUAGES[locale][0], locale, "/"+([locale]+current_page_path).join('/')]
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
module Amber
|
2
|
+
module Render
|
3
|
+
module NavigationHelper
|
4
|
+
|
5
|
+
def has_navigation?
|
6
|
+
if current_page_path.empty? || @site.menu.nil?
|
7
|
+
false
|
8
|
+
else
|
9
|
+
submenu = @site.menu.submenu(current_page_path.first)
|
10
|
+
if submenu
|
11
|
+
second_level_children_count = submenu.size
|
12
|
+
if second_level_children_count.nil?
|
13
|
+
false
|
14
|
+
else
|
15
|
+
second_level_children_count >= 1
|
16
|
+
end
|
17
|
+
else
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# yields each item
|
25
|
+
#
|
26
|
+
def top_navigation_items(options={})
|
27
|
+
if !@site.menu
|
28
|
+
yield({})
|
29
|
+
else
|
30
|
+
first = 'first'
|
31
|
+
if options[:include_home]
|
32
|
+
active = current_page_path.empty? ? 'active' : ''
|
33
|
+
yield({:class => [first, active].compact.join(' '), :href => menu_item_path(@site.menu), :label => menu_item_title(@site.menu)})
|
34
|
+
first = nil
|
35
|
+
end
|
36
|
+
@site.menu.each do |item|
|
37
|
+
active = current_page_path.first == item.name ? 'active' : ''
|
38
|
+
yield({:class => [first, active].compact.join(' '), :href => menu_item_path(item), :label => menu_item_title(item)})
|
39
|
+
first = nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# yields each item
|
46
|
+
#
|
47
|
+
def navigation_items(menu=nil, level=1, &block)
|
48
|
+
if menu.nil?
|
49
|
+
menu = site.menu.submenu(current_page_path.first)
|
50
|
+
end
|
51
|
+
if menu
|
52
|
+
menu.each do |item|
|
53
|
+
title = menu_item_title(item)
|
54
|
+
if title
|
55
|
+
yield({
|
56
|
+
:href => menu_item_path(item),
|
57
|
+
:level => level,
|
58
|
+
:active => path_active_class(current_page_path, item),
|
59
|
+
:label => title
|
60
|
+
})
|
61
|
+
end
|
62
|
+
if path_open?(current_page_path, item)
|
63
|
+
navigation_items(item.submenu, level+1, &block)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def current_page_path
|
70
|
+
@current_page_path ||= begin
|
71
|
+
if @page
|
72
|
+
@page.path
|
73
|
+
#elsif params[:page].is_a? String
|
74
|
+
# params[:page].split('/')
|
75
|
+
else
|
76
|
+
[]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def menu_item_path(item)
|
82
|
+
"/" + ([I18n.locale]+item.path).join('/')
|
83
|
+
end
|
84
|
+
|
85
|
+
def menu_item_title(item)
|
86
|
+
page = @site.find_page_by_path(item.path_str) || @site.find_page_by_name(item.name)
|
87
|
+
if page
|
88
|
+
page.nav_title(I18n.locale)
|
89
|
+
else
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# inserts an directory index built from the page's children
|
96
|
+
#
|
97
|
+
# options:
|
98
|
+
# :levels -- the max levels to descend, default is 1
|
99
|
+
# :page -- StaticPage instance or nil
|
100
|
+
# :include_toc -- true or false
|
101
|
+
# :order_by -- arguments to PageArray#order_by
|
102
|
+
# :heading -- heading level to use
|
103
|
+
#
|
104
|
+
def child_summaries(options={})
|
105
|
+
page = options.delete(:page) || @page
|
106
|
+
unless page.is_a?(StaticPage)
|
107
|
+
page = @site.find_pages(page)
|
108
|
+
end
|
109
|
+
return "" if page.nil? or page.children.empty?
|
110
|
+
|
111
|
+
levels_max = options[:levels] || 1
|
112
|
+
level = options.delete(:level) || 1
|
113
|
+
heading = options.delete(:heading) || 2
|
114
|
+
locale = @locals[:locale]
|
115
|
+
menu = submenu_for_page(page)
|
116
|
+
if menu && menu.children.any?
|
117
|
+
children = menu.children
|
118
|
+
elsif options[:order_by]
|
119
|
+
children = page.children.order_by(*options[:order_by])
|
120
|
+
else
|
121
|
+
children = page.children
|
122
|
+
end
|
123
|
+
|
124
|
+
haml do
|
125
|
+
children.each do |child|
|
126
|
+
child_page = child.is_a?(Amber::Menu) ? page.child(child.name) : child
|
127
|
+
next unless child_page
|
128
|
+
haml "h#{heading}" do
|
129
|
+
haml :a, child_page.nav_title(locale), :href => page_path(child_page)
|
130
|
+
end
|
131
|
+
if summary = child_page.prop(locale, 'summary')
|
132
|
+
haml :p, summary
|
133
|
+
end
|
134
|
+
if options[:include_toc]
|
135
|
+
toc_html = render_toc(child_page, :locale => locale)
|
136
|
+
haml toc_html
|
137
|
+
end
|
138
|
+
if level < levels_max
|
139
|
+
haml(child_summaries({
|
140
|
+
:page => child_page,
|
141
|
+
:levels => levels_max,
|
142
|
+
:level => level+1,
|
143
|
+
:include_toc => options[:include_toc],
|
144
|
+
:order_by => options[:order_by],
|
145
|
+
:heading => heading+1
|
146
|
+
}))
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
rescue Exception => exc
|
151
|
+
Amber.log_exception(exc)
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
#
|
157
|
+
# returns string 'active', 'semi-active', or ''
|
158
|
+
#
|
159
|
+
def path_active_class(page_path, menu_item)
|
160
|
+
active = ''
|
161
|
+
if menu_item.path == page_path
|
162
|
+
active = 'active'
|
163
|
+
elsif menu_item.path_prefix_of?(page_path)
|
164
|
+
if menu_item.leaf_for_path?(page_path)
|
165
|
+
active = 'active'
|
166
|
+
else
|
167
|
+
active = 'semi-active'
|
168
|
+
end
|
169
|
+
end
|
170
|
+
active
|
171
|
+
end
|
172
|
+
|
173
|
+
#
|
174
|
+
# returns true if menu_item represents an parent of page
|
175
|
+
#
|
176
|
+
def path_open?(page_path, menu_item)
|
177
|
+
menu_item.path == page_path || menu_item.path_prefix_of?(page_path)
|
178
|
+
end
|
179
|
+
|
180
|
+
def submenu_for_page(page)
|
181
|
+
menu = @site.menu
|
182
|
+
page.path.each do |segment|
|
183
|
+
menu = menu.submenu(segment)
|
184
|
+
end
|
185
|
+
return menu
|
186
|
+
rescue
|
187
|
+
return nil
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
=begin
|
196
|
+
|
197
|
+
def act_as(page)
|
198
|
+
page = site.find_page(page)
|
199
|
+
@current_page_path = page.path
|
200
|
+
page_body(page)
|
201
|
+
end
|
202
|
+
|
203
|
+
=end
|