mars-nesta 0.9.4

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 (61) hide show
  1. data/.gitignore +13 -0
  2. data/CHANGES +97 -0
  3. data/Gemfile +6 -0
  4. data/Gemfile.lock +44 -0
  5. data/LICENSE +19 -0
  6. data/README.md +42 -0
  7. data/Rakefile +12 -0
  8. data/bin/nesta +79 -0
  9. data/config.ru +9 -0
  10. data/config/deploy.rb.sample +62 -0
  11. data/lib/nesta/app.rb +167 -0
  12. data/lib/nesta/cache.rb +139 -0
  13. data/lib/nesta/commands.rb +188 -0
  14. data/lib/nesta/config.rb +86 -0
  15. data/lib/nesta/models.rb +364 -0
  16. data/lib/nesta/navigation.rb +60 -0
  17. data/lib/nesta/nesta.rb +7 -0
  18. data/lib/nesta/overrides.rb +59 -0
  19. data/lib/nesta/path.rb +11 -0
  20. data/lib/nesta/plugins.rb +15 -0
  21. data/lib/nesta/version.rb +3 -0
  22. data/nesta.gemspec +48 -0
  23. data/scripts/import-from-mephisto +207 -0
  24. data/spec/atom_spec.rb +138 -0
  25. data/spec/commands_spec.rb +292 -0
  26. data/spec/config_spec.rb +69 -0
  27. data/spec/model_factory.rb +94 -0
  28. data/spec/models_spec.rb +554 -0
  29. data/spec/overrides_spec.rb +114 -0
  30. data/spec/page_spec.rb +458 -0
  31. data/spec/path_spec.rb +28 -0
  32. data/spec/sitemap_spec.rb +102 -0
  33. data/spec/spec.opts +1 -0
  34. data/spec/spec_helper.rb +70 -0
  35. data/templates/Gemfile +8 -0
  36. data/templates/Rakefile +11 -0
  37. data/templates/config.ru +9 -0
  38. data/templates/config/config.yml +67 -0
  39. data/templates/config/deploy.rb +47 -0
  40. data/templates/index.haml +1 -0
  41. data/templates/themes/README.md +7 -0
  42. data/templates/themes/app.rb +19 -0
  43. data/views/analytics.haml +12 -0
  44. data/views/atom.haml +28 -0
  45. data/views/categories.haml +4 -0
  46. data/views/colors.sass +10 -0
  47. data/views/comments.haml +8 -0
  48. data/views/error.haml +12 -0
  49. data/views/feed.haml +3 -0
  50. data/views/footer.haml +5 -0
  51. data/views/header.haml +4 -0
  52. data/views/layout.haml +24 -0
  53. data/views/master.sass +246 -0
  54. data/views/mixins.sass +39 -0
  55. data/views/not_found.haml +12 -0
  56. data/views/page.haml +21 -0
  57. data/views/page_meta.haml +16 -0
  58. data/views/sidebar.haml +3 -0
  59. data/views/sitemap.haml +11 -0
  60. data/views/summaries.haml +15 -0
  61. metadata +235 -0
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ *.gem
2
+ ._*
3
+ .*.swp
4
+ .bundle
5
+ .DS_Store
6
+ .rvmrc
7
+ .sass-cache
8
+ config/config.yml
9
+ config/deploy.rb
10
+ db/*.db
11
+ pkg/*
12
+ plugins
13
+ public/cache
data/CHANGES ADDED
@@ -0,0 +1,97 @@
1
+ = 0.9.5 / (Unreleased)
2
+
3
+ * Added --version option to nesta command (Christopher Lindblom).
4
+
5
+ * Bug fix: Made article_summaries render summaries for the articles
6
+ passed to it (Robert Syme).
7
+
8
+ * Bug fix: Don't use parent's heading in page title if parent's heading
9
+ is blank (Christopher Lindblom).
10
+
11
+ * Bug fix: Removed trailing whitespace inside <a> tags generated by
12
+ the display_menu() helper.
13
+
14
+ = 0.9.4 / 18 February 2011
15
+
16
+ * Updated the link colours in the default theme.
17
+
18
+ * Set the default encoding to UTF-8. Without it Heroku would sometimes
19
+ fail to render pages (issue 14).
20
+
21
+ = 0.9.3 / 18 January 2011
22
+
23
+ * The route and view for serving the home page (/) has been removed,
24
+ and the home page must now be created as an index page in
25
+ content/pages.
26
+
27
+ You will have to create `content/pages/index.haml` manually when
28
+ upgrading. Running `nesta new mysite.com` will create a
29
+ `content/pages/index.haml` file that is suitable for a blog.
30
+
31
+ * The URL /my-page can be served from `pages/my-page/index.mdown` as
32
+ well as pages/my-page.mdown (index pages can also be created with
33
+ Textile or Haml, just like any other page).
34
+
35
+ * The description and keywords settings have been removed from
36
+ config.yml as they can now be set on `content/pages/index.haml`.
37
+
38
+ * Added the Title metadata key to override a page's default title tag.
39
+
40
+ * Specify the sort order of pages that are listed on a category page.
41
+ Optionally append a colon and a number to a path in the 'Categories'
42
+ metadata to control the sort order of pages listed on the category
43
+ page.
44
+
45
+ See these files for the syntax:
46
+ https://github.com/gma/nesta-demo-content/tree/master/pages/examples
47
+
48
+ * Support arbitrarily deep hierarchies when generating the breadcrumb
49
+ (see the new helper method added to Nesta::Navigation).
50
+
51
+ * Dropped the --heroku switch (Heroku runs fine without it and there is
52
+ less chance that committing config.yml to your repository will be an
53
+ issue now that Nesta sites live in their own repositories).
54
+
55
+ * Re-implemented /articles.xml and /sitemap.xml in Haml, dropping the
56
+ dependency on builder. This side steps a bug in Ruby 1.9.1, so Nesta
57
+ can now run on 1.9.1 again. Also fixed a validity error in the Atom
58
+ feed.
59
+
60
+ * Bug fix: Don't output empty <li> tags for nested submenus that are
61
+ beneath the requested number of levels.
62
+
63
+ = 0.9.2 / 10 January 2011
64
+
65
+ * Made the FileModel.metadata method public, to allow for custom
66
+ metadata at the top of each page. (Wynn Netherland)
67
+
68
+ * Relaxed the stringent dependency specifications, using pessimistic
69
+ version constraints (see http://docs.rubygems.org/read/chapter/16).
70
+
71
+ * Added templates required by `nesta theme:create`.
72
+
73
+ = 0.9.1 / 31 December 2010
74
+
75
+ * Re-implemented the default theme, using semantic HTML5 and
76
+ Andy Clarke's Universal Internet Explorer 6 CSS. Named the previous
77
+ default theme "slate" and moved it into a separate GitHub project.
78
+ https://github.com/gma/nesta-theme-slate
79
+
80
+ * Added `--git` switch to `nesta new`, that will create a new git
81
+ repository and make an initial commit.
82
+
83
+ * Moved the navigation helpers into the Nesta::Navigation::Renderers
84
+ module.
85
+
86
+ = 0.9.0 / 20 December 2010
87
+
88
+ * Packaged Nesta as a gem for the first time, instead of as a template
89
+ site that can be cloned, edited and deployed. Added the `nesta`
90
+ command for generating new sites and managing themes.
91
+
92
+ = Previous versions / from 26 November 2008
93
+
94
+ * Prior to 0.9.0 Nesta was distributed as a git repository that could
95
+ be forked, edited and deployed. The only change log for these
96
+ versions is the Git commit history.
97
+ https://github.com/gma/nesta/commits/master
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source :gemcutter
2
+
3
+ # Specify your gem's dependencies in nesta.gemspec
4
+ gemspec
5
+
6
+ # gem (RUBY_VERSION =~ /^1.9/) ? 'ruby-debug19': 'ruby-debug'
data/Gemfile.lock ADDED
@@ -0,0 +1,44 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ nesta (0.9.4)
5
+ RedCloth (~> 4.2)
6
+ haml (~> 3.0)
7
+ redcarpet (>= 1.11.0)
8
+ shotgun (>= 0.8)
9
+ sinatra (= 1.1.2)
10
+
11
+ GEM
12
+ remote: http://rubygems.org/
13
+ specs:
14
+ RedCloth (4.2.7)
15
+ haml (3.1.0)
16
+ hoe (2.9.4)
17
+ rake (>= 0.8.7)
18
+ hpricot (0.8.3)
19
+ rack (1.2.2)
20
+ rack-test (0.5.7)
21
+ rack (>= 1.0)
22
+ rake (0.8.7)
23
+ redcarpet (1.11.0)
24
+ rspec (1.3.0)
25
+ rspec_hpricot_matchers (1.0)
26
+ shotgun (0.9)
27
+ rack (>= 1.0)
28
+ sinatra (1.1.2)
29
+ rack (~> 1.1)
30
+ tilt (~> 1.2)
31
+ test-unit (1.2.3)
32
+ hoe (>= 1.5.1)
33
+ tilt (1.2.2)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ hpricot (= 0.8.3)
40
+ nesta!
41
+ rack-test (= 0.5.7)
42
+ rspec (= 1.3.0)
43
+ rspec_hpricot_matchers (= 1.0)
44
+ test-unit (= 1.2.3)
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2008-2011 Graham Ashton
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.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # Nesta - a CMS for Ruby Developers
2
+
3
+ A CMS for small web sites and blogs, written in [Sinatra][frank].
4
+
5
+ Content can be written in [Markdown][markdown] or [Textile][textile] and
6
+ stored in text files (though you can also use Haml if you need to add
7
+ some HTML to your pages). There's no database; write your content in
8
+ your editor. Publish by pushing to a git repository.
9
+
10
+ [frank]: http://www.sinatrarb.com/ "Sinatra"
11
+ [markdown]: http://daringfireball.net/projects/markdown/
12
+ [textile]: http://textism.com/tools/textile/
13
+
14
+ ## Installation
15
+
16
+ Begin by installing the gem:
17
+
18
+ $ gem install nesta
19
+
20
+ Then use the `nesta` command to generate a new site:
21
+
22
+ $ nesta new mysite.com --git
23
+
24
+ Install a few dependencies, and you're away:
25
+
26
+ $ cd mysite.com
27
+ $ bundle
28
+
29
+ You'll find basic configuration options for your site in
30
+ `config/config.yml`. The defaults will work, but you'll want to tweak it
31
+ before you go very far.
32
+
33
+ That's it - you can launch a local web server in development mode using
34
+ shotgun...
35
+
36
+ $ bundle exec shotgun config.ru
37
+
38
+ ...then point your web browser at http://localhost:9393. Start editing
39
+ the files in `content/pages` (see the [Writing content][content] docs
40
+ for full instructions).
41
+
42
+ [content]: http://nestacms.com/docs/creating-content
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ Bundler.require(:default, :test)
5
+
6
+ require "spec/rake/spectask"
7
+ Bundler::GemHelper.install_tasks
8
+
9
+ desc "Run all specs in spec directory"
10
+ Spec::Rake::SpecTask.new(:spec) do |t|
11
+ t.spec_files = FileList["spec/*_spec.rb"]
12
+ end
data/bin/nesta ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'getoptlong'
4
+
5
+ require File.expand_path('../lib/nesta/commands', File.dirname(__FILE__))
6
+
7
+ module Nesta
8
+ class Cli
9
+ def self.usage
10
+ puts <<EOF
11
+ USAGE: #{File.basename($0)} [GLOBAL OPTIONS] <command> [COMMAND OPTIONS]
12
+
13
+ GLOBAL OPTIONS
14
+ --help, -h Display this message.
15
+ --version, -v Display version number.
16
+
17
+ COMMANDS
18
+ new <path> Create a new Nesta project.
19
+ demo:content Install example pages in ./content-demo.
20
+ theme:install <url> Install a theme from a git repository.
21
+ theme:enable <name> Make the theme active, updating config.yml.
22
+ theme:create <name> Makes a template for a new theme in ./themes.
23
+
24
+ OPTIONS FOR new
25
+ --git Create a new git repository for the project.
26
+ --vlad Include config/deploy.rb.
27
+
28
+ EOF
29
+ exit 0
30
+ end
31
+
32
+ def self.version
33
+ puts "Nesta #{Nesta::VERSION}"
34
+ exit 0
35
+ end
36
+
37
+ def self.parse_command_line
38
+ opts = GetoptLong.new(
39
+ ['--git', GetoptLong::NO_ARGUMENT],
40
+ ['--help', '-h', GetoptLong::NO_ARGUMENT],
41
+ ['--version', '-v', GetoptLong::NO_ARGUMENT],
42
+ ['--vlad', GetoptLong::NO_ARGUMENT]
43
+ )
44
+ options = {}
45
+ opts.each do |opt, arg|
46
+ case opt
47
+ when '--help'
48
+ usage
49
+ when '--version'
50
+ version
51
+ else
52
+ options[opt.sub(/^--/, '')] = arg
53
+ end
54
+ end
55
+ options
56
+ end
57
+
58
+ def self.main(options)
59
+ command = ARGV.shift
60
+ command.nil? && usage
61
+ case command
62
+ when 'new'
63
+ Nesta::Commands::New.new(ARGV[0], options).execute
64
+ when 'demo:content'
65
+ Nesta::Commands::Demo::Content.new.execute
66
+ when /^theme:(create|enable|install)$/
67
+ command_cls = Nesta::Commands::Theme.const_get($1.capitalize.to_sym)
68
+ command_cls.new(ARGV[0], options).execute
69
+ else
70
+ usage
71
+ end
72
+ rescue Nesta::Commands::UsageError => e
73
+ $stderr.puts "ERROR: #{e}"
74
+ usage
75
+ end
76
+ end
77
+ end
78
+
79
+ Nesta::Cli.main(Nesta::Cli.parse_command_line)
data/config.ru ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ Bundler.require(:default)
5
+
6
+ $LOAD_PATH.unshift(::File.expand_path('lib', ::File.dirname(__FILE__)))
7
+ require 'nesta/app'
8
+
9
+ run Nesta::App
@@ -0,0 +1,62 @@
1
+ set :application, "nesta"
2
+ set :repository, "git://github.com/gma/nesta.git"
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 :config_yml do
23
+ put "#{shared_path}/config.yml", "vlad.config.yml" do
24
+ File.open(File.join(File.dirname(__FILE__), "config.yml")).read
25
+ end
26
+ end
27
+
28
+ task :setup do
29
+ Rake::Task["vlad:config_yml"].invoke
30
+ end
31
+
32
+ remote_task :symlink_config_yml do
33
+ run "ln -s #{shared_path}/config.yml #{current_path}/config/config.yml"
34
+ end
35
+
36
+ remote_task :symlink_attachments do
37
+ run "ln -s #{shared_path}/content/attachments #{current_path}/public/attachments"
38
+ end
39
+
40
+ task :update do
41
+ Rake::Task["vlad:symlink_config_yml"].invoke
42
+ Rake::Task["vlad:symlink_attachments"].invoke
43
+ end
44
+
45
+ remote_task :bundle do
46
+ run "cd #{current_path} && sudo bundle install --without development test"
47
+ end
48
+
49
+ # Depending on how you host Nesta, you might want to swap :start_app
50
+ # with :start below. The :start_app task will tell your application
51
+ # server (e.g. Passenger) to restart once your new code is deployed by
52
+ # :update. Passenger is the default app server; tell Vlad that you're
53
+ # using a different app server in the call to Vlad.load in Rakefile.
54
+ #
55
+ desc "Deploy the code and restart the server"
56
+ task :deploy => [:update, :start_app]
57
+
58
+ # If you use bundler to manage the installation of gems on your server
59
+ # you can use this definition of the deploy task instead:
60
+ #
61
+ # task :deploy => [:update, :bundle, :start_app]
62
+ end
data/lib/nesta/app.rb ADDED
@@ -0,0 +1,167 @@
1
+ require 'sinatra/base'
2
+ require 'haml'
3
+ require 'sass'
4
+
5
+ require File.expand_path('nesta', File.dirname(__FILE__))
6
+ require File.expand_path('cache', File.dirname(__FILE__))
7
+ require File.expand_path('config', File.dirname(__FILE__))
8
+ require File.expand_path('models', File.dirname(__FILE__))
9
+ require File.expand_path('navigation', File.dirname(__FILE__))
10
+ require File.expand_path('overrides', File.dirname(__FILE__))
11
+ require File.expand_path('path', File.dirname(__FILE__))
12
+ require File.expand_path('plugins', File.dirname(__FILE__))
13
+
14
+ Encoding.default_external = 'utf-8' if RUBY_VERSION =~ /^1.9/
15
+
16
+ Nesta::Plugins.load_local_plugins
17
+
18
+ module Nesta
19
+ class App < Sinatra::Base
20
+ register Sinatra::Cache
21
+
22
+ set :views, File.expand_path('../../views', File.dirname(__FILE__))
23
+ set :cache_enabled, Config.cache
24
+ set :haml, { :format => :html5 }
25
+
26
+ helpers Overrides::Renderers
27
+ helpers Navigation::Renderers
28
+
29
+ helpers do
30
+ def set_from_config(*variables)
31
+ variables.each do |var|
32
+ instance_variable_set("@#{var}", Nesta::Config.send(var))
33
+ end
34
+ end
35
+
36
+ def set_from_page(*variables)
37
+ variables.each do |var|
38
+ instance_variable_set("@#{var}", @page.send(var))
39
+ end
40
+ end
41
+
42
+ def no_widow(text)
43
+ text.split[0...-1].join(" ") + "&nbsp;#{text.split[-1]}"
44
+ end
45
+
46
+ def set_common_variables
47
+ @menu_items = Nesta::Menu.for_path('/')
48
+ @site_title = Nesta::Config.title
49
+ set_from_config(:title, :subtitle, :google_analytics_code)
50
+ @heading = @title
51
+ end
52
+
53
+ def url_for(page)
54
+ File.join(base_url, page.path)
55
+ end
56
+
57
+ def base_url
58
+ url = "http://#{request.host}"
59
+ request.port == 80 ? url : url + ":#{request.port}"
60
+ end
61
+
62
+ def absolute_urls(text)
63
+ text.gsub!(/(<a href=['"])\//, '\1' + base_url + '/')
64
+ text
65
+ end
66
+
67
+ def nesta_atom_id_for_page(page)
68
+ published = page.date.strftime('%Y-%m-%d')
69
+ "tag:#{request.host},#{published}:#{page.abspath}"
70
+ end
71
+
72
+ def atom_id(page = nil)
73
+ if page
74
+ page.atom_id || nesta_atom_id_for_page(page)
75
+ else
76
+ "tag:#{request.host},2009:/"
77
+ end
78
+ end
79
+
80
+ def format_date(date)
81
+ date.strftime("%d %B %Y")
82
+ end
83
+
84
+ def local_stylesheet?
85
+ Nesta.deprecated('local_stylesheet?', 'use local_stylesheet_link_tag')
86
+ File.exist?(File.expand_path('views/local.sass', Nesta::App.root))
87
+ end
88
+
89
+ def local_stylesheet_link_tag(name)
90
+ pattern = File.expand_path("views/#{name}.s{a,c}ss", Nesta::App.root)
91
+ if Dir.glob(pattern).size > 0
92
+ haml_tag :link, :href => "/css/#{name}.css", :rel => "stylesheet"
93
+ end
94
+ end
95
+
96
+ def latest_articles(count = 8)
97
+ Nesta::Page.find_articles[0..count - 1]
98
+ end
99
+
100
+ def article_summaries(articles)
101
+ haml(
102
+ :summaries,
103
+ :layout => false,
104
+ :locals => { :pages => articles }
105
+ )
106
+ end
107
+ end
108
+
109
+ not_found do
110
+ set_common_variables
111
+ haml(:not_found)
112
+ end
113
+
114
+ error do
115
+ set_common_variables
116
+ haml(:error)
117
+ end unless Nesta::App.environment == :development
118
+
119
+ Overrides.load_local_app
120
+ Overrides.load_theme_app
121
+
122
+ get '/robots.txt' do
123
+ content_type 'text/plain', :charset => 'utf-8'
124
+ <<-EOF
125
+ # robots.txt
126
+ # See http://en.wikipedia.org/wiki/Robots_exclusion_standard
127
+ EOF
128
+ end
129
+
130
+ get '/css/:sheet.css' do
131
+ content_type 'text/css', :charset => 'utf-8'
132
+ cache sass(params[:sheet].to_sym)
133
+ end
134
+
135
+ get %r{/attachments/([\w/.-]+)} do
136
+ file = File.join(Nesta::Config.attachment_path, params[:captures].first)
137
+ send_file(file, :disposition => nil)
138
+ end
139
+
140
+ get '/articles.xml' do
141
+ content_type :xml, :charset => 'utf-8'
142
+ set_from_config(:title, :subtitle, :author)
143
+ @articles = Page.find_articles.select { |a| a.date }[0..9]
144
+ cache haml(:atom, :format => :xhtml, :layout => false)
145
+ end
146
+
147
+ get '/sitemap.xml' do
148
+ content_type :xml, :charset => 'utf-8'
149
+ @pages = Page.find_all
150
+ @last = @pages.map { |page| page.last_modified }.inject do |latest, page|
151
+ (page > latest) ? page : latest
152
+ end
153
+ cache haml(:sitemap, :format => :xhtml, :layout => false)
154
+ end
155
+
156
+ get '*' do
157
+ set_common_variables
158
+ @heading = @title
159
+ parts = params[:splat].map { |p| p.sub(/\/$/, '') }
160
+ @page = Nesta::Page.find_by_path(File.join(parts))
161
+ raise Sinatra::NotFound if @page.nil?
162
+ @title = @page.title
163
+ set_from_page(:description, :keywords)
164
+ cache haml(@page.template, :layout => @page.layout)
165
+ end
166
+ end
167
+ end