kuhsaft 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README +9 -0
- data/app/controllers/kuhsaft/admin/admin_controller.rb +18 -0
- data/app/controllers/kuhsaft/admin/assets_controller.rb +1 -4
- data/app/controllers/kuhsaft/admin/pages_controller.rb +17 -17
- data/app/models/kuhsaft/localized_page.rb +22 -3
- data/app/models/kuhsaft/page.rb +22 -18
- data/app/models/kuhsaft/page_part.rb +1 -1
- data/app/models/kuhsaft/page_part/content.rb +55 -0
- data/app/models/kuhsaft/page_part/markdown.rb +8 -0
- data/app/models/kuhsaft/publish_state.rb +29 -0
- data/app/stylesheets/kuhsaft/admin/partials/_generic.sass +29 -10
- data/app/stylesheets/kuhsaft/admin/partials/_pages.sass +6 -2
- data/app/views/kuhsaft/admin/kuhsaft/page_part/markdowns/_markdown.html.haml +1 -0
- data/app/views/kuhsaft/admin/pages/_form.html.haml +22 -11
- data/app/views/kuhsaft/admin/pages/edit.html.haml +7 -1
- data/app/views/kuhsaft/admin/pages/index.html.haml +0 -13
- data/app/views/kuhsaft/admin/pages/new.html.haml +3 -1
- data/app/views/layouts/kuhsaft/admin.html.haml +3 -1
- data/config/initializers/page_parts.rb +16 -0
- data/config/locales/kuhsaft.en.yml +2 -0
- data/config/routes.rb +6 -1
- data/kuhsaft.gemspec +4 -4
- data/lib/generators/kuhsaft/install/migrations_generator.rb +5 -1
- data/lib/kuhsaft/version.rb +1 -1
- data/lib/templates/kuhsaft/install/add_fulltext_to_localized_page.rb +9 -0
- data/lib/templates/kuhsaft/install/add_page_type_to_localized_pages.rb +9 -0
- data/lib/templates/kuhsaft/install/add_published_at_to_localized_pages.rb +9 -0
- data/lib/templates/kuhsaft/install/add_type_to_page_part_contents.rb +9 -0
- data/public/javascripts/kuhsaft/admin/application.js +17 -0
- data/public/javascripts/kuhsaft/admin/jquery-ui-1.8.12.custom.min.js +192 -0
- data/spec/controllers/admin_pages_controller_spec.rb +33 -6
- data/spec/dummy/config/database.yml +2 -2
- data/spec/dummy/config/locales/en.yml +3 -1
- data/spec/factories.rb +0 -9
- data/spec/models/localized_page_spec.rb +103 -15
- data/spec/models/page_part_content_spec.rb +59 -17
- data/spec/models/page_part_spec.rb +1 -1
- data/spec/models/page_spec.rb +34 -29
- data/spec/models/publish_state_spec.rb +45 -0
- data/spec/routing/pages_routing_spec.rb +28 -21
- metadata +38 -21
- data/app/models/kuhsaft/page_parts/base.rb +0 -26
- data/app/models/kuhsaft/page_parts/content.rb +0 -8
- data/app/models/kuhsaft/page_parts/markdown.rb +0 -7
- 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,26 +1,24 @@
|
|
1
1
|
module Kuhsaft
|
2
2
|
module Admin
|
3
|
-
class PagesController <
|
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 =>
|
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 =>
|
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
|
-
|
5
|
-
|
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
|
data/app/models/kuhsaft/page.rb
CHANGED
@@ -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, :
|
10
|
-
:
|
11
|
-
|
12
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
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
|
93
|
+
if translation.page_parts.count == 0 && childs.count > 0
|
94
94
|
childs.first.link
|
95
95
|
else
|
96
|
-
|
96
|
+
if translation.page_type == 'redirect'
|
97
|
+
url
|
98
|
+
else
|
99
|
+
"/#{url}"
|
100
|
+
end
|
97
101
|
end
|
98
102
|
end
|
99
103
|
|
@@ -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,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:
|
3
|
-
font-size:
|
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(
|
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
|
-
|
33
|
+
background: $color3
|
19
34
|
font-size: 18px
|
20
|
-
|
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:
|
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
|
-
|
2
|
-
=
|
3
|
-
=
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|