activeadmin-selleo-cms 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +13 -0
  3. data/Rakefile +40 -0
  4. data/app/admin/activeadmin_selleo_cms/locale.rb +21 -0
  5. data/app/admin/activeadmin_selleo_cms/page.rb +68 -0
  6. data/app/admin/translation.rb +35 -0
  7. data/app/assets/javascripts/activeadmin-selleo-cms/application.js +15 -0
  8. data/app/assets/javascripts/activeadmin-selleo-cms/custom.js +44 -0
  9. data/app/assets/javascripts/activeadmin-selleo-cms/jquery.mjs.nestedSortable.js +429 -0
  10. data/app/assets/stylesheets/activeadmin-selleo-cms/application.css +13 -0
  11. data/app/assets/stylesheets/activeadmin-selleo-cms/custom.css +59 -0
  12. data/app/assets/stylesheets/activeadmin-selleo-cms/jquery-ui.css +517 -0
  13. data/app/controllers/activeadmin_selleo_cms/application_controller.rb +9 -0
  14. data/app/controllers/activeadmin_selleo_cms/locales_controller.rb +8 -0
  15. data/app/controllers/activeadmin_selleo_cms/pages_controller.rb +15 -0
  16. data/app/controllers/activeadmin_selleo_cms/searches_controller.rb +8 -0
  17. data/app/helpers/activeadmin_selleo_cms/application_helper.rb +27 -0
  18. data/app/models/activeadmin_selleo_cms/layout.rb +10 -0
  19. data/app/models/activeadmin_selleo_cms/locale.rb +44 -0
  20. data/app/models/activeadmin_selleo_cms/page.rb +64 -0
  21. data/app/models/activeadmin_selleo_cms/search.rb +10 -0
  22. data/app/models/activeadmin_selleo_cms/section.rb +20 -0
  23. data/app/models/ckeditor/asset.rb +4 -0
  24. data/app/models/ckeditor/attachment_file.rb +12 -0
  25. data/app/models/ckeditor/picture.rb +13 -0
  26. data/app/models/translation.rb +25 -0
  27. data/app/modules/active_admin/views/index_as_list.rb +28 -0
  28. data/app/modules/activeadmin_selleo_cms/content_translation.rb +25 -0
  29. data/app/views/active_admin/resource/update.js +0 -0
  30. data/app/views/activeadmin_selleo_cms/pages/show.html.haml +3 -0
  31. data/app/views/activeadmin_selleo_cms/searches/show.html.haml +6 -0
  32. data/app/views/admin/pages/_fields_additional_locale.html.haml +17 -0
  33. data/app/views/admin/pages/_fields_current_locale.html.haml +14 -0
  34. data/app/views/admin/pages/_form.html.haml +65 -0
  35. data/app/views/admin/pages/_js.html.haml +12 -0
  36. data/app/views/admin/translations/update.js.haml +4 -0
  37. data/app/views/layouts/activeadmin_selleo_cms/application.html.erb +15 -0
  38. data/config/initializers/active_admin.rb +7 -0
  39. data/config/initializers/ckeditor.rb +18 -0
  40. data/config/initializers/i18n.rb +8 -0
  41. data/config/initializers/string_extensions.rb +5 -0
  42. data/config/locales/cms.en.yml +7 -0
  43. data/config/routes.rb +14 -0
  44. data/db/migrate/20121129142932_create_activeadmin_selleo_cms_pages.rb +20 -0
  45. data/db/migrate/20121129160200_create_activeadmin_selleo_cms_locales.rb +19 -0
  46. data/db/migrate/20121204112326_create_ckeditor_assets.rb +26 -0
  47. data/db/migrate/20121206231053_create_activeadmin_selleo_cms_sections.rb +12 -0
  48. data/db/migrate/20121221164723_create_activeadmin_selleo_cms_searches.rb +33 -0
  49. data/db/migrate/20121227222912_create_translations.rb +18 -0
  50. data/lib/activeadmin-selleo-cms.rb +11 -0
  51. data/lib/activeadmin-selleo-cms/application.rb +15 -0
  52. data/lib/activeadmin-selleo-cms/engine.rb +5 -0
  53. data/lib/activeadmin-selleo-cms/version.rb +3 -0
  54. data/lib/tasks/activeadmin-selleo-cms_tasks.rake +4 -0
  55. data/lib/tasks/i18n.rake +6 -0
  56. data/test/activeadmin-selleo-cms_test.rb +7 -0
  57. data/test/dummy/README.rdoc +261 -0
  58. data/test/dummy/Rakefile +7 -0
  59. data/test/dummy/app/assets/javascripts/application.js +15 -0
  60. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  61. data/test/dummy/app/controllers/application_controller.rb +3 -0
  62. data/test/dummy/app/helpers/application_helper.rb +2 -0
  63. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  64. data/test/dummy/config.ru +4 -0
  65. data/test/dummy/config/application.rb +59 -0
  66. data/test/dummy/config/boot.rb +10 -0
  67. data/test/dummy/config/database.yml +25 -0
  68. data/test/dummy/config/environment.rb +5 -0
  69. data/test/dummy/config/environments/development.rb +37 -0
  70. data/test/dummy/config/environments/production.rb +67 -0
  71. data/test/dummy/config/environments/test.rb +37 -0
  72. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  73. data/test/dummy/config/initializers/inflections.rb +15 -0
  74. data/test/dummy/config/initializers/mime_types.rb +5 -0
  75. data/test/dummy/config/initializers/secret_token.rb +7 -0
  76. data/test/dummy/config/initializers/session_store.rb +8 -0
  77. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  78. data/test/dummy/config/locales/en.yml +5 -0
  79. data/test/dummy/config/routes.rb +4 -0
  80. data/test/dummy/public/404.html +26 -0
  81. data/test/dummy/public/422.html +26 -0
  82. data/test/dummy/public/500.html +25 -0
  83. data/test/dummy/public/favicon.ico +0 -0
  84. data/test/dummy/script/rails +6 -0
  85. data/test/fixtures/activeadmin_selleo_cms/layouts.yml +11 -0
  86. data/test/fixtures/activeadmin_selleo_cms/page_parts.yml +11 -0
  87. data/test/fixtures/activeadmin_selleo_cms/pages.yml +11 -0
  88. data/test/integration/navigation_test.rb +10 -0
  89. data/test/test_helper.rb +15 -0
  90. data/test/unit/activeadmin_selleo_cms/page_part_test.rb +9 -0
  91. data/test/unit/activeadmin_selleo_cms/page_test.rb +9 -0
  92. metadata +364 -0
@@ -0,0 +1,9 @@
1
+ module ActiveadminSelleoCms
2
+ class ApplicationController < ActionController::Base
3
+
4
+ before_filter do
5
+ I18n.locale = params[:locale]
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module ActiveadminSelleoCms
2
+ class LocalesController < ActiveadminSelleoCms::ApplicationController
3
+ def change
4
+ I18n.locale = params[:locale]
5
+ redirect_to root_url
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ module ActiveadminSelleoCms
2
+ class PagesController < ActiveadminSelleoCms::ApplicationController
3
+ def show
4
+ if @page = Page.published.find_by_slug(params[:id])
5
+ render action: :show, layout: @page.layout
6
+ elsif params[:id]
7
+ redirect_to "/#{I18n.locale}"
8
+ else
9
+ @page = Page.roots.first
10
+ render action: :show, layout: @page.layout
11
+ end
12
+ @page.increment!(:views) if @page
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ module ActiveadminSelleoCms
2
+ class SearchesController < ActiveadminSelleoCms::ApplicationController
3
+ def show
4
+ @results = Search.current_locale.search_by_content(params[:id]).map(&:searchable).uniq
5
+ render action: :show, layout: 'search'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ module ActiveadminSelleoCms
2
+ module ApplicationHelper
3
+ def link_to_locale(link_name, locale, page=nil)
4
+ if page
5
+ link_to link_name, page_path(locale.code, page.translated_attribute(:slug, locale.code))
6
+ elsif request.fullpath.match(/^\/\w{2}\/.*/)
7
+ link_to link_name, request.fullpath.gsub(/^\/(\w{2})\//, "/#{locale.code}/")
8
+ else
9
+ link_to link_name, "/#{locale.code}"
10
+ end
11
+ end
12
+
13
+ def link_to_search_result(result)
14
+ if result.is_a? Page
15
+ link_to result, page_path(I18n.locale, result)
16
+ end
17
+ end
18
+
19
+ def link_to_page(page)
20
+ if page.is_link_url
21
+ link_to page.title, page.link_url
22
+ else
23
+ link_to page.title, page_path(I18n.locale, page)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ require 'texticle/rails'
2
+ module ActiveadminSelleoCms
3
+ class Layout
4
+ class << self
5
+ def all
6
+ Dir.glob('app/views/layouts/[a-z]*html*').map{|l| l.split('/').last.split('.').first }
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,44 @@
1
+ module ActiveadminSelleoCms
2
+ class Locale < ActiveRecord::Base
3
+ attr_protected :id
4
+
5
+ validates :name, presence: true
6
+ validates :code, presence: true, uniqueness: true
7
+
8
+ scope :enabled, where(enabled: true)
9
+ scope :available_locales, enabled
10
+
11
+ scope :popular, where(code: %w(da de el en es fr hu it lt lv nl no pl pt ru sk sl sv))
12
+
13
+ def to_s
14
+ code
15
+ end
16
+
17
+ def code
18
+ read_attribute(:code).to_sym
19
+ end
20
+
21
+ def url
22
+ "/#{code}"
23
+ end
24
+
25
+ class << self
26
+ def except(sym)
27
+ enabled.map(&code).reject(sym)
28
+ end
29
+
30
+ def available_locale_codes
31
+ available_locales.map(&:to_s)
32
+ end
33
+
34
+ def method_missing(sym, *args)
35
+ if sym.to_s =~ /^[a-z]{2}$/
36
+ Locale.where(code: sym).first
37
+ else
38
+ super
39
+ end
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,64 @@
1
+ module ActiveadminSelleoCms
2
+ class Page < ActiveRecord::Base
3
+ include ContentTranslation
4
+
5
+ translates :title, :slug, :browser_title, :meta_keywords, :meta_description
6
+
7
+ acts_as_nested_set
8
+
9
+ attr_protected :id
10
+
11
+ has_many :sections, as: :sectionable
12
+
13
+ accepts_nested_attributes_for :translations, :sections, :children
14
+
15
+ validates_format_of :link_url, with: /^http/i, allow_blank: false, if: ->(page) { page.is_link_url }
16
+
17
+ scope :show_in_menu, where(show_in_menu: true)
18
+ scope :published, where(is_published: true)
19
+ scope :not_published, where(is_published: false)
20
+ scope :latest, ->(n) { published.reorder("published_at DESC").limit(n) }
21
+ scope :most_read, ->(n) { published.reorder("views DESC").limit(n) }
22
+
23
+ before_validation do
24
+ self.slug = self.title.parameterize if title and slug.blank?
25
+ self.layout = 'application' unless layout
26
+ end
27
+
28
+ before_save do
29
+ if is_published_changed?
30
+ self.published_at = is_published ? Time.now : nil
31
+ end
32
+ end
33
+
34
+ def initialize_missing_sections
35
+ section_names.each do |section_name|
36
+ sections.build(name: section_name) unless sections.detect{|section| section.name == section_name}
37
+ end
38
+ end
39
+
40
+ def to_s
41
+ title
42
+ end
43
+
44
+ def section_names
45
+ begin
46
+ File.open(Dir.glob("app/views/layouts/#{layout}.html*").first).read.scan(/yield\s*\:(\w+)/).flatten
47
+ rescue
48
+ []
49
+ end
50
+ end
51
+
52
+ def to_param
53
+ slug
54
+ end
55
+
56
+ class Translation
57
+ attr_protected :id
58
+
59
+ validates_presence_of :title
60
+ validates_uniqueness_of :slug, scope: :locale #, unless: ->(translation) { translation.page.is_link_url }
61
+ validates_format_of :slug, with: /^[a-z0-9\-_]+$/i #, unless: ->(translation) { translation.page.is_link_url }
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,10 @@
1
+ require 'texticle/rails'
2
+ module ActiveadminSelleoCms
3
+ class Search < ActiveRecord::Base
4
+ extend Texticle
5
+
6
+ belongs_to :searchable, polymorphic: true
7
+
8
+ scope :current_locale, -> { where(locale: I18n.locale) }
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ module ActiveadminSelleoCms
2
+ class Section < ActiveRecord::Base
3
+ include ContentTranslation
4
+
5
+ translates :body
6
+
7
+ attr_protected :id
8
+
9
+ belongs_to :sectionable, polymorphic: true
10
+
11
+ accepts_nested_attributes_for :translations
12
+
13
+ validates_presence_of :name
14
+ validates_uniqueness_of :name, scope: [:sectionable_type, :sectionable_id]
15
+
16
+ class Translation
17
+ attr_protected :id
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ class Ckeditor::Asset < ActiveRecord::Base
2
+ include Ckeditor::Orm::ActiveRecord::AssetBase
3
+ include Ckeditor::Backend::Paperclip
4
+ end
@@ -0,0 +1,12 @@
1
+ class Ckeditor::AttachmentFile < Ckeditor::Asset
2
+ has_attached_file :data,
3
+ :url => "/ckeditor_assets/attachments/:id/:filename",
4
+ :path => ":rails_root/public/ckeditor_assets/attachments/:id/:filename"
5
+
6
+ validates_attachment_size :data, :less_than => 100.megabytes
7
+ validates_attachment_presence :data
8
+
9
+ def url_thumb
10
+ @url_thumb ||= Ckeditor::Utils.filethumb(filename)
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ class Ckeditor::Picture < Ckeditor::Asset
2
+ has_attached_file :data,
3
+ :url => "/ckeditor_assets/pictures/:id/:style_:basename.:extension",
4
+ :path => ":rails_root/public/ckeditor_assets/pictures/:id/:style_:basename.:extension",
5
+ :styles => { :content => '800>', :thumb => '118x100#' }
6
+
7
+ validates_attachment_size :data, :less_than => 2.megabytes
8
+ validates_attachment_presence :data
9
+
10
+ def url_content
11
+ url(:content)
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ class Translation < ActiveRecord::Base
2
+ attr_protected :id
3
+
4
+ serialize :value
5
+ serialize :interpolations, Array
6
+
7
+ validates :locale, presence: true
8
+ validates :key, presence: true, uniqueness: { scope: :locale }
9
+
10
+ scope :incomplete, where(value: nil)
11
+ scope :cms, -> { where("key LIKE '%cms.%'") }
12
+ scope :active_admin, -> { where("key LIKE '%active_admin.%'") }
13
+
14
+ def method_missing(sym, *args)
15
+ if ActiveadminSelleoCms::Locale.enabled.map(&:code).include?(sym)
16
+ Translation.where(locale: sym, key: key).first || ""
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ def to_s
23
+ value.to_s
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ module ActiveAdmin
2
+ module Views
3
+
4
+ class IndexAsList < ActiveAdmin::Component
5
+
6
+ def build(page_presenter, collection)
7
+ add_class "index"
8
+ collection.each do |obj|
9
+ instance_exec(obj, &page_presenter.block)
10
+ end
11
+ end
12
+
13
+ def render_tree(obj)
14
+ ol class: ('sortable' if obj.level == 0) do
15
+ li do
16
+ div do
17
+ obj.to_s
18
+ end
19
+ obj.children.each{|c| render_tree(c)} if obj.children.any?
20
+ end
21
+ end
22
+ render partial: 'js'
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,25 @@
1
+ module ActiveadminSelleoCms
2
+ module ContentTranslation
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ end
10
+
11
+ def initialize_missing_translations
12
+ Locale.available_locale_codes.each do |locale_code|
13
+ translations.build(locale: locale_code) unless translations.detect{|t| t.locale == locale_code}
14
+ end
15
+ end
16
+
17
+ def translated_attribute(attr, locale)
18
+ _locale = I18n.locale
19
+ I18n.locale = locale
20
+ send(attr.to_sym)
21
+ I18n.locale = _locale
22
+ end
23
+
24
+ end
25
+ end
File without changes
@@ -0,0 +1,3 @@
1
+ - @page.sections.each do |section|
2
+ - content_for section.name.to_sym do
3
+ = section.body.html_safe
@@ -0,0 +1,6 @@
1
+ - if @results.any?
2
+ - @results.each do |result|
3
+ %blockquote
4
+ %p= link_to_search_result result
5
+ - else
6
+ %p No results
@@ -0,0 +1,17 @@
1
+ - @page.sections.each do |section|
2
+ - section.initialize_missing_translations
3
+ = form.inputs "#{locale.name} translation" do
4
+ %ol
5
+ = form.input :title
6
+ = form.input :slug
7
+ = form.input :browser_title
8
+ = form.input :meta_keywords
9
+ = form.input :meta_description, input_html: { rows: 3 }
10
+ = form.input :locale, :as => :hidden, :label => false
11
+ - @section_forms.each do |section_form|
12
+ = section_form.semantic_fields_for :translations do |section_form_translated|
13
+ - if section_form_translated.object.locale.to_sym == locale.code
14
+ = section_form_translated.input :body, as: :ckeditor, label: "#{section_form.object.name.titleize} part", input_html: { toolbar: "Full" }
15
+ = section_form_translated.input :locale, :as => :hidden, :label => false
16
+ - else
17
+ = ""
@@ -0,0 +1,14 @@
1
+ = form.inputs "#{locale.name} translation" do
2
+ %ol
3
+ = form.input :title
4
+ = form.input :slug
5
+ = form.input :browser_title
6
+ = form.input :meta_keywords
7
+ = form.input :meta_description, input_html: { rows: 3 }
8
+ = form.semantic_fields_for :sections do |section_form|
9
+ - if @page.section_names.include? section_form.object.name
10
+ - @section_forms << section_form
11
+ = section_form.input :name, as: :hidden, label: false
12
+ = section_form.input :body, as: :ckeditor, label: "#{section_form.object.name.titleize} part", input_html: { toolbar: "Easy" }
13
+ - else
14
+ = ""
@@ -0,0 +1,65 @@
1
+ = semantic_form_for [:admin, @page], url: (@page.new_record? ? admin_pages_path : admin_page_path(@page.id)), html: { multipart: true } do |form|
2
+
3
+ - @page.initialize_missing_translations
4
+ - current_locale = ActiveadminSelleoCms::Locale.find_by_code(I18n.locale)
5
+ - @page.initialize_missing_sections
6
+ - @section_forms = []
7
+
8
+ = form.inputs "General options" do
9
+ = form.input :parent_id, as: :select, collection: nested_set_options(ActiveadminSelleoCms::Page, @page) {|i| "#{'-' * i.level} #{i.title}" }
10
+ = form.input :layout, collection: ActiveadminSelleoCms::Layout.all, include_blank: false
11
+ = form.input :is_published, as: :boolean, input_html: { checked: @page.published_at.present? }
12
+ = form.input :is_link_url, as: :boolean, input_html: { checked: @page.link_url.present? }
13
+ = form.input :link_url
14
+
15
+ .language-tabs
16
+ %ul.language-selection
17
+ %li= link_to current_locale.name, "#lang-#{current_locale.code}"
18
+ - @page.translations.each do |translation|
19
+ - unless translation.locale == current_locale.code
20
+ - additional_locale = ActiveadminSelleoCms::Locale.find_by_code(translation.locale)
21
+ %li= link_to additional_locale.name, "#lang-#{additional_locale.code}"
22
+
23
+ %div{id: "lang-#{current_locale.code}"}
24
+ = render partial: 'fields_current_locale', locals: { locale: current_locale, form: form }
25
+
26
+ = form.semantic_fields_for :translations do |translated_form|
27
+ - unless translated_form.object.locale == current_locale.code
28
+ - additional_locale = ActiveadminSelleoCms::Locale.find_by_code(translated_form.object.locale)
29
+ %div{id: "lang-#{additional_locale.code}", style: "#{'display:none;' if additional_locale.code == current_locale.code}"}
30
+ = render partial: 'fields_additional_locale', locals: { locale: additional_locale, form: translated_form }
31
+ - else
32
+ = ""
33
+
34
+ = form.actions do
35
+ = form.action :submit
36
+ %li.cancel
37
+ = link_to I18n.t('active_admin.cancel'), admin_pages_path
38
+
39
+
40
+ :javascript
41
+ function is_link_url(){
42
+ if($('input#page_is_link_url').is(':checked')){
43
+ $('div.language-tabs').hide();
44
+ $('li#page_link_url_input').show();
45
+ }else{
46
+ $('li#page_link_url_input').hide();
47
+ $('div.language-tabs').show();
48
+ }
49
+ }
50
+
51
+ $(function() {
52
+ $(".language-tabs").tabs();
53
+ is_link_url();
54
+
55
+ $("input[id$='_title']").blur(function(){
56
+ slugId = '#' + $(this).attr('id').replace('_title', '_slug');
57
+ if ($(slugId).attr('value') == '') {
58
+ $(slugId).attr('value', slug($(this).attr('value')) )
59
+ }
60
+ });
61
+
62
+ $('input#page_is_link_url').change(function(){
63
+ is_link_url();
64
+ });
65
+ });