kuhsaft 0.0.6 → 0.0.7

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 (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