strelka-cms 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,7 +11,7 @@ require 'strelka/mixins'
11
11
  require 'strelka/cms'
12
12
 
13
13
 
14
- class Strelka::CMS::ContentManager < Strelka::App
14
+ class Strelka::CMS::Publisher < Strelka::App
15
15
  extend Loggability,
16
16
  Configurability,
17
17
  Strelka::MethodUtilities
@@ -81,11 +81,17 @@ class Strelka::CMS::ContentManager < Strelka::App
81
81
  end
82
82
 
83
83
 
84
+ ##
85
+ # The Strelka::CMS::PageCatalog for the page root.
86
+ attr_reader :catalog
87
+
88
+
84
89
  #
85
90
  # Handler Routes
86
91
  #
87
92
  plugin :routing
88
93
 
94
+
89
95
  # /
90
96
  # -> /.page
91
97
  # -> /index.page
@@ -100,47 +106,66 @@ class Strelka::CMS::ContentManager < Strelka::App
100
106
  # -> /foo/project.html (literal)
101
107
  # -> /foo/project/index.html (literal)
102
108
 
109
+ ### GET /.*
103
110
  get do |request|
111
+ path = self.get_page_path( request )
112
+
113
+ # If there was a matching .page file, use that
114
+ if page = self.get_page_for( path )
115
+ self.log.debug " found page: %p" % [ page ]
116
+ return self.make_page_response( page )
117
+
118
+ # Try a literal HTML page
119
+ elsif htmlpage = self.get_html_path( path )
120
+ return self.make_raw_response( request, htmlpage )
121
+
122
+ else
123
+ # Give up
124
+ self.log.error "No pages matching %p" % [ path ]
125
+ finish_with HTTP::NOT_FOUND
126
+ end
127
+ end
128
+
129
+
130
+ ### Return the page requested by the specified +request+ as a Pathname relative to the
131
+ ### application path.
132
+ def get_page_path( request )
104
133
  unless path = request.app_path[ PAGE_PATH_PATTERN, :path ]
105
134
  self.log.error "Invalid app_path: %p" % [ request.app_path ]
106
135
  finish_with HTTP::NOT_FOUND
107
136
  end
108
137
 
109
138
  # Force the path to be relative and clean it up
110
- path = Pathname( path.gsub(%r{\A\.?/+|/(?=/)|/+\z}, '') )
111
- page = nil
139
+ return Pathname( path.gsub(%r{\A\.?/+|/(?=/)|/+\z}, '') )
140
+ end
141
+
142
+
143
+ ### Look for a static .html file in the catalog and return a Pathname for it if
144
+ ### one exists.
145
+ def get_html_path( path )
146
+ path = self.class.pageroot + path.sub_ext( '.html' )
147
+ return path if path.exist?
148
+ return nil
149
+ end
150
+
112
151
 
113
- # Try to find a matching .page file
152
+ ### Find a page that corresponds to the specified +path+ (a Pathname). Returns +nil+ if
153
+ ### no matching page was found.
154
+ def get_page_for( path )
114
155
  self.log.debug "Page path is: %p" % [ path ]
115
156
  if path.to_s.empty?
116
157
  subcat = @catalog.matching_pattern( 'index.page' )
117
- page = subcat.first
158
+ return subcat.first
118
159
  else
119
160
  subcat = @catalog.relative_to( path.dirname ).
120
161
  matching_pattern( "#{path.basename(path.extname)}{.page,/index.page}" )
121
- page = subcat.first
162
+ return subcat.first
122
163
  end
123
-
124
- # If there was a matching .page file, use that
125
- if page
126
- self.log.debug " found page: %p" % [ page ]
127
- return self.page_response( page )
128
- end
129
-
130
- # Try a literal HTML page
131
- htmlpage = self.class.pageroot + path.sub_ext( '.html' )
132
- if htmlpage.exist?
133
- return self.raw_response( request, htmlpage )
134
- end
135
-
136
- # Give up
137
- self.log.error "No pages matching %p" % [ path ]
138
- finish_with HTTP::NOT_FOUND
139
164
  end
140
165
 
141
166
 
142
167
  ### Package up the specified +page+ in the page template and return it.
143
- def page_response( page )
168
+ def make_page_response( page )
144
169
  tmpl = self.template( :page )
145
170
  tmpl.page = page
146
171
  return tmpl
@@ -148,14 +173,11 @@ class Strelka::CMS::ContentManager < Strelka::App
148
173
 
149
174
 
150
175
  ### Package up the page at the specified +path+ in the response and return it.
151
- def raw_response( request, pagepath )
176
+ def make_raw_response( request, pagepath )
152
177
  response = request.response
153
178
  response.body = pagepath.open( 'r', encoding: 'utf-8' )
154
179
  return response
155
180
  end
156
181
 
157
- end # class Strelka::CMS::ContentManager
158
-
159
- Encoding.default_internal = Encoding::UTF_8
160
- Strelka::CMS::ContentManager.run if __FILE__ == $0
182
+ end # class Strelka::CMS::Publisher
161
183
 
@@ -1,20 +1,6 @@
1
1
  #!/usr/bin/ruby
2
2
  # coding: utf-8
3
3
 
4
- BEGIN {
5
- require 'pathname'
6
- basedir = Pathname.new( __FILE__ ).dirname.parent.parent
7
-
8
- srcdir = basedir.parent
9
- strelkadir = srcdir + 'Strelka/lib'
10
-
11
- libdir = basedir + "lib"
12
-
13
- $LOAD_PATH.unshift( strelkadir.to_s ) unless $LOAD_PATH.include?( strelkadir.to_s )
14
- $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
15
- $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
16
- }
17
-
18
4
  # SimpleCov test coverage reporting; enable this using the :coverage rake task
19
5
  if ENV['COVERAGE']
20
6
  $stderr.puts "\n\n>>> Enabling coverage report.\n\n"
@@ -38,6 +24,8 @@ require 'mongrel2/testing'
38
24
  require 'strelka'
39
25
  require 'strelka/cms'
40
26
 
27
+ require 'fakefs/spec_helpers'
28
+
41
29
 
42
30
  ### RSpec helper functions.
43
31
  module Strelka::CMS::SpecHelpers
@@ -47,7 +35,9 @@ end
47
35
 
48
36
  ### Mock with RSpec
49
37
  RSpec.configure do |c|
50
- c.mock_with( :rspec )
38
+ c.mock_with( :rspec ) do |config|
39
+ config.syntax = :expect
40
+ end
51
41
 
52
42
  c.include( Loggability::SpecHelpers )
53
43
  c.include( Mongrel2::SpecHelpers )
@@ -2,21 +2,13 @@
2
2
  # vim: set nosta noet ts=4 sw=4:
3
3
  # encoding: utf-8
4
4
 
5
- BEGIN {
6
- require 'pathname'
7
- basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
8
- $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
9
- }
5
+ require_relative '../../helpers'
10
6
 
11
7
  require 'pathname'
12
8
  require 'tmpdir'
13
9
  require 'tempfile'
14
10
  require 'stringio'
15
11
 
16
- require 'rspec'
17
-
18
- require 'spec/lib/helpers'
19
- require 'strelka/cms'
20
12
  require 'strelka/cms/page'
21
13
 
22
14
 
@@ -88,10 +80,10 @@ describe Strelka::CMS::Page do
88
80
 
89
81
  page = described_class.load( tmp.path )
90
82
 
91
- page.title.should == 'Fun With TextMate 2'
92
- page.tags.should include( 'editors', 'software', 'tools', 'textmate2' )
93
- page.content.should include( 'One of the things that kept me from switching' )
94
- page.path.to_s.should == tmp.path
83
+ expect( page.title ).to eq( 'Fun With TextMate 2' )
84
+ expect( page.tags ).to include( 'editors', 'software', 'tools', 'textmate2' )
85
+ expect( page.content ).to include( 'One of the things that kept me from switching' )
86
+ expect( page.path.to_s ).to eq( tmp.path )
95
87
  end
96
88
 
97
89
  it "can read a page from an IO stream" do
@@ -99,17 +91,17 @@ describe Strelka::CMS::Page do
99
91
 
100
92
  page = described_class.read( io )
101
93
 
102
- page.title.should == 'Fun With TextMate 2'
103
- page.tags.should include( 'editors', 'software', 'tools', 'textmate2' )
104
- page.content.should include( 'One of the things that kept me from switching' )
94
+ expect( page.title ).to eq( 'Fun With TextMate 2' )
95
+ expect( page.tags ).to include( 'editors', 'software', 'tools', 'textmate2' )
96
+ expect( page.content ).to include( 'One of the things that kept me from switching' )
105
97
  end
106
98
 
107
99
  it "can parse a page from source" do
108
100
  page = described_class.parse( TEST_DOCUMENT )
109
101
 
110
- page.title.should == 'Fun With TextMate 2'
111
- page.tags.should include( 'editors', 'software', 'tools', 'textmate2' )
112
- page.content.should include( 'One of the things that kept me from switching' )
102
+ expect( page.title ).to eq( 'Fun With TextMate 2' )
103
+ expect( page.tags ).to include( 'editors', 'software', 'tools', 'textmate2' )
104
+ expect( page.content ).to include( 'One of the things that kept me from switching' )
113
105
  end
114
106
 
115
107
 
@@ -118,16 +110,16 @@ describe Strelka::CMS::Page do
118
110
  let( :page ) { described_class.parse(TEST_DOCUMENT) }
119
111
 
120
112
  it "can generate a summary of its contents" do
121
- page.summary.should =~ /^If you're using the WebKit formatter,/
113
+ expect( page.summary ).to match( /^If you're using the WebKit formatter,/ )
122
114
  end
123
115
 
124
116
  it "can generate a list of topics from its content" do
125
- page.summary_topics.should include( "formatter", "rspec" )
117
+ expect( page.summary_topics ).to include( "formatter", "rspec" )
126
118
  end
127
119
 
128
120
  it "can generate keywords if none are set by the header" do
129
121
  page.instance_variable_set( :@tags, nil )
130
- page.keywords.should include( 'formatter', 'rspec', 'editor', 'textmate' )
122
+ expect( page.keywords ).to include( 'formatter', 'rspec', 'editor', 'textmate' )
131
123
  end
132
124
 
133
125
  end
@@ -140,15 +132,15 @@ describe Strelka::CMS::Page do
140
132
 
141
133
 
142
134
  it "has a default set of filters" do
143
- page.filters.should == %w[strip textile]
135
+ expect( page.filters ).to eq( %w[strip textile] )
144
136
  end
145
137
 
146
138
  it "returns its contents after applying filters when stringified" do
147
- page.to_s.should == %{<h1>Title</h1>\n<p>Some content.</p>}
139
+ expect( page.to_s ).to eq( %{<h1>Title</h1>\n<p>Some content.</p>} )
148
140
  end
149
141
 
150
142
  it "can return its first heading" do
151
- page.first_heading.should == 'Title'
143
+ expect( page.first_heading ).to eq( 'Title' )
152
144
  end
153
145
 
154
146
  end
@@ -177,7 +169,7 @@ describe Strelka::CMS::Page do
177
169
 
178
170
 
179
171
  it "knows what its path relative to its catalog's base is" do
180
- page.relative_path.should == relative_pagefile_pathname
172
+ expect( page.relative_path ).to eq( relative_pagefile_pathname )
181
173
  end
182
174
 
183
175
  end
@@ -2,22 +2,8 @@
2
2
  # vim: set nosta noet ts=4 sw=4:
3
3
  # encoding: utf-8
4
4
 
5
- BEGIN {
6
- require 'pathname'
7
- basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
8
- $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
9
- }
10
-
11
- require 'pathname'
12
- require 'tmpdir'
13
- require 'tempfile'
14
- require 'stringio'
15
-
16
- require 'rspec'
17
-
18
- require 'spec/lib/helpers'
19
- require 'strelka/cms'
20
- require 'strelka/cms/page'
5
+ require_relative '../../helpers'
6
+
21
7
  require 'strelka/cms/pagecatalog'
22
8
 
23
9
 
@@ -26,10 +12,16 @@ require 'strelka/cms/pagecatalog'
26
12
  #####################################################################
27
13
 
28
14
  describe Strelka::CMS::PageCatalog do
15
+ include FakeFS::SpecHelpers
29
16
 
30
17
  before( :all ) do
31
18
  setup_logging()
32
- @basedir = Pathname( __FILE__ ).dirname.parent.parent.parent
19
+ end
20
+
21
+ before( :each ) do
22
+ FileUtils.mkdir_p( '/var/www/local/test' )
23
+ FileUtils.mkdir_p( '/var/www/local/lib' )
24
+ Dir.chdir( '/var/www/local' )
33
25
  end
34
26
 
35
27
  after( :all ) do
@@ -42,7 +34,27 @@ describe Strelka::CMS::PageCatalog do
42
34
  subject { described_class.new }
43
35
 
44
36
  it "has a glob pattern that matches .page files under the current directory" do
45
- subject.glob.should == "#{Dir.pwd}/**/*.page"
37
+ expect( subject.glob ).to eq( "/var/www/local/**/*.page" )
38
+ end
39
+
40
+ it "can load page files by name" do
41
+ FileUtils.touch( '/var/www/local/test/index.page' )
42
+
43
+ page = subject['test/index']
44
+
45
+ expect( page ).to be_a( Strelka::CMS::Page )
46
+ expect( page.path.to_s ).to eq( '/var/www/local/test/index.page' )
47
+ expect( page.catalog ).to be( subject )
48
+ end
49
+
50
+ it "doesn't require the .page extension when loading page files by name" do
51
+ FileUtils.touch( '/var/www/local/test/index.page' )
52
+
53
+ page = subject['test/index']
54
+
55
+ expect( page ).to be_a( Strelka::CMS::Page )
56
+ expect( page.path.to_s ).to eq( '/var/www/local/test/index.page' )
57
+ expect( page.catalog ).to be( subject )
46
58
  end
47
59
 
48
60
  end
@@ -50,11 +62,11 @@ describe Strelka::CMS::PageCatalog do
50
62
 
51
63
  context "created with a base directory" do
52
64
 
53
- subject { described_class.new(@basedir) }
65
+ subject { described_class.new('/var/www') }
54
66
 
55
67
 
56
68
  it "has a glob pattern that matches .page files under the directory it was created with" do
57
- subject.glob.should == "#@basedir/**/*.page"
69
+ expect( subject.glob ).to eq( "/var/www/**/*.page" )
58
70
  end
59
71
 
60
72
  end
@@ -62,28 +74,32 @@ describe Strelka::CMS::PageCatalog do
62
74
 
63
75
  context "created with a base directory and a glob pattern" do
64
76
 
65
- subject { described_class.new(@basedir, '**/*.rb') }
77
+ subject { described_class.new('/var/www/local', '**/*.rb') }
66
78
 
67
79
 
68
80
  it "has a glob pattern that matches files that match the pattern under the directory it was " +
69
81
  "created with" do
70
- subject.glob.should == "#@basedir/**/*.rb"
82
+ expect( subject.glob ).to eq( "/var/www/local/**/*.rb" )
71
83
  end
72
84
 
73
85
  it "has a mutator that clones it for a subdirectory" do
74
- subject.relative_to( 'lib' ).glob.should == "#@basedir/lib/**/*.rb"
86
+ expect( subject.relative_to('lib').glob ).to eq( "/var/www/local/lib/**/*.rb" )
75
87
  end
76
88
 
77
89
  it "has a mutator that clones it for a different glob pattern" do
78
- subject.matching_pattern( "*.txt" ).glob.should == "#@basedir/*.txt"
90
+ expect( subject.matching_pattern('*.txt').glob ).to eq( "/var/www/local/*.txt" )
79
91
  end
80
92
 
81
93
  it "has an iterator that yields files that match its glob pattern" do
82
- subject.relative_to( 'lib' ).map( &:path ).should include( @basedir + 'lib/strelka/cms.rb' )
94
+ pending "Database rewrite"
95
+ FileUtils.touch( '/var/www/local/lib/payment.rb' )
96
+
97
+ expect( subject.relative_to('lib').map(&:path) ).
98
+ to include( Pathname('/var/www/local/lib/payment.rb') )
83
99
  end
84
100
 
85
101
  it "strips leading directory separators from relative paths" do
86
- subject.relative_to( '/lib' ).glob.should == "#@basedir/lib/**/*.rb"
102
+ expect( subject.relative_to( '/lib' ).glob ).to eq( "/var/www/local/lib/**/*.rb" )
87
103
  end
88
104
 
89
105
 
@@ -0,0 +1,83 @@
1
+ # -*- ruby -*-
2
+ # encoding: utf-8
3
+ # vim: set nosta noet ts=4 sw=4:
4
+
5
+ require_relative '../../../helpers'
6
+
7
+ require 'tmpdir'
8
+ require 'strelka/cms'
9
+ require 'strelka/cms/pagefilter'
10
+
11
+
12
+ #####################################################################
13
+ ### C O N T E X T S
14
+ #####################################################################
15
+
16
+ describe Strelka::CMS::PageFilter, 'AutoIndex' do
17
+
18
+ SIMPLE_TEST_SOURCE = (<<-END_PAGE_SOURCE).gsub( /^\t{2}/, '' ).freeze
19
+ <?autoindex /blog/*.page ?>
20
+ END_PAGE_SOURCE
21
+
22
+ before( :all ) do
23
+ # Need to load this before fakefs hides the filesystem
24
+ Inversion::Template::Tag.load_all
25
+ end
26
+
27
+
28
+ around( :each ) do |example|
29
+ Dir.mktmpdir( "autoindex_spec" ) do |dirname|
30
+ @tmpdir = dirname
31
+ example.call
32
+ end
33
+ end
34
+
35
+
36
+
37
+ it "is ignored when used from a page that isn't part of a catalog" do
38
+ filter = described_class.create( 'autoindex' )
39
+
40
+ page = Strelka::CMS::Page.parse( SIMPLE_TEST_SOURCE )
41
+ output = filter.process( SIMPLE_TEST_SOURCE, page )
42
+
43
+ expect( output ).to match( /<!-- autoindex skipped/i )
44
+ end
45
+
46
+
47
+ it "renders an index of the matched files in the page's catalog" do
48
+ pending "Database rewrite"
49
+ FileUtils.mkdir_p( "#@tmpdir/content/blog" )
50
+ FileUtils.mkdir_p( "#@tmpdir/templates/autoindex" )
51
+
52
+ FileUtils.touch( "#@tmpdir/content/blog/post1.page" )
53
+ FileUtils.touch( "#@tmpdir/content/blog/post2.page" )
54
+ FileUtils.touch( "#@tmpdir/content/blog/post3.page" )
55
+
56
+ File.open( "#@tmpdir/content/test.page", 'w' ) do |fh|
57
+ fh.print( SIMPLE_TEST_SOURCE )
58
+ end
59
+
60
+ File.open( "#@tmpdir/templates/autoindex/default.tmpl", 'w' ) do |fh|
61
+ fh.puts "<?for page in pages ?>"
62
+ fh.puts "-<?call page.relative_html_path ?>-"
63
+ fh.puts "<?end for ?>"
64
+ end
65
+
66
+ Inversion::Template.template_paths.replace( ["#@tmpdir/templates"] )
67
+
68
+ catalog = Strelka::CMS::PageCatalog.new( "#@tmpdir/content", '**/*.page' )
69
+ page = catalog.find {|page| page.relative_path.to_s == 'test.page' } or
70
+ raise "didn't find test.page in catalog %p" % [ catalog ]
71
+
72
+ filter = described_class.create( 'autoindex' )
73
+ output = filter.process( SIMPLE_TEST_SOURCE, page )
74
+
75
+ expect( output ).to match( /post1\.html/ )
76
+ expect( output ).to match( /post2\.html/ )
77
+ expect( output ).to match( /post3\.html/ )
78
+ end
79
+
80
+
81
+
82
+ end
83
+