utopia 0.12.6 → 1.0.0

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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -2
  3. data/Gemfile +6 -0
  4. data/README.md +48 -14
  5. data/Rakefile +5 -0
  6. data/bin/utopia +132 -15
  7. data/lib/utopia.rb +13 -10
  8. data/lib/utopia/content.rb +140 -0
  9. data/lib/utopia/content/link.rb +124 -0
  10. data/lib/utopia/content/links.rb +228 -0
  11. data/lib/utopia/content/node.rb +387 -0
  12. data/lib/utopia/content/processor.rb +128 -0
  13. data/lib/utopia/content/tag.rb +102 -0
  14. data/lib/utopia/controller.rb +137 -0
  15. data/lib/utopia/controller/action.rb +112 -0
  16. data/lib/utopia/controller/base.rb +174 -0
  17. data/lib/utopia/{middleware/controller → controller}/variables.rb +36 -38
  18. data/lib/utopia/exception_handler.rb +79 -0
  19. data/lib/utopia/extensions/array.rb +2 -2
  20. data/lib/utopia/localization.rb +143 -0
  21. data/lib/utopia/mail_exceptions.rb +136 -0
  22. data/lib/utopia/middleware.rb +7 -22
  23. data/lib/utopia/path.rb +150 -60
  24. data/lib/utopia/redirector.rb +152 -0
  25. data/lib/utopia/{extensions/hash.rb → session.rb} +4 -6
  26. data/lib/utopia/session/encrypted_cookie.rb +46 -48
  27. data/lib/utopia/{middleware/directory_index.rb → session/lazy_hash.rb} +44 -27
  28. data/lib/utopia/static.rb +255 -0
  29. data/lib/utopia/tags/deferred.rb +12 -8
  30. data/lib/utopia/tags/environment.rb +18 -6
  31. data/lib/utopia/tags/node.rb +12 -8
  32. data/lib/utopia/tags/override.rb +12 -12
  33. data/lib/utopia/version.rb +1 -1
  34. data/setup/.bowerrc +3 -0
  35. data/{lib/utopia/setup → setup}/Gemfile +1 -1
  36. data/setup/Rakefile +4 -0
  37. data/{lib/utopia/setup → setup}/cache/head/readme.txt +0 -0
  38. data/{lib/utopia/setup → setup}/cache/meta/readme.txt +0 -0
  39. data/setup/config.ru +64 -0
  40. data/{lib/utopia/setup → setup}/lib/readme.txt +0 -0
  41. data/{lib/utopia/setup → setup}/pages/_heading.xnode +0 -0
  42. data/{lib/utopia/setup → setup}/pages/_page.xnode +1 -1
  43. data/{lib/utopia/setup → setup}/pages/_static/icon.png +0 -0
  44. data/setup/pages/_static/site.css +70 -0
  45. data/{lib/utopia/setup → setup}/pages/errors/exception.xnode +0 -0
  46. data/{lib/utopia/setup → setup}/pages/errors/file-not-found.xnode +0 -0
  47. data/{lib/utopia/setup → setup}/pages/links.yaml +0 -0
  48. data/setup/pages/welcome/index.xnode +17 -0
  49. data/{lib/utopia/setup → setup}/public/readme.txt +0 -0
  50. data/spec/utopia/content/link_spec.rb +108 -0
  51. data/spec/utopia/content/links/foo/index.xnode +0 -0
  52. data/spec/utopia/content/links/foo/links.yaml +2 -0
  53. data/spec/utopia/content/links/foo/test.de.xnode +0 -0
  54. data/spec/utopia/content/links/foo/test.en.xnode +0 -0
  55. data/spec/utopia/content/links/links.yaml +9 -0
  56. data/spec/utopia/content/links/welcome.xnode +0 -0
  57. data/spec/utopia/content/localized/five/index.en.xnode +0 -0
  58. data/spec/utopia/content/localized/four/index.en.xnode +0 -0
  59. data/spec/utopia/content/localized/four/index.zh.xnode +0 -0
  60. data/spec/utopia/content/localized/four/links.yaml +4 -0
  61. data/spec/utopia/content/localized/links.yaml +16 -0
  62. data/spec/utopia/content/localized/one.xnode +0 -0
  63. data/spec/utopia/content/localized/three/index.xnode +0 -0
  64. data/spec/utopia/content/localized/two.en.xnode +0 -0
  65. data/spec/utopia/content/localized/two.zh.xnode +0 -0
  66. data/spec/utopia/content/node/ordered/first.xnode +0 -0
  67. data/spec/utopia/content/node/ordered/index.xnode +0 -0
  68. data/spec/utopia/content/node/ordered/links.yaml +4 -0
  69. data/spec/utopia/content/node/ordered/second.xnode +0 -0
  70. data/spec/utopia/content/node/related/foo.en.xnode +0 -0
  71. data/spec/utopia/content/node/related/foo.ja.xnode +0 -0
  72. data/spec/utopia/content/node/related/links.yaml +4 -0
  73. data/spec/utopia/content/node_spec.rb +63 -0
  74. data/spec/utopia/{middleware/content_spec.rb → content/processor_spec.rb} +34 -23
  75. data/spec/utopia/content_spec.rb +87 -0
  76. data/spec/utopia/content_spec.ru +10 -0
  77. data/spec/utopia/{middleware/controller_spec.rb → controller_spec.rb} +61 -16
  78. data/spec/utopia/controller_spec.ru +4 -0
  79. data/spec/utopia/extensions_spec.rb +6 -17
  80. data/spec/utopia/localization_spec.rb +60 -0
  81. data/spec/utopia/localization_spec.ru +11 -0
  82. data/{lib/utopia/tags.rb → spec/utopia/middleware_spec.rb} +8 -14
  83. data/spec/utopia/{middleware/content_root → pages}/_heading.xnode +0 -0
  84. data/spec/utopia/pages/content/_show-value.xnode +1 -0
  85. data/spec/utopia/pages/content/test-partial.xnode +1 -0
  86. data/spec/utopia/pages/controller/controller.rb +28 -0
  87. data/spec/utopia/pages/controller/index.xnode +1 -0
  88. data/spec/utopia/pages/controller/nested/controller.rb +4 -0
  89. data/spec/utopia/{middleware/content_root → pages}/index.xnode +0 -0
  90. data/spec/utopia/pages/localized.de.txt +1 -0
  91. data/spec/utopia/pages/localized.en.txt +1 -0
  92. data/spec/utopia/pages/localized.jp.txt +1 -0
  93. data/spec/utopia/pages/node/index.xnode +1 -0
  94. data/spec/utopia/pages/test.txt +1 -0
  95. data/spec/utopia/path_spec.rb +109 -0
  96. data/spec/utopia/rack_spec.rb +2 -0
  97. data/spec/utopia/session_spec.rb +82 -0
  98. data/spec/utopia/session_spec.ru +20 -0
  99. data/spec/utopia/spec_helper.rb +16 -0
  100. data/{lib/utopia/extensions/string.rb → spec/utopia/static_spec.rb} +24 -15
  101. data/spec/utopia/static_spec.ru +4 -0
  102. data/utopia.gemspec +3 -3
  103. metadata +138 -54
  104. data/lib/utopia/extensions/regexp.rb +0 -33
  105. data/lib/utopia/link.rb +0 -288
  106. data/lib/utopia/middleware/all.rb +0 -33
  107. data/lib/utopia/middleware/content.rb +0 -157
  108. data/lib/utopia/middleware/content/node.rb +0 -386
  109. data/lib/utopia/middleware/content/processor.rb +0 -123
  110. data/lib/utopia/middleware/controller.rb +0 -130
  111. data/lib/utopia/middleware/controller/action.rb +0 -121
  112. data/lib/utopia/middleware/controller/base.rb +0 -184
  113. data/lib/utopia/middleware/exception_handler.rb +0 -80
  114. data/lib/utopia/middleware/localization.rb +0 -147
  115. data/lib/utopia/middleware/localization/name.rb +0 -69
  116. data/lib/utopia/middleware/mail_exceptions.rb +0 -138
  117. data/lib/utopia/middleware/redirector.rb +0 -146
  118. data/lib/utopia/middleware/requester.rb +0 -126
  119. data/lib/utopia/middleware/static.rb +0 -295
  120. data/lib/utopia/setup.rb +0 -60
  121. data/lib/utopia/setup/config.ru +0 -47
  122. data/lib/utopia/setup/pages/_static/background.png +0 -0
  123. data/lib/utopia/setup/pages/_static/site.css +0 -48
  124. data/lib/utopia/setup/pages/welcome/index.xnode +0 -7
  125. data/lib/utopia/tag.rb +0 -105
  126. data/lib/utopia/tags/all.rb +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 296a41faf645d12aa55672af9445a4f94f939da1
4
- data.tar.gz: 53019aaae569b4191d3361d3d2a1094a9e52bcfe
3
+ metadata.gz: 2de92361694a0d93055b13141f7373bdca9ba4c8
4
+ data.tar.gz: abf743ebf57a07d8850fb22719ee62085e4c1166
5
5
  SHA512:
6
- metadata.gz: 34aaf114f9917265dbe27b65379bb77cb66fda5310b27384d2edcae8dc21fc01d7d814d6ea79f98fca46be81cbf2c1b9dc0c1da9f40b6af20dffa7cfb5dd2557
7
- data.tar.gz: 09e47aa4fd61d9d015c7aa836c734dda5f20570efd02bacdd745756b2e02c6fc4e32e413bd47dfd1d140d740adf340dd4f0682b08ad63b579352af2798b0fae7
6
+ metadata.gz: bdeeca349e075376b9a5a65c97195e92e4e67c3b6c21077ab93fbf86395dd4745b41c63cc0362371a9af1b8162ece2a7c65011c081b617ef6e1cd05c0920280d
7
+ data.tar.gz: 0a135fa1fd8069f1a8b90ea8f040bd1dad4f71891e37735099184a3579d2191f21a8e8bf0b87955ffe6d4835561ce28f9b21d97423ba7b423b9a8b0d4afaeec7
@@ -1,5 +1,9 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "1.9.3"
4
3
  - "2.0"
5
- - "2.1"
4
+ - "2.1"
5
+ - "2.2"
6
+ - "rbx-2"
7
+ matrix:
8
+ allow_failures:
9
+ - rvm: "rbx-2"
data/Gemfile CHANGED
@@ -2,3 +2,9 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in utopia.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'rack-test'
8
+ gem 'simplecov'
9
+ gem 'coveralls', require: false
10
+ end
data/README.md CHANGED
@@ -2,38 +2,72 @@
2
2
 
3
3
  Utopia is a website generation framework which provides a robust set of tools
4
4
  to build highly complex dynamic websites. It uses the filesystem heavily for
5
- content and provides frameworks for interacting with files and directories as
5
+ content and provides functions for interacting with files and directories as
6
6
  structure representing the website.
7
7
 
8
8
  Utopia builds on top of Rack with the following middleware:
9
9
 
10
- * `Utopia::Middleware::Static`: Serve static files with recursive lookup
11
- * `Utopia::Middleware::Requester`: Allow nesting of virtual requests
12
- * `Utopia::Middleware::Redirector`: Redirect URL patterns and status codes
13
- * `Utopia::Middleware::Logger`: Advanced rotating access log
14
- * `Utopia::Middleware::Localization`: Non-intrusive localization of resources
15
- * `Utopia::Middleware::DirectoryIndex`: Redirect directory requests to specific files
16
- * `Utopia::Middleware::Controller`: Dynamic behaviour with recursive execution
17
- * `Utopia::Middleware::Content`: XML-style template engine with powerful tag behaviours
18
- * `Utopia::Session::EncryptedCookie`: Session storage using an encrypted cookie
10
+ - `Utopia::Static`: Serve static files with recursive lookup.
11
+ - `Utopia::Redirector`: Redirect URL patterns and status codes.
12
+ - `Utopia::Localization`: Non-intrusive localization of resources.
13
+ - `Utopia::Controller`: Dynamic behaviour with recursive execution.
14
+ - `Utopia::Content`: XML-style template engine with powerful tag behaviours.
15
+ - `Utopia::Session::EncryptedCookie`: Session storage using an encrypted cookie.
19
16
 
20
17
  For more details please see the main [project page][1].
21
18
 
22
19
  [1]: http://www.oriontransfer.co.nz/gems/utopia
23
20
 
24
21
  [![Build Status](https://secure.travis-ci.org/ioquatix/utopia.png)](http://travis-ci.org/ioquatix/utopia)
22
+ [![Coverage Status](https://coveralls.io/repos/ioquatix/utopia/badge.svg)](https://coveralls.io/r/ioquatix/utopia)
23
+
24
+ ## Middleware
25
+
26
+ ### Static
27
+
28
+ This middleware serves static files using the `mime-types` library. By default, it works with `Rack::Sendfile` and `Rack::Cache` and supports `ETag` based caching.
29
+
30
+ ### Redirector
31
+
32
+ A flexible high level URI rewriting system which includes support for string mappings, regular expressions and status codes (e.g. 404 errors).
33
+
34
+ ### Localization
35
+
36
+ The localization middleware uses the `Accept-Language` header to guess the preferred locale out of the given options. If a request path maps to a resource, that resource is returned. Otherwise, a localized request is made.
37
+
38
+ ### Controller
39
+
40
+ A simple recursive controller layer which works in isolation from the view rendering middleware. A controller consists of a set of actions which match against incoming paths and execute code accordingly.
41
+
42
+ ### Content
43
+
44
+ A tag based content generation system which integrates nicely with HTML5. Supports structures which separate generic page templates from dynamically generated content in an easy and consistent way.
45
+
46
+ ### Session
47
+
48
+ The encrypted cookie session management uses symmetric private key encryption to store data on the client and avoid tampering.
25
49
 
26
50
  ## Installation
27
51
 
28
52
  Install utopia:
29
53
 
30
- $ gem install utopia
54
+ $ gem install utopia
31
55
 
32
56
  Create a new site:
33
57
 
34
- $ utopia setup www.example.com
58
+ $ utopia create www.example.com
35
59
  $ cd www.example.com
36
- $ thin start -p 9000
60
+ $ rake server
61
+
62
+ ### Bower Integration
63
+
64
+ If you create a site using the utopia generator, it includes a `.bowerrc` configuration which installs components into `public/_static/components`. To install jquery, for example:
65
+
66
+ bower install jquery
67
+
68
+ Then add the appropriate `<script>` tags to `pages/_page.xnode`:
69
+
70
+ <script src="/_static/components/jquery/dist/jquery.min.js" type="text/javascript"></script>
37
71
 
38
72
  ## Usage
39
73
 
@@ -51,7 +85,7 @@ The default site includes documentation and examples.
51
85
 
52
86
  Released under the MIT license.
53
87
 
54
- Copyright, 2012, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
88
+ Copyright, 2015, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
55
89
 
56
90
  Permission is hereby granted, free of charge, to any person obtaining a copy
57
91
  of this software and associated documentation files (the "Software"), to deal
data/Rakefile CHANGED
@@ -4,3 +4,8 @@ require "rspec/core/rake_task"
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  task :default => :spec
7
+
8
+ task :coverage do
9
+ ENV['COVERAGE'] = 'true'
10
+ Rake::Task['spec'].execute
11
+ end
data/bin/utopia CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
3
+ # Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
4
  #
5
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  # of this software and associated documentation files (the "Software"), to deal
@@ -21,27 +21,73 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  require 'rubygems'
24
- require 'utopia/setup'
24
+ require 'rake'
25
+
26
+ require_relative '../lib/utopia/version'
27
+
28
+ require 'fileutils'
29
+ require 'find'
25
30
  require 'rake'
26
31
 
27
32
  $app = Rake.application = Rake::Application.new
28
33
  $app.init('Utopia')
29
34
 
30
- task :setup do
31
- path = File.expand_path(ARGV.last, Dir.getwd)
32
- FileUtils.mkdir_p path
35
+ module Setup
36
+ DIRECTORIES = ["cache", "cache/meta", "cache/body", "lib", "pages", "public"]
37
+ SYMLINKS = {"public/_static" => "../pages/_static"}
38
+
39
+ CONFIGURATION_FILES = ['config.ru', 'Gemfile', 'Rakefile']
40
+
41
+ # Removed during upgrade process
42
+ OLD_DIRECTORIES = ["access_log"]
43
+ end
33
44
 
34
- Dir.chdir(path) do
35
- Utopia::Setup.copy(path)
45
+ task :create do
46
+ $stderr.puts("Usage: #{File.basename $0} create $path") & exit if ARGV.size != 2
36
47
 
37
- if `which thin`.strip == ""
38
- $stderr.puts "Next, please install thin: `sudo gem install thin'."
39
- end
48
+ destination_root = File.expand_path(ARGV.last, Dir.getwd)
49
+ setup_root = File.expand_path("../../setup", __FILE__)
50
+
51
+ $stderr.puts "Copying files from #{setup_root} to #{destination_root}..."
52
+
53
+ Setup::DIRECTORIES.each do |directory|
54
+ FileUtils.mkdir_p(File.join(destination_root, directory))
55
+ end
40
56
 
41
- if `which git`.strip == ""
42
- $stderr.puts "Now is a good time to learn about git : http://git-scm.com/"
57
+ Find.find(setup_root) do |source_path|
58
+ # What is this doing?
59
+ destination_path = File.join(destination_root, source_path[setup_root.size..-1])
60
+
61
+ if File.directory?(source_path)
62
+ FileUtils.mkdir_p(destination_path)
63
+ else
64
+ if File.exist? destination_path
65
+ $stderr.puts "\tFile already exists: #{destination_path}!"
66
+ else
67
+ $stderr.puts "\tCopying #{source_path} to #{destination_path}..."
68
+ FileUtils.copy_entry(source_path, destination_path)
69
+ end
43
70
  end
71
+ end
44
72
 
73
+ Setup::SYMLINKS.each do |path, target|
74
+ FileUtils.ln_s(target, File.join(destination_root, path))
75
+ end
76
+
77
+ Setup::CONFIGURATION_FILES.each do |configuration_file|
78
+ destination_path = File.join(destination_root, configuration_file)
79
+
80
+ $stderr.puts "Updating #{destination_path}..."
81
+
82
+ buffer = File.read(destination_path).gsub('$UTOPIA_VERSION', Utopia::VERSION)
83
+ File.open(destination_path, "w") { |file| file.write(buffer) }
84
+ end
85
+
86
+ if `which git`.strip == ""
87
+ $stderr.puts "Now is a good time to learn about git : http://git-scm.com/"
88
+ end
89
+
90
+ Dir.chdir(destination_root) do
45
91
  unless File.exist? '.git'
46
92
  sh("git", "init")
47
93
  sh("git", "add", ".")
@@ -49,12 +95,83 @@ task :setup do
49
95
  end
50
96
  end
51
97
 
52
- $stderr.puts "*** Thanks for trying out Utopia! ***"
98
+ $stderr.puts "*** Thanks for using Utopia! ***"
99
+ $stderr.puts "To start the server:\n\tcd #{ARGV.last}\n\trake server"
100
+ end
101
+
102
+ task :upgrade do
103
+ $stderr.puts("Usage: #{File.basename $0} upgrade $path") & exit if ARGV.size != 2
104
+
105
+ destination_root = File.expand_path(ARGV.last || '.', Dir.getwd)
106
+ setup_root = File.expand_path("../../setup", __FILE__)
107
+ directories = ["cache", "cache/meta", "cache/body", "lib", "pages", "public"]
108
+ symlinks = {"public/_static" => "../pages/_static"}
109
+ branch_name = "utopia-upgrade-#{Utopia::VERSION}"
110
+
111
+ $stderr.puts "Upgrading #{destination_root}..."
112
+
113
+ Dir.chdir(destination_root) do
114
+ sh('git', 'checkout', '-b', branch_name)
115
+ end
116
+
117
+ Setup::DIRECTORIES.each do |directory|
118
+ FileUtils.mkdir_p(File.join(destination_root, directory))
119
+ end
120
+
121
+ Setup::OLD_DIRECTORIES.each do |directory|
122
+ path = File.join(destination_root, directory)
123
+ $stderr.puts "\tRemoving #{path}..."
124
+ FileUtils.rm_rf(path)
125
+ end
126
+
127
+ Setup::SYMLINKS.each do |path, target|
128
+ FileUtils.ln_s(target, File.join(destination_root, path), force: true)
129
+ end
130
+
131
+ Setup::CONFIGURATION_FILES.each do |configuration_file|
132
+ source_path = File.join(setup_root, configuration_file)
133
+ destination_path = File.join(destination_root, configuration_file)
134
+
135
+ $stderr.puts "Updating #{destination_path}..."
136
+
137
+ FileUtils.copy_entry(source_path, destination_path)
138
+ buffer = File.read(destination_path).gsub('$UTOPIA_VERSION', Utopia::VERSION)
139
+ File.open(destination_path, "w") { |file| file.write(buffer) }
140
+ end
141
+
142
+ begin
143
+ Dir.chdir(destination_root) do
144
+ # Stage any files that have been changed or removed:
145
+ sh("git", "add", "-u")
146
+
147
+ # Stage any new files that we have explicitly added:
148
+ sh("git", "add", *Setup::CONFIGURATION_FILES, *Setup::SYMLINKS.keys)
149
+
150
+ # Commit all changes:
151
+ sh("git", "commit", "-m", "Upgrade to utopia #{Utopia::VERSION}.")
152
+
153
+ # Checkout master..
154
+ sh("git", "checkout", "master")
155
+
156
+ # and merge:
157
+ sh("git", "merge", "--no-commit", "--no-ff", branch_name)
158
+ end
159
+ rescue RuntimeError
160
+ $stderr.puts "** Detected error with upgrade, reverting changes. Some new files may still exist in tree. **"
161
+
162
+ sh("git", "checkout", "master")
163
+ sh("git", "branch", "-d", branch_name)
164
+ end
165
+
166
+ $stderr.puts "*** Thanks for using Utopia! ***"
53
167
  end
54
168
 
55
169
  task :help do
56
- $stderr.puts "To create a new site, use the setup task:"
57
- $stderr.puts "$ #{File.basename($0)} setup www.example.com"
170
+ $stderr.puts "To create a new site, use the create task:"
171
+ $stderr.puts "\t#{File.basename($0)} create path/to/www.example.com"
172
+
173
+ $stderr.puts "To upgrade an existing site, use the upgrade task:"
174
+ $stderr.puts "\t#{File.basename($0)} upgrade path/to/www.example.com"
58
175
  end
59
176
 
60
177
  task :default => :help
@@ -18,14 +18,17 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require 'utopia/version'
21
+ require_relative 'utopia/version'
22
22
 
23
- require 'utopia/middleware/content'
24
- require 'utopia/middleware/controller'
25
- require 'utopia/middleware/directory_index'
26
- require 'utopia/middleware/exception_handler'
27
- require 'utopia/middleware/localization'
28
- require 'utopia/middleware/mail_exceptions'
29
- require 'utopia/middleware/redirector'
30
- require 'utopia/middleware/requester'
31
- require 'utopia/middleware/static'
23
+ require_relative 'utopia/content'
24
+ require_relative 'utopia/controller'
25
+ require_relative 'utopia/exception_handler'
26
+ require_relative 'utopia/localization'
27
+ require_relative 'utopia/mail_exceptions'
28
+ require_relative 'utopia/redirector'
29
+ require_relative 'utopia/static'
30
+
31
+ require_relative 'utopia/tags/deferred'
32
+ require_relative 'utopia/tags/environment'
33
+ require_relative 'utopia/tags/node'
34
+ require_relative 'utopia/tags/override'
@@ -0,0 +1,140 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'middleware'
22
+ require_relative 'localization'
23
+
24
+ require_relative 'content/node'
25
+ require_relative 'content/processor'
26
+
27
+ require 'trenni/template'
28
+
29
+ module Utopia
30
+ class Content
31
+ def initialize(app, options = {})
32
+ @app = app
33
+
34
+ @root = File.expand_path(options[:root] || Utopia::default_root)
35
+
36
+ @templates = options[:cache_templates] ? {} : nil
37
+
38
+ @tags = options.fetch(:tags, {})
39
+ end
40
+
41
+ attr :root
42
+ attr :passthrough
43
+
44
+ def fetch_xml(path)
45
+ if @templates
46
+ @templates.fetch(path) do |key|
47
+ @templates[key] = Trenni::Template.load(path)
48
+ end
49
+ else
50
+ Trenni::Template.load(path)
51
+ end
52
+ end
53
+
54
+ # Look up a named tag such as <entry />
55
+ def lookup_tag(name, parent_path)
56
+ if @tags.key? name
57
+ return @tags[name]
58
+ end
59
+
60
+ if String === name && name.index("/")
61
+ name = Path.create(name)
62
+ end
63
+
64
+ if Path === name
65
+ name = parent_path + name
66
+ name_path = name.components.dup
67
+ name_path[-1] += XNODE_EXTENSION
68
+ else
69
+ name_path = name + XNODE_EXTENSION
70
+ end
71
+
72
+ parent_path.ascend do |dir|
73
+ tag_path = File.join(root, dir.components, name_path)
74
+
75
+ if File.exist? tag_path
76
+ return Node.new(self, dir + name, parent_path + name, tag_path)
77
+ end
78
+
79
+ if String === name_path
80
+ tag_path = File.join(root, dir.components, "_" + name_path)
81
+
82
+ if File.exist? tag_path
83
+ return Node.new(self, dir + name, parent_path + name, tag_path)
84
+ end
85
+ end
86
+ end
87
+
88
+ return nil
89
+ end
90
+
91
+ # The request_path is an absolute uri path, e.g. /foo/bar. If an xnode file exists on disk for this exact path, it is instantiated, otherwise nil.
92
+ def lookup_node(request_path)
93
+ name = request_path.last
94
+ name_xnode = name.to_s + XNODE_EXTENSION
95
+
96
+ node_path = File.join(@root, request_path.dirname.components, name_xnode)
97
+
98
+ if File.exist? node_path
99
+ return Node.new(self, request_path.dirname + name, request_path, node_path)
100
+ end
101
+
102
+ return nil
103
+ end
104
+
105
+ def call(env)
106
+ request = Rack::Request.new(env)
107
+ path = Path.create(request.path_info)
108
+
109
+ # Check if the request is to a non-specific index. This only works for requests with a given name:
110
+ basename = path.basename
111
+ directory_path = File.join(@root, path.dirname.components, basename.name)
112
+
113
+ # If the request for /foo/bar{extensions} is actually a directory, rewrite it to /foo/bar/index{extensions}:
114
+ if File.directory? directory_path
115
+ index_path = [basename.name, basename.rename("index")]
116
+
117
+ return [307, {"Location" => path.dirname.join(index_path).to_s}, []]
118
+ end
119
+
120
+ locale = env[Localization::CURRENT_LOCALE_KEY]
121
+ if link = Links.for(@root, path, locale)
122
+ if node = lookup_node(link.path)
123
+ response = Rack::Response.new
124
+
125
+ attributes = nil
126
+
127
+ if request.respond_to?(:controller)
128
+ attributes = request.controller
129
+ end
130
+
131
+ node.process!(request, response, (attributes || {}).to_hash)
132
+
133
+ return response.finish
134
+ end
135
+ end
136
+
137
+ return @app.call(env)
138
+ end
139
+ end
140
+ end