kuhsaft 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/README +9 -0
  2. data/app/controllers/kuhsaft/admin/admin_controller.rb +18 -0
  3. data/app/controllers/kuhsaft/admin/assets_controller.rb +1 -4
  4. data/app/controllers/kuhsaft/admin/pages_controller.rb +17 -17
  5. data/app/models/kuhsaft/localized_page.rb +22 -3
  6. data/app/models/kuhsaft/page.rb +22 -18
  7. data/app/models/kuhsaft/page_part.rb +1 -1
  8. data/app/models/kuhsaft/page_part/content.rb +55 -0
  9. data/app/models/kuhsaft/page_part/markdown.rb +8 -0
  10. data/app/models/kuhsaft/publish_state.rb +29 -0
  11. data/app/stylesheets/kuhsaft/admin/partials/_generic.sass +29 -10
  12. data/app/stylesheets/kuhsaft/admin/partials/_pages.sass +6 -2
  13. data/app/views/kuhsaft/admin/kuhsaft/page_part/markdowns/_markdown.html.haml +1 -0
  14. data/app/views/kuhsaft/admin/pages/_form.html.haml +22 -11
  15. data/app/views/kuhsaft/admin/pages/edit.html.haml +7 -1
  16. data/app/views/kuhsaft/admin/pages/index.html.haml +0 -13
  17. data/app/views/kuhsaft/admin/pages/new.html.haml +3 -1
  18. data/app/views/layouts/kuhsaft/admin.html.haml +3 -1
  19. data/config/initializers/page_parts.rb +16 -0
  20. data/config/locales/kuhsaft.en.yml +2 -0
  21. data/config/routes.rb +6 -1
  22. data/kuhsaft.gemspec +4 -4
  23. data/lib/generators/kuhsaft/install/migrations_generator.rb +5 -1
  24. data/lib/kuhsaft/version.rb +1 -1
  25. data/lib/templates/kuhsaft/install/add_fulltext_to_localized_page.rb +9 -0
  26. data/lib/templates/kuhsaft/install/add_page_type_to_localized_pages.rb +9 -0
  27. data/lib/templates/kuhsaft/install/add_published_at_to_localized_pages.rb +9 -0
  28. data/lib/templates/kuhsaft/install/add_type_to_page_part_contents.rb +9 -0
  29. data/public/javascripts/kuhsaft/admin/application.js +17 -0
  30. data/public/javascripts/kuhsaft/admin/jquery-ui-1.8.12.custom.min.js +192 -0
  31. data/spec/controllers/admin_pages_controller_spec.rb +33 -6
  32. data/spec/dummy/config/database.yml +2 -2
  33. data/spec/dummy/config/locales/en.yml +3 -1
  34. data/spec/factories.rb +0 -9
  35. data/spec/models/localized_page_spec.rb +103 -15
  36. data/spec/models/page_part_content_spec.rb +59 -17
  37. data/spec/models/page_part_spec.rb +1 -1
  38. data/spec/models/page_spec.rb +34 -29
  39. data/spec/models/publish_state_spec.rb +45 -0
  40. data/spec/routing/pages_routing_spec.rb +28 -21
  41. metadata +38 -21
  42. data/app/models/kuhsaft/page_parts/base.rb +0 -26
  43. data/app/models/kuhsaft/page_parts/content.rb +0 -8
  44. data/app/models/kuhsaft/page_parts/markdown.rb +0 -7
  45. data/public/javascripts/kuhsaft/admin/jquery-ui-1.8.10.custom.min.js +0 -110
data/README CHANGED
@@ -56,3 +56,12 @@ end
56
56
  == Usage
57
57
 
58
58
  ... to be continued
59
+
60
+
61
+ == Adding new migrations in development
62
+
63
+ 1. create your_migration.rb in lib/temlates/kuhsaft/install
64
+ 2. drop migrations in spec/dummy/db/migrate: rm spec/dummy/db/migrate/*.rb
65
+ 3. drop existing development and test DB for the spec/dummy app: rake db:drop:all
66
+ 4. install new migrations:rails g kuhsaft:install:migrations
67
+ 5. run specs for your engine: rspec spec/, which generates your test tables with the new migrations (see spec_helper.rb)
@@ -0,0 +1,18 @@
1
+ module Kuhsaft
2
+ module Admin
3
+ class AdminController < ApplicationController
4
+
5
+ respond_to :html
6
+ layout 'kuhsaft/admin'
7
+ before_filter :set_translation_locale
8
+
9
+ def default_url_options
10
+ { :locale => params[:locale].presence || :en }
11
+ end
12
+
13
+ def set_translation_locale
14
+ Kuhsaft::Page.current_translation_locale = params[:locale] if params[:locale].present?
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,9 +1,6 @@
1
1
  module Kuhsaft
2
2
  module Admin
3
- class AssetsController < ApplicationController
4
- respond_to :html
5
- layout 'kuhsaft/admin'
6
-
3
+ class AssetsController < AdminController
7
4
  def index
8
5
  @assets = Kuhsaft::Asset.by_date
9
6
  respond_with @assets
@@ -1,26 +1,24 @@
1
1
  module Kuhsaft
2
2
  module Admin
3
- class PagesController < ApplicationController
4
- respond_to :html
5
- layout 'kuhsaft/admin'
6
- before_filter :set_translation_locale
3
+ class PagesController < AdminController
7
4
  helper :all
8
-
5
+
9
6
  def index
10
7
  @pages = Kuhsaft::Page.root_pages
11
8
  respond_with @pages
12
9
  end
13
-
10
+
14
11
  def show
15
12
  @page = Kuhsaft::Page.find(params[:id])
16
13
  respond_with @page
17
14
  end
18
-
15
+
19
16
  def new
20
17
  @page = Kuhsaft::Page.new
18
+ @localized_page = @page.localized_pages.find_or_initialize_by_locale(params[:locale])
21
19
  respond_with @page
22
20
  end
23
-
21
+
24
22
  def create
25
23
  parent = Kuhsaft::Page.find(params[:kuhsaft_page][:parent_id]) if params[:kuhsaft_page][:parent_id].present?
26
24
  @page = Kuhsaft::Page.create params[:kuhsaft_page]
@@ -28,31 +26,33 @@ module Kuhsaft
28
26
  parent.childs << @page
29
27
  parent.save
30
28
  end
31
- respond_with @page, :location => admin_pages_path
29
+ respond_with @page, :location => edit_admin_page_path(@page)
32
30
  end
33
-
31
+
34
32
  def edit
35
33
  @page = Kuhsaft::Page.find(params[:id])
34
+ @localized_page = @page.localized_pages.find_or_initialize_by_locale(params[:locale])
35
+
36
+ if params[:add_page_part].present?
37
+ @localized_page.page_parts.build :type => params[:kuhsaft_page][:page_part_type].constantize
38
+ end
39
+
36
40
  respond_with @page
37
41
  end
38
-
42
+
39
43
  def update
40
44
  @page = Kuhsaft::Page.find(params[:id])
41
45
  @page.update_attributes(params[:kuhsaft_page]) if params[:kuhsaft_page].present?
42
46
  # TODO: refactor 'reposition' as a page attribute, so it can be set through update_attributes
43
47
  @page.reposition params[:reposition] if params[:reposition].present? || params.key?(:reposition)
44
- respond_with @page, :location => admin_pages_path
48
+ respond_with @page, :location => edit_admin_page_path(@page)
45
49
  end
46
-
50
+
47
51
  def destroy
48
52
  @page = Kuhsaft::Page.find(params[:id])
49
53
  @page.destroy
50
54
  redirect_to admin_pages_path
51
55
  end
52
-
53
- def set_translation_locale
54
- Kuhsaft::Page.current_translation_locale = params[:translation_locale] if params[:translation_locale].present?
55
- end
56
56
  end
57
57
  end
58
58
  end
@@ -1,20 +1,28 @@
1
1
  class Kuhsaft::LocalizedPage < ActiveRecord::Base
2
2
  belongs_to :page
3
- has_many :page_parts, :class_name => 'Kuhsaft::PagePart::Content'
4
- before_validation :create_slug
5
- before_validation :create_url
3
+ has_many :page_parts, :class_name => 'Kuhsaft::PagePart::Content', :autosave => true
4
+ scope :published, lambda{ where('published = ? OR published_at < ?', Kuhsaft::PublishState::PUBLISHED, DateTime.now) }
5
+ scope :search, lambda{ |term| published.where('fulltext LIKE ?', "%#{term}%").where('locale = ?', Kuhsaft::Page.current_translation_locale) }
6
6
 
7
+ before_validation :create_slug, :create_url, :collect_fulltext
7
8
  delegate :childs, :to => :page
8
9
 
9
10
  validates :title, :presence => true
10
11
  validates :locale, :presence => true
11
12
  validates :slug, :presence => true
12
13
 
14
+ accepts_nested_attributes_for :page_parts, :allow_destroy => true
15
+
16
+ def published?
17
+ published > 0 || (published_at < DateTime.now if published_at.present?)
18
+ end
19
+
13
20
  def locale
14
21
  read_attribute(:locale).to_sym unless read_attribute(:locale).nil?
15
22
  end
16
23
 
17
24
  def create_url
25
+ return if self.page_type == 'redirect'
18
26
  complete_slug = ''
19
27
  if page.present? && page.parent.present?
20
28
  complete_slug << page.parent.url.to_s
@@ -30,4 +38,15 @@ class Kuhsaft::LocalizedPage < ActiveRecord::Base
30
38
  write_attribute(:slug, read_attribute(:title).downcase.parameterize)
31
39
  end
32
40
  end
41
+
42
+ def collect_fulltext
43
+ self.fulltext = page_parts.inject('') do |text, page_part|
44
+ page_part.class.searchable_attributes.each do |attr|
45
+ text << ' '
46
+ text << page_part.send(attr).to_s
47
+ end
48
+ text
49
+ end
50
+ self.fulltext << [title.to_s, keywords.to_s, description.to_s].join(' ')
51
+ end
33
52
  end
@@ -6,33 +6,33 @@ class Kuhsaft::Page < ActiveRecord::Base
6
6
  scope :root_pages, where('parent_id IS NULL')
7
7
  default_scope order('position ASC')
8
8
 
9
- delegate :title, :title=,
10
- :slug, :slug=,
11
- :published, :published=,
12
- :keywords, :keywords=,
13
- :description, :description=,
14
- :locale, :locale=,
15
- :body, :body=,
16
- :url, :url=,
17
- :to => :translation
9
+ delegate :title, :slug, :published, :keywords, :description, :locale, :body, :url, :fulltext,
10
+ :to => :translation, :allow_nil => true
11
+
12
+ accepts_nested_attributes_for :localized_pages
18
13
 
19
14
  after_save :save_translation
20
15
  after_create :set_position
21
16
 
17
+ #
18
+ # Stores the selected type of page_part when created through the form
19
+ #
20
+ attr_accessor :page_part_type
21
+
22
22
  def root?
23
23
  parent.nil?
24
24
  end
25
25
 
26
- def translation
27
- unless @localized_page.present?
28
- pages = localized_pages.where('locale = ?', Kuhsaft::Page.current_translation_locale)
29
- @localized_page = pages.first unless pages.blank?
30
- end
31
- @localized_page ||= localized_pages.build :locale => Kuhsaft::Page.current_translation_locale
26
+ def translation lang = nil
27
+ lang ||= Kuhsaft::Page.current_translation_locale
28
+ @translation = localized_pages.where('locale = ?', lang).first if @translation.blank? || @translation.locale != lang
29
+ @translation
32
30
  end
33
31
 
34
32
  def save_translation
35
- @localized_page.save unless @localized_page.blank?
33
+ unless @translation.blank?
34
+ @translation.save
35
+ end
36
36
  childs.each do |child|
37
37
  child.translation.save if child.translation.persisted?
38
38
  end
@@ -90,10 +90,14 @@ class Kuhsaft::Page < ActiveRecord::Base
90
90
  end
91
91
 
92
92
  def link
93
- if body.blank? && childs.count > 0
93
+ if translation.page_parts.count == 0 && childs.count > 0
94
94
  childs.first.link
95
95
  else
96
- "/#{url}"
96
+ if translation.page_type == 'redirect'
97
+ url
98
+ else
99
+ "/#{url}"
100
+ end
97
101
  end
98
102
  end
99
103
 
@@ -9,4 +9,4 @@ module Kuhsaft
9
9
  descendants.map { |d| d.to_s.underscore.to_sym }
10
10
  end
11
11
  end
12
- end
12
+ end
@@ -0,0 +1,55 @@
1
+ module Kuhsaft
2
+ module PagePart
3
+ class Content < ActiveRecord::Base
4
+ belongs_to :localized_page
5
+ serialize :content
6
+
7
+ class << self
8
+ def serialize_attr name
9
+ name = name.to_sym
10
+ serializeable_attributes << name
11
+
12
+ define_method name do
13
+ self.content ||= {}
14
+ self.content[name].presence
15
+ end
16
+
17
+ define_method "#{name}=" do |val|
18
+ self.content_will_change!
19
+ self.content ||= {}
20
+ self.content[name] = val
21
+ end
22
+ end
23
+
24
+ def searchable_attr name
25
+ name = name.to_sym
26
+ searchable_attributes << name
27
+ end
28
+
29
+ def searchable_attributes
30
+ @searchable_attributes ||= []
31
+ end
32
+
33
+ def serializeable_attributes
34
+ @serializeable_attributes ||= []
35
+ end
36
+
37
+ def page_part_types
38
+ descendants
39
+ end
40
+
41
+ def to_name
42
+ self.to_s.split('::').last
43
+ end
44
+ end
45
+
46
+ private
47
+ #
48
+ # OMFG, OMFG!!! http://stackoverflow.com/questions/5178204/what-is-a-better-way-to-create-sti-model-instance
49
+ #
50
+ def atributes_protected_by_default
51
+ super - [self.class.inheritance_column]
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,8 @@
1
+ module Kuhsaft
2
+ module PagePart
3
+ class Markdown < Kuhsaft::PagePart::Content
4
+ serialize_attr :text
5
+ searchable_attr :text
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,29 @@
1
+ module Kuhsaft
2
+ class PublishState
3
+
4
+ extend ActiveModel::Translation
5
+
6
+ UNPUBLISHED = 0
7
+ PUBLISHED = 1
8
+ PUBLISHED_AT = 2
9
+
10
+ attr_reader :name
11
+ attr_reader :value
12
+
13
+ def initialize options
14
+ options.each_pair { |k,v| instance_variable_set("@#{k}", v) if respond_to?(k) }
15
+ end
16
+
17
+ def human_name
18
+ I18n.translate(name)
19
+ end
20
+
21
+ def self.all
22
+ @all ||= [
23
+ PublishState.new(:name => 'unpublished', :value => UNPUBLISHED),
24
+ PublishState.new(:name => 'published', :value => PUBLISHED),
25
+ PublishState.new(:name => 'published_at', :value => PUBLISHED_AT)
26
+ ]
27
+ end
28
+ end
29
+ end
@@ -1,29 +1,48 @@
1
+ $color1: #2c5eb0
2
+ $color2: #161f38
3
+ $color3: #e4e9f2
4
+
1
5
  body
2
- line-height: 135%
3
- font-size: 12px
6
+ line-height: 150%
7
+ font-size: 16px
8
+ background: #efefef
9
+ font-family: 'Helvetica Neue', 'Helvetica', Arial, sans-serif
10
+
11
+ #kuhsaft-wrapper
12
+ background: #f9f9f9
13
+ padding: 24px
14
+ margin: 48px auto
15
+ max-width: 912px
4
16
 
5
17
  a
6
18
  text-decoration: none
7
- +link-colors(#000, #666, #000, #000, #000)
19
+ +link-colors($color1, $color2, $color1, $color1, $color2)
8
20
 
9
21
  .clear
10
22
  clear: both
11
23
 
24
+ .clearfix
25
+ +clearfix
26
+
12
27
  .toolbar
13
28
  padding: 5px 0px
14
29
  a
15
30
  +float_right
16
31
 
17
32
  .module-nav
18
- +horizontal-list(10px)
33
+ background: $color3
19
34
  font-size: 18px
20
- line-height: 26px
35
+ font-weight: bold
36
+ margin: -24px
37
+ +horizontal-list(12px)
38
+ padding-left: 24px
39
+ width: 936px
40
+ margin-left: -24px
41
+
42
+ a
43
+ line-height: 48px
21
44
 
22
45
  .list
23
46
  border-top: 1px solid #444
24
47
  li
25
- border-bottom: 1px solid #444
26
-
27
- #kuhsaft-wrapper
28
- margin: 50px auto
29
- max-width: 900px
48
+ border-bottom: 1px solid #444
@@ -21,7 +21,6 @@
21
21
 
22
22
  .page-branch
23
23
  margin: 5px 0px
24
- background: url(../../../images/drag-handle.png) no-repeat
25
24
  padding-left: 25px
26
25
 
27
26
  .new-child, .delete
@@ -39,4 +38,9 @@
39
38
 
40
39
  textarea
41
40
  width: 100%
42
- height: 600px
41
+ height: 150px
42
+ margin-bottom: 12px
43
+
44
+ select, select + input[type=submit]
45
+ float: left
46
+ margin-right: 20px
@@ -0,0 +1 @@
1
+ = input_form.input :text, :as => :text
@@ -1,11 +1,22 @@
1
- - Kuhsaft::Page.translation_locales.each do |locale|
2
- = link_to locale.to_s, link_url.call(:translation_locale => locale), :class => 'button'
3
- = simple_form_for @page, :url => url.call(:translation_locale => Kuhsaft::Page.current_translation_locale) do |f|
4
- %p= t('kuhsaft.admin.pages.current_translation_locale', :translation_locale => Kuhsaft::Page.current_translation_locale)
5
- = f.input :title
6
- = f.input :slug
7
- = f.input :keywords
8
- = f.input :description
9
- = f.input :body, :as => :text
10
- = f.input :parent_id, :as => :hidden, :input_html => { :value => params[:parent_id] } if params[:parent_id].present?
11
- = f.button :submit
1
+ = simple_form_for @page, :url => url do |page|
2
+ = page.fields_for :localized_pages, @localized_page do |localized|
3
+ = localized.input :title
4
+ = localized.input :slug, :required => false
5
+ = localized.input :page_type, :as => :radio, :collection => ['', 'redirect']
6
+ = localized.input :published, :collection => Kuhsaft::PublishState.all, :label_method => :human_name, :value_method => :value
7
+ .clear
8
+ - unless localized.object.page_type == 'redirect'
9
+ - if localized.object.published == Kuhsaft::PublishState::PUBLISHED_AT
10
+ = localized.input :published_at, :as => :datetime
11
+ = localized.input :keywords
12
+ = localized.input :description
13
+ = localized.input :locale, :as => :hidden
14
+ = localized.fields_for :page_parts, @localized_page.page_parts do |page_part|
15
+ - unless page_part.object.persisted?
16
+ = page_part.input :type, :as => :hidden, :input_html => { :value => page_part.object.class.to_s }
17
+ = render :partial => page_part.object, :locals => { :input_form => page_part }
18
+ = page_part.input :_destroy, :as => :boolean
19
+ - else
20
+ = localized.input :url, :as => :string
21
+ = page.input :parent_id, :as => :hidden, :input_html => { :value => params[:parent_id] } if params[:parent_id].present?
22
+ = page.button :submit