alchemy-custom-model 2.1.2 → 2.2.0

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 (42) hide show
  1. checksums.yaml +5 -5
  2. data/app/assets/javascripts/alchemy-custom-model/alchemy_custom_model_select.js +62 -0
  3. data/app/assets/javascripts/alchemy-custom-model/common_init.js +17 -14
  4. data/app/assets/javascripts/alchemy-custom-model/el_finder.js.coffee.erb +31 -0
  5. data/app/assets/javascripts/alchemy-custom-model/manifest.js +5 -0
  6. data/app/assets/javascripts/backend/date_picker.js +24 -0
  7. data/app/assets/javascripts/backend/fix_more_image_in_element.js.coffee +10 -0
  8. data/app/assets/javascripts/backend/override_alchemy_selectbox.js +8 -0
  9. data/app/assets/stylesheets/alchemy-custom-model/custom_elfinder.css.scss +20 -2
  10. data/app/controllers/alchemy/custom/model/admin/base_controller.rb +3 -0
  11. data/app/controllers/alchemy/custom/model/admin/base_with_globalize_controller.rb +38 -0
  12. data/app/controllers/concerns/alchemy/admin/nodes_controller_dec.rb +55 -0
  13. data/app/helpers/alchemy/custom/model/admin/base_helper.rb +5 -2
  14. data/app/helpers/alchemy/pages_helper_decorator.rb +38 -0
  15. data/app/models/concerns/alchemy/node_dec.rb +45 -0
  16. data/app/views/alchemy/admin/nodes/_form.html.erb +126 -0
  17. data/app/views/alchemy/admin/nodes/custom_models.json.jbuilder +10 -0
  18. data/app/views/alchemy/admin/nodes/custom_models_methods.json.jbuilder +10 -0
  19. data/app/views/alchemy/admin/pictures/_custom_model_info.html.erb +27 -0
  20. data/app/views/alchemy/admin/pictures/_infos.html.erb +65 -0
  21. data/app/views/alchemy/custom/model/admin/base/_gallery_item.html.erb +7 -2
  22. data/app/views/alchemy/custom/model/admin/base/_seo.html.erb +5 -5
  23. data/app/views/alchemy/custom/model/admin/base/_title.html.erb +1 -1
  24. data/app/views/alchemy/custom/model/admin/base/edit.html.erb +2 -2
  25. data/app/views/alchemy/custom/model/admin/base/index.html.erb +1 -1
  26. data/app/views/alchemy/custom/model/admin/base/new.html.erb +2 -2
  27. data/app/views/alchemy/custom/model/admin/base/show.html.erb +2 -2
  28. data/config/locales/it.yml +6 -0
  29. data/config/routes.rb +16 -0
  30. data/db/migrate/20200424184007_add_fields_to_node.rb +8 -0
  31. data/lib/{alchemy-custom-model.rb → alchemy/custom/model.rb} +20 -0
  32. data/lib/alchemy/custom/model/engine.rb +7 -1
  33. data/lib/alchemy/custom/model/globalize_model_decoration.rb +25 -0
  34. data/lib/alchemy/custom/model/menu_methods.rb +16 -0
  35. data/lib/alchemy/custom/model/model_decoration.rb +2 -0
  36. data/lib/alchemy/custom/model/model_utils_methods.rb +28 -0
  37. data/lib/alchemy/custom/model/picture_used_by.rb +51 -0
  38. data/lib/alchemy/custom/model/slug_optimizer.rb +23 -0
  39. data/lib/alchemy/custom/model/version.rb +1 -1
  40. data/lib/tasks/alchemy_custom_model_tasks.rake +3 -0
  41. data/vendor/assets/javascripts/flatpickr/i10n/it.js +71 -0
  42. metadata +53 -7
@@ -0,0 +1,126 @@
1
+ <%= alchemy_form_for([:admin, node]) do |f| %>
2
+
3
+ <% if node.root? %>
4
+
5
+ <% if Alchemy::Node.respond_to? :available_menu_names %>
6
+ <%= f.input :name,
7
+ collection: Alchemy::Node.available_menu_names.map { |n| [I18n.t(n, scope: [:alchemy, :menu_names]), n] },
8
+ include_blank: false,
9
+ input_html: {class: 'alchemy_selectbox'} %>
10
+ <% else %>
11
+ <%= f.input :name, input_html: {
12
+ autofocus: true,
13
+ value: node.page && node.read_attribute(:name).blank? ? nil : node.name,
14
+ placeholder: node.page ? node.page.name : nil
15
+ } %>
16
+ <% end %>
17
+
18
+ <% else %>
19
+
20
+ <%= f.input :name, as: :string, input_html: {
21
+ autofocus: true,
22
+ value: node.page && node.read_attribute(:name).blank? ? nil : node.name,
23
+ placeholder: node.page ? node.page.name : nil
24
+ } %>
25
+
26
+ <%
27
+ active_klass = (node.errors.keys.include? :custom_model_klass or
28
+ node.custom_model?) ? "ui-tabs-active" : ""
29
+ %>
30
+
31
+ <div class="container_selctor_age_custom_model">
32
+ <div id="tabs_nodes" class="ui-tabs ui-corner-all ui-widget ui-widget-content">
33
+ <ul role="tablist" class="ui-tabs-nav ui-corner-all ui-helper-reset ui-helper-clearfix ui-widget-header">
34
+ <li role="tab" tabindex="0" class="ui-tabs-tab ui-corner-top ui-state-default ui-tab">
35
+ <a href="#pages" role="presentation" tabindex="-1" class="ui-tabs-anchor" id="ui-id-1">
36
+ <%= Alchemy.t(:pages_select) %>
37
+ </a>
38
+ </li>
39
+ <li role="tab" tabindex="1" class="ui-tabs-tab ui-corner-top ui-tab <%= active_klass %>">
40
+ <a href="#custom_models" role="presentation" tabindex="1" class="ui-tabs-anchor" id="ui-id-2">
41
+ <%= Alchemy.t(:custom_models) %>
42
+ </a>
43
+ </li>
44
+ </ul>
45
+ <div id="custom_models" aria-labelledby="legacy_urls_label" role="tabpanel" class="ui-tabs-panel ui-corner-bottom ui-widget-content" aria-hidden="false">
46
+ <%= f.input :custom_model_klass, input_html: {class: 'alchemy_selectbox'} %>
47
+ <%= f.input :custom_model_method, input_html: {class: 'alchemy_selectbox'} %>
48
+ </div>
49
+ <div id="pages" aria-labelledby="ui-id-1" role="tabpanel" class="ui-tabs-panel ui-corner-bottom ui-widget-content" aria-hidden="false">
50
+ <%= f.input :page_id, label: Alchemy::Page.model_name.human, input_html: {class: 'alchemy_selectbox'} %>
51
+ <%= f.input :url, input_html: {disabled: node.page}, hint: Alchemy.t(:node_url_hint) %>
52
+ <%= f.input :title %>
53
+ <%= f.input :nofollow %>
54
+ <%= f.input :external %>
55
+ <%= f.hidden_field :parent_id %>
56
+ </div>
57
+
58
+ </div>
59
+ </div>
60
+
61
+
62
+
63
+
64
+
65
+
66
+ <% end %>
67
+ <% if node.respond_to? :site_id %>
68
+ <%= f.hidden_field :site_id %>
69
+ <% end %>
70
+ <% if node.respond_to? :language_id %>
71
+ <%= f.hidden_field :language_id %>
72
+ <% end %>
73
+ <%= f.submit button_label %>
74
+ <% end %>
75
+
76
+ <script>
77
+
78
+ $("#tabs_nodes").tabs();
79
+
80
+
81
+ $('#node_custom_model_klass').alchemyCustomModelSelect({
82
+ placeholder: "<%= Alchemy.t(:select_custom_model_method) %>",
83
+ url: "<%= alchemy.custom_models_admin_nodes_path %>",
84
+
85
+ }).on("change", function (event) {
86
+ $('#node_custom_model_method').select2('enable');
87
+
88
+ }).on("select2-removed", function (e) {
89
+ $('#node_custom_model_method').val(null).trigger("change");
90
+ })
91
+
92
+
93
+ $('#node_custom_model_method').alchemyCustomModelSelect({
94
+ placeholder: "<%= Alchemy.t(:select_custom_model) %>",
95
+ url: "<%= alchemy.custom_models_methods_admin_nodes_path %>",
96
+ query_params: function (term, page) {
97
+ var klass = $('#node_custom_model_klass').val()
98
+ return {
99
+ custom_model_klass: klass
100
+ }
101
+ }
102
+
103
+ })
104
+
105
+ $('#node_custom_model_method').select2('disable');
106
+
107
+ $('#node_page_id').alchemyPageSelect({
108
+ placeholder: "<%= Alchemy.t(:search_page) %>",
109
+ url: "<%= alchemy.api_pages_path %>",
110
+ <% if node.page %>
111
+ initialSelection: {
112
+ id: <%= node.page_id %>,
113
+ text: "<%= node.page.name %>",
114
+ url: "/<%= node.page.urlname %>"
115
+ }
116
+ <% end %>
117
+ }).on('change', function (e) {
118
+ if (e.val === '') {
119
+ $('#node_name').removeAttr('placeholder')
120
+ $('#node_url').val('').prop('disabled', false)
121
+ } else {
122
+ $('#node_name').attr('placeholder', e.added.name)
123
+ $('#node_url').val('/' + e.added.urlname).prop('disabled', true)
124
+ }
125
+ })
126
+ </script>
@@ -0,0 +1,10 @@
1
+
2
+ json.meta do
3
+ json.total_count @custom_model_klasses.count
4
+ json.page params[:page]
5
+ json.per_page 10
6
+ end
7
+ json.results @custom_model_klasses do |result|
8
+ json.id result
9
+ json.text result
10
+ end
@@ -0,0 +1,10 @@
1
+
2
+ json.meta do
3
+ json.total_count @custom_model_methods.count
4
+ json.page params[:page]
5
+ json.per_page 10
6
+ end
7
+ json.results @custom_model_methods do |result|
8
+ json.id result
9
+ json.text result
10
+ end
@@ -0,0 +1,27 @@
1
+ <div class="picture-usage-info resource_info">
2
+ <h3>
3
+ <%= I18n.t(:image_used_in_this_models, scope: :alchemy_custom_model) %>
4
+ </h3>
5
+ <div id="pictures_page_list">
6
+ <% used_in = Alchemy::Custom::Model::PictureUsedBy.used_by(@picture.id)%>
7
+ <% if used_in.any? %>
8
+ <ul>
9
+ <% used_in.each do |m| %>
10
+ <li>
11
+ <% begin %>
12
+ <h3>
13
+ <%= render_icon 'file-alt' %>
14
+ <p><%= link_to "#{m.model_name.human}, #{m.try(:slug).to_s}", main_app.edit_polymorphic_path([:admin, m]) %></p>
15
+ </h3>
16
+ <% rescue %>
17
+ <% end %>
18
+ </li>
19
+ <% end %>
20
+ </ul>
21
+ <% else %>
22
+ <%= render_message do %>
23
+ <%= Alchemy.t(:picture_not_in_use_yet) %>
24
+ <% end %>
25
+ <% end %>
26
+ </div>
27
+ </div>
@@ -0,0 +1,65 @@
1
+ <div class="resource_info">
2
+ <div class="picture-file-infos">
3
+ <div class="value">
4
+ <label><%= Alchemy::Picture.human_attribute_name(:image_file_name) %></label>
5
+ <p><%= @picture.image_file_name %></p>
6
+ </div>
7
+ <div class="value">
8
+ <label><%= Alchemy::Picture.human_attribute_name(:image_file_dimensions) %></label>
9
+ <p><%= @picture.image_file_dimensions %>px</p>
10
+ </div>
11
+ <div class="value">
12
+ <label><%= Alchemy::Picture.human_attribute_name(:image_file_size) %></label>
13
+ <p><%= number_to_human_size @picture.image_file_size %></p>
14
+ </div>
15
+ </div>
16
+ </div>
17
+
18
+ <div class="picture-usage-info resource_info">
19
+ <h3>
20
+ <%= Alchemy.t(:this_picture_is_used_on_these_pages) %>
21
+ </h3>
22
+ <div id="pictures_page_list">
23
+ <% if @assignments.any? %>
24
+ <ul>
25
+ <% @assignments.group_by(&:page).each do |page, essence_pictures| %>
26
+ <% if page %>
27
+ <li>
28
+ <h3>
29
+ <%= render_icon 'file-alt' %>
30
+ <p><%= link_to page.name, edit_admin_page_path(page) %></p>
31
+ </h3>
32
+ <ul class="list">
33
+ <% essence_pictures.group_by(&:element).each do |element, essence_pictures| %>
34
+ <li class="<%= cycle('even', 'odd') %>">
35
+ <% page_link = link_to element.display_name_with_preview_text,
36
+ edit_admin_page_path(page, anchor: "element_#{element.id}") %>
37
+ <% pictures = essence_pictures.collect do |e|
38
+ e.content.name_for_label
39
+ end.to_sentence %>
40
+ <% if element.public? %>
41
+ <%= render_icon('window-maximize', style: 'regular') %>
42
+ <% else %>
43
+ <%= render_icon('window-close') %>
44
+ <% end %>
45
+ <p>
46
+ <%== Alchemy.t(:pictures_in_page, page: page_link, pictures: pictures) %>
47
+ <em><%= Alchemy::Element.human_attribute_name(:trashed) if element.trashed? %></em>
48
+ </p>
49
+ </li>
50
+ <% end %>
51
+ </ul>
52
+ </li>
53
+ <% end %>
54
+ <% end %>
55
+ </ul>
56
+ <% else %>
57
+ <%= render_message do %>
58
+ <%= Alchemy.t(:picture_not_in_use_yet) %>
59
+ <% end %>
60
+ <% end %>
61
+ </div>
62
+ </div>
63
+
64
+ <%= render partial: "custom_model_info" %>
65
+
@@ -1,4 +1,9 @@
1
- <div class="gallery_item_blk">
2
- <%= image_tag(picture.image_file.thumb("100x100#").url) %>
1
+ <div class="gallery_item_blk" data-id="<%= jr_id %>">
2
+ <%= image_tag(picture.image_file.thumb("140x140#").url) %>
3
3
  <%= yield if block_given? %>
4
+ <div class="command_area">
5
+ <div class="destroy">
6
+ <i class="fas fa-times fa-lg fa-fw"></i>
7
+ </div>
8
+ </div>
4
9
  </div>
@@ -1,8 +1,8 @@
1
1
  <fieldset>
2
2
  <legend><%= t(:seo_fields)%></legend>
3
- <%= f.input :meta_title %>
4
- <%= f.input :meta_description %>
5
- <%= f.input :meta_keywords %>
6
- <%= f.input :robot_follow %>
7
- <%= f.input :robot_index %>
3
+ <%= f.input :meta_title, as: :string %>
4
+ <%= f.input :meta_description, as: :text%>
5
+ <%= f.input :meta_keywords, as: :text %>
6
+ <%= f.input :robot_follow, as: :boolean %>
7
+ <%= f.input :robot_index, as: :boolean %>
8
8
  </fieldset>
@@ -1,3 +1,3 @@
1
1
  <h1>
2
- <%= t(:title_action, action: t(action_name, scope: :actions), model: base_class.model_name.human) %>
2
+ <%= acm_t(:title_action, action: acm_t(action_name, scope: :actions), model: base_class.model_name.human) %>
3
3
  </h1>
@@ -2,9 +2,9 @@
2
2
  buttons: [
3
3
  {
4
4
  icon: "angle-double-left ",
5
- label: t(:title_action, action: t(:index, scope: :actions), model: base_class.model_name.human),
5
+ label: acm_t(:title_action, action: acm_t(:index, scope: :actions), model: base_class.model_name.human),
6
6
  url: polymorphic_path(url_namespace),
7
- title: t(:title_action, action: t(:index, scope: :actions), model: base_class.model_name.human),
7
+ title: acm_t(:title_action, action: acm_t(:index, scope: :actions), model: base_class.model_name.human),
8
8
  hotkey: 'alt+b',
9
9
  dialog: false,
10
10
  if_permitted_to: [:index, @obj.class]
@@ -65,7 +65,7 @@
65
65
 
66
66
  <div id="archive_all" class="resources-table-wrapper">
67
67
 
68
- <%= content_tag :h1, "#{@objects.count} #{base_class.model_name.human(count: @objects.count)}", class: 'resources-header' %>
68
+ <%= content_tag :h1, "#{@total_objects.count} #{base_class.model_name.human(count: @objects.count)}", class: 'resources-header' %>
69
69
 
70
70
 
71
71
  <%= render partial: "table" %>
@@ -2,9 +2,9 @@
2
2
  buttons: [
3
3
  {
4
4
  icon: "angle-double-left ",
5
- label: acm_t(:title_action, action: t(:index, scope: :actions), model: base_class.model_name.human),
5
+ label: acm_t(:title_action, action: acm_t(:index, scope: :actions), model: base_class.model_name.human),
6
6
  url: polymorphic_path(url_namespace),
7
- title: acm_t(:title_action, action: t(:index, scope: :actions), model: base_class.model_name.human),
7
+ title: acm_t(:title_action, action: acm_t(:index, scope: :actions), model: base_class.model_name.human),
8
8
  hotkey: 'alt+b',
9
9
  dialog: false,
10
10
  if_permitted_to: [:index, @obj.class]
@@ -3,9 +3,9 @@
3
3
 
4
4
  buttons << {
5
5
  icon: "angle-double-left ",
6
- label: acm_t(:title_action, action: t(:index, scope: :actions), model: base_class.model_name.human),
6
+ label: acm_t(:title_action, action: acm_t(:index, scope: :actions), model: base_class.model_name.human),
7
7
  url: polymorphic_path(url_namespace),
8
- title: acm_t(:title_action, action: t(:index, scope: :actions), model: base_class.model_name.human),
8
+ title: acm_t(:title_action, action: acm_t(:index, scope: :actions), model: base_class.model_name.human),
9
9
  hotkey: 'alt+b',
10
10
  dialog: false,
11
11
  if_permitted_to: [:index, @obj.class]
@@ -19,3 +19,9 @@ it:
19
19
  minimize_all: Minimizza
20
20
  maxzimize_all: Massimizza
21
21
 
22
+ image_used_in_this_models: Immagine usata nei seguenti modelli
23
+
24
+ alchemy:
25
+ custom_models: Custom Models
26
+ pages_select: Pagine
27
+
@@ -6,3 +6,19 @@ Alchemy::Custom::Model::Engine.routes.draw do
6
6
  end
7
7
 
8
8
  end
9
+
10
+
11
+ Alchemy::Engine.routes.draw do
12
+
13
+ if "Alchemy::Node".safe_constantize
14
+ namespace :admin do
15
+ resources :nodes do
16
+ collection do
17
+ get :custom_models, defaults: {format: 'json'}, constraints: {format: :json}
18
+ get :custom_models_methods, defaults: {format: 'json'}, constraints: {format: :json}
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,8 @@
1
+ class AddFieldsToNode < ActiveRecord::Migration[5.2]
2
+ def change
3
+ if "Alchemy::Node".safe_constantize
4
+ add_column :alchemy_nodes, :custom_model_klass, :string
5
+ add_column :alchemy_nodes, :custom_model_method, :string
6
+ end
7
+ end
8
+ end
@@ -2,26 +2,46 @@ require "alchemy_cms"
2
2
  require "jquery/ui/rails"
3
3
  require "el_finder"
4
4
  require "friendly_id"
5
+ require "globalize"
6
+ require 'friendly_id/globalize'
5
7
  require "active_type"
6
8
  require "alchemy/custom/model/engine"
7
9
 
8
10
 
9
11
  module Alchemy
12
+ extend ActiveSupport::Autoload
13
+ autoload :NodeDec
14
+
15
+ module Admin
16
+ extend ActiveSupport::Autoload
17
+ autoload :NodesControllerDec
18
+ end
19
+
20
+
10
21
  module Custom
11
22
  module Model
12
23
  extend ActiveSupport::Autoload
13
24
 
14
25
  autoload :ElFinder
15
26
  autoload :GlobalIdSetter
27
+ autoload :MenuMethods
28
+ autoload :SlugOptimizer
16
29
  autoload :ModelDecoration
17
30
  autoload :TranslationScope
18
31
  autoload :PagesControllerDec
32
+ autoload :PictureUsedBy
33
+ autoload :ModelUtilsMethod
34
+ autoload :GlobalizeModelDecoration
35
+
19
36
 
20
37
 
21
38
  mattr_accessor :base_admin_controller_class
22
39
 
23
40
  @@base_admin_controller_class = 'Alchemy::Admin::BaseController'
24
41
 
42
+ mattr_accessor :allowed_custom_models_for_menu
43
+ @@allowed_custom_models_for_menu = []
44
+
25
45
 
26
46
  def self.admin_controller_class
27
47
  @@base_admin_controller_class.constantize
@@ -20,9 +20,15 @@ module Alchemy
20
20
 
21
21
  Alchemy::PagesController.include(PagesControllerDec)
22
22
 
23
+
24
+ if "Alchemy::Node".safe_constantize
25
+ Alchemy::Node.include Alchemy::NodeDec
26
+ Alchemy::Admin::NodesController.include Alchemy::Admin::NodesControllerDec
27
+ end
28
+
23
29
  # load degli helpers per alchemy
24
30
  [
25
- Alchemy::Custom::Model::Engine.root.join('app', 'helpers', 'alchemy', 'pages_helper_decorator.rb')
31
+ Alchemy::Custom::Model::Engine.root.join('app', 'helpers', 'alchemy', 'pages_helper_decorator.rb')
26
32
  ].each do |f|
27
33
  Rails.configuration.cache_classes ? require(f) : load(f)
28
34
  end
@@ -0,0 +1,25 @@
1
+ module Alchemy::Custom::Model
2
+ module GlobalizeModelDecoration
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+
7
+ include GlobalIdSetter
8
+ include MenuMethods
9
+ include ModelUtilsMethods
10
+
11
+
12
+
13
+ def self.use_friendly(base = nil, options = {}, &block)
14
+ extend FriendlyId
15
+
16
+ self.friendly_id(base, options.merge(use: [:globalize]), &block)
17
+
18
+ include SlugOptimizer
19
+
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end