strelka-cms 0.0.1.pre.15

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 (56) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.gemtest +0 -0
  3. data/ChangeLog +33 -0
  4. data/History.rdoc +4 -0
  5. data/Manifest.txt +52 -0
  6. data/Procfile +4 -0
  7. data/README.rdoc +74 -0
  8. data/Rakefile +68 -0
  9. data/data/strelka-cms/apps/content-feeds +194 -0
  10. data/data/strelka-cms/apps/content-manager +159 -0
  11. data/data/strelka-cms/templates/autoindex/default.tmpl +11 -0
  12. data/data/strelka-cms/templates/layout.tmpl +58 -0
  13. data/data/strelka-cms/templates/page.tmpl +21 -0
  14. data/etc/mongrel.rb +34 -0
  15. data/lib/strelka/cms.rb +42 -0
  16. data/lib/strelka/cms/page.rb +322 -0
  17. data/lib/strelka/cms/pagecatalog.rb +121 -0
  18. data/lib/strelka/cms/pagefilter.rb +76 -0
  19. data/lib/strelka/cms/pagefilter/autoindex.rb +140 -0
  20. data/lib/strelka/cms/pagefilter/cleanup.rb +40 -0
  21. data/lib/strelka/cms/pagefilter/editorial.rb +55 -0
  22. data/lib/strelka/cms/pagefilter/example.rb +232 -0
  23. data/lib/strelka/cms/pagefilter/strip.rb +30 -0
  24. data/lib/strelka/cms/pagefilter/textile.rb +20 -0
  25. data/public/humans.txt +8 -0
  26. data/public/images/misc/button-gloss.png +0 -0
  27. data/public/images/misc/button-overlay.png +0 -0
  28. data/public/images/misc/custom-form-sprites.png +0 -0
  29. data/public/images/misc/input-bg-outset.png +0 -0
  30. data/public/images/misc/input-bg.png +0 -0
  31. data/public/images/misc/modal-gloss.png +0 -0
  32. data/public/images/misc/table-sorter.png +0 -0
  33. data/public/images/orbit/bullets.jpg +0 -0
  34. data/public/images/orbit/left-arrow.png +0 -0
  35. data/public/images/orbit/loading.gif +0 -0
  36. data/public/images/orbit/mask-black.png +0 -0
  37. data/public/images/orbit/pause-black.png +0 -0
  38. data/public/images/orbit/right-arrow.png +0 -0
  39. data/public/images/orbit/rotator-black.png +0 -0
  40. data/public/images/orbit/timer-black.png +0 -0
  41. data/public/index.page +46 -0
  42. data/public/javascripts/app.js +98 -0
  43. data/public/javascripts/foundation.js +12 -0
  44. data/public/javascripts/jquery.min.js +4 -0
  45. data/public/javascripts/modernizr.foundation.js +4 -0
  46. data/public/robots.txt +4 -0
  47. data/public/stylesheets/app.css +30 -0
  48. data/public/stylesheets/foundation.css +1424 -0
  49. data/public/stylesheets/ie.css +13 -0
  50. data/spec/data/test.page +22 -0
  51. data/spec/lib/helpers.rb +58 -0
  52. data/spec/strelka/cms/page_spec.rb +139 -0
  53. data/spec/strelka/cms/pagecatalog_spec.rb +94 -0
  54. data/spec/strelka/cms_spec.rb +27 -0
  55. metadata +346 -0
  56. metadata.gz.sig +0 -0
data.tar.gz.sig ADDED
Binary file
data/.gemtest ADDED
File without changes
data/ChangeLog ADDED
@@ -0,0 +1,33 @@
1
+ 2012-06-29 Michael Granger <ged@FaerieMUD.org>
2
+
3
+ * .hgignore, .pryrc, .rvm.gems, .rvmrc, History.rdoc, Manifest.txt,
4
+ Procfile, README.rdoc, Rakefile, data/strelka-cms/apps/content-
5
+ feeds, data/strelka-cms/apps/content-manager, data/strelka-
6
+ cms/templates/autoindex/default.tmpl, data/strelka-
7
+ cms/templates/layout.tmpl, data/strelka-cms/templates/page.tmpl,
8
+ etc/config.yml, etc/mongrel.rb, lib/strelka/cms.rb,
9
+ lib/strelka/cms/page.rb, lib/strelka/cms/pagecatalog.rb,
10
+ lib/strelka/cms/pagefilter.rb,
11
+ lib/strelka/cms/pagefilter/autoindex.rb,
12
+ lib/strelka/cms/pagefilter/cleanup.rb,
13
+ lib/strelka/cms/pagefilter/editorial.rb,
14
+ lib/strelka/cms/pagefilter/example.rb,
15
+ lib/strelka/cms/pagefilter/strip.rb,
16
+ lib/strelka/cms/pagefilter/textile.rb, public/humans.txt,
17
+ public/images/misc/button-gloss.png, public/images/misc/button-
18
+ overlay.png, public/images/misc/custom-form-sprites.png,
19
+ public/images/misc/input-bg-outset.png, public/images/misc/input-
20
+ bg.png, public/images/misc/modal-gloss.png, public/images/misc
21
+ /table-sorter.png, public/images/orbit/bullets.jpg,
22
+ public/images/orbit/left-arrow.png, public/images/orbit/loading.gif,
23
+ public/images/orbit/mask-black.png, public/images/orbit/pause-
24
+ black.png, public/images/orbit/right-arrow.png, public/images/orbit
25
+ /rotator-black.png, public/images/orbit/timer-black.png,
26
+ public/index.page, public/javascripts/app.js,
27
+ public/javascripts/foundation.js, public/javascripts/jquery.min.js,
28
+ public/javascripts/modernizr.foundation.js, public/robots.txt,
29
+ public/stylesheets/app.css, public/stylesheets/foundation.css,
30
+ public/stylesheets/ie.css, spec/data/test.page, spec/lib/helpers.rb,
31
+ spec/strelka/cms/page_spec.rb, spec/strelka/cms_spec.rb:
32
+ Initial commit
33
+ [5f4c4eb6ef5b] [tip]
data/History.rdoc ADDED
@@ -0,0 +1,4 @@
1
+ == v0.0.1 [2012-06-29] Michael Granger <ged@FaerieMUD.org>
2
+
3
+ Initial release.
4
+
data/Manifest.txt ADDED
@@ -0,0 +1,52 @@
1
+ ChangeLog
2
+ History.rdoc
3
+ Manifest.txt
4
+ Procfile
5
+ README.rdoc
6
+ Rakefile
7
+ data/strelka-cms/apps/content-feeds
8
+ data/strelka-cms/apps/content-manager
9
+ data/strelka-cms/templates/autoindex/default.tmpl
10
+ data/strelka-cms/templates/layout.tmpl
11
+ data/strelka-cms/templates/page.tmpl
12
+ etc/mongrel.rb
13
+ lib/strelka/cms.rb
14
+ lib/strelka/cms/page.rb
15
+ lib/strelka/cms/pagecatalog.rb
16
+ lib/strelka/cms/pagefilter.rb
17
+ lib/strelka/cms/pagefilter/autoindex.rb
18
+ lib/strelka/cms/pagefilter/cleanup.rb
19
+ lib/strelka/cms/pagefilter/editorial.rb
20
+ lib/strelka/cms/pagefilter/example.rb
21
+ lib/strelka/cms/pagefilter/strip.rb
22
+ lib/strelka/cms/pagefilter/textile.rb
23
+ public/humans.txt
24
+ public/images/misc/button-gloss.png
25
+ public/images/misc/button-overlay.png
26
+ public/images/misc/custom-form-sprites.png
27
+ public/images/misc/input-bg-outset.png
28
+ public/images/misc/input-bg.png
29
+ public/images/misc/modal-gloss.png
30
+ public/images/misc/table-sorter.png
31
+ public/images/orbit/bullets.jpg
32
+ public/images/orbit/left-arrow.png
33
+ public/images/orbit/loading.gif
34
+ public/images/orbit/mask-black.png
35
+ public/images/orbit/pause-black.png
36
+ public/images/orbit/right-arrow.png
37
+ public/images/orbit/rotator-black.png
38
+ public/images/orbit/timer-black.png
39
+ public/index.page
40
+ public/javascripts/app.js
41
+ public/javascripts/foundation.js
42
+ public/javascripts/jquery.min.js
43
+ public/javascripts/modernizr.foundation.js
44
+ public/robots.txt
45
+ public/stylesheets/app.css
46
+ public/stylesheets/foundation.css
47
+ public/stylesheets/ie.css
48
+ spec/data/test.page
49
+ spec/lib/helpers.rb
50
+ spec/strelka/cms/page_spec.rb
51
+ spec/strelka/cms/pagecatalog_spec.rb
52
+ spec/strelka/cms_spec.rb
data/Procfile ADDED
@@ -0,0 +1,4 @@
1
+ # Foreman Procfile
2
+ mongrel: m2sh.rb -c strelka.sqlite start
3
+ cms: strelka -l debug -c etc/config.yml start content-manager
4
+ feeds: strelka -l debug -c etc/config.yml start content-feeds
data/README.rdoc ADDED
@@ -0,0 +1,74 @@
1
+ = Strelka CMS
2
+
3
+ home :: https://bitbucket.org/ged/strelka-cms
4
+ github :: https://github.com/ged/strelka-cms
5
+ docs :: http://deveiate.org/code/strelka-cms
6
+
7
+
8
+ == Description
9
+
10
+ This is a content-management application for Mongrel2 servers
11
+ written as a Strelka plugin.
12
+
13
+
14
+ == Prerequisites
15
+
16
+ * Strelka
17
+ * Ruby 1.9.3 or better
18
+
19
+
20
+ == Installation
21
+
22
+ $ gem install strelka-cms
23
+ $ strelka setup --config mongrel2.sqlite \
24
+ --server main \
25
+ --url /docs \
26
+ --append
27
+ strelka-cms content-manager
28
+
29
+
30
+ == Contributing
31
+
32
+ You can check out the current development source with Mercurial via its
33
+ {project page}[https://bitbucket.org/ged/strelka-cms]. Or if you prefer Git, via
34
+ {its Github mirror}[https://github.com/ged/strelka-cms].
35
+
36
+ After checking out the source, run:
37
+
38
+ $ rake newb
39
+
40
+ This task will install any missing dependencies, run the tests/specs,
41
+ and generate the API documentation.
42
+
43
+
44
+ == License
45
+
46
+ Copyright (c) 2012, Michael Granger
47
+ All rights reserved.
48
+
49
+ Redistribution and use in source and binary forms, with or without
50
+ modification, are permitted provided that the following conditions are met:
51
+
52
+ * Redistributions of source code must retain the above copyright notice,
53
+ this list of conditions and the following disclaimer.
54
+
55
+ * Redistributions in binary form must reproduce the above copyright notice,
56
+ this list of conditions and the following disclaimer in the documentation
57
+ and/or other materials provided with the distribution.
58
+
59
+ * Neither the name of the author/s, nor the names of the project's
60
+ contributors may be used to endorse or promote products derived from this
61
+ software without specific prior written permission.
62
+
63
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
64
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
67
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
69
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
70
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
71
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
72
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73
+
74
+
data/Rakefile ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'rake/clean'
4
+
5
+ begin
6
+ require 'hoe'
7
+ rescue LoadError
8
+ abort "This Rakefile requires 'hoe' (gem install hoe)"
9
+ end
10
+
11
+ Hoe.plugin :mercurial
12
+ Hoe.plugin :signing
13
+ Hoe.plugin :manualgen
14
+ Hoe.plugin :deveiate
15
+
16
+ Hoe.plugins.delete :rubyforge
17
+
18
+ hoespec = Hoe.spec 'strelka-cms' do
19
+ self.readme_file = 'README.rdoc'
20
+ self.history_file = 'History.rdoc'
21
+ self.extra_rdoc_files = FileList[ '*.rdoc' ]
22
+
23
+ self.developer 'Michael Granger', 'ged@FaerieMUD.org'
24
+
25
+ self.dependency 'strelka', '~> 0.0'
26
+ self.dependency 'ratom', '~> 0.6'
27
+ self.dependency 'RedCloth', '~> 4.2'
28
+ self.dependency 'summarize', '~> 1.0'
29
+ self.dependency 'nokogiri', '~> 1.4'
30
+ self.dependency 'pluginfactory', '~> 1.0'
31
+ self.dependency 'tidy-ext', '~> 0.1'
32
+ self.dependency 'rcodetools', '~> 0.8'
33
+
34
+ self.dependency 'hoe-deveiate', '~> 0.1', :developer
35
+
36
+ self.spec_extras[:licenses] = ["BSD"]
37
+ self.spec_extras[:rdoc_options] = ['-f', 'fivefish', '-t', 'Strelka CMS']
38
+ self.require_ruby_version( '>=1.9.2' )
39
+ self.hg_sign_tags = true if self.respond_to?( :hg_sign_tags= )
40
+ self.check_history_on_release = true if self.respond_to?( :check_history_on_release= )
41
+
42
+ self.rdoc_locations << "deveiate:/usr/local/www/public/code/#{remote_rdoc_dir}"
43
+ end
44
+
45
+ ENV['VERSION'] ||= hoespec.spec.version.to_s
46
+
47
+ # Ensure the specs pass before checking in
48
+ task 'hg:precheckin' => [ :check_history, :check_manifest, :spec ]
49
+
50
+
51
+ desc "Build a coverage report"
52
+ task :coverage do
53
+ ENV["COVERAGE"] = 'yes'
54
+ Rake::Task[:spec].invoke
55
+ end
56
+
57
+ if Rake::Task.task_defined?( '.gemtest' )
58
+ Rake::Task['.gemtest'].clear
59
+ task '.gemtest' do
60
+ $stderr.puts "Not including a .gemtest until I'm confident the test suite is idempotent."
61
+ end
62
+ end
63
+
64
+
65
+ # Add admin app testing directories to the clobber list
66
+ CLOBBER.include( 'static', 'run', 'logs', 'strelka.sqlite' )
67
+
68
+
@@ -0,0 +1,194 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'pathname'
4
+ require 'rss/maker'
5
+ require 'atom'
6
+ require 'uuidtools'
7
+ require 'time'
8
+ require 'socket'
9
+ require 'configurability'
10
+
11
+ require 'strelka'
12
+ require 'strelka/mixins'
13
+
14
+ require 'strelka/cms'
15
+ require 'strelka/cms/pagecatalog'
16
+ require 'strelka/cms/page'
17
+
18
+
19
+ # The Feed applet -- generate RSS and Atom feeds for various things.
20
+ class Strelka::CMS::ContentFeeds < Strelka::App
21
+ extend Configurability,
22
+ Strelka::MethodUtilities
23
+ include UUIDTools
24
+
25
+
26
+ # Configurability API -- configure this app with the 'feeds' section of the
27
+ # config.
28
+ config_key :content_feeds
29
+
30
+
31
+ # Strelka app ID
32
+ ID = 'content-feeds'
33
+
34
+ # Configuration defaults
35
+ DEFAULT_CONFIG = {
36
+ uuid: UUID.sha1_create( UUID_DNS_NAMESPACE, Socket.gethostname ).to_s,
37
+ entry_count: 10,
38
+ pageroot: Pathname( __FILE__ ).dirname.parent.parent.parent + 'public',
39
+ paths: [''],
40
+ }
41
+
42
+
43
+ # The feed's site UUID (for Atom feeds)
44
+ singleton_attr_accessor :uuid
45
+
46
+ # The number of entries to include in a feed
47
+ singleton_attr_accessor :entry_count
48
+
49
+ # The page root
50
+ singleton_attr_accessor :pageroot
51
+
52
+ # The paths, relative to the pageroot, that can be served as a feed
53
+ singleton_attr_accessor :paths
54
+
55
+
56
+ ### Configurability API -- configure the app.
57
+ def self::configure( config=nil )
58
+ if config
59
+ self.uuid = config[:uuid]
60
+ self.entry_count = config[:entry_count]
61
+ self.pageroot = config[:pageroot]
62
+ self.paths = config[:paths]
63
+ end
64
+ end
65
+
66
+
67
+ ### Set up the feeds app.
68
+ def initialize( * )
69
+ super
70
+ @catalog = Strelka::CMS::PageCatalog.new( self.class.pageroot )
71
+ @site_uuid = UUID.parse( self.class.uuid )
72
+ end
73
+
74
+ ######
75
+ public
76
+ ######
77
+
78
+ # The PageCatalog to use for building feeds
79
+ attr_reader :catalog
80
+
81
+
82
+ #
83
+ # Routing
84
+ #
85
+ plugin :routing
86
+
87
+ get 'rss' do |req|
88
+ feedpath = req.app_path[ %r{/rss/(.*)}, 1 ]
89
+ newest_pages = self.find_newest_pages( feedpath, req )
90
+
91
+ baseuri = req.uri
92
+ baseuri.path = ''
93
+
94
+ # Generate the feed out of the newest 10 pages
95
+ feed = RSS::Maker.make( '2.0' ) do |feed|
96
+ feed.channel.title = "DevEiate: %s" % [ feedpath.capitalize ]
97
+ feed.channel.link = "http://deveiate.org/#{feedpath}/"
98
+ feed.channel.description = "Making stuff up since 1994"
99
+ feed.items.do_sort = true # sort items by date
100
+
101
+ newest_pages.each do |page|
102
+ entry_url = baseuri.dup
103
+ entry_url.path = '/' + File.join( feedpath, page.relative_html_path )
104
+
105
+ item = feed.items.new_item
106
+ item.title = page.title
107
+ item.link = entry_url
108
+ item.date = page.date
109
+ end
110
+ end
111
+
112
+ res = req.response
113
+
114
+ # Set the cache header and set the mimetype
115
+ res.headers.last_modified = newest_pages.first.date.httpdate
116
+ res.content_type = 'application/rss+xml'
117
+ res.body = feed.to_s
118
+
119
+ return res
120
+ end
121
+
122
+
123
+ ### Action: Return an ATOM feed for the pages under the path made up of +pathparts+.
124
+ get 'atom' do |req|
125
+ feedpath = req.app_path[ %r{/atom/(.*)}, 1 ]
126
+ newest_pages = self.find_newest_pages( feedpath, req )
127
+ newest_page = newest_pages.first
128
+
129
+ baseuri = req.uri
130
+ baseuri.path = ''
131
+
132
+ feed = Atom::Feed.new do |feed|
133
+ feed.title = "DevEiate: %s" % [ feedpath.capitalize ]
134
+ feed.links << Atom::Link.new( :href => baseuri )
135
+ feed.updated = newest_page.date
136
+ feed.authors << Atom::Person.new( :name => 'Michael Granger' )
137
+ feed.id = @site_uuid.to_uri
138
+
139
+ newest_pages.each do |page|
140
+ entry_url = baseuri.dup
141
+ entry_url.path = '/' + File.join( feedpath, page.relative_html_path )
142
+
143
+ feed.entries << Atom::Entry.new do |entry|
144
+ entry.title = page.title
145
+ entry.id = UUID.sha1_create( UUID_URL_NAMESPACE, entry_url.to_s ).to_uri
146
+ entry.updated = page.date
147
+ entry.summary = page.summary
148
+
149
+ entry.links << Atom::Link.new( :href => entry_url )
150
+ end
151
+ end
152
+ end
153
+
154
+ res = req.response
155
+
156
+ # Set the cache header and set the mimetype
157
+ res.headers.last_modified = newest_page.date.httpdate
158
+ res.content_type = 'application/atom+xml'
159
+ res.body = feed.to_xml
160
+
161
+ return res
162
+ end
163
+
164
+
165
+ #########
166
+ protected
167
+ #########
168
+
169
+ ### Find the newest pages for the path of the +request+ and return them.
170
+ def find_newest_pages( feedpath, req )
171
+ self.log.debug "Looking for newest pages in feed path: %p" % [ feedpath ]
172
+ finish_with HTTP::NOT_FOUND unless self.class.paths.include?( feedpath )
173
+ feedpath.untaint
174
+
175
+ count = self.class.entry_count
176
+ newest_pages = self.catalog.relative_to( feedpath ).sort_by( &:date ).first( count )
177
+ newest_page = newest_pages.first
178
+
179
+ # Just 304 if the feed doesn't need to be updated
180
+ if req.headers.if_modified_since &&
181
+ Time.parse(req.headers.if_modified_since) > newest_page.date
182
+
183
+ self.log.info "Not modified since %s" % [ req.headers.if_modified_since ]
184
+ finish_with HTTP::NOT_MODIFIED, "No changes since %s" % [ req.headers.if_modified_since ]
185
+ end
186
+
187
+ return newest_pages
188
+ end
189
+
190
+
191
+ end # class Strelka::CMS::Feeds
192
+
193
+ Encoding.default_internal = Encoding::UTF_8
194
+ Strelka::CMS::Feeds.run if __FILE__ == $0
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'loggability'
4
+ require 'pathname'
5
+ require 'redcloth'
6
+ require 'mail'
7
+
8
+ require 'strelka/app'
9
+ require 'strelka/mixins'
10
+
11
+ require 'strelka/cms'
12
+
13
+
14
+ class Strelka::CMS::ContentManager < Strelka::App
15
+ extend Loggability,
16
+ Configurability,
17
+ Strelka::MethodUtilities
18
+
19
+ # Loggability API -- log to Strelka::CMS's logger
20
+ log_to :strelka_cms
21
+
22
+ # Configurability API -- use values from the 'cms' section of the config
23
+ config_key :content_manager
24
+
25
+
26
+ # Strelka App ID
27
+ ID = 'content-manager'
28
+
29
+ # The default directory to scan for pages
30
+ DEFAULT_CONFIG = {
31
+ pageroot: Pathname( __FILE__ ).dirname.parent.parent.parent + 'public'
32
+ }
33
+
34
+ # Pattern for untainting the page path
35
+ PAGE_PATH_PATTERN = %r{
36
+ \A
37
+ (?<path>(?:
38
+ [\w\-/] # Allow word characters, slashes, and hyphens
39
+ )*)
40
+ (?:\.(?<suffix>html|page))? # optional suffix
41
+ \z
42
+ }x
43
+
44
+
45
+ ##
46
+ # The configured catalog root
47
+ singleton_attr_accessor :pageroot
48
+
49
+ ##
50
+ # The default content-type
51
+ default_type 'text/html'
52
+
53
+
54
+ # Strelka App setup
55
+ plugin :templating
56
+ layout 'layout.tmpl'
57
+ templates \
58
+ page: 'page.tmpl'
59
+
60
+ # Error-handler
61
+ plugin :fancyerrors
62
+
63
+
64
+ ### Configurability API -- configure the CMS class once the config is loaded.
65
+ def self::configure( config=nil )
66
+ if config && config.member?( :pageroot )
67
+ self.log.debug "Config is: %p" % [ config ]
68
+ self.pageroot = Pathname( config.pageroot )
69
+ else
70
+ self.pageroot = DEFAULT_CONFIG[:pageroot]
71
+ end
72
+ end
73
+
74
+
75
+ ### Create a new instance of the CMS handler application.
76
+ def initialize( * )
77
+ super
78
+ @catalog = Strelka::CMS::PageCatalog.new( self.class.pageroot )
79
+ end
80
+
81
+
82
+ #
83
+ # Handler Routes
84
+ #
85
+ plugin :routing
86
+
87
+ # /
88
+ # -> /.page
89
+ # -> /index.page
90
+
91
+ # /foo/
92
+ # -> /foo.page
93
+ # -> /foo/index.page
94
+
95
+ # /foo/project
96
+ # -> /foo/project.page
97
+ # -> /foo/project/index.page
98
+ # -> /foo/project.html (literal)
99
+ # -> /foo/project/index.html (literal)
100
+
101
+ get do |request|
102
+ unless path = request.app_path[ PAGE_PATH_PATTERN, :path ]
103
+ self.log.error "Invalid app_path: %p" % [ request.app_path ]
104
+ finish_with HTTP::NOT_FOUND
105
+ end
106
+
107
+ # Force the path to be relative and clean it up
108
+ path = Pathname( path.gsub(%r{\A\.?/+|/(?=/)|/+\z}, '') )
109
+ page = nil
110
+
111
+ # Try to find a matching .page file
112
+ self.log.debug "Page path is: %p" % [ path ]
113
+ if path.to_s.empty?
114
+ subcat = @catalog.matching_pattern( 'index.page' )
115
+ page = subcat.first
116
+ else
117
+ subcat = @catalog.relative_to( path.dirname ).
118
+ matching_pattern( "#{path.basename(path.extname)}{.page,/index.page}" )
119
+ page = subcat.first
120
+ end
121
+
122
+ # If there was a matching .page file, use that
123
+ if page
124
+ self.log.debug " found page: %p" % [ page ]
125
+ return self.page_response( page )
126
+ end
127
+
128
+ # Try a literal HTML page
129
+ htmlpage = self.class.pageroot + path.sub_ext( '.html' )
130
+ if htmlpage.exist?
131
+ return self.raw_response( request, htmlpage )
132
+ end
133
+
134
+ # Give up
135
+ self.log.error "No pages matching %p" % [ path ]
136
+ finish_with HTTP::NOT_FOUND
137
+ end
138
+
139
+
140
+ ### Package up the specified +page+ in the page template and return it.
141
+ def page_response( page )
142
+ tmpl = self.template( :page )
143
+ tmpl.page = page
144
+ return tmpl
145
+ end
146
+
147
+
148
+ ### Package up the page at the specified +path+ in the response and return it.
149
+ def raw_response( request, pagepath )
150
+ response = request.response
151
+ response.body = pagepath.open( 'r', encoding: 'utf-8' )
152
+ return response
153
+ end
154
+
155
+ end # class Strelka::CMS::ContentManager
156
+
157
+ Encoding.default_internal = Encoding::UTF_8
158
+ Strelka::CMS::ContentManager.run if __FILE__ == $0
159
+