fullstack-cms 0.3.10 → 0.3.11

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