jabe 0.5.0

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 (106) hide show
  1. data/Gemfile +35 -0
  2. data/Gemfile.lock +217 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.textile +12 -0
  5. data/Rakefile +55 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/admin/base_controller.rb +3 -0
  8. data/app/controllers/admin/entries_controller.rb +42 -0
  9. data/app/controllers/admin/settings_controller.rb +11 -0
  10. data/app/controllers/comments_controller.rb +25 -0
  11. data/app/controllers/entries_controller.rb +26 -0
  12. data/app/helpers/application_helper.rb +9 -0
  13. data/app/models/admin.rb +9 -0
  14. data/app/models/comment.rb +17 -0
  15. data/app/models/entry.rb +17 -0
  16. data/app/models/settings.rb +2 -0
  17. data/app/stylesheets/_will_paginate.scss +102 -0
  18. data/app/stylesheets/application.scss +247 -0
  19. data/app/stylesheets/grid.scss +336 -0
  20. data/app/stylesheets/handheld.scss +7 -0
  21. data/app/stylesheets/style.scss +273 -0
  22. data/app/views/admin/entries/_form.html.haml +6 -0
  23. data/app/views/admin/entries/edit.html.haml +1 -0
  24. data/app/views/admin/entries/index.html.haml +43 -0
  25. data/app/views/admin/entries/new.html.haml +1 -0
  26. data/app/views/admin/settings/edit.html.haml +9 -0
  27. data/app/views/entries/_comment.html.haml +0 -0
  28. data/app/views/entries/_comment_form.html.haml +3 -0
  29. data/app/views/entries/index.html.haml +13 -0
  30. data/app/views/entries/show.html.haml +36 -0
  31. data/app/views/layouts/_footer.html.haml +2 -0
  32. data/app/views/layouts/_header.html.haml +4 -0
  33. data/app/views/layouts/_sidebar.html.haml +0 -0
  34. data/app/views/layouts/application.html.haml +59 -0
  35. data/config/initializers/sass.rb +5 -0
  36. data/config/initializers/settings.rb +5 -0
  37. data/config/initializers/time_formats.rb +4 -0
  38. data/config/routes.rb +26 -0
  39. data/features/admin.feature +30 -0
  40. data/features/entries.feature +24 -0
  41. data/features/step_definitions/admin_steps.rb +14 -0
  42. data/features/step_definitions/entry_steps.rb +35 -0
  43. data/features/step_definitions/support_steps.rb +3 -0
  44. data/features/step_definitions/web_steps.rb +219 -0
  45. data/features/support/blueprints.rb +31 -0
  46. data/features/support/env.rb +59 -0
  47. data/features/support/paths.rb +37 -0
  48. data/lib/generators/jabe/migrations/migrations_generator.rb +42 -0
  49. data/lib/generators/jabe/templates/migrations/create_comments.rb +20 -0
  50. data/lib/generators/jabe/templates/migrations/create_entries.rb +16 -0
  51. data/lib/generators/jabe/templates/migrations/create_settings.rb +21 -0
  52. data/lib/generators/jabe/templates/migrations/create_slugs.rb +18 -0
  53. data/lib/generators/jabe/templates/migrations/devise_create_admins.rb +26 -0
  54. data/lib/jabe.rb +9 -0
  55. data/public/.htaccess +220 -0
  56. data/public/apple-touch-icon.png +0 -0
  57. data/public/blackbird/blackbird.css +80 -0
  58. data/public/blackbird/blackbird.js +365 -0
  59. data/public/blackbird/blackbird.png +0 -0
  60. data/public/crossdomain.xml +25 -0
  61. data/public/images/delete_page.png +0 -0
  62. data/public/images/full_page.png +0 -0
  63. data/public/javascripts/application.js +34 -0
  64. data/public/javascripts/jquery-ui.js +11511 -0
  65. data/public/javascripts/jquery-ui.min.js +404 -0
  66. data/public/javascripts/jquery.js +7179 -0
  67. data/public/javascripts/jquery.min.js +167 -0
  68. data/public/javascripts/libs/dd_belatedpng.js +13 -0
  69. data/public/javascripts/libs/modernizr-1.6.min.js +30 -0
  70. data/public/javascripts/libs/profiling/charts.swf +0 -0
  71. data/public/javascripts/libs/profiling/config.js +59 -0
  72. data/public/javascripts/libs/profiling/yahoo-profiling.css +7 -0
  73. data/public/javascripts/libs/profiling/yahoo-profiling.min.js +39 -0
  74. data/public/javascripts/plugins.js +40 -0
  75. data/public/javascripts/rails.js +154 -0
  76. data/public/nginx.conf +108 -0
  77. data/public/robots.txt +5 -0
  78. data/spec/support/blueprints.rb +31 -0
  79. data/test/dummy/app/controllers/application_controller.rb +3 -0
  80. data/test/dummy/app/helpers/application_helper.rb +2 -0
  81. data/test/dummy/config/application.rb +45 -0
  82. data/test/dummy/config/boot.rb +10 -0
  83. data/test/dummy/config/environment.rb +5 -0
  84. data/test/dummy/config/environments/development.rb +26 -0
  85. data/test/dummy/config/environments/production.rb +49 -0
  86. data/test/dummy/config/environments/test.rb +35 -0
  87. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  88. data/test/dummy/config/initializers/devise.rb +142 -0
  89. data/test/dummy/config/initializers/inflections.rb +10 -0
  90. data/test/dummy/config/initializers/mime_types.rb +5 -0
  91. data/test/dummy/config/initializers/secret_token.rb +7 -0
  92. data/test/dummy/config/initializers/session_store.rb +8 -0
  93. data/test/dummy/config/routes.rb +58 -0
  94. data/test/dummy/db/migrate/20101229224027_create_settings.rb +21 -0
  95. data/test/dummy/db/migrate/20101229224028_create_slugs.rb +18 -0
  96. data/test/dummy/db/migrate/20101229224029_devise_create_admins.rb +26 -0
  97. data/test/dummy/db/migrate/20101229224030_create_entries.rb +16 -0
  98. data/test/dummy/db/migrate/20101229224031_create_comments.rb +20 -0
  99. data/test/dummy/db/schema.rb +82 -0
  100. data/test/dummy/vendor/plugins/acts_as_textiled/init.rb +8 -0
  101. data/test/dummy/vendor/plugins/acts_as_textiled/lib/acts_as_textiled.rb +108 -0
  102. data/test/dummy/vendor/plugins/acts_as_textiled/test/fixtures/author.rb +4 -0
  103. data/test/dummy/vendor/plugins/acts_as_textiled/test/fixtures/story.rb +4 -0
  104. data/test/dummy/vendor/plugins/acts_as_textiled/test/helper.rb +87 -0
  105. data/test/dummy/vendor/plugins/acts_as_textiled/test/textiled_test.rb +145 -0
  106. metadata +641 -0
@@ -0,0 +1,10 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new inflection rules using the following format
4
+ # (all these examples are active by default):
5
+ # ActiveSupport::Inflector.inflections do |inflect|
6
+ # inflect.plural /^(ox)$/i, '\1en'
7
+ # inflect.singular /^(ox)en/i, '\1'
8
+ # inflect.irregular 'person', 'people'
9
+ # inflect.uncountable %w( fish sheep )
10
+ # end
@@ -0,0 +1,5 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Add new mime types for use in respond_to blocks:
4
+ # Mime::Type.register "text/richtext", :rtf
5
+ # Mime::Type.register_alias "text/html", :iphone
@@ -0,0 +1,7 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key for verifying the integrity of signed cookies.
4
+ # If you change this key, all old signed cookies will become invalid!
5
+ # Make sure the secret is at least 30 characters and all random,
6
+ # no regular words or you'll be exposed to dictionary attacks.
7
+ Dummy::Application.config.secret_token = '93d0f7de2f6e6d2823619dee9f7ceed61e556e716123b37ceeb057307e533dda17e93026a271190aa52ddcbf1ebee33443624a020ae97cd64f4dd8cf61999fc4'
@@ -0,0 +1,8 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ Dummy::Application.config.session_store :cookie_store, :key => '_dummy_session'
4
+
5
+ # Use the database for sessions instead of the cookie-based default,
6
+ # which shouldn't be used to store highly confidential information
7
+ # (create the session table with "rails generate session_migration")
8
+ # Dummy::Application.config.session_store :active_record_store
@@ -0,0 +1,58 @@
1
+ Dummy::Application.routes.draw do
2
+ # The priority is based upon order of creation:
3
+ # first created -> highest priority.
4
+
5
+ # Sample of regular route:
6
+ # match 'products/:id' => 'catalog#view'
7
+ # Keep in mind you can assign values other than :controller and :action
8
+
9
+ # Sample of named route:
10
+ # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
11
+ # This route can be invoked with purchase_url(:id => product.id)
12
+
13
+ # Sample resource route (maps HTTP verbs to controller actions automatically):
14
+ # resources :products
15
+
16
+ # Sample resource route with options:
17
+ # resources :products do
18
+ # member do
19
+ # get 'short'
20
+ # post 'toggle'
21
+ # end
22
+ #
23
+ # collection do
24
+ # get 'sold'
25
+ # end
26
+ # end
27
+
28
+ # Sample resource route with sub-resources:
29
+ # resources :products do
30
+ # resources :comments, :sales
31
+ # resource :seller
32
+ # end
33
+
34
+ # Sample resource route with more complex sub-resources
35
+ # resources :products do
36
+ # resources :comments
37
+ # resources :sales do
38
+ # get 'recent', :on => :collection
39
+ # end
40
+ # end
41
+
42
+ # Sample resource route within a namespace:
43
+ # namespace :admin do
44
+ # # Directs /admin/products/* to Admin::ProductsController
45
+ # # (app/controllers/admin/products_controller.rb)
46
+ # resources :products
47
+ # end
48
+
49
+ # You can have the root of your site routed with "root"
50
+ # just remember to delete public/index.html.
51
+ # root :to => "welcome#index"
52
+
53
+ # See how all your routes lay out with "rake routes"
54
+
55
+ # This is a legacy wild controller route that's not recommended for RESTful applications.
56
+ # Note: This route will make all actions in every controller accessible via GET requests.
57
+ # match ':controller(/:action(/:id(.:format)))'
58
+ end
@@ -0,0 +1,21 @@
1
+ class CreateSettings < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :settings do |t|
4
+ t.string :site_url
5
+ t.string :host_name
6
+ t.string :mail_from
7
+ t.string :site_name
8
+ t.string :tagline
9
+ t.string :time_zone
10
+ t.string :google_tracker_id
11
+ t.boolean :blackbird_enabled
12
+ t.integer :entries_per_page
13
+
14
+ t.timestamps
15
+ end
16
+ end
17
+
18
+ def self.down
19
+ drop_table :settings
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ class CreateSlugs < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :slugs do |t|
4
+ t.string :name
5
+ t.integer :sluggable_id
6
+ t.integer :sequence, :null => false, :default => 1
7
+ t.string :sluggable_type, :limit => 40
8
+ t.string :scope
9
+ t.datetime :created_at
10
+ end
11
+ add_index :slugs, :sluggable_id
12
+ add_index :slugs, [:name, :sluggable_type, :sequence, :scope], :name => "index_slugs_on_n_s_s_and_s", :unique => true
13
+ end
14
+
15
+ def self.down
16
+ drop_table :slugs
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ class DeviseCreateAdmins < ActiveRecord::Migration
2
+ def self.up
3
+ create_table(:admins) do |t|
4
+ t.database_authenticatable :null => false
5
+ t.recoverable
6
+ t.rememberable
7
+ t.trackable
8
+
9
+ # t.confirmable
10
+ # t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both
11
+ # t.token_authenticatable
12
+
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ add_index :admins, :email, :unique => true
18
+ add_index :admins, :reset_password_token, :unique => true
19
+ # add_index :admins, :confirmation_token, :unique => true
20
+ # add_index :admins, :unlock_token, :unique => true
21
+ end
22
+
23
+ def self.down
24
+ drop_table :admins
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ class CreateEntries < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :entries do |t|
4
+ t.string :cached_slug
5
+ t.string :title
6
+ t.text :body
7
+ t.boolean :draft
8
+ t.datetime :published_at
9
+ t.timestamps
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :entries
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ class CreateComments < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :comments do |t|
4
+ t.integer :entry_id
5
+ t.string :name
6
+ t.string :email
7
+ t.string :url
8
+ t.text :body
9
+
10
+ t.timestamps
11
+ end
12
+
13
+ add_index :comments, :entry_id
14
+ end
15
+
16
+ def self.down
17
+ remove_index :comments, :entry_id
18
+ drop_table :comments
19
+ end
20
+ end
@@ -0,0 +1,82 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your
6
+ # database schema. If you need to create the application database on another
7
+ # system, you should be using db:schema:load, not running all the migrations
8
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
10
+ #
11
+ # It's strongly recommended to check this file into your version control system.
12
+
13
+ ActiveRecord::Schema.define(:version => 20101229224031) do
14
+
15
+ create_table "admins", :force => true do |t|
16
+ t.string "email", :default => "", :null => false
17
+ t.string "encrypted_password", :limit => 128, :default => "", :null => false
18
+ t.string "password_salt", :default => "", :null => false
19
+ t.string "reset_password_token"
20
+ t.string "remember_token"
21
+ t.datetime "remember_created_at"
22
+ t.integer "sign_in_count", :default => 0
23
+ t.datetime "current_sign_in_at"
24
+ t.datetime "last_sign_in_at"
25
+ t.string "current_sign_in_ip"
26
+ t.string "last_sign_in_ip"
27
+ t.datetime "created_at"
28
+ t.datetime "updated_at"
29
+ end
30
+
31
+ add_index "admins", ["email"], :name => "index_admins_on_email", :unique => true
32
+ add_index "admins", ["reset_password_token"], :name => "index_admins_on_reset_password_token", :unique => true
33
+
34
+ create_table "comments", :force => true do |t|
35
+ t.integer "entry_id"
36
+ t.string "name"
37
+ t.string "email"
38
+ t.string "url"
39
+ t.text "body"
40
+ t.datetime "created_at"
41
+ t.datetime "updated_at"
42
+ end
43
+
44
+ add_index "comments", ["entry_id"], :name => "index_comments_on_entry_id"
45
+
46
+ create_table "entries", :force => true do |t|
47
+ t.string "cached_slug"
48
+ t.string "title"
49
+ t.text "body"
50
+ t.boolean "draft"
51
+ t.datetime "published_at"
52
+ t.datetime "created_at"
53
+ t.datetime "updated_at"
54
+ end
55
+
56
+ create_table "settings", :force => true do |t|
57
+ t.string "site_url"
58
+ t.string "host_name"
59
+ t.string "mail_from"
60
+ t.string "site_name"
61
+ t.string "tagline"
62
+ t.string "time_zone"
63
+ t.string "google_tracker_id"
64
+ t.boolean "blackbird_enabled"
65
+ t.integer "entries_per_page"
66
+ t.datetime "created_at"
67
+ t.datetime "updated_at"
68
+ end
69
+
70
+ create_table "slugs", :force => true do |t|
71
+ t.string "name"
72
+ t.integer "sluggable_id"
73
+ t.integer "sequence", :default => 1, :null => false
74
+ t.string "sluggable_type", :limit => 40
75
+ t.string "scope"
76
+ t.datetime "created_at"
77
+ end
78
+
79
+ add_index "slugs", ["name", "sluggable_type", "sequence", "scope"], :name => "index_slugs_on_n_s_s_and_s", :unique => true
80
+ add_index "slugs", ["sluggable_id"], :name => "index_slugs_on_sluggable_id"
81
+
82
+ end
@@ -0,0 +1,8 @@
1
+ begin
2
+ require 'RedCloth' unless defined? RedCloth
3
+ rescue LoadError
4
+ nil
5
+ end
6
+
7
+ require 'acts_as_textiled'
8
+ ActiveRecord::Base.send(:include, Err::Acts::Textiled)
@@ -0,0 +1,108 @@
1
+ module Err
2
+ module Acts #:nodoc: all
3
+ module Textiled
4
+ def self.included(klass)
5
+ klass.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def acts_as_textiled(*attributes)
10
+ @textiled_attributes = []
11
+
12
+ @textiled_unicode = String.new.respond_to? :chars
13
+
14
+ ruled = attributes.last.is_a?(Hash) ? attributes.pop : {}
15
+ attributes += ruled.keys
16
+
17
+ type_options = %w( plain source )
18
+
19
+ attributes.each do |attribute|
20
+ define_method(attribute) do |*type|
21
+ type = type.first
22
+
23
+ if type.nil? && self[attribute]
24
+ textiled[attribute.to_s] ||= RedCloth.new(self[attribute], Array(ruled[attribute])).to_html
25
+ elsif type.nil? && self[attribute].nil?
26
+ nil
27
+ elsif type_options.include?(type.to_s)
28
+ send("#{attribute}_#{type}")
29
+ else
30
+ raise "I don't understand the `#{type}' option. Try #{type_options.join(' or ')}."
31
+ end
32
+ end
33
+
34
+ define_method("#{attribute}_plain", proc { strip_redcloth_html(__send__(attribute)) if __send__(attribute) } )
35
+ define_method("#{attribute}_source", proc { __send__("#{attribute}_before_type_cast") } )
36
+
37
+ @textiled_attributes << attribute
38
+ end
39
+
40
+ include Err::Acts::Textiled::InstanceMethods
41
+ end
42
+
43
+ def textiled_attributes
44
+ Array(@textiled_attributes)
45
+ end
46
+ end
47
+
48
+ module InstanceMethods
49
+ def textiled
50
+ textiled? ? (@textiled ||= {}) : @attributes.dup
51
+ end
52
+
53
+ def textiled?
54
+ @is_textiled != false
55
+ end
56
+
57
+ def textiled=(bool)
58
+ @is_textiled = !!bool
59
+ end
60
+
61
+ def textilize
62
+ self.class.textiled_attributes.each { |attr| __send__(attr) }
63
+ end
64
+
65
+ def reload
66
+ textiled.clear
67
+ super
68
+ end
69
+
70
+ def write_attribute(attr_name, value)
71
+ textiled[attr_name.to_s] = nil
72
+ super
73
+ end
74
+
75
+ private
76
+ def strip_redcloth_html(html)
77
+ returning html.dup.gsub(html_regexp, '') do |h|
78
+ redcloth_glyphs.each do |(entity, char)|
79
+ sub = [ :gsub!, entity, char ]
80
+ @textiled_unicode ? h.chars.send(*sub) : h.send(*sub)
81
+ end
82
+ end
83
+ end
84
+
85
+ def redcloth_glyphs
86
+ [[ '&#8217;', "'" ],
87
+ [ '&#8216;', "'" ],
88
+ [ '&lt;', '<' ],
89
+ [ '&gt;', '>' ],
90
+ [ '&#8221;', '"' ],
91
+ [ '&#8220;', '"' ],
92
+ [ '&#8230;', '...' ],
93
+ [ '\1&#8212;', '--' ],
94
+ [ ' &rarr; ', '->' ],
95
+ [ ' &#8211; ', '-' ],
96
+ [ '&#215;', 'x' ],
97
+ [ '&#8482;', '(TM)' ],
98
+ [ '&#174;', '(R)' ],
99
+ [ '&#169;', '(C)' ]]
100
+ end
101
+
102
+ def html_regexp
103
+ %r{<(?:[^>"']+|"(?:\\.|[^\\"]+)*"|'(?:\\.|[^\\']+)*')*>}xm
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,4 @@
1
+ class Author < ActiveRecord::Base
2
+ has_many :stories
3
+ acts_as_textiled :blog => :lite_mode
4
+ end
@@ -0,0 +1,4 @@
1
+ class Story < ActiveRecord::Base
2
+ belongs_to :author
3
+ acts_as_textiled :body, :description => :lite_mode
4
+ end
@@ -0,0 +1,87 @@
1
+ $:.unshift File.dirname(__FILE__) + '/../lib'
2
+
3
+ begin
4
+ require 'rubygems'
5
+ require 'yaml'
6
+ require 'mocha'
7
+ require 'active_support'
8
+ require 'test/spec'
9
+ require 'RedCloth'
10
+ rescue LoadError
11
+ puts "acts_as_textiled requires the mocha and test-spec gems to run its tests"
12
+ exit
13
+ end
14
+
15
+ class ActiveRecord
16
+ class Base
17
+ attr_reader :attributes
18
+
19
+ def initialize(attributes = {})
20
+ @attributes = attributes.dup
21
+ after_find if respond_to?(:after_find)
22
+ end
23
+
24
+ def method_missing(name, *args)
25
+ if name.to_s[/=/]
26
+ @attributes[key = name.to_s.sub('=','')] = value = args.first
27
+ write_attribute key, value
28
+ else
29
+ self[name.to_s]
30
+ end
31
+ end
32
+
33
+ def save
34
+ true
35
+ end
36
+
37
+ def reload
38
+ self
39
+ end
40
+
41
+ def [](value)
42
+ @attributes[value.to_s.sub('_before_type_cast', '')]
43
+ end
44
+
45
+ def self.global
46
+ eval("$#{name.downcase}")
47
+ end
48
+
49
+ def self.find(id)
50
+ item = global.detect { |key, hash| hash['id'] == id }.last
51
+ new(item)
52
+ end
53
+ end
54
+ end unless defined? ActiveRecord
55
+
56
+ require File.dirname(__FILE__) + '/../init'
57
+
58
+ class Author < ActiveRecord::Base
59
+ acts_as_textiled :blog => :lite_mode
60
+ end
61
+
62
+ class Story < ActiveRecord::Base
63
+ acts_as_textiled :body, :description => :lite_mode
64
+
65
+ def author
66
+ @author ||= Author.find(author_id)
67
+ end
68
+ end
69
+
70
+ class StoryWithAfterFind < Story
71
+ acts_as_textiled :body, :description => :lite_mode
72
+
73
+ def after_find
74
+ textilize
75
+ end
76
+
77
+ def self.name
78
+ Story.name
79
+ end
80
+
81
+ def author
82
+ @author ||= Author.find(author_id)
83
+ end
84
+ end
85
+
86
+ $author = YAML.load_file(File.dirname(__FILE__) + '/fixtures/authors.yml')
87
+ $story = YAML.load_file(File.dirname(__FILE__) + '/fixtures/stories.yml')