amber 0.2.6 → 0.3.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +14 -1
- data/README.md +88 -19
- data/bin/amber +26 -13
- data/lib/amber.rb +25 -39
- data/lib/amber/cli.rb +25 -1
- data/lib/amber/i18n.rb +43 -0
- data/lib/amber/render/apache.rb +44 -0
- data/lib/amber/render/asset.rb +28 -2
- data/lib/amber/render/helpers/blog_helper.rb +35 -0
- data/lib/amber/render/helpers/date_helper.rb +14 -0
- data/lib/amber/render/helpers/haml_helper.rb +9 -0
- data/lib/amber/render/helpers/html_helper.rb +30 -8
- data/lib/amber/render/helpers/navigation_helper.rb +31 -32
- data/lib/amber/render/layout.rb +2 -1
- data/lib/amber/render/template.rb +24 -11
- data/lib/amber/render/view.rb +31 -12
- data/lib/amber/server.rb +122 -56
- data/lib/amber/site.rb +171 -29
- data/lib/amber/site_configuration.rb +26 -11
- data/lib/amber/static_page.rb +34 -20
- data/lib/amber/static_page/filesystem.rb +3 -7
- data/lib/amber/static_page/page_properties.rb +7 -0
- data/lib/amber/static_page/render.rb +47 -31
- data/lib/amber/templates/apache_config.erb +12 -0
- data/lib/amber/templates/apache_config_with_prefix.erb +14 -0
- data/lib/amber/templates/htaccess.erb +176 -0
- data/lib/amber/version.rb +5 -0
- data/locales/rails-i18n/af.yml +201 -0
- data/locales/rails-i18n/ar.yml +274 -0
- data/locales/rails-i18n/az.yml +192 -0
- data/locales/rails-i18n/bg.yml +192 -0
- data/locales/rails-i18n/bn.yml +175 -0
- data/locales/rails-i18n/bs.yml +243 -0
- data/locales/rails-i18n/ca.yml +192 -0
- data/locales/rails-i18n/cs.yml +210 -0
- data/locales/rails-i18n/cy.yml +242 -0
- data/locales/rails-i18n/da.yml +198 -0
- data/locales/rails-i18n/de-AT.yml +202 -0
- data/locales/rails-i18n/de-CH.yml +206 -0
- data/locales/rails-i18n/de.yml +202 -0
- data/locales/rails-i18n/el.yml +198 -0
- data/locales/rails-i18n/en-AU.yml +198 -0
- data/locales/rails-i18n/en-CA.yml +207 -0
- data/locales/rails-i18n/en-GB.yml +198 -0
- data/locales/rails-i18n/en-IE.yml +198 -0
- data/locales/rails-i18n/en-IN.yml +198 -0
- data/locales/rails-i18n/en-NZ.yml +198 -0
- data/locales/rails-i18n/en-US.yml +204 -0
- data/locales/rails-i18n/en-ZA.yml +204 -0
- data/locales/rails-i18n/en.yml +204 -0
- data/locales/rails-i18n/eo.yml +194 -0
- data/locales/rails-i18n/es-419.yml +207 -0
- data/locales/rails-i18n/es-AR.yml +198 -0
- data/locales/rails-i18n/es-CL.yml +192 -0
- data/locales/rails-i18n/es-CO.yml +198 -0
- data/locales/rails-i18n/es-CR.yml +198 -0
- data/locales/rails-i18n/es-EC.yml +204 -0
- data/locales/rails-i18n/es-MX.yml +204 -0
- data/locales/rails-i18n/es-PA.yml +204 -0
- data/locales/rails-i18n/es-PE.yml +177 -0
- data/locales/rails-i18n/es-US.yml +198 -0
- data/locales/rails-i18n/es-VE.yml +198 -0
- data/locales/rails-i18n/es.yml +192 -0
- data/locales/rails-i18n/et.yml +192 -0
- data/locales/rails-i18n/eu.yml +192 -0
- data/locales/rails-i18n/fa.yml +192 -0
- data/locales/rails-i18n/fi.yml +192 -0
- data/locales/rails-i18n/fr-CA.yml +200 -0
- data/locales/rails-i18n/fr-CH.yml +200 -0
- data/locales/rails-i18n/fr.yml +214 -0
- data/locales/rails-i18n/gl.yml +171 -0
- data/locales/rails-i18n/he.yml +194 -0
- data/locales/rails-i18n/hi-IN.yml +192 -0
- data/locales/rails-i18n/hi.yml +192 -0
- data/locales/rails-i18n/hr.yml +236 -0
- data/locales/rails-i18n/hu.yml +192 -0
- data/locales/rails-i18n/id.yml +193 -0
- data/locales/rails-i18n/is.yml +212 -0
- data/locales/rails-i18n/iso-639-2/csb.yml +203 -0
- data/locales/rails-i18n/iso-639-2/dsb.yml +208 -0
- data/locales/rails-i18n/iso-639-2/fur.yml +192 -0
- data/locales/rails-i18n/iso-639-2/gsw-CH.yml +196 -0
- data/locales/rails-i18n/iso-639-2/hsb.yml +207 -0
- data/locales/rails-i18n/iso-639-2/pap-AW.yml +205 -0
- data/locales/rails-i18n/iso-639-2/pap-CW.yml +205 -0
- data/locales/rails-i18n/iso-639-2/scr.yml +236 -0
- data/locales/rails-i18n/it-CH.yml +198 -0
- data/locales/rails-i18n/it.yml +204 -0
- data/locales/rails-i18n/ja.yml +194 -0
- data/locales/rails-i18n/km.yml +54 -0
- data/locales/rails-i18n/kn.yml +192 -0
- data/locales/rails-i18n/ko.yml +190 -0
- data/locales/rails-i18n/lo.yml +227 -0
- data/locales/rails-i18n/lt.yml +217 -0
- data/locales/rails-i18n/lv.yml +229 -0
- data/locales/rails-i18n/mk.yml +198 -0
- data/locales/rails-i18n/mn.yml +198 -0
- data/locales/rails-i18n/ms.yml +200 -0
- data/locales/rails-i18n/nb.yml +205 -0
- data/locales/rails-i18n/ne.yml +198 -0
- data/locales/rails-i18n/nl.yml +204 -0
- data/locales/rails-i18n/nn.yml +201 -0
- data/locales/rails-i18n/or.yml +192 -0
- data/locales/rails-i18n/pl.yml +236 -0
- data/locales/rails-i18n/pt-BR.yml +206 -0
- data/locales/rails-i18n/pt.yml +200 -0
- data/locales/rails-i18n/rm.yml +223 -0
- data/locales/rails-i18n/ro.yml +205 -0
- data/locales/rails-i18n/ru.yml +256 -0
- data/locales/rails-i18n/sk.yml +206 -0
- data/locales/rails-i18n/sl.yml +205 -0
- data/locales/rails-i18n/sr.yml +236 -0
- data/locales/rails-i18n/sv.yml +192 -0
- data/locales/rails-i18n/sw.yml +190 -0
- data/locales/rails-i18n/ta.yml +204 -0
- data/locales/rails-i18n/th.yml +166 -0
- data/locales/rails-i18n/tl.yml +224 -0
- data/locales/rails-i18n/tr.yml +204 -0
- data/locales/rails-i18n/uk.yml +250 -0
- data/locales/rails-i18n/ur.yml +204 -0
- data/locales/rails-i18n/uz.yml +250 -0
- data/locales/rails-i18n/vi.yml +198 -0
- data/locales/rails-i18n/wo.yml +198 -0
- data/locales/rails-i18n/zh-CN.yml +203 -0
- data/locales/rails-i18n/zh-HK.yml +204 -0
- data/locales/rails-i18n/zh-TW.yml +203 -0
- data/locales/rails-i18n/zh-YUE.yml +204 -0
- metadata +164 -74
data/lib/amber/server.rb
CHANGED
@@ -15,8 +15,9 @@ module Amber
|
|
15
15
|
|
16
16
|
def initialize(options)
|
17
17
|
@site = options[:site]
|
18
|
+
@host = options[:host]
|
18
19
|
@port = options[:port]
|
19
|
-
@server = WEBrick::HTTPServer.new :Port => @port, :BindAddress =>
|
20
|
+
@server = WEBrick::HTTPServer.new :Port => @port, :BindAddress => @host, :DocumentRoot => @site.dest_dir
|
20
21
|
@server.mount '/', StaticPageServlet, self
|
21
22
|
end
|
22
23
|
|
@@ -30,6 +31,9 @@ module Amber
|
|
30
31
|
|
31
32
|
class StaticPageServlet < WEBrick::HTTPServlet::FileHandler
|
32
33
|
|
34
|
+
RENDERABLE_ASSET_RE = /(#{Amber::Render::Asset::SOURCE_MAP.keys.join('|')})$/
|
35
|
+
ASSET_RE = /\.(jpg|jpeg|png|gif|webm|css|js|ico)$/
|
36
|
+
|
33
37
|
def initialize(http_server, amber_server)
|
34
38
|
@logger = http_server.logger
|
35
39
|
@server = amber_server
|
@@ -37,77 +41,139 @@ module Amber
|
|
37
41
|
end
|
38
42
|
|
39
43
|
def do_GET(request, response)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
if request.path !~ /\.[a-z]{2,4}$/
|
44
|
-
locale = get_locale(request)
|
45
|
-
if !locale
|
46
|
-
location = "http://localhost:#{@server.port}/#{I18n.default_locale}#{request.path.sub(/\/$/,'')}"
|
47
|
-
@logger.info "Redirect %s ==> %s" % [request.path, location]
|
48
|
-
response.header['Location'] = location
|
49
|
-
response.status = 307
|
50
|
-
return
|
51
|
-
end
|
44
|
+
if path_needs_to_be_prefixed?(request.path)
|
45
|
+
redirect_with_prefix(request, response)
|
46
|
+
return
|
52
47
|
end
|
53
48
|
|
54
|
-
|
55
|
-
|
49
|
+
path = strip_locale_and_prefix(request.path)
|
50
|
+
|
51
|
+
if renderable_asset?(path)
|
52
|
+
@logger.info "Rendering asset file %s" % asset_source_file(path)
|
53
|
+
render_asset(path, request, response)
|
56
54
|
super(request, response)
|
55
|
+
elsif static_file_exists?(request.path)
|
56
|
+
@logger.info "Serve static file %s" % static_file_path(request.path)
|
57
|
+
super(request, response)
|
58
|
+
elsif static_file_exists?(path)
|
59
|
+
request = request.clone
|
60
|
+
request.instance_variable_set(:@path_info, "/"+path)
|
61
|
+
@logger.info "Serve static file with locale prefix %s" % static_file_path(path)
|
62
|
+
super(request, response)
|
63
|
+
elsif path !~ ASSET_RE
|
64
|
+
render_page(path, request, response)
|
57
65
|
else
|
58
|
-
|
59
|
-
@server.site.load_pages
|
60
|
-
page = @server.site.find_page_by_path(path)
|
61
|
-
if page
|
62
|
-
@logger.info "Serving Page %s" % page.path.join('/')
|
63
|
-
response.status = 200
|
64
|
-
response.content_type = "text/html; charset=utf-8"
|
65
|
-
# always refresh the page we are fetching
|
66
|
-
Amber::Render::Layout.reload
|
67
|
-
@server.site.render
|
68
|
-
page.render_to_file(dest_dir, :force => true)
|
69
|
-
file = page.destination_file(dest_dir, locale)
|
70
|
-
if File.exists?(file)
|
71
|
-
content = File.read(file)
|
72
|
-
else
|
73
|
-
file = page.destination_file(dest_dir, I18n.default_locale)
|
74
|
-
if File.exists?(file)
|
75
|
-
content = File.read(file)
|
76
|
-
else
|
77
|
-
view = Render::View.new(page, @server.site)
|
78
|
-
content = view.render(:text => "No file found at #{file}")
|
79
|
-
end
|
80
|
-
end
|
81
|
-
response.body = content
|
82
|
-
else
|
83
|
-
request = request.clone
|
84
|
-
request.instance_variable_set(:@path_info, "/" + strip_locale(request.path_info))
|
85
|
-
@logger.info "Serve static file %s" % File.join(dest_dir, request.path_info)
|
86
|
-
super(request, response)
|
87
|
-
end
|
66
|
+
super(request, response)
|
88
67
|
end
|
89
68
|
end
|
90
|
-
#rescue Exception => exc
|
91
|
-
# @logger.error exc.to_s
|
92
|
-
# @logger.error exc.backtrace
|
93
|
-
# response.status = 500
|
94
|
-
# response.content_type = 'text/text'
|
95
|
-
# response.body = exc.to_s + "\n\n\n\n" + exc.backtrace
|
96
69
|
|
97
70
|
private
|
98
71
|
|
99
|
-
def
|
100
|
-
|
72
|
+
def strip_locale_and_prefix(path)
|
73
|
+
# The path comes to the server as URL escaped codes, that are then
|
74
|
+
# converty to ascii. But these codes might be utf-8 characters, so we force
|
75
|
+
# utf-8 encouding to allows non-ascii paths. I am not sure if always forcing
|
76
|
+
# will be a problem.
|
77
|
+
path = path.force_encoding('utf-8')
|
78
|
+
if @server.site.path_prefix
|
79
|
+
path = path.sub(%r{^/?#{Regexp.escape(@server.site.path_prefix)}}, '')
|
80
|
+
end
|
81
|
+
path.sub(%r{^/?(#{Amber::POSSIBLE_LANGUAGE_CODES.join('|')})(/|$)}, '').sub(%r{/$}, '')
|
101
82
|
end
|
102
83
|
|
103
|
-
def get_locale(
|
104
|
-
match = /\/(#{Amber::POSSIBLE_LANGUAGE_CODES.join('|')})(\/|$)/.match(
|
84
|
+
def get_locale(path)
|
85
|
+
match = /\/(#{Amber::POSSIBLE_LANGUAGE_CODES.join('|')})(\/|$)/.match(path)
|
105
86
|
if match.nil?
|
106
87
|
nil
|
107
88
|
else
|
108
89
|
match[1]
|
109
90
|
end
|
110
91
|
end
|
111
|
-
end
|
112
92
|
|
93
|
+
def path_needs_to_be_prefixed?(path)
|
94
|
+
if @server.site.path_prefix
|
95
|
+
path !~ /\.[a-z]{2,4}$/ && (
|
96
|
+
path !~ %r{^/?#{Regexp.escape(@server.site.path_prefix)}} ||
|
97
|
+
get_locale(path).nil?
|
98
|
+
)
|
99
|
+
else
|
100
|
+
path !~ /\.[a-z]{2,4}$/ && get_locale(path).nil?
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def redirect_with_prefix(request, response)
|
105
|
+
path = request.path.gsub(%r{^/|/$}, '')
|
106
|
+
location = ["http://localhost:#{@server.port}", @server.site.path_prefix, I18n.default_locale, path].compact.join('/')
|
107
|
+
@logger.info "Redirect %s ==> %s" % [request.path, location]
|
108
|
+
response.header['Location'] = location
|
109
|
+
response.status = 307
|
110
|
+
end
|
111
|
+
|
112
|
+
def dst_dir
|
113
|
+
@server.site.dest_dir
|
114
|
+
end
|
115
|
+
|
116
|
+
def src_dir
|
117
|
+
@server.site.pages_dir
|
118
|
+
end
|
119
|
+
|
120
|
+
def static_file_exists?(path)
|
121
|
+
File.file?(File.join(dst_dir, path))
|
122
|
+
end
|
123
|
+
|
124
|
+
def static_file_path(path)
|
125
|
+
File.join(dst_dir, path)
|
126
|
+
end
|
127
|
+
|
128
|
+
def render_page(path, request, response)
|
129
|
+
locale = get_locale(request.path)
|
130
|
+
@server.site.load_pages
|
131
|
+
page = @server.site.find_page_by_path(path, locale)
|
132
|
+
if page
|
133
|
+
@logger.info "Serving Page %s" % page.path.join('/')
|
134
|
+
response.status = 200
|
135
|
+
response.content_type = "text/html; charset=utf-8"
|
136
|
+
# always refresh the page we are fetching
|
137
|
+
Amber::Render::Layout.reload
|
138
|
+
@server.site.render
|
139
|
+
page.render_to_file(dst_dir, :force => true)
|
140
|
+
file = page.destination_file(dst_dir, locale)
|
141
|
+
if File.exists?(file)
|
142
|
+
content = File.read(file)
|
143
|
+
else
|
144
|
+
file = page.destination_file(dst_dir, I18n.default_locale)
|
145
|
+
if File.exists?(file)
|
146
|
+
content = File.read(file)
|
147
|
+
else
|
148
|
+
view = Render::View.new(page, @server.site)
|
149
|
+
content = view.render(:text => "No file found at #{file}")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
response.body = content
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def renderable_asset?(path)
|
157
|
+
path =~ RENDERABLE_ASSET_RE && asset_source_file(path)
|
158
|
+
end
|
159
|
+
|
160
|
+
def asset_source_file(path)
|
161
|
+
dest_suffix = File.extname(path)
|
162
|
+
base_path = path.sub(RENDERABLE_ASSET_RE, '')
|
163
|
+
Amber::Render::Asset::SOURCE_MAP[dest_suffix].each do |source_suffix|
|
164
|
+
source_file_path = File.join(src_dir, base_path + source_suffix)
|
165
|
+
if File.exists?(source_file_path)
|
166
|
+
return source_file_path
|
167
|
+
end
|
168
|
+
end
|
169
|
+
return nil
|
170
|
+
end
|
171
|
+
|
172
|
+
def render_asset(path, request, response)
|
173
|
+
src_file = asset_source_file(path)
|
174
|
+
dst_file = [dst_dir, path].join
|
175
|
+
Amber::Render::Asset.render(src_file, dst_file)
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
113
179
|
end
|
data/lib/amber/site.rb
CHANGED
@@ -9,32 +9,39 @@ module Amber
|
|
9
9
|
attr_accessor :root
|
10
10
|
attr_accessor :continue_on_error
|
11
11
|
|
12
|
-
|
12
|
+
# @config is the primary SiteConfiguration
|
13
|
+
def_delegators :@config, :pages_dir, :dest_dir, :locales, :default_locale, :path_prefix
|
13
14
|
|
14
15
|
def initialize(root_dir)
|
15
16
|
@continue_on_error = true
|
16
17
|
@config = SiteConfiguration.load(self, root_dir)
|
17
18
|
end
|
18
19
|
|
20
|
+
def add_config(config)
|
21
|
+
@config.children << config
|
22
|
+
end
|
23
|
+
|
19
24
|
def load_pages
|
20
25
|
@root = nil
|
21
|
-
@pages_by_path = {}
|
22
|
-
@pages_by_name = {}
|
26
|
+
@pages_by_path = {} # hash of pages keyed by page path
|
27
|
+
@pages_by_name = {} # hash of pages keyed by page name
|
23
28
|
@page_list = PageArray.new
|
24
|
-
@dir_list = []
|
25
|
-
@
|
26
|
-
add_mount_point(mp)
|
27
|
-
mp.reset_timestamp
|
28
|
-
end
|
29
|
-
end
|
29
|
+
@dir_list = [] # an array of non-page directories
|
30
|
+
@page_paths = [] # an array of page paths, used for greping through paths.
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
32
|
+
# some paths are specific to only one locale (e.g aliases)
|
33
|
+
@pages_by_locale_path = POSSIBLE_LANGUAGES.keys.inject(Hash.new({})) {|h,locale| h[locale] = {}; h}
|
34
|
+
|
35
|
+
add_configuration(@config)
|
36
36
|
end
|
37
37
|
|
38
|
+
#def reload_pages_if_needed
|
39
|
+
# if @pages_by_path.nil? || @config.pages_changed?
|
40
|
+
# puts "Reloading pages ................."
|
41
|
+
# load_pages
|
42
|
+
# end
|
43
|
+
#end
|
44
|
+
|
38
45
|
def render
|
39
46
|
@page_list.each do |page|
|
40
47
|
page.render_to_file(@config.dest_dir)
|
@@ -46,6 +53,10 @@ module Amber
|
|
46
53
|
Render::Asset.render_dir(src, dst)
|
47
54
|
putc '.'; $stdout.flush
|
48
55
|
end
|
56
|
+
if @config.short_paths
|
57
|
+
render_short_path_symlinks
|
58
|
+
end
|
59
|
+
Render::Apache.write_htaccess(@config, @config.pages_dir, @config.dest_dir)
|
49
60
|
puts
|
50
61
|
end
|
51
62
|
|
@@ -62,6 +73,13 @@ module Amber
|
|
62
73
|
@config.dest_dir = dest_dir
|
63
74
|
end
|
64
75
|
|
76
|
+
#
|
77
|
+
# find pages by a filter.
|
78
|
+
# filter is a string composing a path segment.
|
79
|
+
# For example:
|
80
|
+
# "chat/security"
|
81
|
+
# Which would match "/services/chat/security" but not "/services/security"
|
82
|
+
#
|
65
83
|
def find_pages(filter)
|
66
84
|
filter = filter.downcase
|
67
85
|
if filter =~ /\//
|
@@ -89,54 +107,100 @@ module Amber
|
|
89
107
|
@page_list
|
90
108
|
end
|
91
109
|
|
92
|
-
def find_page_by_path(path)
|
93
|
-
|
110
|
+
def find_page_by_path(path, locale=I18n.default_locale)
|
111
|
+
if locale.is_a? String
|
112
|
+
if I18n.locale_available?(locale)
|
113
|
+
locale = locale.to_sym
|
114
|
+
end
|
115
|
+
end
|
116
|
+
if path.is_a? Array
|
117
|
+
path = path.join('/')
|
118
|
+
end
|
119
|
+
@pages_by_locale_path[locale][path] || @pages_by_path[path]
|
94
120
|
end
|
95
121
|
|
96
122
|
def find_page_by_name(name)
|
97
123
|
@pages_by_name[name]
|
98
124
|
end
|
99
125
|
|
126
|
+
#
|
127
|
+
# returns the shortest possible path for a page, such that the path doesn't collide with
|
128
|
+
# another page or another page's aliases.
|
129
|
+
#
|
130
|
+
def shortest_path(page)
|
131
|
+
path_so_far = []
|
132
|
+
page.path.reverse.each do |path_segment|
|
133
|
+
path_so_far.push(path_segment)
|
134
|
+
path_str = path_so_far.join('/')
|
135
|
+
if @pages_by_path[path_str].nil? && short_paths[path_str] == page
|
136
|
+
return path_so_far
|
137
|
+
end
|
138
|
+
end
|
139
|
+
return []
|
140
|
+
end
|
141
|
+
|
100
142
|
private
|
101
143
|
|
102
|
-
def
|
144
|
+
def add_configuration(config)
|
145
|
+
config.reset_timestamp
|
146
|
+
|
103
147
|
# create base_page
|
104
148
|
base_page = begin
|
105
|
-
if
|
106
|
-
@root = StaticPage.new(nil, 'root',
|
149
|
+
if config.path.nil?
|
150
|
+
@root = StaticPage.new(nil, 'root', config.pages_dir)
|
107
151
|
add_page(@root)
|
108
152
|
@root
|
109
153
|
else
|
110
|
-
name = File.basename(
|
111
|
-
page = StaticPage.new(find_parent(
|
154
|
+
name = File.basename(config.path)
|
155
|
+
page = StaticPage.new(find_parent(config.path), name, config.pages_dir, config.path_prefix)
|
112
156
|
add_page(page)
|
113
157
|
page
|
114
158
|
end
|
115
159
|
end
|
116
|
-
base_page.
|
160
|
+
base_page.config = config
|
117
161
|
|
118
162
|
# load menu and locals
|
119
|
-
I18n.load_path += Dir[File.join(
|
163
|
+
I18n.load_path += Dir[File.join(config.locales_dir, '/*.{rb,yml,yaml}')] if config.locales_dir
|
120
164
|
|
121
165
|
# add the full directory tree
|
122
166
|
base_page.scan_directory_tree do |page, asset_dir|
|
123
167
|
add_page(page) if page
|
124
168
|
@dir_list << asset_dir if asset_dir
|
125
169
|
end
|
126
|
-
@page_paths
|
170
|
+
@page_paths += @pages_by_path.keys
|
171
|
+
|
172
|
+
# recursively add sub-sites
|
173
|
+
config.children.each do |sub_config|
|
174
|
+
add_configuration(sub_config)
|
175
|
+
end
|
127
176
|
end
|
128
177
|
|
178
|
+
#
|
179
|
+
# registers a page with the site, indexing the page path in our various hashes
|
180
|
+
#
|
129
181
|
def add_page(page)
|
130
182
|
@pages_by_name[page.name] = page
|
131
183
|
@pages_by_path[page.path.join('/')] = page
|
132
|
-
|
133
|
-
|
134
|
-
|
184
|
+
add_aliases(I18n.default_locale, page, @pages_by_path)
|
185
|
+
page.locales.each do |locale|
|
186
|
+
next if locale == I18n.default_locale
|
187
|
+
add_aliases(locale, page, @pages_by_locale_path[locale])
|
188
|
+
end
|
189
|
+
@page_list << page
|
190
|
+
end
|
191
|
+
|
192
|
+
#
|
193
|
+
# registers a page's aliases with the site
|
194
|
+
#
|
195
|
+
def add_aliases(locale, page, path_hash)
|
196
|
+
page.aliases(locale).each do |alias_path|
|
197
|
+
alias_path_str = alias_path.join('/')
|
198
|
+
if path_hash[alias_path_str]
|
199
|
+
Amber.logger.warn "WARNING: page `#{page.path.join('/')}` has alias `#{alias_path_str}`, but this path is already taken by `#{path_hash[alias_path_str].path.join('/')}` (locale = #{locale})."
|
135
200
|
else
|
136
|
-
|
201
|
+
path_hash[alias_path_str] = page
|
137
202
|
end
|
138
203
|
end
|
139
|
-
@page_list << page
|
140
204
|
end
|
141
205
|
|
142
206
|
def find_parent(path)
|
@@ -150,5 +214,83 @@ module Amber
|
|
150
214
|
return @root
|
151
215
|
end
|
152
216
|
|
217
|
+
#
|
218
|
+
# adds symlinks for all possible 'short paths' for every page.
|
219
|
+
# this works by:
|
220
|
+
# (1) examine all pages in order of longest path depth and assign 'short paths' for each page.
|
221
|
+
# (2) examine all short paths in order of shortest path depth and create symlinks
|
222
|
+
#
|
223
|
+
def render_short_path_symlinks
|
224
|
+
short_paths.each do |path, page|
|
225
|
+
page.link_page_aliases(@config.dest_dir, [path])
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
#
|
230
|
+
# returns a hash containing all the automatically determined shortest paths for every page.
|
231
|
+
# the data structure looks like so:
|
232
|
+
#
|
233
|
+
# {
|
234
|
+
# "ddd" => <page 'bbb/ddd'>,
|
235
|
+
# "ccc" => <page 'bbb/ccc'>,
|
236
|
+
# "red" => <page 'autoalias/red'>,
|
237
|
+
# "blue"=> <page 'autoalias/blue'>,
|
238
|
+
# "red/blue" => <page 'autoalias/red/blue'>
|
239
|
+
# }
|
240
|
+
#
|
241
|
+
# short_paths does not include the normal paths or normal aliases, just the automatic short path aliases.
|
242
|
+
#
|
243
|
+
def short_paths
|
244
|
+
@short_paths ||= begin
|
245
|
+
hash = {}
|
246
|
+
pages_in_path_depth_order.each do |record|
|
247
|
+
page = record[:page]
|
248
|
+
path = record[:path]
|
249
|
+
next if path.length == 1
|
250
|
+
path_prefix = path.dup
|
251
|
+
path.length.times do |depth|
|
252
|
+
path_prefix.shift
|
253
|
+
path_str = path_prefix.join('/')
|
254
|
+
if @pages_by_path[path_str].nil? && hash[path_str].nil?
|
255
|
+
hash[path_str] = page
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
# debug:
|
260
|
+
#hash.each do |path, record|
|
261
|
+
# puts "#{record[:page].path.join('/')} => #{record[:path].join('/')}"
|
262
|
+
#end
|
263
|
+
hash
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
#
|
268
|
+
# Returns an array like this:
|
269
|
+
#
|
270
|
+
# [
|
271
|
+
# {:page => <page1>, :path => ['a', 'page1']},
|
272
|
+
# {:page => <page2>, :path => ['a','b', 'page2']},
|
273
|
+
# ]
|
274
|
+
#
|
275
|
+
# This array is sorted by the depth of the path (shortest first)
|
276
|
+
# Pages will appear multiple times (once for each path, including aliases)
|
277
|
+
#
|
278
|
+
def pages_in_path_depth_order
|
279
|
+
paths = {}
|
280
|
+
@page_list.each do |page|
|
281
|
+
paths[page.path] ||= page
|
282
|
+
locales = page.locales
|
283
|
+
locales << I18n.default_locale unless locales.include? I18n.default_locale
|
284
|
+
locales.each do |locale|
|
285
|
+
page.aliases(locale).each do |alias_path|
|
286
|
+
paths[alias_path] ||= page
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
paths.collect{|path, page| {page:page, path:path}}.sort{|a,b|
|
291
|
+
a[:path].length <=> a[:path].length
|
292
|
+
}
|
293
|
+
end
|
294
|
+
|
153
295
|
end
|
154
296
|
end
|