fullstack-cms 0.3.10 → 0.3.11

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 (32) hide show
  1. data/Gemfile.lock +0 -1
  2. data/VERSION +1 -1
  3. data/app/controllers/admin/photos_controller.rb +0 -9
  4. data/app/controllers/site/base_controller.rb +76 -0
  5. data/app/errors/denied_error.rb +3 -0
  6. data/app/helpers/i18n_helper.rb +9 -0
  7. data/app/helpers/pages_helper.rb +22 -27
  8. data/app/helpers/site_form_helper.rb +259 -0
  9. data/app/inputs/simple_date_select_input.rb +16 -0
  10. data/app/models/photo.rb +1 -1
  11. data/app/support/deny.rb +41 -0
  12. data/app/support/enum.rb +49 -0
  13. data/app/support/page_not_found_error.rb +3 -0
  14. data/app/{models → support}/pageable.rb +0 -31
  15. data/app/support/publisher.rb +7 -0
  16. data/app/support/sitemap.rb +42 -0
  17. data/app/support/subscriber.rb +24 -0
  18. data/app/views/admin/photos/_photo.html.erb +2 -4
  19. data/config/locales/it.yml +15 -8
  20. data/config/routes.rb +0 -1
  21. data/fullstack-cms.gemspec +17 -6
  22. data/lib/generators/fullstack/cms/install_generator.rb +8 -8
  23. data/lib/generators/fullstack/cms/templates/rails/app/controllers/site/site_controller.rb +4 -49
  24. data/lib/generators/fullstack/cms/templates/rails/config/fullstack.rb +26 -15
  25. data/lib/generators/fullstack/cms/templates/rails/config/initializers/ckeditor_controller.rb +1 -1
  26. data/lib/generators/fullstack/cms/templates/rails/public/admin/rotate-left.png +0 -0
  27. data/lib/generators/fullstack/cms/templates/rails/public/admin/rotate-right.png +0 -0
  28. data/lib/generators/fullstack/cms/templates/rails/public/img/glyphicons-halflings-white.png +0 -0
  29. metadata +18 -7
  30. data/lib/generators/fullstack/cms/templates/rails/config/initializers/devise_mailer.rb +0 -1
  31. data/lib/generators/fullstack/cms/templates/rails/config/initializers/sitemap.rb +0 -10
  32. data/lib/generators/fullstack/cms/templates/rails/config/sitemap.rb.tt +0 -28
data/Gemfile.lock CHANGED
@@ -53,7 +53,6 @@ GEM
53
53
  bootstrap-helpers (0.1.8)
54
54
  rails
55
55
  builder (3.0.0)
56
- checkin (0.5.1)
57
56
  chosen-rails (0.9.8.3)
58
57
  railties (~> 3.0)
59
58
  thor (~> 0.14)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.10
1
+ 0.3.11
@@ -29,15 +29,6 @@ class Admin::PhotosController < Admin::BaseController
29
29
  def edit
30
30
  end
31
31
 
32
- def rotate
33
- @photo ||= Photo.find(params[:id])
34
- rotation = params[:deg].to_f
35
- rotation ||= 90
36
- @photo.rotate!(rotation)
37
- # flash[:notice] = "The image has been rotated"
38
- end
39
-
40
-
41
32
  def update
42
33
  @photo.attributes = params[:photo]
43
34
  @photo.save
@@ -0,0 +1,76 @@
1
+ class Site::BaseController < ApplicationController
2
+ include Pageable
3
+ include Sitemap
4
+ include Deny
5
+
6
+ prepend_before_filter(:set_locale) if Fullstack::Cms.localized?
7
+
8
+ rescue_from ActiveRecord::RecordNotFound, :with => :render_404
9
+ rescue_from DeniedError, :with => :handle_unauthorized
10
+ rescue_from PageNotFoundError, :with => :render_404
11
+
12
+ # ===========
13
+ # = Helpers =
14
+ # ===========
15
+
16
+ helper_method :current_locale
17
+ helper_method :current_locale?
18
+ helper_method :logged_in?
19
+ helper_method :guest?
20
+
21
+ protected
22
+ def current_locale
23
+ I18n.locale.to_s
24
+ end
25
+
26
+ def current_locale?(locale)
27
+ current_locale == locale.to_s
28
+ end
29
+
30
+ def set_locale
31
+ I18n.locale = "#{params[:locale]}".to_sym if params[:locale]
32
+ render_404 if I18n.locale.nil? || !I18n.available_locales.include?(I18n.locale.to_sym)
33
+ end
34
+
35
+ def instantiate_resource_by_slug!(resource)
36
+ res = resource.find_by_slug!(params[:slug])
37
+ instance_variable_set("@#{resource.name.underscore}", res)
38
+ @object = res
39
+ res
40
+ end
41
+
42
+ alias :resource_by_slug! :instantiate_resource_by_slug!
43
+
44
+ def instantiate_resource_by_slug_and_locale!(resource)
45
+ res = resource.find_by_slug_and_locale!(params[:slug], current_locale)
46
+ instance_variable_set("@#{resource.name.underscore}", res)
47
+ @object = res
48
+ res
49
+ end
50
+
51
+ alias :resource_by_slug_and_locale! :instantiate_resource_by_slug_and_locale!
52
+
53
+ def render_404
54
+ render :file => Rails.root.join("public", "404.html"), :layout => false, :status => :not_found
55
+ end
56
+
57
+ def handle_unauthorized
58
+ if guest?
59
+ redirect_to new_user_session_path
60
+ else
61
+ render_404
62
+ end
63
+ end
64
+
65
+ def render_404!
66
+ raise PageNotFoundError.new
67
+ end
68
+
69
+ def guest?
70
+ !current_user
71
+ end
72
+
73
+ def logged_in?
74
+ current_user
75
+ end
76
+ end
@@ -0,0 +1,3 @@
1
+ class DeniedError < Exception
2
+
3
+ end
@@ -0,0 +1,9 @@
1
+ module I18nHelper
2
+
3
+ def site_translate(key)
4
+ I18n.t( key, :scope => "site", :default => "#{key}".humanize )
5
+ end
6
+
7
+ alias :st :site_translate
8
+
9
+ end
@@ -1,32 +1,31 @@
1
1
  module PagesHelper
2
-
3
2
  def current_page
4
3
  @current_page
5
4
  end
6
-
5
+
7
6
  def part(name, opts = {}, &block)
8
7
  if @current_page
9
8
  schema = opts.delete(:schema) || PagePart
10
-
11
- klass = schema.is_a?(Class) ? schema : "#{schema.to_s.camelize}PagePart".constantize
9
+
10
+ klass = schema.is_a?(Class) ? schema : "#{schema.to_s.camelize}PagePart".constantize
12
11
  p = klass.where(:name => "#{name}", :page_id => @current_page.id).first
13
12
  p ||= klass.create!(:name => "#{name}", :page_id => @current_page.id)
14
-
13
+
15
14
  if block_given?
16
15
  capture do
17
16
  block.call(p)
18
17
  end
19
18
  else
20
- p
19
+ p
21
20
  end
22
-
21
+
23
22
  end
24
23
  end
25
-
24
+
26
25
  def page_path_for(resource_or_page)
27
26
  page = resource_or_page.is_a?(Page) ? resource_or_page : page_by_resource(resource_or_page)
28
27
  path = page.try(:path)
29
- if path.blank?
28
+ if path.blank?
30
29
  "#not-found"
31
30
  else
32
31
  path.gsub(/:[A-z_]+/) do |seg|
@@ -36,33 +35,29 @@ module PagesHelper
36
35
  end
37
36
 
38
37
  end
39
-
38
+
40
39
  def page_url_for(resource_or_page)
41
40
  "#{request.protocol}#{request.host_with_port}#{page_path_for(resource_or_page)}"
42
41
  end
43
-
42
+
44
43
  def current_page_resource()
45
44
  if current_page && current_page.resourceful?
46
- controller.instance_variable_get("@#{current_page.resource_type}")
45
+ controller.instance_variable_get("@#{current_page.resource_type}")
47
46
  end
48
47
  end
49
-
50
- def home?
51
- request.path == "/"
52
- end
53
-
54
48
 
55
49
  private
50
+
56
51
  def page_by_resource(resource)
57
- resource_type = resource.class.name.underscore
58
-
59
- if Fullstack::Cms.config.localize
60
- locale = resource.respond_to?(:locale) ? resource.send(:locale) : I18n.locale.to_s
61
- Page.find_by_resource_type_and_locale(resource_type, locale)
62
-
63
- else
64
- Page.find_by_resource_type(resource_type)
65
- end
52
+ resource_type = resource.class.name.underscore
53
+
54
+ if Fullstack::Cms.config.localize
55
+ locale = resource.respond_to?(:locale) ? resource.send(:locale) : I18n.locale.to_s
56
+ Page.find_by_resource_type_and_locale(resource_type, locale)
57
+
58
+ else
59
+ Page.find_by_resource_type(resource_type)
60
+ end
66
61
  end
67
-
62
+
68
63
  end
@@ -0,0 +1,259 @@
1
+ module SiteFormHelper
2
+
3
+ class SiteFormBuilder < FormtasticBootstrap::FormBuilder
4
+ def model_name
5
+ super || (object && object.class.model_name)
6
+ end
7
+
8
+ def initialize(*args)
9
+ @target = self
10
+ super(*args)
11
+ end
12
+
13
+ def method_missing(method, *args, &block)
14
+ @target.send(method, *args, &block)
15
+ end
16
+
17
+ def actions(*args, &proc)
18
+ @target.template.form_actions(&proc)
19
+ end
20
+
21
+ def default_action
22
+ action(@target.object.persisted? ? :update : :create, :primary => true)
23
+ end
24
+
25
+ def form_errors(options = {:wrap => true})
26
+ wrap = options.delete(:wrap)
27
+ options[:exclude] ||= [:slug]
28
+ f = @target
29
+ unless f.object.errors.empty?
30
+ if wrap
31
+ @target.template.content_tag :div, :class => "alert alert-block" do
32
+ @target.template.link_to "&times;", :class => "close", :data => {:dismiss => "alert"}
33
+ @target.template.content_tag(:h4, I18n.t('fullstack.admin.form.correct_these_errors_and_retry', :default => "Correct these errors and retry"), :class => "alert-heading")
34
+ f.semantic_errors *(f.object.errors.keys - (options[:exclude] || []))
35
+ end
36
+ else
37
+ f.semantic_errors *(f.object.errors.keys - (options[:exclude] || []))
38
+ end
39
+
40
+ end
41
+ end
42
+ alias :errors :form_errors
43
+
44
+ def action(method, options = {})
45
+ default_label = I18n.t("fullstack.admin_form.labels.#{method}", :default => "#{method}".humanize)
46
+ options[:type] ||= !!options[:primary] ? :primary : nil
47
+ @target.template.button((options.delete(:label) || default_label), options)
48
+ end
49
+
50
+
51
+ def resource_inputs(*args)
52
+ model = @target.object.class
53
+ options = args.extract_options!
54
+
55
+ only_attributes = options[:only] || []
56
+ except_arg = options[:except] || []
57
+ except_attributes = except_arg + model.protected_attributes.to_a + %W(created_at updated_at slug slugs lat lng position)
58
+
59
+ only_attributes.map! {|a| a.to_s}
60
+ except_attributes.map! {|a| a.to_s}
61
+
62
+ columns = model.schema.hierarchy_field_names
63
+
64
+ # ===============
65
+ # = Attachments =
66
+ # ===============
67
+
68
+ attachment_definitions = (model.attachment_definitions || {}).keys
69
+ attachment_columns = attachment_definitions.map {|a|
70
+ ["#{a}_file_name", "#{a}_file_size", "#{a}_content_type", "#{a}_updated_at"]
71
+ }.flatten
72
+
73
+ columns -= attachment_columns
74
+ columns += attachment_definitions
75
+
76
+
77
+ # ================
78
+ # = Associations =
79
+ # ================
80
+
81
+ columns = columns.map {|field_name|
82
+ field_name.to_s.gsub(/_id$/, "").gsub(/_type$/, "")
83
+ }.uniq
84
+
85
+ belongs_to_associations = model.reflect_on_all_associations(:belongs_to).select {|a|
86
+ !a.options[:polymorphic] && !a.options[:autosave]
87
+ }.map {|assoc| assoc.name.to_s}
88
+
89
+ polymorphic_associations = model.reflect_on_all_associations(:belongs_to).select {|a|
90
+ a.options[:polymorphic] && !a.options[:autosave]
91
+ }.map {|assoc| assoc.name.to_s}
92
+
93
+ autosave_belongs_to = model.reflect_on_all_associations(:belongs_to).select {|a|
94
+ a.options[:autosave]
95
+ }.map {|assoc| assoc.name.to_s}.compact
96
+
97
+ has_many_associations = model.reflect_on_all_associations(:has_many).select {|a|
98
+ a.options[:autosave]
99
+ }.map {|assoc| assoc.name.to_s}
100
+
101
+
102
+
103
+ columns -= polymorphic_associations
104
+ columns += has_many_associations
105
+
106
+
107
+ # ====================================
108
+ # = Intersect with :only and :except =
109
+ # ====================================
110
+
111
+ if only_attributes.any?
112
+ columns = columns.select {|k| only_attributes.include?(k)}
113
+ elsif except_attributes.any?
114
+ columns = columns.delete_if {|k| except_attributes.include?(k)}
115
+ end
116
+
117
+
118
+ # =============
119
+ # = Rendering =
120
+ # =============
121
+
122
+ buff = ""
123
+
124
+ columns.each do |column|
125
+ sym = column.to_sym
126
+ field = model.schema.hierarchy_fields[sym]
127
+ is_belongs_to_associaiton = belongs_to_associations.include?(column)
128
+ is_has_many_association = has_many_associations.include?(column)
129
+ is_autosave_belongs_to = autosave_belongs_to.include?(column)
130
+
131
+ buff << if is_belongs_to_associaiton
132
+ @target.input(sym, :as => :select)
133
+
134
+ elsif is_has_many_association || is_autosave_belongs_to
135
+ association_inputs(sym)
136
+
137
+ else
138
+ opts = {}
139
+ args = [sym]
140
+
141
+ if field && field.options[:markup]
142
+ opts[:as] = :markup
143
+
144
+ elsif field && field.options[:simple_markup]
145
+ opts[:as] = :simple_markup
146
+
147
+ elsif field && field.options[:in]
148
+ opts[:as] = :select
149
+ opts[:collection] = field.options[:in]
150
+
151
+ elsif column == "locale"
152
+ opts[:as] = :select
153
+ opts[:collection] = I18n.available_locales.map {|locale| [I18n.t("locale_names.#{locale}", :default => "#{locale}".humanize), locale.to_s] }
154
+
155
+ else
156
+ nil
157
+ end
158
+
159
+ args << opts unless opts.empty?
160
+
161
+ @target.input(*args)
162
+
163
+ end
164
+ end
165
+
166
+ inputs do
167
+ buff.html_safe
168
+ end
169
+
170
+ end
171
+
172
+ def resource_submit
173
+ @target.template.button (@target.object.persisted? ? I18n.t('fullstack.admin.update', :default => "Update") : I18n.t('fullstack.admin.create', :default => "Create")),
174
+ :type => :primary,
175
+ :size => :large
176
+ end
177
+
178
+ def actions(&block)
179
+ @target.template.form_actions(&block)
180
+ end
181
+
182
+ def admin_fields_for(*args)
183
+ @target.semantic_fields_for(*args) do |f|
184
+ yield(FormBuilderDecorator.new(f))
185
+ end
186
+ end
187
+
188
+ def box(title, options = {})
189
+ options[:orientation] ||= "form-horizontal"
190
+
191
+ @target.template.content_tag(:div, :class => ("box " << options[:orientation])) do
192
+ buff = ""
193
+ buff << @target.template.content_tag(:div, title, :class => "box-header")
194
+ buff << @target.template.content_tag(:div, :class => "box-content") do
195
+ yield
196
+ end
197
+ buff.html_safe
198
+ end
199
+
200
+ end
201
+
202
+
203
+ def sort_association(association, options = {})
204
+ assoc_str = association.to_s
205
+ @target.template.render :partial => "sort", :locals => {
206
+ :association => association, :f => self, :options => options }
207
+
208
+ end
209
+
210
+ def association_inputs(association, options = {})
211
+
212
+ assoc_str = association.to_s
213
+ is_singular = assoc_str.pluralize != assoc_str and assoc_str.singularize == assoc_str
214
+
215
+ if is_singular
216
+ if @target.template.partial?("nested_belongs_to_#{assoc_str}_fields")
217
+ @target.template.render :partial => "nested_belongs_to_#{assoc_str}_fields", :locals => {
218
+ :association => association, :f => self, :options => options }
219
+ else
220
+ @target.template.render :partial => "nested_belongs_to_fields", :locals => {
221
+ :association => association, :f => self, :options => options }
222
+ end
223
+
224
+ else
225
+
226
+ if @target.template.partial?("associated_#{assoc_str}_table")
227
+ @target.template.render :partial => "associated_#{assoc_str}_table", :locals => {
228
+ :association => association, :f => self, :options => options }
229
+ else
230
+ @target.template.render :partial => "associated_resources_table", :locals => {
231
+ :association => association, :f => self, :options => options }
232
+ end
233
+
234
+ end
235
+
236
+ end
237
+
238
+ end # ~
239
+
240
+ def site_form_for(record_or_name_or_array, *args)
241
+
242
+ options = args.extract_options!
243
+ options[:builder] ||= SiteFormBuilder
244
+ options[:html] ||= {}
245
+ options[:html][:multipart] = true
246
+
247
+ obj = nil
248
+ if record_or_name_or_array.is_a?(Array) || record_or_name_or_array.is_a?(String) || record_or_name_or_array.is_a?(Hash) || record_or_name_or_array.is_a?(Symbol)
249
+ obj = record_or_name_or_array
250
+ else
251
+ obj = [:site, record_or_name_or_array]
252
+ end
253
+
254
+ form_for(obj, *(args << options)) do |f|
255
+ yield(f)
256
+ end
257
+ end
258
+
259
+ end
@@ -0,0 +1,16 @@
1
+ class SimpleDateSelectInput < FormtasticBootstrap::Inputs::DateSelectInput
2
+
3
+ include Formtastic::Inputs::Base
4
+ include FormtasticBootstrap::Inputs::Base::Labelling
5
+ include FormtasticBootstrap::Inputs::Base::Wrapping
6
+ include FormtasticBootstrap::Inputs::Base::Errors
7
+ include FormtasticBootstrap::Inputs::Base::Hints
8
+
9
+ def to_html
10
+ generic_input_wrapping do
11
+ builder.date_select(method, {:start_year => 100.years.ago.year, :include_blank => true}, {:class => "datetime-selector"})
12
+ end
13
+ end
14
+
15
+ end
16
+
data/app/models/photo.rb CHANGED
@@ -5,7 +5,7 @@ class Photo < ActiveRecord::Base
5
5
  validates_attachment :image, :presence => true,
6
6
  :size => { :in => 0..2.megabytes }
7
7
 
8
- has_attached :image, :processors => [:auto_orient, :rotator]
8
+ has_attached :image, :processors => [:auto_orient, :thumbnail]
9
9
 
10
10
  acts_as_taggable
11
11
 
@@ -0,0 +1,41 @@
1
+ module Deny
2
+ extend ActiveSupport::Concern
3
+
4
+ # es.
5
+ #
6
+ # deny! :if => user.logged_in?
7
+ # deny! :if => -> { ... }
8
+ # deny!
9
+ #
10
+ # before_filter :deny! :if => :guest?
11
+ #
12
+ # def guest?
13
+ # !current_user
14
+ # end
15
+
16
+ def deny!(options = {})
17
+ negate = false
18
+ expr = options.has_key?(:if)
19
+ options.delete(:if)
20
+ elsif options.has_key?(:unless)
21
+ negate = true
22
+ options.delete(:unless)
23
+ else
24
+ true
25
+ end
26
+
27
+ condition = if expr.is_a?(Proc)
28
+ expr.arity != 0 ? expr.call(self) : expr.call
29
+ else
30
+ expr
31
+ end
32
+ condition = negate ? !condition : condition
33
+
34
+ if condition
35
+ raise DeniedError.new
36
+ end
37
+
38
+ false
39
+ end
40
+
41
+ end
@@ -0,0 +1,49 @@
1
+ class Enum
2
+
3
+ class Term
4
+ def initialize(scope, term)
5
+ @term = term
6
+ @scope = scope
7
+ end
8
+
9
+ def id
10
+ @term
11
+ end
12
+
13
+ def to_label
14
+ I18n.t(@term, :scope => @scope, :default => @term.to_s.humanize)
15
+ end
16
+ end
17
+
18
+ attr_reader :terms
19
+
20
+ def initialize(scope, *keys)
21
+ @keys = [keys].flatten
22
+ @keys_to_terms = {}
23
+ @terms = @keys.map do |key|
24
+ t = Term.new(scope, key.to_s)
25
+ @keys_to_terms[key.to_s] = t
26
+ t
27
+ end
28
+ end
29
+
30
+ def keys
31
+ @keys
32
+ end
33
+
34
+ def to_a
35
+ keys
36
+ end
37
+
38
+
39
+ def get_term(key)
40
+ @keys_to_terms[key.to_s]
41
+ end
42
+
43
+ def to_options
44
+ terms.map {|t|
45
+ [t.to_label,t.id]
46
+ }
47
+ end
48
+
49
+ end
@@ -0,0 +1,3 @@
1
+ class PageNotFoundError < Exception
2
+
3
+ end
@@ -1,37 +1,6 @@
1
1
  module Pageable
2
2
  extend ActiveSupport::Concern
3
3
 
4
- def page_to_sitemap_entries(controller, page)
5
-
6
- path = nil
7
- options = {}
8
- entries = []
9
-
10
- if page.resourceful?
11
- page.resource_class.find_each do |object|
12
- path = Rails.application.routes.url_helpers.url_for({ :only_path => true, :controller => controller, :action => page.name }.merge(page.resource_params(object)))
13
- options[:updated_at] = object.updated_at if object.respond_to?(:updated_at)
14
- entries << {:path => path, :options => options}
15
- end
16
- else
17
- path = Rails.application.routes.url_helpers.url_for( :only_path => true, :controller => controller, :action => page.name)
18
- entries << {:path => path, :options => {}}
19
- end
20
-
21
- entries
22
-
23
- end
24
- module_function :page_to_sitemap_entries
25
-
26
- def controller_sitemap_entries(controller)
27
- entries = []
28
- Pageable.controller_pages(controller).map do |name, page|
29
- entries += page_to_sitemap_entries(controller, page)
30
- end
31
- entries
32
- end
33
- module_function :controller_sitemap_entries
34
-
35
4
  #
36
5
  # Pageable.controller_pages("site/site")
37
6
  #
@@ -0,0 +1,7 @@
1
+ module Publisher
2
+ extend ActiveSupport::Concern
3
+
4
+ def trigger(*args)
5
+ ActiveSupport::Notifications.instrument(*args)
6
+ end
7
+ end
@@ -0,0 +1,42 @@
1
+ module Site
2
+ module Sitemap
3
+ extend ActiveSupport::Concern
4
+
5
+ def render_sitemap(allowed_locales = nil)
6
+ allowed_locales ||= I18n.available_locales.map(&:to_s)
7
+ @pages = Page.where("locale IN (?)", allowed_locales).sort do |p1, p2|
8
+ (p1.path || "").split("/").size <=> (p2.path || "").split("/").size
9
+ end
10
+
11
+ erb = <<-eos
12
+ <?xml version="1.0" encoding="UTF-8"?>
13
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
14
+ <% @pages.each do |page| -%>
15
+ <% if !page.resourceful? -%>
16
+ <% begin -%>
17
+ <% loc = polymorphic_url([:site, page.uid.split("#").last, page.locale].compact) -%>
18
+ <url>
19
+ <loc><%= loc %></loc>
20
+ </url>
21
+ <% rescue Exception => e -%>
22
+ <% end -%>
23
+ <% else -%>
24
+ <% page.resource_class.where(:locale => page.locale).each do |resource| -%>
25
+ <url>
26
+ <loc><%= page_url_for(resource) -%></loc>
27
+ <% if resource.respond_to?(:updated_at) -%>
28
+ <lastmod><%= resource.updated_at.strftime("%F") -%></lastmod>
29
+ <% end -%>
30
+ </url>
31
+ <% end -%>
32
+ <% end -%>
33
+ <% end -%>
34
+ </urlset>
35
+
36
+ eos
37
+
38
+ render :inline => erb, :layout => false
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,24 @@
1
+ class Subscriber
2
+
3
+ class Event
4
+ def initialize(hash)
5
+ hash.each do |k,v|
6
+ self.instance_variable_set("@#{k}", v) ## create and initialize an instance variable for this key/value pair
7
+ self.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")}) ## create the getter that returns the instance variable
8
+ self.class.send(:define_method, "#{k}=", proc{|v| self.instance_variable_set("@#{k}", v)}) ## create the setter that sets the instance variable
9
+ end
10
+ end
11
+ end
12
+
13
+ class << self
14
+ def on(*events, &block)
15
+ instance = @instance ||= self.new
16
+ events.each do |event|
17
+ ActiveSupport::Notifications.subscribe( event ) do |name, start, finish, id, payload|
18
+ instance.instance_exec(Event.new(payload), &block)
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ end
@@ -2,12 +2,10 @@
2
2
  <div class="thumbnail">
3
3
  <%= image_tag photo.url(:thumb), :style => "height: 141px" %>
4
4
  <div class="thumbnail-toolbar">
5
- <%= btn '<i class="icon-repeat"></i>'.html_safe, rotate_admin_photo_path(photo, :deg => 90), :remote => true, :method => :post %>
6
- <%= btn '<i class="icon-zoom-in"></i>'.html_safe, photo.url, :rel => "facebox", :'data-tip' => t('fullstack.admin.preview', :default => "Preview") %>
7
-
5
+ <%= btn '<i class="icon-zoom-in"></i>'.html_safe, photo.url, :rel => "facebox", :'data-tip' => t('fullstack.admin.preview', :default => "Preview") %>
8
6
  <%= btn '<i class="icon-edit"></i>'.html_safe, edit_admin_photo_path(photo), :'data-target' => '#edit-photo-modal', :'data-toggle' => 'modal', :"data-tip" => t('fullstack.admin.edit', :default => "Edit") %>
9
7
  <%= btn '', admin_photo_path(photo), :remote => true, :method => :delete, :confirm => t('fullstack.admin.are_you_sure', :default => "Are you sure?"), :icon => :trash, :type => :danger, :icon_color => :white, :'data-tip' => t('fullstack.admin.delete', :default => "Delete") %>
10
- </div>
8
+ </div>
11
9
  </div>
12
10
  </li>
13
11
 
@@ -8,17 +8,24 @@ it:
8
8
  commons: "Tutte le lingue"
9
9
  empty: "Vuoto"
10
10
  this_page_is_linked_to_a_resource: "Questa pagina è collegata ad una risorsa. Il titolo e la descrizione della pagina saranno gli stessi della risorsa collegata"
11
+ rotate_left: "Ruota a sinistra"
12
+ rotate_right: "Ruota a destra"
13
+ pages:
14
+ home: Homepage
15
+ text: Testo
16
+ contacts: Contatti
17
+ blog: Blog
18
+ post: Post
19
+
11
20
  admin:
12
21
  groups:
13
22
  global: "Generale"
14
23
  contacts: "Contatti"
15
- pages:
16
- home: Homepage
17
- text: Testo
18
- contacts: Contatti
19
- blog: Blog
20
- post: Post
21
-
24
+ settings: "Configurazione"
25
+ contacts: "Contatti"
26
+ resources:
27
+ posts: "Post"
28
+ contacts: "Contatti"
22
29
 
23
30
  helpers:
24
31
  label:
@@ -26,4 +33,4 @@ it:
26
33
  site_description: "Descrizione del sito"
27
34
  site_slogan: "Slogan"
28
35
  site_title: "Titolo del sito"
29
- value: "Valore"
36
+ value: "Valore"
data/config/routes.rb CHANGED
@@ -12,7 +12,6 @@ Rails.application.routes.draw do
12
12
  resources :photos, :except => [:new, :index, :show, :create] do
13
13
  get "search", :on => :collection
14
14
  post "create", :format => :js, :on => :collection
15
- post "rotate", :format => :js, :on => :member
16
15
  end
17
16
 
18
17
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "fullstack-cms"
8
- s.version = "0.3.10"
8
+ s.version = "0.3.11"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["mcasimir"]
12
- s.date = "2012-11-22"
12
+ s.date = "2012-12-07"
13
13
  s.description = "CMS system built on fullstack"
14
14
  s.email = "maurizio.cas@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -29,12 +29,17 @@ Gem::Specification.new do |s|
29
29
  "app/controllers/admin/settings_controller.rb",
30
30
  "app/controllers/admin/tags_controller.rb",
31
31
  "app/controllers/admin/users_controller.rb",
32
+ "app/controllers/site/base_controller.rb",
33
+ "app/errors/denied_error.rb",
34
+ "app/helpers/i18n_helper.rb",
32
35
  "app/helpers/markdown_helper.rb",
33
36
  "app/helpers/menus_helper.rb",
34
37
  "app/helpers/mobile_helper.rb",
35
38
  "app/helpers/pages_helper.rb",
36
39
  "app/helpers/photos_helper.rb",
37
40
  "app/helpers/settings_helper.rb",
41
+ "app/helpers/site_form_helper.rb",
42
+ "app/inputs/simple_date_select_input.rb",
38
43
  "app/models/.gitkeep",
39
44
  "app/models/attachment.rb",
40
45
  "app/models/link.rb",
@@ -44,7 +49,6 @@ Gem::Specification.new do |s|
44
49
  "app/models/nestable.rb",
45
50
  "app/models/page.rb",
46
51
  "app/models/page_part.rb",
47
- "app/models/pageable.rb",
48
52
  "app/models/photo.rb",
49
53
  "app/models/redirect.rb",
50
54
  "app/models/setting.rb",
@@ -52,6 +56,13 @@ Gem::Specification.new do |s|
52
56
  "app/models/text_page_part.rb",
53
57
  "app/models/text_with_title_page_part.rb",
54
58
  "app/models/uid.rb",
59
+ "app/support/deny.rb",
60
+ "app/support/enum.rb",
61
+ "app/support/page_not_found_error.rb",
62
+ "app/support/pageable.rb",
63
+ "app/support/publisher.rb",
64
+ "app/support/sitemap.rb",
65
+ "app/support/subscriber.rb",
55
66
  "app/views/admin/base/_fields.html.erb",
56
67
  "app/views/admin/base/_form.html.erb",
57
68
  "app/views/admin/base/_simple_form.html.erb",
@@ -121,10 +132,7 @@ Gem::Specification.new do |s|
121
132
  "lib/generators/fullstack/cms/templates/rails/config/fullstack.rb",
122
133
  "lib/generators/fullstack/cms/templates/rails/config/initializers/ckeditor_controller.rb",
123
134
  "lib/generators/fullstack/cms/templates/rails/config/initializers/devise_controller.rb",
124
- "lib/generators/fullstack/cms/templates/rails/config/initializers/devise_mailer.rb",
125
- "lib/generators/fullstack/cms/templates/rails/config/initializers/sitemap.rb",
126
135
  "lib/generators/fullstack/cms/templates/rails/config/schedule.rb",
127
- "lib/generators/fullstack/cms/templates/rails/config/sitemap.rb.tt",
128
136
  "lib/generators/fullstack/cms/templates/rails/config/styles.yml",
129
137
  "lib/generators/fullstack/cms/templates/rails/lib/support/content.rb",
130
138
  "lib/generators/fullstack/cms/templates/rails/lib/support/timestamped_content.rb",
@@ -132,10 +140,13 @@ Gem::Specification.new do |s|
132
140
  "lib/generators/fullstack/cms/templates/rails/public/422.html",
133
141
  "lib/generators/fullstack/cms/templates/rails/public/500.html",
134
142
  "lib/generators/fullstack/cms/templates/rails/public/admin/drag-handle.png",
143
+ "lib/generators/fullstack/cms/templates/rails/public/admin/rotate-left.png",
144
+ "lib/generators/fullstack/cms/templates/rails/public/admin/rotate-right.png",
135
145
  "lib/generators/fullstack/cms/templates/rails/public/apple-touch-icon.png",
136
146
  "lib/generators/fullstack/cms/templates/rails/public/crossdomain.xml",
137
147
  "lib/generators/fullstack/cms/templates/rails/public/favicon.ico",
138
148
  "lib/generators/fullstack/cms/templates/rails/public/img/.gitignore",
149
+ "lib/generators/fullstack/cms/templates/rails/public/img/glyphicons-halflings-white.png",
139
150
  "lib/generators/fullstack/cms/templates/rails/public/img/glyphicons-halflings.png",
140
151
  "lib/generators/fullstack/cms/templates/rails/public/js/modernizr-2.5.3.min.js",
141
152
  "lib/generators/fullstack/cms/templates/rails/public/robots.txt"
@@ -50,8 +50,11 @@ eos
50
50
  if !localize
51
51
  route '''
52
52
  constraints(:host => /^#{Regexp.escape(Settings.app.domain)}/) do
53
- root :to => redirect("http://www.#{Settings.app.domain}")
54
- match \'/*path\', :to => redirect {|params| "http://www.#{Settings.app.domain}/#{params[:path]}"}
53
+ root :to => redirect("http://www.#{Settings.app.domain}")
54
+ match "/*path", :to => redirect {|params, request|
55
+ query_part = request.query_string.present? ? "?#{request.query_string}" : ""
56
+ "http://www.#{Settings.app.domain}/#{params[:path]}#{query_part}"
57
+ }
55
58
  end
56
59
 
57
60
  # namespace :site, :path => "/" do
@@ -86,19 +89,16 @@ eos
86
89
 
87
90
  }
88
91
  end
92
+ else
89
93
 
90
94
 
91
95
  end
92
96
  end
93
97
 
94
98
  def home_page_helper
95
- append_to_file "app/controllers/application_controller.rb", :after => "protect_from_forgery" do
99
+ append_to_file "app/helpers/application_helper.rb", :after => "ApplicationHelper" do
96
100
  %q{
97
-
98
- helper_method :home_page?
99
-
100
- protected
101
-
101
+
102
102
  def home_page?
103
103
  self.class == Site::SiteController && action_name == "home"
104
104
  end
@@ -1,8 +1,4 @@
1
- class Site::SiteController < ApplicationController
2
- include Pageable
3
- rescue_from ActiveRecord::RecordNotFound, :with => :render_404
4
- authorize :scope => "site", :resourceful => false
5
- prepend_before_filter(:set_locale) if Fullstack::Cms.localized?
1
+ class Site::SiteController < Site::BaseController
6
2
 
7
3
  # =========
8
4
  # = Pages =
@@ -11,50 +7,9 @@ class Site::SiteController < ApplicationController
11
7
  page :home, "/" do
12
8
  end
13
9
 
14
- # ===========
15
- # = Helpers =
16
- # ===========
17
-
18
- helper_method :current_locale
19
- helper_method :home_page?
20
-
21
- protected
22
-
23
- def current_locale
24
- I18n.locale.to_s
25
- end
26
-
27
- # ===================
28
- # = Private Methods =
29
- # ===================
30
-
31
- private
32
-
33
- def set_locale
34
- I18n.locale = "#{params[:locale]}".to_sym if params[:locale]
35
- render_404 if I18n.locale.nil? || !I18n.available_locales.include?(I18n.locale.to_sym)
36
- end
37
-
38
- def instantiate_resource_by_slug!(resource)
39
- res = resource.find_by_slug!(params[:slug])
40
- instance_variable_set("@#{resource.name.underscore}", res)
41
- @object = res
42
- res
43
- end
44
-
45
- alias :resource_by_slug! :instantiate_resource_by_slug!
46
-
47
- def instantiate_resource_by_slug_and_locale!(resource)
48
- res = resource.find_by_slug_and_locale!(params[:slug], current_locale)
49
- instance_variable_set("@#{resource.name.underscore}", res)
50
- @object = res
51
- res
10
+ caches_action(:sitemap, :expires_in => 3.hours)
11
+ def sitemap
12
+ render_sitemap
52
13
  end
53
14
 
54
- alias :resource_by_slug_and_locale! :instantiate_resource_by_slug_and_locale!
55
-
56
- def render_404
57
- render :file => Rails.root.join("public", "404.html"), :layout => false, :status => :not_found
58
- end
59
-
60
15
  end
@@ -5,18 +5,27 @@ Fullstack::Cms.configure do |config|
5
5
  # =============
6
6
 
7
7
  config.resources do |admin|
8
- admin.group :website do |g|
8
+ # admin.group :website do |g|
9
+ # g.icon= "globe"
10
+ # g.resource :texts
11
+ # end
12
+
13
+ # admin.group :blog do |g|
14
+ # g.icon= "book"
15
+ # g.resource :posts
16
+ # end
17
+
18
+ # admin.group :contacts do |g|
19
+ # g.icon= "user"
20
+ # g.resource :contacts
21
+ # end
22
+
23
+ admin.group :settings do |g|
24
+ g.icon= "wrench"
9
25
  g.resource :pages
10
26
  g.resource :menus
11
27
  g.resource :settings
12
28
  end
13
-
14
- admin.group :contents do |g|
15
- end
16
-
17
- admin.group :users do |g|
18
- g.resource :users
19
- end
20
29
  end
21
30
 
22
31
  # =============
@@ -30,19 +39,21 @@ Fullstack::Cms.configure do |config|
30
39
  # =========
31
40
 
32
41
  config.menu(:main)
33
- config.menu(:social)
42
+ # config.menu(:social)
34
43
 
35
44
  # ============
36
45
  # = Settings =
37
46
  # ============
38
-
39
47
  config.setting(:google_analytics_code, :localized => false)
48
+
40
49
  config.setting(:title)
41
50
  config.setting(:slogan)
42
51
  config.setting(:description, :kind => :text)
43
-
44
- config.setting(:address, :kind => :text, :group => :contacts)
45
- config.setting(:phone, :group => :contacts)
46
- config.setting(:email, :group => :contacts)
47
-
52
+ config.setting(:keywords)
53
+
54
+ config.setting(:address, :kind => :text, :group => :contacts)
55
+ config.setting(:phone, :group => :contacts)
56
+ config.setting(:email, :group => :contacts)
57
+ config.setting(:notifies_recipient, :group => :contacts)
58
+
48
59
  end
@@ -1,3 +1,3 @@
1
1
  Ckeditor::ApplicationController.class_eval do
2
- authorize :scope => "admin"
2
+ before_filter :authenticate_administrator!
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fullstack-cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.10
4
+ version: 0.3.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-22 00:00:00.000000000 Z
12
+ date: 2012-12-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fullstack-admin
@@ -191,12 +191,17 @@ files:
191
191
  - app/controllers/admin/settings_controller.rb
192
192
  - app/controllers/admin/tags_controller.rb
193
193
  - app/controllers/admin/users_controller.rb
194
+ - app/controllers/site/base_controller.rb
195
+ - app/errors/denied_error.rb
196
+ - app/helpers/i18n_helper.rb
194
197
  - app/helpers/markdown_helper.rb
195
198
  - app/helpers/menus_helper.rb
196
199
  - app/helpers/mobile_helper.rb
197
200
  - app/helpers/pages_helper.rb
198
201
  - app/helpers/photos_helper.rb
199
202
  - app/helpers/settings_helper.rb
203
+ - app/helpers/site_form_helper.rb
204
+ - app/inputs/simple_date_select_input.rb
200
205
  - app/models/.gitkeep
201
206
  - app/models/attachment.rb
202
207
  - app/models/link.rb
@@ -206,7 +211,6 @@ files:
206
211
  - app/models/nestable.rb
207
212
  - app/models/page.rb
208
213
  - app/models/page_part.rb
209
- - app/models/pageable.rb
210
214
  - app/models/photo.rb
211
215
  - app/models/redirect.rb
212
216
  - app/models/setting.rb
@@ -214,6 +218,13 @@ files:
214
218
  - app/models/text_page_part.rb
215
219
  - app/models/text_with_title_page_part.rb
216
220
  - app/models/uid.rb
221
+ - app/support/deny.rb
222
+ - app/support/enum.rb
223
+ - app/support/page_not_found_error.rb
224
+ - app/support/pageable.rb
225
+ - app/support/publisher.rb
226
+ - app/support/sitemap.rb
227
+ - app/support/subscriber.rb
217
228
  - app/views/admin/base/_fields.html.erb
218
229
  - app/views/admin/base/_form.html.erb
219
230
  - app/views/admin/base/_simple_form.html.erb
@@ -283,10 +294,7 @@ files:
283
294
  - lib/generators/fullstack/cms/templates/rails/config/fullstack.rb
284
295
  - lib/generators/fullstack/cms/templates/rails/config/initializers/ckeditor_controller.rb
285
296
  - lib/generators/fullstack/cms/templates/rails/config/initializers/devise_controller.rb
286
- - lib/generators/fullstack/cms/templates/rails/config/initializers/devise_mailer.rb
287
- - lib/generators/fullstack/cms/templates/rails/config/initializers/sitemap.rb
288
297
  - lib/generators/fullstack/cms/templates/rails/config/schedule.rb
289
- - lib/generators/fullstack/cms/templates/rails/config/sitemap.rb.tt
290
298
  - lib/generators/fullstack/cms/templates/rails/config/styles.yml
291
299
  - lib/generators/fullstack/cms/templates/rails/lib/support/content.rb
292
300
  - lib/generators/fullstack/cms/templates/rails/lib/support/timestamped_content.rb
@@ -294,10 +302,13 @@ files:
294
302
  - lib/generators/fullstack/cms/templates/rails/public/422.html
295
303
  - lib/generators/fullstack/cms/templates/rails/public/500.html
296
304
  - lib/generators/fullstack/cms/templates/rails/public/admin/drag-handle.png
305
+ - lib/generators/fullstack/cms/templates/rails/public/admin/rotate-left.png
306
+ - lib/generators/fullstack/cms/templates/rails/public/admin/rotate-right.png
297
307
  - lib/generators/fullstack/cms/templates/rails/public/apple-touch-icon.png
298
308
  - lib/generators/fullstack/cms/templates/rails/public/crossdomain.xml
299
309
  - lib/generators/fullstack/cms/templates/rails/public/favicon.ico
300
310
  - lib/generators/fullstack/cms/templates/rails/public/img/.gitignore
311
+ - lib/generators/fullstack/cms/templates/rails/public/img/glyphicons-halflings-white.png
301
312
  - lib/generators/fullstack/cms/templates/rails/public/img/glyphicons-halflings.png
302
313
  - lib/generators/fullstack/cms/templates/rails/public/js/modernizr-2.5.3.min.js
303
314
  - lib/generators/fullstack/cms/templates/rails/public/robots.txt
@@ -316,7 +327,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
316
327
  version: '0'
317
328
  segments:
318
329
  - 0
319
- hash: 635953353485388565
330
+ hash: 4011575220836530722
320
331
  required_rubygems_version: !ruby/object:Gem::Requirement
321
332
  none: false
322
333
  requirements:
@@ -1 +0,0 @@
1
- Devise::Mailer.layout "email"
@@ -1,10 +0,0 @@
1
- if Rails.env.development?
2
-
3
- # Set save path to a git-ignored destination for development environment
4
- # comment these lines to use the default `Rails.root/public` instead
5
-
6
- Sitemap.configure do |config|
7
- config.save_path = Rails.root.join("tmp")
8
- end
9
-
10
- end
@@ -1,28 +0,0 @@
1
- Sitemap::Generator.instance.load :host => "www.#{Settings.app.domain}" do
2
-
3
- path :home
4
-
5
- # Sample path:
6
- # path :faq
7
- # The specified path must exist in your routes file (usually specified through :as).
8
-
9
- # Sample path with params:
10
- # path :faq, :params => { :format => "html", :filter => "recent" }
11
- # Depending on the route, the resolved url could be http://mywebsite.com/frequent-questions.html?filter=recent.
12
-
13
- # Sample resource:
14
- # resources :articles
15
-
16
- # Sample resource with custom objects:
17
- # resources :articles, :objects => proc { Article.published }
18
-
19
- # Sample resource with search options:
20
- # resources :articles, :priority => 0.8, :change_frequency => "monthly"
21
-
22
- # Sample resource with block options:
23
- # resources :activities,
24
- # :skip_index => true,
25
- # :updated_at => proc { |activity| activity.published_at.strftime("%Y-%m-%d") }
26
- # :params => { :subdomain => proc { |activity| activity.location } }
27
-
28
- end