amber 0.2.6 → 0.3.8

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.
Files changed (129) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +14 -1
  3. data/README.md +88 -19
  4. data/bin/amber +26 -13
  5. data/lib/amber.rb +25 -39
  6. data/lib/amber/cli.rb +25 -1
  7. data/lib/amber/i18n.rb +43 -0
  8. data/lib/amber/render/apache.rb +44 -0
  9. data/lib/amber/render/asset.rb +28 -2
  10. data/lib/amber/render/helpers/blog_helper.rb +35 -0
  11. data/lib/amber/render/helpers/date_helper.rb +14 -0
  12. data/lib/amber/render/helpers/haml_helper.rb +9 -0
  13. data/lib/amber/render/helpers/html_helper.rb +30 -8
  14. data/lib/amber/render/helpers/navigation_helper.rb +31 -32
  15. data/lib/amber/render/layout.rb +2 -1
  16. data/lib/amber/render/template.rb +24 -11
  17. data/lib/amber/render/view.rb +31 -12
  18. data/lib/amber/server.rb +122 -56
  19. data/lib/amber/site.rb +171 -29
  20. data/lib/amber/site_configuration.rb +26 -11
  21. data/lib/amber/static_page.rb +34 -20
  22. data/lib/amber/static_page/filesystem.rb +3 -7
  23. data/lib/amber/static_page/page_properties.rb +7 -0
  24. data/lib/amber/static_page/render.rb +47 -31
  25. data/lib/amber/templates/apache_config.erb +12 -0
  26. data/lib/amber/templates/apache_config_with_prefix.erb +14 -0
  27. data/lib/amber/templates/htaccess.erb +176 -0
  28. data/lib/amber/version.rb +5 -0
  29. data/locales/rails-i18n/af.yml +201 -0
  30. data/locales/rails-i18n/ar.yml +274 -0
  31. data/locales/rails-i18n/az.yml +192 -0
  32. data/locales/rails-i18n/bg.yml +192 -0
  33. data/locales/rails-i18n/bn.yml +175 -0
  34. data/locales/rails-i18n/bs.yml +243 -0
  35. data/locales/rails-i18n/ca.yml +192 -0
  36. data/locales/rails-i18n/cs.yml +210 -0
  37. data/locales/rails-i18n/cy.yml +242 -0
  38. data/locales/rails-i18n/da.yml +198 -0
  39. data/locales/rails-i18n/de-AT.yml +202 -0
  40. data/locales/rails-i18n/de-CH.yml +206 -0
  41. data/locales/rails-i18n/de.yml +202 -0
  42. data/locales/rails-i18n/el.yml +198 -0
  43. data/locales/rails-i18n/en-AU.yml +198 -0
  44. data/locales/rails-i18n/en-CA.yml +207 -0
  45. data/locales/rails-i18n/en-GB.yml +198 -0
  46. data/locales/rails-i18n/en-IE.yml +198 -0
  47. data/locales/rails-i18n/en-IN.yml +198 -0
  48. data/locales/rails-i18n/en-NZ.yml +198 -0
  49. data/locales/rails-i18n/en-US.yml +204 -0
  50. data/locales/rails-i18n/en-ZA.yml +204 -0
  51. data/locales/rails-i18n/en.yml +204 -0
  52. data/locales/rails-i18n/eo.yml +194 -0
  53. data/locales/rails-i18n/es-419.yml +207 -0
  54. data/locales/rails-i18n/es-AR.yml +198 -0
  55. data/locales/rails-i18n/es-CL.yml +192 -0
  56. data/locales/rails-i18n/es-CO.yml +198 -0
  57. data/locales/rails-i18n/es-CR.yml +198 -0
  58. data/locales/rails-i18n/es-EC.yml +204 -0
  59. data/locales/rails-i18n/es-MX.yml +204 -0
  60. data/locales/rails-i18n/es-PA.yml +204 -0
  61. data/locales/rails-i18n/es-PE.yml +177 -0
  62. data/locales/rails-i18n/es-US.yml +198 -0
  63. data/locales/rails-i18n/es-VE.yml +198 -0
  64. data/locales/rails-i18n/es.yml +192 -0
  65. data/locales/rails-i18n/et.yml +192 -0
  66. data/locales/rails-i18n/eu.yml +192 -0
  67. data/locales/rails-i18n/fa.yml +192 -0
  68. data/locales/rails-i18n/fi.yml +192 -0
  69. data/locales/rails-i18n/fr-CA.yml +200 -0
  70. data/locales/rails-i18n/fr-CH.yml +200 -0
  71. data/locales/rails-i18n/fr.yml +214 -0
  72. data/locales/rails-i18n/gl.yml +171 -0
  73. data/locales/rails-i18n/he.yml +194 -0
  74. data/locales/rails-i18n/hi-IN.yml +192 -0
  75. data/locales/rails-i18n/hi.yml +192 -0
  76. data/locales/rails-i18n/hr.yml +236 -0
  77. data/locales/rails-i18n/hu.yml +192 -0
  78. data/locales/rails-i18n/id.yml +193 -0
  79. data/locales/rails-i18n/is.yml +212 -0
  80. data/locales/rails-i18n/iso-639-2/csb.yml +203 -0
  81. data/locales/rails-i18n/iso-639-2/dsb.yml +208 -0
  82. data/locales/rails-i18n/iso-639-2/fur.yml +192 -0
  83. data/locales/rails-i18n/iso-639-2/gsw-CH.yml +196 -0
  84. data/locales/rails-i18n/iso-639-2/hsb.yml +207 -0
  85. data/locales/rails-i18n/iso-639-2/pap-AW.yml +205 -0
  86. data/locales/rails-i18n/iso-639-2/pap-CW.yml +205 -0
  87. data/locales/rails-i18n/iso-639-2/scr.yml +236 -0
  88. data/locales/rails-i18n/it-CH.yml +198 -0
  89. data/locales/rails-i18n/it.yml +204 -0
  90. data/locales/rails-i18n/ja.yml +194 -0
  91. data/locales/rails-i18n/km.yml +54 -0
  92. data/locales/rails-i18n/kn.yml +192 -0
  93. data/locales/rails-i18n/ko.yml +190 -0
  94. data/locales/rails-i18n/lo.yml +227 -0
  95. data/locales/rails-i18n/lt.yml +217 -0
  96. data/locales/rails-i18n/lv.yml +229 -0
  97. data/locales/rails-i18n/mk.yml +198 -0
  98. data/locales/rails-i18n/mn.yml +198 -0
  99. data/locales/rails-i18n/ms.yml +200 -0
  100. data/locales/rails-i18n/nb.yml +205 -0
  101. data/locales/rails-i18n/ne.yml +198 -0
  102. data/locales/rails-i18n/nl.yml +204 -0
  103. data/locales/rails-i18n/nn.yml +201 -0
  104. data/locales/rails-i18n/or.yml +192 -0
  105. data/locales/rails-i18n/pl.yml +236 -0
  106. data/locales/rails-i18n/pt-BR.yml +206 -0
  107. data/locales/rails-i18n/pt.yml +200 -0
  108. data/locales/rails-i18n/rm.yml +223 -0
  109. data/locales/rails-i18n/ro.yml +205 -0
  110. data/locales/rails-i18n/ru.yml +256 -0
  111. data/locales/rails-i18n/sk.yml +206 -0
  112. data/locales/rails-i18n/sl.yml +205 -0
  113. data/locales/rails-i18n/sr.yml +236 -0
  114. data/locales/rails-i18n/sv.yml +192 -0
  115. data/locales/rails-i18n/sw.yml +190 -0
  116. data/locales/rails-i18n/ta.yml +204 -0
  117. data/locales/rails-i18n/th.yml +166 -0
  118. data/locales/rails-i18n/tl.yml +224 -0
  119. data/locales/rails-i18n/tr.yml +204 -0
  120. data/locales/rails-i18n/uk.yml +250 -0
  121. data/locales/rails-i18n/ur.yml +204 -0
  122. data/locales/rails-i18n/uz.yml +250 -0
  123. data/locales/rails-i18n/vi.yml +198 -0
  124. data/locales/rails-i18n/wo.yml +198 -0
  125. data/locales/rails-i18n/zh-CN.yml +203 -0
  126. data/locales/rails-i18n/zh-HK.yml +204 -0
  127. data/locales/rails-i18n/zh-TW.yml +203 -0
  128. data/locales/rails-i18n/zh-YUE.yml +204 -0
  129. metadata +164 -74
@@ -14,6 +14,10 @@ module Amber
14
14
  '.scss' => {:method => 'render_sass', :new_suffix => '.css', :args => [:scss]}
15
15
  }
16
16
 
17
+ SOURCE_MAP = {
18
+ '.css' => ['.sass', '.scss']
19
+ }
20
+
17
21
  def self.render(src_file, dst_file)
18
22
  unless Dir.exists?(File.dirname(dst_file))
19
23
  FileUtils.mkdir_p(File.dirname(dst_file))
@@ -27,6 +31,10 @@ module Amber
27
31
  File.open(new_dst_file,'w') do |w|
28
32
  w.write(content)
29
33
  end
34
+ elsif File.basename(src_file) == '.htaccess'
35
+ # existing htaccess file must be copied, not linked, since
36
+ # the render will change its contents.
37
+ FileUtils.cp(src_file, dst_file)
30
38
  else
31
39
  File.link(src_file, dst_file)
32
40
  end
@@ -34,10 +42,19 @@ module Amber
34
42
  Amber.log_exception(exc)
35
43
  end
36
44
 
45
+ #
46
+ # Render assets in a single directory (does not walk
47
+ # directory tree). Files prefixed with an _ are treated
48
+ # as partials and not rendered.
49
+ #
37
50
  def self.render_dir(src_dir, dst_dir)
38
51
  Dir.chdir(src_dir) do
39
52
  Dir.glob('*').each do |file|
40
- next if File.directory?(file) || file =~ /^\./
53
+ if File.directory?(file) ||
54
+ file =~ /^\./ ||
55
+ file =~ /^_/
56
+ next
57
+ end
41
58
  src_file = File.join(src_dir, file)
42
59
  dst_file = File.join(dst_dir, file)
43
60
  render(src_file, dst_file)
@@ -46,10 +63,19 @@ module Amber
46
63
  end
47
64
 
48
65
  def self.render_sass(src_file, syntax)
49
- engine = Sass::Engine.new(File.read(src_file), :syntax => syntax)
66
+ engine = Sass::Engine.new(
67
+ File.read(src_file),
68
+ :syntax => syntax,
69
+ :load_paths => [File.dirname(src_file)],
70
+ :style => self.sass_render_style
71
+ )
50
72
  engine.render
51
73
  end
52
74
 
75
+ def self.sass_render_style
76
+ Amber::env == :production ? :compact : :nested
77
+ end
78
+
53
79
  end
54
80
  end
55
81
  end
@@ -0,0 +1,35 @@
1
+ module Amber
2
+ module Render
3
+ module BlogHelper
4
+
5
+ def recent_summaries(options={}, &block)
6
+ limit = options[:limit] || @site.pagination_size
7
+ order = options[:order] || :posted_at
8
+ direction = options[:direction] || :desc
9
+ partial = options[:partial]
10
+ if options[:path]
11
+ @site.find_page(options[:path])
12
+ else
13
+ root = @site.root
14
+ end
15
+ if root
16
+ pages = root.all_children.order_by(order, :direction => direction).limit(limit)
17
+ haml do
18
+ pages.each do |page|
19
+ if block
20
+ yield page
21
+ else
22
+ render_page_summary(page)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ #@def news_feed_link
30
+ # link_to(image_tag('/img/feed-icon-14x14.png'), "/#{I18n.locale}/news.atom")
31
+ #end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ module Amber
2
+ module Render
3
+ module HtmlHelper
4
+ def time_tag(date_or_time, *args, &block)
5
+ options = args.last.is_a?(Hash) ? args.pop : {}
6
+ format = options.delete(:format) || :long
7
+ content = args.first || I18n.l(date_or_time, :format => format)
8
+ #datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.iso8601
9
+ datetime = date_or_time.iso8601
10
+ content_tag(:time, content, {:datetime => datetime}.merge(options), &block)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -51,4 +51,13 @@ module HamlHelper
51
51
  end
52
52
  end
53
53
 
54
+ def content_tag(name, content_or_options_with_block = nil, options = nil, &block)
55
+ if block_given?
56
+ options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
57
+ capture_haml { haml(name, options, &block) }
58
+ else
59
+ capture_haml { haml_tag(name, content_or_options_with_block, options) }
60
+ end
61
+ end
62
+
54
63
  end
@@ -2,9 +2,18 @@ module Amber
2
2
  module Render
3
3
  module HtmlHelper
4
4
 
5
+ #
6
+ # return html markup suitable for setting the href base
7
+ # of the document. If this is added to the document's HEAD,
8
+ # then relative urls will work as expected even though the
9
+ # url path does not end with a '/'
10
+ #
5
11
  def html_head_base
6
- href = (['..'] * @page.path.count).join('/')
7
- "<base href=\"#{href}\" />"
12
+ if @page
13
+ "<base href=\"#{amber_path(@page)}/\" />"
14
+ else
15
+ ""
16
+ end
8
17
  end
9
18
 
10
19
  #
@@ -44,7 +53,7 @@ module Amber
44
53
  page = @site.find_page(name_without_anchor)
45
54
  if page
46
55
  label ||= page.nav_title
47
- path = page_path(page) + anchor
56
+ path = amber_path(page) + anchor
48
57
  else
49
58
  puts "warning: dead link to `#{name_without_anchor}` from page `/#{I18n.locale}/#{@page.path.join('/')}`"
50
59
  label ||= name_without_anchor
@@ -60,14 +69,27 @@ module Amber
60
69
  end
61
70
 
62
71
  #
63
- # returns the shortest possible path. this would be nice to support some day, but more difficult with statically rendered sites.
72
+ # returns the ideal full url path for a page or path (expressed as an array).
64
73
  #
65
- def page_path(page, locale=I18n.locale)
66
- if page.prop(locale, :alias)
67
- "/#{locale}/#{page.prop(locale, :alias).first}/#{page.name}"
74
+ def amber_path(page_or_array, locale=I18n.locale)
75
+ page = nil
76
+ if page_or_array.is_a? Array
77
+ page = @site.find_page_by_path(page_or_array)
78
+ elsif page_or_array.is_a? StaticPage
79
+ page = page_or_array
80
+ end
81
+ if page.nil?
82
+ return ''
83
+ end
84
+ full_path = []
85
+ full_path << @site.path_prefix if @site.path_prefix
86
+ full_path << locale # always do this?
87
+ if page.aliases(locale).any?
88
+ full_path += page.aliases(locale).first
68
89
  else
69
- "/#{locale}/#{page.path.join('/')}"
90
+ full_path += page.path
70
91
  end
92
+ "/" + full_path.join('/')
71
93
  end
72
94
 
73
95
  end
@@ -30,12 +30,12 @@ module Amber
30
30
  first = 'first'
31
31
  if options[:include_home]
32
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)})
33
+ yield({:class => [first, active].compact.join(' '), :href => amber_path(@site.menu.path), :label => menu_item_title(@site.menu)})
34
34
  first = nil
35
35
  end
36
36
  @site.menu.each do |item|
37
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)})
38
+ yield({:class => [first, active].compact.join(' '), :href => amber_path(item.path), :label => menu_item_title(item)})
39
39
  first = nil
40
40
  end
41
41
  end
@@ -53,7 +53,7 @@ module Amber
53
53
  title = menu_item_title(item)
54
54
  if title
55
55
  yield({
56
- :href => menu_item_path(item),
56
+ :href => amber_path(item.path),
57
57
  :level => level,
58
58
  :active => path_active_class(current_page_path, item),
59
59
  :label => title
@@ -78,10 +78,6 @@ module Amber
78
78
  end
79
79
  end
80
80
 
81
- def menu_item_path(item)
82
- "/" + ([I18n.locale]+item.path).join('/')
83
- end
84
-
85
81
  def menu_item_title(item)
86
82
  page = @site.find_page_by_path(item.path_str) || @site.find_page_by_name(item.name)
87
83
  if page
@@ -95,11 +91,12 @@ module Amber
95
91
  # inserts an directory index built from the page's children
96
92
  #
97
93
  # options:
98
- # :levels -- the max levels to descend, default is 1
94
+ # :levels -- the max levels to descend (default 1)
99
95
  # :page -- StaticPage instance or nil
100
- # :include_toc -- true or false
96
+ # :include_toc -- true or false (default false)
101
97
  # :order_by -- arguments to PageArray#order_by
102
- # :heading -- heading level to use
98
+ # :heading -- heading level to use (default 2)
99
+ # :summary -- to show summaries or not (default true)
103
100
  #
104
101
  def child_summaries(options={})
105
102
  page = options.delete(:page) || @page
@@ -125,16 +122,7 @@ module Amber
125
122
  children.each do |child|
126
123
  child_page = child.is_a?(Amber::Menu) ? page.child(child.name) : child
127
124
  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
125
+ render_page_summary(child_page, heading, options)
138
126
  if level < levels_max
139
127
  haml(child_summaries({
140
128
  :page => child_page,
@@ -142,7 +130,8 @@ module Amber
142
130
  :level => level+1,
143
131
  :include_toc => options[:include_toc],
144
132
  :order_by => options[:order_by],
145
- :heading => heading+1
133
+ :heading => heading+1,
134
+ :summary => options[:summary]
146
135
  }))
147
136
  end
148
137
  end
@@ -151,6 +140,27 @@ module Amber
151
140
  Amber.log_exception(exc)
152
141
  end
153
142
 
143
+ def render_page_summary(page, heading=2, options={})
144
+ locale = @locals[:locale]
145
+ klass = options[:class] || '.page-summary'
146
+ haml ".#{klass}" do
147
+ haml "h#{heading}" do
148
+ haml :a, page.nav_title(locale), :href => amber_path(page)
149
+ end
150
+ if options[:summary] != false
151
+ if summary = page.prop(locale, 'summary')
152
+ haml '.summary', summary
153
+ elsif preview = page.prop(locale, 'preview')
154
+ haml '.preview', preview
155
+ end
156
+ end
157
+ if options[:include_toc]
158
+ toc_html = render_toc(page, :locale => locale)
159
+ haml toc_html
160
+ end
161
+ end
162
+ end
163
+
154
164
  private
155
165
 
156
166
  #
@@ -190,14 +200,3 @@ module Amber
190
200
  end
191
201
  end
192
202
  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
@@ -35,7 +35,8 @@ module Amber
35
35
 
36
36
  def initialize(file_path, &block)
37
37
  if file_path =~ /\.haml$/
38
- @template = Tilt::HamlTemplate.new(file_path, {:format => :html5})
38
+ ugly = Amber.env != :test
39
+ @template = Tilt::HamlTemplate.new(file_path, {:format => :html5, :ugly => ugly})
39
40
  else
40
41
  @template = Tilt.new(file_path, &block)
41
42
  end
@@ -14,7 +14,10 @@ module Amber
14
14
  :textile => 'render_textile',
15
15
  :md => 'render_markdown',
16
16
  :markdown => 'render_markdown',
17
- :html => 'render_raw'
17
+ :html => 'render_raw',
18
+ :raw => 'render_raw',
19
+ :none => 'render_none',
20
+ :erb => 'render_none'
18
21
  }
19
22
 
20
23
  TEXTILE_TOC_RE = /^\s*h([1-6])\.\s+(.*)/
@@ -30,7 +33,7 @@ module Amber
30
33
  def initialize(options={})
31
34
  if options[:file]
32
35
  @file = options[:file]
33
- @type = type_from_file(@file)
36
+ @type = options[:type] || type_from_file(@file)
34
37
  elsif options[:content]
35
38
  @content = options[:content]
36
39
  @type = options[:type] # e.g. :haml. required if @content
@@ -39,24 +42,26 @@ module Amber
39
42
  end
40
43
 
41
44
  #
42
- # returns rendered content or title, depending on render_mode
45
+ # returns rendered content or title, depending on render_mode.
46
+ # anchors are always automatically added to content headings.
43
47
  #
44
48
  def render(view, options={})
45
49
  view.locals[:_type] = @type
46
50
  render_mode = options.delete(:mode) || :content
47
- toc = options.delete(:toc)
48
-
51
+ toc_option = options.delete(:toc)
49
52
  if render_mode == :title
50
53
  render_title(view)
51
54
  else
52
55
  html = render_html(view)
56
+ toc_renderer = RegexTableOfContents.new(html, options)
53
57
  if render_mode == :toc
54
- RegexTableOfContents.new(html, options).to_toc
55
- elsif toc || render_mode == :toc_and_content
56
- toc = RegexTableOfContents.new(html, options)
57
- %(<div id="TOC">%s</div>\n\n%s) % [toc.to_toc, toc.to_html]
58
+ toc_renderer.to_toc
59
+ elsif toc_option === false
60
+ toc_renderer.to_html
61
+ elsif toc_option || render_mode == :toc_and_content
62
+ %(<div id="TOC">%s</div>\n\n%s) % [toc_renderer.to_toc, toc_renderer.to_html]
58
63
  else
59
- html
64
+ toc_renderer.to_html
60
65
  end
61
66
  end
62
67
  end
@@ -120,7 +125,11 @@ module Amber
120
125
 
121
126
  def render_haml(file_path, view)
122
127
  template = Tilt::HamlTemplate.new(file_path, {:format => :html5, :default_encoding => 'UTF-8'})
123
- add_bracket_links(view, template.render(view))
128
+ add_bracket_links(view, template.render(view, view.locals))
129
+ rescue Haml::Error => ex
130
+ msg = "Line #{ex.line + 1} of file `#{file_path}`: #{ex.to_s}"
131
+ Amber::logger.error(msg)
132
+ return msg
124
133
  end
125
134
 
126
135
  def render_textile(view, content)
@@ -137,6 +146,10 @@ module Amber
137
146
  add_bracket_links(view, content)
138
147
  end
139
148
 
149
+ def render_none(view, content)
150
+ content
151
+ end
152
+
140
153
  def add_bracket_links(view, content)
141
154
  content = Bracketlink.bracket_link(content) do |from, to|
142
155
  view.link({from => to})
@@ -9,6 +9,8 @@ require 'amber/render/helpers/html_helper'
9
9
  require 'amber/render/helpers/navigation_helper'
10
10
  require 'amber/render/helpers/haml_helper'
11
11
  require 'amber/render/helpers/language_helper'
12
+ require 'amber/render/helpers/date_helper'
13
+ require 'amber/render/helpers/blog_helper'
12
14
 
13
15
  module Amber
14
16
  module Render
@@ -22,6 +24,7 @@ module Amber
22
24
  include NavigationHelper
23
25
  include HamlHelper
24
26
  include LanguageHelper
27
+ include BlogHelper
25
28
 
26
29
  def initialize(page, site)
27
30
  @page = page
@@ -36,14 +39,18 @@ module Amber
36
39
  # more or less the same as Rails render()
37
40
  #
38
41
  # supported options:
39
- # :page -- page path or page object to render
40
- # :file -- renders the file specified, using suffix to determine type.
41
- # :partial -- same as :file, but disables layout
42
- # :text -- string to render
43
- # :type -- required for :text
42
+ # :page -- page path or page object to render
43
+ # :file -- generic file to render, disables layout or toc.
44
+ # type determined by suffix or :type
45
+ # :partial -- same as :file, but searches for files with leading _
46
+ # :text -- string to render
47
+ # :type -- the format of the input, required for :text
44
48
  #
45
49
  def render(options={}, locals={}, toc_only=false, &block)
46
50
  push_context @locals, @page
51
+ if options.is_a?(Hash) && options[:locals].is_a?(Hash)
52
+ locals = options.delete(:locals)
53
+ end
47
54
  @locals = @locals.merge(locals)
48
55
  locale = I18n.locale = @locals[:locale]
49
56
  options = parse_render_options(locale, options)
@@ -79,7 +86,12 @@ module Amber
79
86
 
80
87
  private
81
88
 
89
+ #
90
+ # search possible paths for the file to be rendered.
91
+ # called only from parse_render_options()
92
+ #
82
93
  def find_file(path, site, page, locale)
94
+ return path if File.exists?(path)
83
95
  search = [
84
96
  path,
85
97
  "#{site.pages_dir}/#{path}",
@@ -87,15 +99,22 @@ module Amber
87
99
  "#{File.dirname(page.file_path)}/#{path}",
88
100
  "#{site.config_dir}/#{path}"
89
101
  ]
102
+ # attempt to find a file with preferred locale
90
103
  search.each do |path|
91
104
  return path if File.exists?(path)
92
- Dir["#{path}.#{locale}.*"].each do |path_with_locale|
105
+ Dir["#{path}.#{locale}.#{StaticPage::PAGE_SUFFIXES_GLOB}"].each do |path_with_locale|
93
106
  return path_with_locale if File.exists?(path_with_locale)
94
107
  end
95
- Dir["#{path}.*"].each do |path_with_suffix|
108
+ Dir["#{path}.#{StaticPage::PAGE_SUFFIXES_GLOB}"].each do |path_with_suffix|
96
109
  return path_with_suffix if File.exists?(path_with_suffix)
97
110
  end
98
111
  end
112
+ # attempt to find a file with default locale
113
+ search.each do |path|
114
+ Dir["#{path}.#{I18n.default_locale}.#{StaticPage::PAGE_SUFFIXES_GLOB}"].each do |path_with_locale|
115
+ return path_with_locale if File.exists?(path_with_locale)
116
+ end
117
+ end
99
118
  raise MissingTemplate.new(path)
100
119
  end
101
120
 
@@ -132,7 +151,7 @@ module Amber
132
151
  if options[:page].is_a?(String)
133
152
  options[:page] = @site.find_page(options[:page])
134
153
  end
135
- options[:href_base] ||= page_path(options[:page], locale)
154
+ options[:href_base] ||= amber_path(options[:page], locale)
136
155
  elsif options[:partial]
137
156
  options[:partial] = find_file(partialize(options[:partial]), @site, @page, locale)
138
157
  elsif options[:file]
@@ -142,14 +161,14 @@ module Amber
142
161
  end
143
162
 
144
163
  def should_render_toc?(locale, options, page)
145
- if options[:partial].nil?
164
+ if options[:partial] || options[:file]
165
+ false
166
+ else
146
167
  if page.prop(locale, :toc).nil?
147
168
  true
148
169
  else
149
170
  page.prop(locale, :toc)
150
171
  end
151
- else
152
- false
153
172
  end
154
173
  end
155
174
 
@@ -157,7 +176,7 @@ module Amber
157
176
  if options[:page]
158
177
  Template.new(file: options[:page].content_file(locale))
159
178
  elsif options[:file]
160
- Template.new(file: options[:file])
179
+ Template.new(file: options[:file], type: options[:type])
161
180
  elsif options[:partial]
162
181
  Template.new(file: options[:partial], partial: true)
163
182
  elsif options[:text]