amber 0.2.6 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -12,9 +12,11 @@ module Amber
12
12
 
13
13
  attr_accessor :title
14
14
  attr_accessor :pagination_size
15
- attr_accessor :mount_points
16
15
  attr_accessor :locales
17
16
  attr_accessor :default_locale
17
+ attr_accessor :path_prefix
18
+ alias :path :path_prefix
19
+ attr_accessor :short_paths
18
20
 
19
21
  attr_accessor :menu
20
22
 
@@ -29,8 +31,13 @@ module Amber
29
31
  attr_accessor :locales_dir
30
32
  attr_accessor :timestamp
31
33
 
34
+ # an array of SiteConfigurations that are attached as sub-sites
35
+ # to this one.
36
+ attr_accessor :children
37
+
32
38
  extend Forwardable
33
- def_delegators :@site, :pages, :find_page, :find_pages, :find_page_by_path, :find_page_by_name, :continue_on_error
39
+ def_delegators :@site, :pages, :find_page, :find_pages, :find_page_by_path,
40
+ :find_page_by_name, :continue_on_error, :root
34
41
 
35
42
  ##
36
43
  ## CLASS METHODS
@@ -48,6 +55,7 @@ module Amber
48
55
  # accepts a file_path to a configuration file.
49
56
  #
50
57
  def initialize(site, root_dir, options={})
58
+ @children = []
51
59
  @site = site
52
60
  @root_dir = File.expand_path(find_in_directory_tree('amber', 'config.rb', root_dir))
53
61
  if @root_dir == '/'
@@ -61,9 +69,6 @@ module Amber
61
69
  @menu_file = config_path('menu.txt')
62
70
  @locales_dir = config_path('locales')
63
71
  @layouts_dir = config_path('layouts')
64
- @path = '/'
65
- @mount_points = []
66
- @mount_points << self
67
72
  @title = "untitled"
68
73
  @pagination_size = 20
69
74
 
@@ -71,15 +76,21 @@ module Amber
71
76
  @menu.load(@menu_file) if @menu_file
72
77
 
73
78
  self.eval
79
+ @path_prefix = options[:path_prefix] if options[:path_prefix]
74
80
  self.cleanup
75
81
 
76
82
  reset_timestamp
77
83
  Render::Layout.load(@layouts_dir)
78
84
  end
79
85
 
80
- #def include_site(directory_source, options={})
81
- # @mount_points << SiteMountPoint.new(self, directory_source, options)
82
- #end
86
+ #
87
+ # map('/path' => '../othersite')
88
+ #
89
+ def map(path_to_directory_source, options={})
90
+ path, root_dir = path_to_directory_source.to_a.first
91
+ config = self.load(@site, root_dir, {:path_prefix => path})
92
+ @site.add_config(config)
93
+ end
83
94
 
84
95
  def cleanup
85
96
  @locale ||= I18n.default_locale
@@ -92,11 +103,15 @@ module Amber
92
103
  nil
93
104
  end
94
105
  }.compact
106
+ if @path_prefix
107
+ @path_prefix.gsub!(%r{^/|/$}, '')
108
+ @path_prefix = nil if @path_prefix == ''
109
+ end
95
110
  end
96
111
 
97
- def pages_changed?
98
- @mount_points.detect {|mp| mp.changed?}
99
- end
112
+ #def pages_changed?
113
+ # self.changed? || @children.detect {|child| child.changed?}
114
+ #end
100
115
 
101
116
  def eval
102
117
  self.instance_eval(File.read(@config_file), @config_file)
@@ -13,9 +13,8 @@ module Amber
13
13
  :name, # the name of the page
14
14
  :file_path, #
15
15
  :parent, # parent page (nil for root page)
16
- :mount_point, # associated SiteConfiguration
17
- :site, # associated Site
18
- :locales, # currently unused
16
+ :config, # associated SiteConfiguration (site might have several)
17
+ :site, # associated Site (only one)
19
18
  :valid # `false` if there is some problem with this page.
20
19
 
21
20
  attr_reader :props # set of page properties (PropertySet)
@@ -28,7 +27,7 @@ module Amber
28
27
 
29
28
  FORBIDDEN_PAGE_CHARS_RE = /[A-Z\.\?\|\[\]\{\}\$\^\*~!@#%&='"<>]/
30
29
 
31
- def initialize(parent, name, file_path=nil)
30
+ def initialize(parent, name, file_path=nil, path_prefix="/")
32
31
  @valid = true
33
32
  @children = PageArray.new # array of StaticPages
34
33
  @nav_title = {} # key is locale
@@ -39,11 +38,11 @@ module Amber
39
38
  # set @parent & @path
40
39
  if parent
41
40
  @parent = parent
42
- @mount_point = @parent.mount_point
41
+ @config = @parent.config
43
42
  @parent.add_child(self)
44
43
  @path = [@parent.path, @name].flatten.compact
45
44
  else
46
- @path = []
45
+ @path = (path_prefix||"").split('/')
47
46
  end
48
47
 
49
48
  if @name =~ FORBIDDEN_PAGE_CHARS_RE
@@ -113,32 +112,47 @@ module Amber
113
112
  @props.prop(*args)
114
113
  end
115
114
 
115
+ #
116
+ # Returns array of locale symbols for all locales with properties set
117
+ # Note: there might be a content for a locale that does not show up in this array,
118
+ # if the content file does not set any properties.
119
+ #
120
+ def locales
121
+ @props.locales
122
+ end
123
+
116
124
  #
117
125
  # returns an array of normalized aliases based on the :alias property
118
126
  # defined for a page.
119
127
  #
120
128
  # aliases are defined with a leading slash for absolute paths, or without a slash
121
129
  # for relative paths. this method converts this to a format that amber uses
122
- # (all absolute, with no leading slash).
123
- #
124
- # currently, we do not maintain per-locale paths or aliases.
130
+ # (all absolute, with no leading slash, as an array instead of a string).
125
131
  #
126
- def aliases
132
+ def aliases(locale=I18n.default_locale)
127
133
  @aliases ||= begin
128
- if @props.alias.nil?
129
- []
130
- else
131
- @props.alias.collect {|alias_path|
132
- if alias_path =~ /^\//
133
- alias_path.sub(/^\//, '')
134
- elsif @parent
135
- (@parent.path + [alias_path]).join('/')
134
+ aliases_hash = Hash.new([])
135
+ @props.locales.each do |locale|
136
+ aliases = @props.prop_without_inheritance(locale, :alias)
137
+ aliases_hash[locale] = begin
138
+ if aliases.nil?
139
+ []
136
140
  else
137
- alias_path
141
+ [aliases].flatten.collect {|alias_path|
142
+ if alias_path =~ /^\//
143
+ alias_path.sub(/^\//, '').split('/')
144
+ elsif @parent
145
+ @parent.path + [alias_path]
146
+ else
147
+ alias_path.split('/')
148
+ end
149
+ }
138
150
  end
139
- }
151
+ end
140
152
  end
153
+ aliases_hash
141
154
  end
155
+ @aliases[locale]
142
156
  end
143
157
 
144
158
  protected
@@ -95,15 +95,9 @@ module Amber
95
95
  # e.g. /home/user/mysite/public/about-us/contact/index.en.html
96
96
  #
97
97
  def destination_file(dest_dir, locale)
98
- if @simple_page
99
- File.join(dest_dir, "#{File.join(@path)}.#{locale}.html")
100
- else
101
- File.join(dest_dir, *@path, "index.#{locale}.html")
102
- end
98
+ File.join(dest_dir, *@path, "index.#{locale}.html")
103
99
  end
104
100
 
105
- private
106
-
107
101
  # e.g. en, de, pt
108
102
  LOCALES_RE = /(?<locale>#{Amber::POSSIBLE_LANGUAGE_CODES.join('|')})/
109
103
  LOCALES_GLOB = "{#{Amber::POSSIBLE_LANGUAGE_CODES.join(',')}}"
@@ -118,6 +112,8 @@ module Amber
118
112
 
119
113
  SIMPLE_FILE_MATCH_RE = lambda {|name| /^(#{Regexp.escape(name)})(\.#{LOCALES_RE})?\.#{PAGE_SUFFIXES_RE}$/ }
120
114
 
115
+ private
116
+
121
117
  #
122
118
  # returns true if the name of a file could be a 'simple' static page
123
119
  # that is not a directory.
@@ -111,6 +111,13 @@ module Amber
111
111
  end
112
112
  end
113
113
 
114
+ #
115
+ # returns an array of locale symbols that are active for this page.
116
+ #
117
+ def locales
118
+ @locales.keys
119
+ end
120
+
114
121
  #
115
122
  # tries to get the value of an inherited variable
116
123
  #
@@ -34,8 +34,26 @@ module Amber
34
34
  def render_to_file(dest_dir, options={})
35
35
  render_content_files(dest_dir, options)
36
36
  render_assets(dest_dir)
37
- if aliases.any?
38
- link_page_aliases(dest_dir)
37
+ @props.locales.each do |locale|
38
+ if aliases(locale).any?
39
+ link_page_aliases(dest_dir, aliases(locale), locale)
40
+ end
41
+ end
42
+ end
43
+
44
+ #
45
+ # creates symlinks for aliases to this page.
46
+ # called by Page#render_to_file and Site#render_short_path_aliases
47
+ #
48
+ def link_page_aliases(dest_dir, alias_paths, locale=I18n.default_locale)
49
+ alias_paths.each do |alias_path|
50
+ alias_file_path = File.join(dest_dir, alias_path)
51
+ #if locale != I18n.default_locale
52
+ # alias_file_path += ".#{locale}"
53
+ #end
54
+ alias_file_path = Pathname.new(alias_file_path)
55
+ page_file_path = Pathname.new(File.join(dest_dir, *@path))
56
+ symlink(page_file_path, alias_file_path)
39
57
  end
40
58
  end
41
59
 
@@ -69,40 +87,38 @@ module Amber
69
87
  end
70
88
  end
71
89
 
72
- # called only by render_to_file
73
- # for now, we only support aliases on pages that are directories, for simplicity sake.
74
- def link_page_aliases(dest_dir)
75
- if @simple_page
76
- Amber.logger.warn { "The page `#{@file_path}` sets a path alias, but currently aliases are only supported for directory-based pages. Skipping." }
90
+ #
91
+ # create a symlink. arguments must be of type Pathname.
92
+ #
93
+ def symlink(from_path, to_path)
94
+ to_path = realpath(to_path)
95
+ target = from_path.relative_path_from(to_path).to_s.sub(/^\.\.\//, '')
96
+ if !to_path.dirname.directory?
97
+ Amber.logger.warn { "On page `#{@file_path}`, the parent directories for alias name `#{to_path}` don't exist. Skipping alias." }
98
+ return
99
+ end
100
+ if to_path.exist? && to_path.symlink?
101
+ File.unlink(to_path)
102
+ end
103
+ if !to_path.exist?
104
+ Amber.logger.debug { "Symlink #{to_path} => #{target}" }
105
+ FileUtils.ln_s(target, to_path)
106
+ end
107
+ end
108
+
109
+ def realpath(pathname)
110
+ dir = pathname.dirname
111
+ if dir.directory? || dir.symlink?
112
+ dir.realpath + pathname.basename
77
113
  else
78
- aliases.each do |alias_path|
79
- alias_path = Pathname.new(File.join(dest_dir, alias_path))
80
- if !File.directory?(File.dirname(alias_path))
81
- Amber.logger.warn { "On page `#{@file_path}`, the parent directories for alias name `#{alias_path}` don't exist. Skipping alias." }
82
- else
83
- page_path = Pathname.new(File.join(dest_dir, *@path))
84
- target = page_path.relative_path_from(alias_path).to_s.sub(/^\.\.\//, '')
85
- if File.exists?(alias_path)
86
- if File.symlink?(alias_path)
87
- File.unlink(alias_path)
88
- Amber.logger.debug { "Alias #{alias_path} => #{target}" }
89
- FileUtils.ln_s(target, alias_path)
90
- else
91
- Amber.logger.warn { "The page `#{@file_path}` sets a path alias, but there is already a file in the way (`#{alias_path}`)" }
92
- end
93
- else
94
- Amber.logger.debug { "Alias #{alias_path} => #{target}" }
95
- FileUtils.ln_s(target, alias_path)
96
- end
97
- end
98
- end
114
+ pathname
99
115
  end
100
116
  end
101
117
 
102
118
  # called only by render_to_file
103
119
  def render_content_files(dest_dir, options)
104
- view = Render::View.new(self, self.mount_point)
105
- @mount_point.locales.each do |file_locale|
120
+ view = Render::View.new(self, @config)
121
+ @config.locales.each do |file_locale|
106
122
  content_file = content_file(file_locale)
107
123
  next unless content_file
108
124
  dest = destination_file(dest_dir, file_locale)
@@ -112,7 +128,7 @@ module Amber
112
128
  if options[:force] || !File.exist?(dest) || File.mtime(content_file) > File.mtime(dest)
113
129
  File.open(dest, 'w') do |f|
114
130
  layout = @props.layout || 'default'
115
- f.write view.render({file: content_file, layout: layout}, {locale: file_locale})
131
+ f.write view.render({page: self, layout: layout}, {locale: file_locale})
116
132
  end
117
133
  end
118
134
  end
@@ -0,0 +1,12 @@
1
+ AccessFileName .htaccess
2
+ DocumentRoot "/<%= @directory %>"
3
+ <Directory "/<%= @directory %>">
4
+ AllowOverride FileInfo Indexes Options=All,MultiViews
5
+ <IfModule !mod_authz_core.c>
6
+ Order deny,allow
7
+ Allow from all
8
+ </IfModule>
9
+ <IfModule mod_authz_core.c>
10
+ Require all granted
11
+ </IfModule>
12
+ </Directory>
@@ -0,0 +1,14 @@
1
+ AccessFileName .htaccess
2
+ AliasMatch ^/[a-z]{2}/<%=@site.path_prefix%>(/.+|/|)$ "/<%=@directory%>/$1"
3
+ Alias /<%=@site.path_prefix%> "/<%=@directory%>/"
4
+
5
+ <Directory "/<%=@directory%>/">
6
+ AllowOverride FileInfo Indexes Options=All,MultiViews
7
+ <IfModule !mod_authz_core.c>
8
+ Order deny,allow
9
+ Allow from all
10
+ </IfModule>
11
+ <IfModule mod_authz_core.c>
12
+ Require all granted
13
+ </IfModule>
14
+ </Directory>
@@ -0,0 +1,176 @@
1
+ ##
2
+ ## AUTO NEGOTIATED LOCALE
3
+ ##
4
+
5
+ LanguagePriority en
6
+ ForceLanguagePriority Prefer Fallback
7
+ DirectoryIndex index
8
+ DirectorySlash Off
9
+ Options +MultiViews
10
+
11
+ ##
12
+ ## REWRITES
13
+ ##
14
+
15
+ Options +FollowSymLinks
16
+ RewriteEngine On
17
+
18
+ <% if @site.path_prefix %>
19
+ <% @path_prefix = Regexp.escape(@site.path_prefix) %>
20
+ RewriteBase /<%= @path_prefix %>/
21
+
22
+ ##
23
+ ## remove trailing slashes (except for paths where we added the slash)
24
+ ##
25
+
26
+ # /path_prefix/foo/bar/ => /path_prefix/foo/bar
27
+ # /en/path_prefix/foo/bar => /en/path_prefix/foo/bar
28
+ # rewrite sees this as:
29
+ # /path_prefix/foo/bar.en.html/ => /path_prefix/foo/bar
30
+ RewriteCond %{QUERY_STRING} !end
31
+ RewriteCond %{REQUEST_URI} ^/([a-z]{2}/)?(<%= @path_prefix %>/)?.+\.html/$
32
+ RewriteRule ^(.+)\.[a-z]{2}\.html/$ /%1%2$1 [R=307,L]
33
+
34
+ # en/path_prefix/blah/ => /en/path_prefix/blah
35
+ RewriteCond %{QUERY_STRING} !end
36
+ RewriteCond %{REQUEST_URI} ^/([a-z]{2})/
37
+ RewriteCond %{REQUEST_URI} !\.html$
38
+ RewriteRule ^(.+)/$ /%1/<%= @path_prefix %>/$1 [R=307,L]
39
+
40
+ # en/path_prefix/ => en/path_prefix
41
+ RewriteCond %{QUERY_STRING} !end
42
+ RewriteCond %{REQUEST_URI} ^/([a-z]{2})/<%= @site.path_prefix %>/$
43
+ RewriteRule ^$ /%1/<%= @path_prefix %> [R=307,L]
44
+
45
+ # path_prefix/ => path_prefix
46
+ RewriteCond %{QUERY_STRING} !end
47
+ RewriteCond %{REQUEST_URI} /$
48
+ RewriteRule ^$ /<%= @path_prefix %> [R=307,L]
49
+
50
+ # path_prefix/blah/ => path_prefix/blah
51
+ RewriteCond %{QUERY_STRING} !end
52
+ RewriteRule ^(.+)/$ $1 [R=307,L]
53
+
54
+ ##
55
+ ## rewrite all paths with a local prefix to use
56
+ ## the appropriate index.{local}.html file
57
+ ##
58
+
59
+ ## /en/prefix_path => /index.en.html
60
+ RewriteCond %{QUERY_STRING} !end
61
+ RewriteCond %{REQUEST_URI} ^/([a-z]{2})/<%= @path_prefix %>$
62
+ RewriteRule ^(.*) index.%1.html?end [L]
63
+
64
+ # /en/path_prefix/blah => /path_prefix/blah/index.en.html
65
+ RewriteCond %{QUERY_STRING} !end
66
+ RewriteCond %{REQUEST_URI} !/$
67
+ RewriteCond %{REQUEST_URI} ^/([a-z]{2})/
68
+ RewriteCond %{REQUEST_FILENAME}/index.%1.html -f
69
+ RewriteRule ^(.*) $1/index.%1.html?end [L]
70
+
71
+ # /de/path_prefix/foo/bar => /path_prefix/foo/bar.de.html
72
+ # rewrite sees this as:
73
+ # /de/path_prefix/foo/bar.en.html => /path_prefix/foo/bar.de.html
74
+ RewriteCond %{QUERY_STRING} !end
75
+ RewriteCond %{REQUEST_URI} !/$
76
+ RewriteCond %{REQUEST_FILENAME} en\.html$
77
+ RewriteCond %{REQUEST_FILENAME} -f
78
+ RewriteCond %{REQUEST_URI} ^/([a-z]{2})/
79
+ RewriteRule ^(.*)?\.en\.html $1.%1.html?end [L]
80
+
81
+ ##
82
+ ## internally simulate a trailing slashes for directories in order
83
+ ## to trigger DirectoryIndex and autonegotiated locale.
84
+ ##
85
+
86
+ # /path_prefix/foo/bar => /path_prefix/foo/bar/
87
+ RewriteCond %{QUERY_STRING} !end
88
+ RewriteCond %{REQUEST_FILENAME} -d
89
+ RewriteRule ^(.*[^/])$ $1/?end [PT]
90
+
91
+ # /path_prefix => /path_prefix/
92
+ RewriteCond %{QUERY_STRING} !end
93
+ RewriteCond %{REQUEST_FILENAME} -d
94
+ RewriteRule ^$ /<%= @path_prefix %>/?end [PT]
95
+
96
+ ##
97
+ ## redirect assets that are locale prefixed
98
+ ## (in order to allow relative paths)
99
+ ##
100
+
101
+ # e.g. /de/foo/assets/style.css => /foo/assets/style.css
102
+ RewriteCond %{QUERY_STRING} !end
103
+ RewriteCond %{REQUEST_FILENAME} -f
104
+ RewriteCond %{REQUEST_URI} ^/([a-z]{2})/<%= @path_prefix %>/
105
+ RewriteRule (.*) /$1 [R=307,L]
106
+
107
+ <% else %>
108
+ RewriteBase /
109
+
110
+ ##
111
+ ## remove trailing slashes (except for paths where we added the slash)
112
+ ##
113
+
114
+ # /en/ => /en
115
+ RewriteCond %{QUERY_STRING} !end
116
+ RewriteRule ^([a-z]{2})/$ /$1 [R=307,L]
117
+
118
+ # /en/aaa/ => /en/aaa
119
+ RewriteCond %{QUERY_STRING} !end
120
+ RewriteCond %{REQUEST_URI} ^/([a-z]{2})/
121
+ RewriteCond %{REQUEST_URI} !\.html$
122
+ RewriteRule ^(.+)/$ /$1 [R=307,L]
123
+
124
+ # /foo/bar.en.html/ => /foo/bar
125
+ RewriteCond %{QUERY_STRING} !end
126
+ RewriteCond %{REQUEST_URI} \.html/$
127
+ RewriteRule ^(.+)\.[a-z]{2}\.html/$ $1 [R=307,L]
128
+
129
+ # /foo/bar/ => /foo/blah
130
+ RewriteCond %{QUERY_STRING} !end
131
+ RewriteRule ^(.+)/$ $1 [R=307,L]
132
+
133
+ ##
134
+ ## rewrite all paths with a local prefix to use
135
+ ## the appropriate index.{local}.html file or
136
+ ## filename.{local}.html file.
137
+ ##
138
+
139
+ # /en => /index.en.html
140
+ RewriteCond %{QUERY_STRING} !end
141
+ RewriteCond %{DOCUMENT_ROOT}/index.$1.html -f
142
+ RewriteCond %{REQUEST_URI} ^/([a-z]{2})$
143
+ RewriteRule ^(.*) /index.%1.html?end [L]
144
+
145
+ # /en/aaa => /aaa/index.en.html
146
+ RewriteCond %{QUERY_STRING} !end
147
+ RewriteCond %{DOCUMENT_ROOT}/$2/index.$1.html -f
148
+ RewriteRule ^([a-z]{2})/(.*) /$2/index.$1.html?end [L]
149
+
150
+ # /de/foo/bar => /foo/bar.de.html
151
+ RewriteCond %{QUERY_STRING} !end
152
+ RewriteCond %{DOCUMENT_ROOT}/$2.$1.html -f
153
+ RewriteRule ^([a-z]{2})/(.*) /$2.$1.html?end [L]
154
+
155
+ ##
156
+ ## internally simulate a trailing slashes for directories in order
157
+ ## to trigger DirectoryIndex and autonegotiated locale.
158
+ ##
159
+
160
+ # /foo/bar => /foo/bar/
161
+ RewriteCond %{QUERY_STRING} !end
162
+ RewriteCond %{DOCUMENT_ROOT}/$1 -d
163
+ RewriteRule ^(.*[^/])$ /$1/?end [PT]
164
+
165
+ ##
166
+ ## redirect assets that are locale prefixed
167
+ ## (in order to allow relative paths)
168
+ ##
169
+
170
+ # e.g. /de/foo/assets/style.css => /foo/assets/style.css
171
+ RewriteCond %{QUERY_STRING} !end
172
+ RewriteCond %{DOCUMENT_ROOT}/$2 -f
173
+ RewriteRule ^([a-z]{2})/(.*) /$2 [R=307,L]
174
+
175
+ <% end %>
176
+