releaf 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +15 -12
- data/Rakefile +8 -0
- data/app/assets/javascripts/releaf/controllers/base.js +0 -40
- data/app/assets/javascripts/releaf/include/field.type_date_or_datetime_or_time.js +43 -0
- data/app/assets/javascripts/releaf/include/nested_fields.js +58 -65
- data/app/assets/javascripts/releaf/include/sortable.js +19 -17
- data/app/assets/stylesheets/releaf/controllers/releaf/content.css.erb +6 -0
- data/app/assets/stylesheets/releaf/include/field.css.erb +37 -13
- data/app/controllers/releaf/admins_controller.rb +13 -6
- data/app/controllers/releaf/base_application_controller.rb +4 -1
- data/app/controllers/releaf/base_controller.rb +415 -154
- data/app/controllers/releaf/content_controller.rb +62 -45
- data/app/controllers/releaf/roles_controller.rb +11 -9
- data/app/controllers/releaf/sessions_controller.rb +23 -1
- data/app/controllers/releaf/translations_controller.rb +21 -25
- data/app/helpers/releaf/admin_helper.rb +0 -20
- data/app/models/releaf/admin.rb +9 -0
- data/app/models/releaf/blank_node_base.rb +29 -0
- data/app/models/releaf/node.rb +6 -5
- data/app/models/releaf/node_base.rb +9 -3
- data/app/models/releaf/role.rb +9 -2
- data/app/views/layouts/releaf/admin.html.haml +12 -6
- data/app/views/layouts/releaf/devise.html.haml +32 -0
- data/app/views/releaf/aliases/{_edit.body.haml → _edit.body.html.haml} +0 -0
- data/app/views/releaf/aliases/{_edit.header.haml → _edit.header.html.haml} +1 -1
- data/app/views/releaf/aliases/_index.row.html.haml +5 -0
- data/app/views/releaf/aliases/{_secondary_panel.haml → _secondary_panel.html.haml} +0 -0
- data/app/views/releaf/base/_edit.body.html.haml +11 -0
- data/app/views/releaf/base/_edit.field.html.haml +23 -0
- data/app/views/releaf/base/{_edit.field.type_autocomplete.haml → _edit.field_type_autocomplete.html.haml} +1 -1
- data/app/views/releaf/base/{_edit.field.type_checkbox.haml → _edit.field_type_boolean.html.haml} +1 -1
- data/app/views/releaf/base/{_edit.field.type_date.haml → _edit.field_type_date.html.haml} +0 -0
- data/app/views/releaf/base/{_edit.field.type_datetime.haml → _edit.field_type_datetime.html.haml} +0 -0
- data/app/views/releaf/base/{_edit.field.type_delete_nested.haml → _edit.field_type_delete_nested.html.haml} +0 -0
- data/app/views/releaf/base/{_edit.field.type_file.haml → _edit.field_type_file.html.haml} +0 -0
- data/app/views/releaf/base/_edit.field_type_image.html.haml +12 -0
- data/app/views/releaf/base/_edit.field_type_item.html.haml +31 -0
- data/app/views/releaf/base/{_edit.field.type_link.haml → _edit.field_type_link.html.haml} +0 -0
- data/app/views/releaf/base/_edit.field_type_link_i18n.html.haml +26 -0
- data/app/views/releaf/base/{_edit.field.type_password.haml → _edit.field_type_password.html.haml} +0 -0
- data/app/views/releaf/base/{_edit.field.type_richtext.haml → _edit.field_type_richtext.html.haml} +0 -0
- data/app/views/releaf/base/{_edit.field.type_richtext_i18n.haml → _edit.field_type_richtext_i18n.html.haml} +0 -0
- data/app/views/releaf/base/{_edit.field.type_text.haml → _edit.field_type_text.html.haml} +0 -0
- data/app/views/releaf/base/{_edit.field.type_text_i18n.haml → _edit.field_type_text_i18n.html.haml} +0 -0
- data/app/views/releaf/base/{_edit.field.type_textarea.haml → _edit.field_type_textarea.html.haml} +0 -0
- data/app/views/releaf/base/{_edit.field.type_textarea_i18n.haml → _edit.field_type_textarea_i18n.html.haml} +0 -0
- data/app/views/releaf/base/{_edit.field.type_time.haml → _edit.field_type_time.html.haml} +0 -0
- data/app/views/releaf/base/_edit.fields.association.html.haml +48 -0
- data/app/views/releaf/base/_edit.fields.has_many_template.html.haml +15 -0
- data/app/views/releaf/base/_edit.fields.html.haml +20 -0
- data/app/views/releaf/base/{_edit.footer.haml → _edit.footer.html.haml} +2 -2
- data/app/views/releaf/base/_edit.form.html.haml +4 -0
- data/app/views/releaf/base/_edit.header.html.haml +3 -0
- data/app/views/releaf/base/{_index.body.haml → _index.body.html.haml} +2 -2
- data/app/views/releaf/base/_index.cell.html.haml +20 -0
- data/app/views/releaf/base/_index.footer.html.haml +28 -0
- data/app/views/releaf/base/_index.header.html.haml +4 -0
- data/app/views/releaf/base/_index.row.html.haml +6 -0
- data/app/views/releaf/base/_index.search.html.haml +5 -0
- data/app/views/releaf/base/_index.table.html.haml +24 -0
- data/app/views/releaf/base/_secondary_panel.html.haml +10 -0
- data/app/views/releaf/base/_show.body.html.haml +3 -0
- data/app/views/releaf/base/_show.field.html.haml +20 -0
- data/app/views/releaf/base/_show.field_type_date.html.haml +9 -0
- data/app/views/releaf/base/_show.field_type_date_time.html.haml +9 -0
- data/app/views/releaf/base/_show.field_type_email.html.haml +6 -0
- data/app/views/releaf/base/_show.field_type_file.html.haml +7 -0
- data/app/views/releaf/base/_show.field_type_image.html.haml +10 -0
- data/app/views/releaf/base/_show.field_type_item.html.haml +11 -0
- data/app/views/releaf/base/_show.field_type_link.html.haml +14 -0
- data/app/views/releaf/base/_show.field_type_password.html.haml +6 -0
- data/app/views/releaf/base/_show.field_type_richtext.html.haml +6 -0
- data/app/views/releaf/base/_show.field_type_text.html.haml +6 -0
- data/app/views/releaf/base/_show.field_type_textarea.html.haml +6 -0
- data/app/views/releaf/base/_show.field_type_time.html.haml +9 -0
- data/app/views/releaf/base/_show.field_type_url.html.haml +7 -0
- data/app/views/releaf/base/_show.fields.association.html.haml +36 -0
- data/app/views/releaf/base/_show.fields.has_many_template.html.haml +12 -0
- data/app/views/releaf/base/_show.fields.html.haml +17 -0
- data/app/views/releaf/base/{_show.footer.haml → _show.footer.html.haml} +6 -4
- data/app/views/releaf/base/_show.header.html.haml +3 -0
- data/app/views/releaf/base/confirm_destroy.html.haml +17 -0
- data/app/views/releaf/base/edit.html.haml +1 -0
- data/app/views/releaf/base/index.html.haml +3 -0
- data/app/views/releaf/base/new.html.haml +1 -0
- data/app/views/releaf/base/show.html.haml +3 -0
- data/app/views/releaf/content/{_edit.body.haml → _edit.body.html.haml} +7 -6
- data/app/views/releaf/content/_edit.content_fields.html.haml +11 -0
- data/app/views/releaf/content/_edit.fields.html.haml +17 -0
- data/app/views/releaf/content/{_edit.slug.haml → _edit.slug.html.haml} +0 -0
- data/app/views/releaf/content/{_get_content_form.haml → _get_content_form.html.haml} +2 -2
- data/app/views/releaf/content/{_secondary_panel.haml → _secondary_panel.html.haml} +0 -0
- data/app/views/releaf/content/{_tree_level.haml → _tree_level.html.haml} +0 -0
- data/app/views/releaf/content/{ajax.new.haml → ajax.new.html.haml} +0 -0
- data/app/views/releaf/content/{index.haml → index.html.haml} +0 -0
- data/app/views/releaf/roles/_edit.field.permissions.html.haml +5 -0
- data/app/views/releaf/roles/{_show.field.default.haml → _show.field.default.html.haml} +1 -1
- data/app/views/releaf/roles/{_show.field.permissions.haml → _show.field.permissions.html.haml} +2 -2
- data/app/views/releaf/translations/{_edit.body.haml → _edit.body.html.haml} +0 -0
- data/app/views/releaf/translations/{_edit.header.haml → _edit.header.html.haml} +1 -1
- data/app/views/releaf/translations/_index.row.html.haml +5 -0
- data/app/views/releaf/translations/{_secondary_panel.haml → _secondary_panel.html.haml} +0 -0
- data/lib/generators/releaf/templates/initializers/releaf.rb +0 -39
- data/lib/generators/releaf/templates/initializers/releaf_i18n.rb +17 -0
- data/lib/generators/releaf/templates/javascripts/3rd_party/jquery.jcarousel.js +1058 -0
- data/lib/generators/releaf/templates/javascripts/lib/init_jcarousel.js +40 -0
- data/lib/generators/releaf/templates/migrations/create_releaf_roles.rb +1 -0
- data/lib/generators/releaf/templates/migrations/create_releaf_tinymce_assets.rb +1 -0
- data/lib/generators/releaf/templates/models/admin_ability.rb +1 -1
- data/lib/i18n/backend/releaf.rb +5 -4
- data/lib/i18n/backend/releaf/translation.rb +5 -0
- data/lib/i18n/backend/releaf/translation_data.rb +7 -0
- data/lib/i18n/backend/releaf/translation_group.rb +4 -0
- data/lib/releaf.rb +4 -0
- data/lib/releaf/boolean_at.rb +77 -0
- data/lib/releaf/globalize3/fallbacks.rb +19 -0
- data/lib/releaf/resources.rb +101 -0
- data/lib/releaf/slug.rb +99 -60
- data/lib/releaf/version.rb +1 -1
- data/spec/spec_helper.rb +6 -0
- data/templates/releaf/installer.rb +15 -4
- metadata +275 -329
- data/app/views/releaf/aliases/_index.row.haml +0 -5
- data/app/views/releaf/base/_edit.body.haml +0 -19
- data/app/views/releaf/base/_edit.field.haml +0 -96
- data/app/views/releaf/base/_edit.field.type_image.haml +0 -14
- data/app/views/releaf/base/_edit.field.type_select.haml +0 -11
- data/app/views/releaf/base/_edit.form.haml +0 -4
- data/app/views/releaf/base/_edit.has_many_associations.haml +0 -45
- data/app/views/releaf/base/_edit.header.haml +0 -3
- data/app/views/releaf/base/_index.cell.haml +0 -19
- data/app/views/releaf/base/_index.footer.haml +0 -22
- data/app/views/releaf/base/_index.header.haml +0 -4
- data/app/views/releaf/base/_index.row.haml +0 -6
- data/app/views/releaf/base/_index.search.haml +0 -5
- data/app/views/releaf/base/_index.table.haml +0 -8
- data/app/views/releaf/base/_secondary_panel.haml +0 -9
- data/app/views/releaf/base/_show.body.haml +0 -7
- data/app/views/releaf/base/_show.field.haml +0 -78
- data/app/views/releaf/base/_show.field.type_html.haml +0 -1
- data/app/views/releaf/base/_show.header.haml +0 -3
- data/app/views/releaf/base/confirm_destroy.haml +0 -10
- data/app/views/releaf/base/edit.haml +0 -1
- data/app/views/releaf/base/index.haml +0 -3
- data/app/views/releaf/base/new.haml +0 -1
- data/app/views/releaf/base/show.haml +0 -3
- data/app/views/releaf/content/_edit.content_fields.haml +0 -19
- data/app/views/releaf/content/_show.field.content.haml +0 -11
- data/app/views/releaf/roles/_edit.field.admins.haml +0 -0
- data/app/views/releaf/roles/_edit.field.permissions.haml +0 -5
- data/app/views/releaf/translations/_index.row.haml +0 -5
- data/spec/dummy/README.rdoc +0 -261
- data/spec/dummy/Rakefile +0 -7
- data/spec/dummy/app/assets/images/rails.png +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +0 -15
- data/spec/dummy/app/assets/stylesheets/application.css +0 -13
- data/spec/dummy/app/controllers/application_controller.rb +0 -3
- data/spec/dummy/app/helpers/application_helper.rb +0 -2
- data/spec/dummy/app/models/admin_ability.rb +0 -51
- data/spec/dummy/app/models/settings.rb +0 -2
- data/spec/dummy/app/views/layouts/application.html.haml +0 -10
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/config/application.rb +0 -68
- data/spec/dummy/config/boot.rb +0 -6
- data/spec/dummy/config/common_fields.yml.example +0 -17
- data/spec/dummy/config/database.yml +0 -42
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -37
- data/spec/dummy/config/environments/production.rb +0 -67
- data/spec/dummy/config/environments/test.rb +0 -37
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/devise.rb +0 -232
- data/spec/dummy/config/initializers/dragonfly.rb +0 -1
- data/spec/dummy/config/initializers/inflections.rb +0 -15
- data/spec/dummy/config/initializers/mime_types.rb +0 -5
- data/spec/dummy/config/initializers/releaf.rb +0 -59
- data/spec/dummy/config/initializers/releaf_i18n.rb +0 -8
- data/spec/dummy/config/initializers/releaf_store_current_template.rb +0 -25
- data/spec/dummy/config/initializers/secret_token.rb +0 -7
- data/spec/dummy/config/initializers/session_store.rb +0 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/devise.en.yml +0 -58
- data/spec/dummy/config/locales/en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -11
- data/spec/dummy/db/migrate/20130204164516_create_settings.rb +0 -17
- data/spec/dummy/db/migrate/20130204164523_create_releaf_nodes.rb +0 -25
- data/spec/dummy/db/migrate/20130204164524_create_releaf_roles.rb +0 -11
- data/spec/dummy/db/migrate/20130204164525_create_releaf_translations.rb +0 -31
- data/spec/dummy/db/migrate/20130204164526_create_releaf_admins.rb +0 -53
- data/spec/dummy/db/schema.rb +0 -112
- data/spec/dummy/db/seeds.rb +0 -64
- data/spec/dummy/doc/README_FOR_APP +0 -2
- data/spec/dummy/log/development.log +0 -74
- data/spec/dummy/log/test.log +0 -129
- data/spec/dummy/public/404.html +0 -26
- data/spec/dummy/public/422.html +0 -26
- data/spec/dummy/public/500.html +0 -25
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +0 -6
- data/spec/dummy/tmp/cache/9C5/660/settings%3Ai18n_updated_at +0 -1
@@ -0,0 +1,40 @@
|
|
1
|
+
//= require ../3rd_party/jquery.jcarousel
|
2
|
+
|
3
|
+
jQuery(document).ready(function() {
|
4
|
+
|
5
|
+
jQuery(document.body).on('initcarousel', function(e) {
|
6
|
+
var target = jQuery(e.target);
|
7
|
+
|
8
|
+
target.find('.carousel_wrap').each(function() {
|
9
|
+
var carousel_wrap = jQuery(this);
|
10
|
+
var carousel_controls_wrap = carousel_wrap.find('.carousel_controls');
|
11
|
+
var carousel_controls = carousel_controls_wrap.find('a[data-nr], button[data-nr]');
|
12
|
+
|
13
|
+
carousel_wrap.find('.jcarousel').jcarousel({
|
14
|
+
wrap: 'circular',
|
15
|
+
vertical: false,
|
16
|
+
scroll: 1,
|
17
|
+
buttonNextHTML: null,
|
18
|
+
buttonPrevHTML: null,
|
19
|
+
auto: 5,
|
20
|
+
itemVisibleInCallback: {
|
21
|
+
onBeforeAnimation: function (carousel, item, idx, state) {
|
22
|
+
var jitem = jQuery(item);
|
23
|
+
carousel_controls.removeClass('active');
|
24
|
+
jQuery(carousel_controls[jitem.attr('data-nr')]).addClass('active');
|
25
|
+
}
|
26
|
+
},
|
27
|
+
initCallback: function(carousel) {
|
28
|
+
carousel_controls_wrap.on('click', 'a[data-nr], button[data-nr]', function() {
|
29
|
+
var link = jQuery(this);
|
30
|
+
carousel.scroll(jQuery.jcarousel.intval(link.attr('data-nr')));
|
31
|
+
});
|
32
|
+
}
|
33
|
+
});
|
34
|
+
});
|
35
|
+
});
|
36
|
+
|
37
|
+
jQuery(document.body).trigger('initcarousel');
|
38
|
+
|
39
|
+
});
|
40
|
+
|
data/lib/i18n/backend/releaf.rb
CHANGED
@@ -40,7 +40,7 @@ module I18n
|
|
40
40
|
|
41
41
|
# Lookup translation from database
|
42
42
|
def lookup(locale, key, scope = [], options = {})
|
43
|
-
if scope.blank?
|
43
|
+
if scope.blank? && key !~ /\./
|
44
44
|
scope = DEFAULT_SCOPE
|
45
45
|
end
|
46
46
|
|
@@ -59,14 +59,15 @@ module I18n
|
|
59
59
|
keys_to_check_for_other_locales.push check_key
|
60
60
|
|
61
61
|
next if result.nil? # nothing in cache was found
|
62
|
-
return
|
62
|
+
return nil if result == false # found nil translaiton in cache
|
63
63
|
return result unless result.blank? # found translation in cache
|
64
64
|
end while chain.empty? == false
|
65
65
|
|
66
|
-
return
|
66
|
+
return nil if I18N_CACHE.read [:missing, [locale, check_key]]
|
67
|
+
I18N_CACHE.write([:missing, [locale, check_key]], true) if Translation.where('releaf_translations.key IN (?)', keys_to_check_for_other_locales).exists?
|
67
68
|
|
68
69
|
save_missing_translation(locale, key)
|
69
|
-
return
|
70
|
+
return nil
|
70
71
|
rescue ::ActiveRecord::StatementInvalid
|
71
72
|
# is the translations table missing?
|
72
73
|
nil
|
@@ -9,9 +9,14 @@ module I18n
|
|
9
9
|
|
10
10
|
validates_presence_of :group_id, :key
|
11
11
|
validates_uniqueness_of :key, :scope => :group_id
|
12
|
+
|
12
13
|
belongs_to :translation_group, :foreign_key => :group_id
|
13
14
|
has_many :translation_data, :dependent => :destroy, :class_name => 'Releaf::TranslationData'
|
14
15
|
|
16
|
+
attr_accessible \
|
17
|
+
:group_id,
|
18
|
+
:key
|
19
|
+
|
15
20
|
scope :joined, select('releaf_translations.*, releaf_translation_data.lang as "lang", releaf_translation_data.localization as "localization", releaf_translation_groups.scope as "scope"').
|
16
21
|
joins(:translation_data, :translation_group)
|
17
22
|
|
@@ -9,9 +9,16 @@ module I18n
|
|
9
9
|
|
10
10
|
validates_presence_of :translation_id, :lang
|
11
11
|
validates_uniqueness_of :translation_id, :scope => :lang
|
12
|
+
|
12
13
|
belongs_to :translation
|
13
14
|
|
15
|
+
attr_accessible \
|
16
|
+
:lang,
|
17
|
+
:localization,
|
18
|
+
:translation_id
|
19
|
+
|
14
20
|
scope :available_locales, where('lang IS NOT NULL').group(:lang).pluck(:lang)
|
21
|
+
|
15
22
|
after_commit :reload_cache
|
16
23
|
|
17
24
|
def text
|
data/lib/releaf.rb
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
module Releaf
|
2
|
+
# Adds boolean_at class method, that can be used to create boolean setter and
|
3
|
+
# getter for DateTime, Date and Time fields. It will also create scopes for
|
4
|
+
# when given attribute is set and when it is not set.
|
5
|
+
module BooleanAt
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
# Create boolean setter and getter for given DateTime, Date and Time
|
9
|
+
# attributes.
|
10
|
+
#
|
11
|
+
# Setter will accept "0", 0, false as false, everything else will
|
12
|
+
# evaluate to true. Setter accepts TrueClass, FalseClass, String, Fixnum.
|
13
|
+
# If you pass nil, it not change current value.
|
14
|
+
#
|
15
|
+
# Getter returns true or false
|
16
|
+
#
|
17
|
+
# Unless you add <tt>:without_scopes => true</tt> as last argument, two scopes
|
18
|
+
# will be created. One to list all resources with given attribute set and
|
19
|
+
# one that does the opposite.
|
20
|
+
#
|
21
|
+
# For example, if you use
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# boolean_at :published_at
|
25
|
+
#
|
26
|
+
# it will create +published+, +published?+, +published=+ methods and
|
27
|
+
# +published+ and +unpublished+ scopes.
|
28
|
+
#
|
29
|
+
# @param args list of DateTime, Date and Time attributes that ends with
|
30
|
+
# _at or _on for which you'd like to create boolean setter and getter
|
31
|
+
# and scopes
|
32
|
+
def boolean_at *args
|
33
|
+
options = {}
|
34
|
+
options = args.pop if args.last.is_a? Hash
|
35
|
+
|
36
|
+
my_table_name = self.table_name
|
37
|
+
|
38
|
+
args.each do |name|
|
39
|
+
# raise ArgumentError, "column must be of type DateTime, Date or Time" unless [:datetime, :date, :time].include?(self.columns_hash[name.to_s].try(:type).try(:to_sym))
|
40
|
+
raise ArgumentError, "column name must end with _at or _on" unless name =~ /_(at|on)$/
|
41
|
+
|
42
|
+
fun_name = name.to_s.sub(/_(at|on)$/, '')
|
43
|
+
|
44
|
+
# create getter
|
45
|
+
define_method fun_name do
|
46
|
+
self.send(:"#{name}?")
|
47
|
+
end
|
48
|
+
alias_method :"#{fun_name}?", :"#{fun_name}"
|
49
|
+
|
50
|
+
# create setter
|
51
|
+
define_method :"#{fun_name}=" do |b|
|
52
|
+
return if b.nil?
|
53
|
+
raise ArgumentError unless b.is_a?(FalseClass) or b.is_a?(TrueClass) or b.is_a?(String) or b.is_a?(Fixnum)
|
54
|
+
if b == false or b == "0" or b == 0
|
55
|
+
self.send(:"#{name}=", nil)
|
56
|
+
else
|
57
|
+
self.send(:"#{name}=", Time.now)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
unless options[:without_scopes]
|
62
|
+
# create scopes
|
63
|
+
self.class_eval do
|
64
|
+
scope "#{fun_name}", where("#{my_table_name}.#{name} IS NOT NULL")
|
65
|
+
scope "un#{fun_name}", where("#{my_table_name}.#{name} IS NULL")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.included base
|
74
|
+
base.extend ClassMethods
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Releaf
|
2
|
+
module Globalize3
|
3
|
+
module Fallbacks
|
4
|
+
def self.set
|
5
|
+
i18n_fallbacks = {}
|
6
|
+
|
7
|
+
I18n.default_locale ||= 'en'
|
8
|
+
I18n.locale ||= 'en'
|
9
|
+
|
10
|
+
valid_locales = Settings.i18n_locales || []
|
11
|
+
|
12
|
+
(valid_locales + [I18n.default_locale, I18n.locale]).uniq.each do |locale|
|
13
|
+
i18n_fallbacks[locale] = valid_locales - [locale]
|
14
|
+
end
|
15
|
+
Globalize.fallbacks = i18n_fallbacks
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'action_dispatch/routing/mapper'
|
2
|
+
|
3
|
+
module ActionDispatch::Routing
|
4
|
+
class Mapper
|
5
|
+
|
6
|
+
def releaf_resources(*args, &block)
|
7
|
+
resources *args do
|
8
|
+
yield if block_given?
|
9
|
+
|
10
|
+
add_urls = true
|
11
|
+
add_confirm_destroy = true
|
12
|
+
|
13
|
+
if args.last.is_a? Hash
|
14
|
+
options = args.last
|
15
|
+
if options.has_key? :only
|
16
|
+
add_urls = false unless options[:only].include? :urls
|
17
|
+
add_confirm_destroy = false unless options[:only].include? :destroy
|
18
|
+
end
|
19
|
+
|
20
|
+
if options.has_key? :except
|
21
|
+
add_urls = false if options[:except].include? :urls
|
22
|
+
add_confirm_destroy = false if options[:except].include? :destroy
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
match :urls, :on => :collection if add_urls
|
27
|
+
get :confirm_destroy, :on => :member if add_confirm_destroy
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def slugged_resources(*args, &block)
|
32
|
+
add_routes = {
|
33
|
+
:new => true,
|
34
|
+
:create => true,
|
35
|
+
:edit => true,
|
36
|
+
:update => true,
|
37
|
+
:show => true,
|
38
|
+
:index => true,
|
39
|
+
:destroy => true
|
40
|
+
}
|
41
|
+
|
42
|
+
new_resources = args
|
43
|
+
|
44
|
+
if args.last.is_a? Hash
|
45
|
+
|
46
|
+
options = new_resources.pop
|
47
|
+
|
48
|
+
if options.has_key? :only
|
49
|
+
add_routes.each_key do |key|
|
50
|
+
add_routes[key] = false unless options[:only].include? key
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
if options.has_key? :except
|
55
|
+
add_routes.each_key do |key|
|
56
|
+
add_routes[key] = false if options[:only].include? key
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
new_resources.each do |resource_name|
|
63
|
+
res_name = resource_name.to_s
|
64
|
+
get res_name, :to => "#{res_name}#index", :as => res_name if add_routes[:index]
|
65
|
+
post res_name, :to => "#{res_name}#create" if add_routes[:create]
|
66
|
+
get "#{res_name}/new", :to => "#{res_name}#new", :as => "new_#{res_name.singularize}" if add_routes[:new]
|
67
|
+
yield if block_given?
|
68
|
+
get "#{res_name}/*slug/edit", :to => "#{res_name}#edit", :as => "edit_#{res_name.singularize}" if add_routes[:edit]
|
69
|
+
get "#{res_name}/*slug", :to => "#{res_name}#show", :as => "show_#{res_name.singularize}" if add_routes[:show]
|
70
|
+
put "#{res_name}/*slug", :to => "#{res_name}#update" if add_routes[:update]
|
71
|
+
post "#{res_name}/*slug", :to => "#{res_name}#create" if add_routes[:create]
|
72
|
+
delete "#{res_name}/*slug", :to => "#{res_name}#destroy" if add_routes[:destroy]
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
def mount_releaf_at mount_location
|
78
|
+
|
79
|
+
post '/tinymce_assets' => 'releaf/tinymce_assets#create'
|
80
|
+
|
81
|
+
devise_for Releaf.devise_for, :path => mount_location, :controllers => { :sessions => "releaf/sessions" }
|
82
|
+
|
83
|
+
scope mount_location do
|
84
|
+
namespace :releaf, :path => nil do
|
85
|
+
|
86
|
+
releaf_resources :admins, :roles
|
87
|
+
|
88
|
+
releaf_resources :nodes, :controller => "content", :path => "content", :except => [:show], :path_names => { :edit => '' } do
|
89
|
+
get :generate_url, :on => :collection
|
90
|
+
end
|
91
|
+
|
92
|
+
releaf_resources :translation_groups, :controller => "translations", :path => "translations", :except => [:show], :path_names => { :edit => '' }
|
93
|
+
|
94
|
+
root :to => "content#index"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
end # class Mapper
|
101
|
+
end # module ActionDispatch::Routing
|
data/lib/releaf/slug.rb
CHANGED
@@ -1,79 +1,118 @@
|
|
1
1
|
module Releaf
|
2
|
+
# Provides common methods for finding object by slug. Also overrides to_html
|
3
|
+
# method.
|
4
|
+
#
|
5
|
+
# Simply add this line to your models
|
6
|
+
#
|
7
|
+
# include Releaf::Slug
|
8
|
+
#
|
9
|
+
# or
|
10
|
+
#
|
11
|
+
# ActiveRecord::Base.send(:include, Releaf::Slug)
|
12
|
+
#
|
13
|
+
# to some initializer (<tt>config/initializers/releaf.rb</tt> for example).
|
14
|
+
# Then use find_object or find_object! instead of find
|
2
15
|
module Slug
|
3
|
-
|
4
|
-
base.class_eval {
|
16
|
+
module ClassMethods
|
5
17
|
|
6
|
-
|
7
|
-
|
18
|
+
# same as find_object, except that it will raise
|
19
|
+
# ActiveRecord::RecordNotFound error if no resource was found.
|
20
|
+
def find_object! id_or_slug, scope_name=nil, scope_args=nil
|
21
|
+
obj = find_object(id_or_slug, scope_name, scope_args)
|
22
|
+
raise ActiveRecord::RecordNotFound unless obj
|
23
|
+
return obj
|
24
|
+
end
|
8
25
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
26
|
+
# Find object by slug or id.
|
27
|
+
#
|
28
|
+
# If id_or_slug looks like id, then tries to find by id first
|
29
|
+
# Otherwise it will search by slug field.
|
30
|
+
#
|
31
|
+
# If instance responds to children method, then it's possible to search
|
32
|
+
# for hierarchic resources
|
33
|
+
#
|
34
|
+
# @param id_or_slug either id of object to find (can be String or Fixnum)
|
35
|
+
# or slug (string) slug, may contain slash ('/')
|
36
|
+
#
|
37
|
+
# @param scope_name optional scope_name to be used for searching. This is
|
38
|
+
# especially useful when you are searching hierarchic resources. For
|
39
|
+
# example you want to find 2nd level active resource.
|
40
|
+
#
|
41
|
+
# @param scope_args any arguments that are required for scope
|
42
|
+
#
|
43
|
+
# @return resource
|
44
|
+
def find_object id_or_slug, scope_name=nil, scope_args=nil
|
45
|
+
raise ArgumentError, "id_or_slug must be String or Fixnum" unless id_or_slug.is_a?(String) or id_or_slug.is_a?(Fixnum)
|
16
46
|
|
17
|
-
|
47
|
+
unless column_names.include?('slug')
|
48
|
+
return scoped_for_find_by_slug(self, scope_name, scope_args).find(id_or_slug)
|
49
|
+
end
|
18
50
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
obj = self.send(scope).find_by_id(id_or_slug)
|
25
|
-
end
|
26
|
-
end
|
51
|
+
# if it looks like id, search by id first
|
52
|
+
if id_or_slug.to_s =~ /\A\d+\z/
|
53
|
+
obj = scoped_for_find_by_slug(self, scope_name, scope_args).find_by_id(id_or_slug)
|
54
|
+
return obj if obj
|
55
|
+
end
|
27
56
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
else
|
33
|
-
obj = self.send(scope).find_by_slug(id_or_slug)
|
34
|
-
end
|
35
|
-
else
|
36
|
-
slugs = id_or_slug.split('/')
|
37
|
-
if scope.blank?
|
38
|
-
obj = self.find_by_slug( slugs.shift )
|
39
|
-
else
|
40
|
-
obj = self.send(scope).find_by_slug( slugs.shift )
|
41
|
-
end
|
42
|
-
raise ActiveRecord::RecordNotFound unless obj
|
43
|
-
slugs.each do |slug_part|
|
44
|
-
if scope.blank?
|
45
|
-
obj = obj.children.find_by_slug(slug_part)
|
46
|
-
else
|
47
|
-
obj = obj.children.send(scope).find_by_slug(slug_part)
|
48
|
-
end
|
49
|
-
raise ActiveRecord::RecordNotFound unless obj
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
57
|
+
unless column_names.include?('ancestry') || self.new.respond_to?(:children)
|
58
|
+
return scoped_for_find_by_slug(self, scope_name, scope_args).find_by_slug(id_or_slug)
|
59
|
+
else
|
60
|
+
slugs = id_or_slug.split('/')
|
53
61
|
|
54
|
-
|
62
|
+
obj = scoped_for_find_by_slug(self, scope_name, scope_args).find_by_slug( slugs.shift )
|
63
|
+
return nil unless obj
|
64
|
+
slugs.each do |slug_part|
|
65
|
+
obj = scoped_for_find_by_slug(obj.children, scope_name, scope_args).find_by_slug( slug_part )
|
66
|
+
return nil unless obj
|
67
|
+
end
|
55
68
|
return obj
|
56
69
|
end
|
70
|
+
end
|
57
71
|
|
58
|
-
|
59
|
-
return id unless self.class.column_names.include?('slug')
|
60
|
-
return id if self.slug.blank?
|
61
|
-
col_names = self.class.column_names
|
72
|
+
private
|
62
73
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
return parent.to_param + '/' + slug
|
68
|
-
else
|
69
|
-
return slug
|
70
|
-
end
|
74
|
+
def scoped_for_find_by_slug obj, scope_name=nil, scope_args=nil
|
75
|
+
unless scope_name.blank?
|
76
|
+
if scope_args.nil?
|
77
|
+
obj.send(scope_name.to_sym)
|
71
78
|
else
|
72
|
-
|
79
|
+
obj.send(scope_name.to_sym, *scope_args)
|
73
80
|
end
|
81
|
+
else
|
82
|
+
obj
|
74
83
|
end
|
75
|
-
|
84
|
+
end
|
76
85
|
|
77
86
|
end
|
87
|
+
|
88
|
+
|
89
|
+
module InstanceMethods
|
90
|
+
# Ovverrides to_param method to prefer slug field over id (when
|
91
|
+
# possible). It will also generate hearachical uri part if instance
|
92
|
+
# supports parrent method, or has ancestry column (ancestry gem
|
93
|
+
# {http://rubygems.org/gems/ancestry})
|
94
|
+
#
|
95
|
+
# @return String or Fixnum
|
96
|
+
def to_param
|
97
|
+
return id unless self.class.column_names.include?('slug')
|
98
|
+
return id if self.slug.blank?
|
99
|
+
col_names = self.class.column_names
|
100
|
+
|
101
|
+
if col_names.include?('ancestry')
|
102
|
+
return path.pluck(:slug).join('/')
|
103
|
+
elsif self.respond_to?(:parent) && parent
|
104
|
+
return parent.to_param + '/' + slug
|
105
|
+
else
|
106
|
+
return slug
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
def self.included base
|
113
|
+
base.extend ClassMethods
|
114
|
+
include InstanceMethods
|
115
|
+
end
|
116
|
+
|
78
117
|
end
|
79
118
|
end
|