utopia 0.12.6 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -2
- data/Gemfile +6 -0
- data/README.md +48 -14
- data/Rakefile +5 -0
- data/bin/utopia +132 -15
- data/lib/utopia.rb +13 -10
- data/lib/utopia/content.rb +140 -0
- data/lib/utopia/content/link.rb +124 -0
- data/lib/utopia/content/links.rb +228 -0
- data/lib/utopia/content/node.rb +387 -0
- data/lib/utopia/content/processor.rb +128 -0
- data/lib/utopia/content/tag.rb +102 -0
- data/lib/utopia/controller.rb +137 -0
- data/lib/utopia/controller/action.rb +112 -0
- data/lib/utopia/controller/base.rb +174 -0
- data/lib/utopia/{middleware/controller → controller}/variables.rb +36 -38
- data/lib/utopia/exception_handler.rb +79 -0
- data/lib/utopia/extensions/array.rb +2 -2
- data/lib/utopia/localization.rb +143 -0
- data/lib/utopia/mail_exceptions.rb +136 -0
- data/lib/utopia/middleware.rb +7 -22
- data/lib/utopia/path.rb +150 -60
- data/lib/utopia/redirector.rb +152 -0
- data/lib/utopia/{extensions/hash.rb → session.rb} +4 -6
- data/lib/utopia/session/encrypted_cookie.rb +46 -48
- data/lib/utopia/{middleware/directory_index.rb → session/lazy_hash.rb} +44 -27
- data/lib/utopia/static.rb +255 -0
- data/lib/utopia/tags/deferred.rb +12 -8
- data/lib/utopia/tags/environment.rb +18 -6
- data/lib/utopia/tags/node.rb +12 -8
- data/lib/utopia/tags/override.rb +12 -12
- data/lib/utopia/version.rb +1 -1
- data/setup/.bowerrc +3 -0
- data/{lib/utopia/setup → setup}/Gemfile +1 -1
- data/setup/Rakefile +4 -0
- data/{lib/utopia/setup → setup}/cache/head/readme.txt +0 -0
- data/{lib/utopia/setup → setup}/cache/meta/readme.txt +0 -0
- data/setup/config.ru +64 -0
- data/{lib/utopia/setup → setup}/lib/readme.txt +0 -0
- data/{lib/utopia/setup → setup}/pages/_heading.xnode +0 -0
- data/{lib/utopia/setup → setup}/pages/_page.xnode +1 -1
- data/{lib/utopia/setup → setup}/pages/_static/icon.png +0 -0
- data/setup/pages/_static/site.css +70 -0
- data/{lib/utopia/setup → setup}/pages/errors/exception.xnode +0 -0
- data/{lib/utopia/setup → setup}/pages/errors/file-not-found.xnode +0 -0
- data/{lib/utopia/setup → setup}/pages/links.yaml +0 -0
- data/setup/pages/welcome/index.xnode +17 -0
- data/{lib/utopia/setup → setup}/public/readme.txt +0 -0
- data/spec/utopia/content/link_spec.rb +108 -0
- data/spec/utopia/content/links/foo/index.xnode +0 -0
- data/spec/utopia/content/links/foo/links.yaml +2 -0
- data/spec/utopia/content/links/foo/test.de.xnode +0 -0
- data/spec/utopia/content/links/foo/test.en.xnode +0 -0
- data/spec/utopia/content/links/links.yaml +9 -0
- data/spec/utopia/content/links/welcome.xnode +0 -0
- data/spec/utopia/content/localized/five/index.en.xnode +0 -0
- data/spec/utopia/content/localized/four/index.en.xnode +0 -0
- data/spec/utopia/content/localized/four/index.zh.xnode +0 -0
- data/spec/utopia/content/localized/four/links.yaml +4 -0
- data/spec/utopia/content/localized/links.yaml +16 -0
- data/spec/utopia/content/localized/one.xnode +0 -0
- data/spec/utopia/content/localized/three/index.xnode +0 -0
- data/spec/utopia/content/localized/two.en.xnode +0 -0
- data/spec/utopia/content/localized/two.zh.xnode +0 -0
- data/spec/utopia/content/node/ordered/first.xnode +0 -0
- data/spec/utopia/content/node/ordered/index.xnode +0 -0
- data/spec/utopia/content/node/ordered/links.yaml +4 -0
- data/spec/utopia/content/node/ordered/second.xnode +0 -0
- data/spec/utopia/content/node/related/foo.en.xnode +0 -0
- data/spec/utopia/content/node/related/foo.ja.xnode +0 -0
- data/spec/utopia/content/node/related/links.yaml +4 -0
- data/spec/utopia/content/node_spec.rb +63 -0
- data/spec/utopia/{middleware/content_spec.rb → content/processor_spec.rb} +34 -23
- data/spec/utopia/content_spec.rb +87 -0
- data/spec/utopia/content_spec.ru +10 -0
- data/spec/utopia/{middleware/controller_spec.rb → controller_spec.rb} +61 -16
- data/spec/utopia/controller_spec.ru +4 -0
- data/spec/utopia/extensions_spec.rb +6 -17
- data/spec/utopia/localization_spec.rb +60 -0
- data/spec/utopia/localization_spec.ru +11 -0
- data/{lib/utopia/tags.rb → spec/utopia/middleware_spec.rb} +8 -14
- data/spec/utopia/{middleware/content_root → pages}/_heading.xnode +0 -0
- data/spec/utopia/pages/content/_show-value.xnode +1 -0
- data/spec/utopia/pages/content/test-partial.xnode +1 -0
- data/spec/utopia/pages/controller/controller.rb +28 -0
- data/spec/utopia/pages/controller/index.xnode +1 -0
- data/spec/utopia/pages/controller/nested/controller.rb +4 -0
- data/spec/utopia/{middleware/content_root → pages}/index.xnode +0 -0
- data/spec/utopia/pages/localized.de.txt +1 -0
- data/spec/utopia/pages/localized.en.txt +1 -0
- data/spec/utopia/pages/localized.jp.txt +1 -0
- data/spec/utopia/pages/node/index.xnode +1 -0
- data/spec/utopia/pages/test.txt +1 -0
- data/spec/utopia/path_spec.rb +109 -0
- data/spec/utopia/rack_spec.rb +2 -0
- data/spec/utopia/session_spec.rb +82 -0
- data/spec/utopia/session_spec.ru +20 -0
- data/spec/utopia/spec_helper.rb +16 -0
- data/{lib/utopia/extensions/string.rb → spec/utopia/static_spec.rb} +24 -15
- data/spec/utopia/static_spec.ru +4 -0
- data/utopia.gemspec +3 -3
- metadata +138 -54
- data/lib/utopia/extensions/regexp.rb +0 -33
- data/lib/utopia/link.rb +0 -288
- data/lib/utopia/middleware/all.rb +0 -33
- data/lib/utopia/middleware/content.rb +0 -157
- data/lib/utopia/middleware/content/node.rb +0 -386
- data/lib/utopia/middleware/content/processor.rb +0 -123
- data/lib/utopia/middleware/controller.rb +0 -130
- data/lib/utopia/middleware/controller/action.rb +0 -121
- data/lib/utopia/middleware/controller/base.rb +0 -184
- data/lib/utopia/middleware/exception_handler.rb +0 -80
- data/lib/utopia/middleware/localization.rb +0 -147
- data/lib/utopia/middleware/localization/name.rb +0 -69
- data/lib/utopia/middleware/mail_exceptions.rb +0 -138
- data/lib/utopia/middleware/redirector.rb +0 -146
- data/lib/utopia/middleware/requester.rb +0 -126
- data/lib/utopia/middleware/static.rb +0 -295
- data/lib/utopia/setup.rb +0 -60
- data/lib/utopia/setup/config.ru +0 -47
- data/lib/utopia/setup/pages/_static/background.png +0 -0
- data/lib/utopia/setup/pages/_static/site.css +0 -48
- data/lib/utopia/setup/pages/welcome/index.xnode +0 -7
- data/lib/utopia/tag.rb +0 -105
- data/lib/utopia/tags/all.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2de92361694a0d93055b13141f7373bdca9ba4c8
|
4
|
+
data.tar.gz: abf743ebf57a07d8850fb22719ee62085e4c1166
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdeeca349e075376b9a5a65c97195e92e4e67c3b6c21077ab93fbf86395dd4745b41c63cc0362371a9af1b8162ece2a7c65011c081b617ef6e1cd05c0920280d
|
7
|
+
data.tar.gz: 0a135fa1fd8069f1a8b90ea8f040bd1dad4f71891e37735099184a3579d2191f21a8e8bf0b87955ffe6d4835561ce28f9b21d97423ba7b423b9a8b0d4afaeec7
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
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
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
54
|
+
$ gem install utopia
|
31
55
|
|
32
56
|
Create a new site:
|
33
57
|
|
34
|
-
$ utopia
|
58
|
+
$ utopia create www.example.com
|
35
59
|
$ cd www.example.com
|
36
|
-
$
|
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,
|
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
data/bin/utopia
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
# Copyright,
|
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 '
|
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
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
35
|
-
|
45
|
+
task :create do
|
46
|
+
$stderr.puts("Usage: #{File.basename $0} create $path") & exit if ARGV.size != 2
|
36
47
|
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
42
|
-
|
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
|
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
|
57
|
-
$stderr.puts "
|
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
|
data/lib/utopia.rb
CHANGED
@@ -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
|
-
|
21
|
+
require_relative 'utopia/version'
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|