nesta 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.gitignore +13 -0
  2. data/Gemfile +6 -0
  3. data/Gemfile.lock +58 -0
  4. data/LICENSE +19 -0
  5. data/README.md +45 -0
  6. data/Rakefile +12 -0
  7. data/bin/nesta +67 -0
  8. data/config.ru +9 -0
  9. data/config/config.yml.sample +73 -0
  10. data/config/deploy.rb.sample +62 -0
  11. data/lib/nesta/app.rb +199 -0
  12. data/lib/nesta/cache.rb +139 -0
  13. data/lib/nesta/commands.rb +135 -0
  14. data/lib/nesta/config.rb +87 -0
  15. data/lib/nesta/models.rb +313 -0
  16. data/lib/nesta/nesta.rb +0 -0
  17. data/lib/nesta/overrides.rb +59 -0
  18. data/lib/nesta/path.rb +11 -0
  19. data/lib/nesta/plugins.rb +15 -0
  20. data/lib/nesta/version.rb +3 -0
  21. data/nesta.gemspec +49 -0
  22. data/scripts/import-from-mephisto +207 -0
  23. data/spec/atom_spec.rb +138 -0
  24. data/spec/commands_spec.rb +220 -0
  25. data/spec/config_spec.rb +69 -0
  26. data/spec/model_factory.rb +94 -0
  27. data/spec/models_spec.rb +445 -0
  28. data/spec/overrides_spec.rb +113 -0
  29. data/spec/page_spec.rb +428 -0
  30. data/spec/path_spec.rb +28 -0
  31. data/spec/sitemap_spec.rb +102 -0
  32. data/spec/spec.opts +1 -0
  33. data/spec/spec_helper.rb +72 -0
  34. data/templates/Gemfile +8 -0
  35. data/templates/Rakefile +35 -0
  36. data/templates/config.ru +9 -0
  37. data/templates/config/config.yml +73 -0
  38. data/templates/config/deploy.rb +47 -0
  39. data/views/analytics.haml +12 -0
  40. data/views/atom.builder +28 -0
  41. data/views/categories.haml +3 -0
  42. data/views/comments.haml +8 -0
  43. data/views/error.haml +13 -0
  44. data/views/feed.haml +3 -0
  45. data/views/index.haml +5 -0
  46. data/views/layout.haml +27 -0
  47. data/views/master.sass +246 -0
  48. data/views/not_found.haml +13 -0
  49. data/views/page.haml +29 -0
  50. data/views/sidebar.haml +3 -0
  51. data/views/sitemap.builder +15 -0
  52. data/views/summaries.haml +14 -0
  53. metadata +302 -0
data/spec/path_spec.rb ADDED
@@ -0,0 +1,28 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ describe 'Nesta::Path' do
4
+ before(:each) do
5
+ @root = File.expand_path('..', File.dirname(__FILE__))
6
+ @local_foo_bar = File.join(@root, 'foo/bar')
7
+ end
8
+
9
+ it 'should return local path' do
10
+ Nesta::Path.local.should == @root
11
+ end
12
+
13
+ it 'should return path for file within local directory' do
14
+ Nesta::Path.local('foo/bar').should == @local_foo_bar
15
+ end
16
+
17
+ it 'should combine path components' do
18
+ Nesta::Path.local('foo', 'bar').should == @local_foo_bar
19
+ end
20
+
21
+ it 'should return themes path' do
22
+ Nesta::Path.themes.should == File.expand_path('themes', @root)
23
+ end
24
+
25
+ it 'should return path for file within themes directory' do
26
+ Nesta::Path.themes('foo/bar').should == File.join(@root, 'themes/foo/bar')
27
+ end
28
+ end
@@ -0,0 +1,102 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+ require File.expand_path('model_factory', File.dirname(__FILE__))
3
+
4
+ describe "sitemap XML" do
5
+ include ConfigSpecHelper
6
+ include RequestSpecHelper
7
+ include ModelFactory
8
+
9
+ before(:each) do
10
+ stub_configuration
11
+ @category = create_category do |path|
12
+ mock_file_stat(:stub!, path, "3 Jan 2009, 15:07")
13
+ end
14
+ @article = create_article do |path|
15
+ mock_file_stat(:stub!, path, "3 Jan 2009, 15:10")
16
+ end
17
+ get "/sitemap.xml"
18
+ end
19
+
20
+ after(:each) do
21
+ Nesta::FileModel.purge_cache
22
+ remove_fixtures
23
+ end
24
+
25
+ it "should render successfully" do
26
+ last_response.should be_ok
27
+ end
28
+
29
+ it "should have a urlset tag" do
30
+ namespace = "http://www.sitemaps.org/schemas/sitemap/0.9"
31
+ body.should have_tag("/urlset[@xmlns=#{namespace}]")
32
+ end
33
+
34
+ it "should reference the home page" do
35
+ body.should have_tag("/urlset/url/loc", "http://example.org")
36
+ end
37
+
38
+ it "should configure home page to be checked frequently" do
39
+ body.should have_tag("/urlset/url") do |url|
40
+ url.should have_tag("loc", "http://example.org")
41
+ url.should have_tag("changefreq", "daily")
42
+ url.should have_tag("priority", "1.0")
43
+ end
44
+ end
45
+
46
+ it "should set the homepage lastmod from latest article" do
47
+ body.should have_tag("/urlset/url") do |url|
48
+ url.should have_tag("loc", "http://example.org")
49
+ url.should have_tag("lastmod", /^2009-01-03T15:10:00/)
50
+ end
51
+ end
52
+
53
+ it "should reference category pages" do
54
+ body.should have_tag(
55
+ "/urlset/url/loc", "http://example.org/#{@category.path}")
56
+ end
57
+
58
+ it "should reference article pages" do
59
+ body.should have_tag(
60
+ "/urlset/url/loc", "http://example.org/#{@article.path}")
61
+ end
62
+ end
63
+
64
+ describe "sitemap XML lastmod" do
65
+ include ConfigSpecHelper
66
+ include ModelFactory
67
+ include RequestSpecHelper
68
+
69
+ before(:each) do
70
+ stub_configuration
71
+ end
72
+
73
+ after(:each) do
74
+ remove_fixtures
75
+ Nesta::FileModel.purge_cache
76
+ end
77
+
78
+ it "should be set for file based page" do
79
+ create_article do |path|
80
+ mock_file_stat(:stub!, path, "3 January 2009, 15:37:01")
81
+ end
82
+ get "/sitemap.xml"
83
+ body.should have_tag("url") do |url|
84
+ url.should have_tag("loc", /my-article$/)
85
+ url.should have_tag("lastmod", /^2009-01-03T15:37:01/)
86
+ end
87
+ end
88
+
89
+ it "should be set to latest page for home page" do
90
+ create_article(:path => "article-1") do |path|
91
+ mock_file_stat(:stub!, path, "4 January 2009")
92
+ end
93
+ create_article(:path => "article-2") do |path|
94
+ mock_file_stat(:stub!, path, "3 January 2009")
95
+ end
96
+ get "/sitemap.xml"
97
+ body.should have_tag("url") do |url|
98
+ url.should have_tag("loc", "http://example.org")
99
+ url.should have_tag("lastmod", /^2009-01-04/)
100
+ end
101
+ end
102
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,72 @@
1
+ require "rubygems"
2
+ require "spec"
3
+ require "spec/interop/test"
4
+ require "rack/test"
5
+ require "rspec_hpricot_matchers"
6
+ require "sinatra"
7
+
8
+ Test::Unit::TestCase.send :include, Rack::Test::Methods
9
+
10
+ Spec::Runner.configure do |config|
11
+ config.include(RspecHpricotMatchers)
12
+ end
13
+
14
+ module Nesta
15
+ class App < Sinatra::Base
16
+ set :environment, :test
17
+ set :reload_templates, true
18
+ end
19
+ end
20
+
21
+ require File.expand_path("../lib/nesta/app", File.dirname(__FILE__))
22
+
23
+ module FixtureHelper
24
+ FIXTURE_DIR = File.expand_path("fixtures", File.dirname(__FILE__))
25
+
26
+ def create_fixtures_directory
27
+ FileUtils.mkdir_p(FixtureHelper::FIXTURE_DIR)
28
+ end
29
+
30
+ def remove_fixtures
31
+ FileUtils.rm_r(FixtureHelper::FIXTURE_DIR, :force => true)
32
+ end
33
+ end
34
+
35
+ module RequestSpecHelper
36
+ def app
37
+ Nesta::App
38
+ end
39
+
40
+ def body
41
+ last_response.body
42
+ end
43
+ end
44
+
45
+ module ConfigSpecHelper
46
+ include FixtureHelper
47
+
48
+ def stub_yaml_config
49
+ @config = {}
50
+ Nesta::Config.stub!(:yaml_exists?).and_return(true)
51
+ Nesta::Config.stub!(:yaml_conf).and_return(@config)
52
+ end
53
+
54
+ def stub_config_key(key, value, options = {})
55
+ stub_yaml_config unless @config
56
+ if options[:rack_env]
57
+ @config['test'] ||= {}
58
+ @config['test'][key] = value
59
+ else
60
+ @config[key] = value
61
+ end
62
+ end
63
+
64
+ def stub_configuration(options = {})
65
+ stub_config_key("title", "My blog", options)
66
+ stub_config_key("subtitle", "about stuff", options)
67
+ stub_config_key("description", "great web site", options)
68
+ stub_config_key("keywords", "home, page", options)
69
+ content_path = File.join(FixtureHelper::FIXTURE_DIR, "content")
70
+ stub_config_key("content", content_path, options.merge(:rack_env => true))
71
+ end
72
+ end
data/templates/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'nesta', '<%= Nesta::VERSION %>'
4
+ <% if @options['heroku'] %>gem 'heroku'<% end %>
5
+ <% if @options['vlad'] %>gem 'vlad', '2.1.0'
6
+ gem 'vlad-git', '2.2.0'<% end %>
7
+
8
+ # gem (RUBY_VERSION =~ /^1.9/) ? 'ruby-debug19': 'ruby-debug'
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ Bundler.require(:default, :test)
5
+ <% if @options['vlad'] %>
6
+ begin
7
+ require 'vlad'
8
+ # Set :app to :passenger if you're using Phusion Passenger.
9
+ Vlad.load(:scm => :git, :app => nil, :web => nil)
10
+ rescue LoadError
11
+ end<% end %>
12
+ <% if @options['heroku'] %>
13
+ require 'nesta/config'
14
+ require 'nesta/models'
15
+
16
+ namespace :heroku do
17
+ desc "Set Heroku config vars from config.yml"
18
+ task :config do
19
+ Nesta::App.environment = ENV['RACK_ENV'] || 'production'
20
+ settings = {}
21
+ Nesta::Config.settings.map do |variable|
22
+ value = Nesta::Config.send(variable)
23
+ value && settings["NESTA_#{variable.upcase}"] = value
24
+ end
25
+ if Nesta::Config.author
26
+ Nesta::Config.author_settings.map do |author_var|
27
+ value = Nesta::Config.author[author_var]
28
+ if value
29
+ value && settings["NESTA_AUTHOR__#{author_var.upcase}"] = value
30
+ end
31
+ end
32
+ params = settings.map { |k, v| %Q{#{k}="#{v}"} }.join(" ")
33
+ system("heroku config:add #{params}")
34
+ end
35
+ end<% end %>
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ Bundler.require(:default)
5
+
6
+ require 'nesta/app'
7
+
8
+ Nesta::App.root = ::File.expand_path('.', ::File.dirname(__FILE__))
9
+ run Nesta::App
@@ -0,0 +1,73 @@
1
+ # Title and subheading for your site. Used on the home page and in page
2
+ # titles.
3
+ #
4
+ title: "My Site"
5
+ subtitle: "(change this text in config/config.yml)"
6
+
7
+ # If you want to set the descrition or keywords meta tags on your site's
8
+ # home page, do it here.
9
+ #
10
+ # description: "Set this to something that describes your home page"
11
+ # keywords: "enter 3 or 4, comma separated, keywords"
12
+
13
+ # You should really specify your content's author when generating an
14
+ # Atom feed. Specify at least one of name, uri or email, and Nesta will
15
+ # include it in your feed. See the Atom spec for more info:
16
+ #
17
+ # http://www.atomenabled.org/developers/syndication/atom-format-spec.php#element.feed
18
+ #
19
+ # author:
20
+ # name: Your Name
21
+ # uri: http://yourhomepage.com
22
+ # email: you@yourdomain.com
23
+
24
+ # You can stick with the default look and feel, or use a theme. Themes are
25
+ # easy to create or install, and live inside the themes directory. You
26
+ # can also use scripts/theme to install them.
27
+ #
28
+ # theme: name-of-theme
29
+
30
+ # If you want to use the Disqus service (http://disqus.com) to display
31
+ # comments on your site, register a Disqus account and then specify your
32
+ # site's short name here. A comment form will automatically be added to
33
+ # the bottom of your pages.
34
+ #
35
+ # disqus_short_name: mysite
36
+
37
+ # cache
38
+ # Set it to true if you'd like Nesta to cache your pages in ./public.
39
+ # Useful if you're deploying Nesta with a proxy server such as Nginx,
40
+ # but not in the least bit helpful if your pages are dynamic, or you're
41
+ # deploying Nesta to Heroku.
42
+ #
43
+ cache: false
44
+
45
+ # content
46
+ # The root directory where nesta will look for your article files.
47
+ # Should contain "pages" and "attachments" subdirectories that contain
48
+ # your actual content and the (optional) menu.txt file that links to your
49
+ # main category pages.
50
+ #
51
+ content: content
52
+
53
+ # google_analytics_code
54
+ # Set this if you want Google Analytics to track traffic on your site.
55
+ # Probably best not to set a default value, but to set it in production.
56
+ #
57
+ # The production settings are used if you're deploying to Heroku, so
58
+ # scroll down a bit to set it in production even if you're not deploying
59
+ # to your own server.
60
+ #
61
+ # google_analytics_code: "UA-???????-?"
62
+
63
+ # Overriding "cache" and "content" in production is recommended if you're
64
+ # deploying Nesta to your own server (but see the deployment documentation
65
+ # on the Nesta site). Setting google_analytics_code in production is
66
+ # recommended regardless of how you're deploying (if you have a GA account!).
67
+ #
68
+ # Don't forget to uncomment the "production:" line too...
69
+
70
+ # production:
71
+ # cache: true
72
+ # content: /var/apps/nesta/shared/content
73
+ # google_analytics_code: "UA-???????-?"
@@ -0,0 +1,47 @@
1
+ set :application, '<%= File.basename(@path) %>'
2
+ set :repository, "set this to URL of your site's repo"
3
+
4
+ # Set :user if you want to connect (via ssh) to your server using a
5
+ # different username. You will also need to include the user in :domain
6
+ # (see below).
7
+ #
8
+ #set :user, "deploy"
9
+ #set :domain, "#{user}@example.com"
10
+ set :domain, "example.com"
11
+
12
+ set :deploy_to, "/var/apps/#{application}"
13
+
14
+ # ============================================================================
15
+ # You probably don't need to worry about anything beneath this point...
16
+ # ============================================================================
17
+
18
+ require "tempfile"
19
+ require "vlad"
20
+
21
+ namespace :vlad do
22
+ remote_task :symlink_attachments do
23
+ run "ln -s #{shared_path}/content/attachments #{current_path}/public/attachments"
24
+ end
25
+
26
+ task :update do
27
+ Rake::Task["vlad:symlink_attachments"].invoke
28
+ end
29
+
30
+ remote_task :bundle do
31
+ run "cd #{current_path} && sudo bundle install --without development test"
32
+ end
33
+
34
+ # Depending on how you host Nesta, you might want to swap :start_app
35
+ # with :start below. The :start_app task will tell your application
36
+ # server (e.g. Passenger) to restart once your new code is deployed by
37
+ # :update. Passenger is the default app server; tell Vlad that you're
38
+ # using a different app server in the call to Vlad.load in Rakefile.
39
+ #
40
+ desc "Deploy the code and restart the server"
41
+ task :deploy => [:update, :start_app]
42
+
43
+ # If you use bundler to manage the installation of gems on your server
44
+ # you can use this definition of the deploy task instead:
45
+ #
46
+ # task :deploy => [:update, :bundle, :start_app]
47
+ end
@@ -0,0 +1,12 @@
1
+ - if @google_analytics_code
2
+ :plain
3
+ <script type="text/javascript">
4
+ var _gaq = _gaq || [];
5
+ _gaq.push(['_setAccount', '#{@google_analytics_code}']);
6
+ _gaq.push(['_trackPageview']);
7
+ (function() {
8
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
9
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
10
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
11
+ })();
12
+ </script>
@@ -0,0 +1,28 @@
1
+ xml.instruct!
2
+ xml.feed :xmlns => "http://www.w3.org/2005/Atom" do
3
+ xml.title @title, :type => "text"
4
+ xml.generator "Nesta", :uri => "http://effectif.com/nesta"
5
+ xml.id atom_id
6
+ xml.link :href => "#{base_url}/articles.xml", :rel => "self"
7
+ xml.link :href => base_url, :rel => "alternate"
8
+ xml.subtitle @subtitle, :type => "text"
9
+ xml.author do
10
+ xml.name @author["name"] if @author["name"]
11
+ xml.uri @author["uri"] if @author["uri"]
12
+ xml.email @author["email"] if @author["email"]
13
+ end if @author
14
+ @articles.each do |article|
15
+ xml.entry do
16
+ xml.title article.heading
17
+ xml.link :href => url_for(article),
18
+ :type => "text/html",
19
+ :rel => "alternate"
20
+ xml.id atom_id(article)
21
+ xml.content absolute_urls(article.body), :type => "html"
22
+ xml.published article.date(:xmlschema)
23
+ article.categories.each do |category|
24
+ xml.category :term => category.permalink
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ - if ! @menu_items.empty?
2
+ %h2 Articles by category
3
+ - display_menu(@menu_items, :class => "menu")
@@ -0,0 +1,8 @@
1
+ - if short_name = Nesta::Config.disqus_short_name
2
+ #disqus_thread
3
+ - if Sinatra::Application.environment == :development
4
+ %script{ :type => "text/javascript" }
5
+ var disqus_developer = true;
6
+ %script{ :type => "text/javascript", :src => "http://disqus.com/forums/#{short_name}/embed.js" }
7
+ %noscript
8
+ %a{ :href => "http://disqus.com/forums/#{short_name}/?url=ref" } View comments.