mars-nesta 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
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