dynamic_content 1.0.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.
- checksums.yaml +7 -0
- data/lib/dynamic_content/engine.rb +4 -0
- data/lib/dynamic_content/error.rb +19 -0
- data/lib/dynamic_content/generators/boilerplate.rb +45 -0
- data/lib/dynamic_content/processor.rb +148 -0
- data/lib/dynamic_content/tag_serializer.rb +11 -0
- data/lib/dynamic_content/version.rb +3 -0
- data/lib/dynamic_content.rb +73 -0
- data/lib/generators/dynamic_content/install/install_generator.rb +61 -0
- data/lib/generators/dynamic_content/install/templates/_dynamic_inputs.html.erb +57 -0
- data/lib/generators/dynamic_content/install/templates/_forms.html.erb +12 -0
- data/lib/generators/dynamic_content/install/templates/admin_pages.rb +101 -0
- data/lib/generators/dynamic_content/install/templates/dragonfly_initializer.rb.erb +26 -0
- data/lib/generators/dynamic_content/install/templates/initializer.rb.erb +7 -0
- data/lib/generators/dynamic_content/install/templates/migrations/create_dynamic_content_contents.rb.erb +36 -0
- data/lib/generators/dynamic_content/install/templates/migrations/create_dynamic_content_pages.rb.erb +26 -0
- data/lib/generators/dynamic_content/install/templates/migrations/create_dynamic_content_sections.rb.erb +25 -0
- data/lib/generators/dynamic_content/install/templates/structure.yml +29 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2434c0cebf28a904c5b48ccda9b30d47ff1ef904
|
4
|
+
data.tar.gz: 85a75f7304d490400b9d52b4cc13dec963b8ffef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5cc5c4ac273f16e5e99e7fc15eaa266688737acb548f7b426d6138d4ff71b1fdfb9eac564697e7445b5c44e2de8964fbbd1703936e13b08df2fd162208fde8c8
|
7
|
+
data.tar.gz: 58138bdd8e5dfd17dde3e025016d852ef6746c63ec09850e4b23a65e75c7a2e217045b40d67e2c8d3ed444983dbb789d80e96fed1d0f6966e290c4c90675b38b
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DynamicContent
|
2
|
+
class ErrorLoading < RuntimeError
|
3
|
+
end
|
4
|
+
|
5
|
+
class Error < RuntimeError
|
6
|
+
end
|
7
|
+
|
8
|
+
class DependencyError < ErrorLoading
|
9
|
+
end
|
10
|
+
|
11
|
+
class NoStructureFileError < KeyError
|
12
|
+
end
|
13
|
+
|
14
|
+
class InvalidStructureError < KeyError
|
15
|
+
end
|
16
|
+
|
17
|
+
class GeneratorError < Error
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Generators
|
3
|
+
class Boilerplate
|
4
|
+
def initialize(class_name)
|
5
|
+
@class_name = class_name
|
6
|
+
end
|
7
|
+
|
8
|
+
def attributes
|
9
|
+
@class_name.constantize.new.attributes.keys
|
10
|
+
end
|
11
|
+
|
12
|
+
def rows
|
13
|
+
attributes.map { |a| row(a) }.join("\n")
|
14
|
+
end
|
15
|
+
|
16
|
+
def row(name)
|
17
|
+
"# row :#{name.gsub(/_id$/, '')}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def columns
|
21
|
+
attributes.map { |a| column(a) }.join("\n")
|
22
|
+
end
|
23
|
+
|
24
|
+
def column(name)
|
25
|
+
"# column :#{name.gsub(/_id$/, '')}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def filters
|
29
|
+
attributes.map { |a| filter(a) }.join("\n")
|
30
|
+
end
|
31
|
+
|
32
|
+
def filter(name)
|
33
|
+
"# filter :#{name.gsub(/_id$/, '')}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def form_inputs
|
37
|
+
attributes.reject{|a| %w(id created_at updated_at).include? a}.map{ |a| form_input(a) }.join("\n")
|
38
|
+
end
|
39
|
+
|
40
|
+
def form_input(name)
|
41
|
+
"# f.input :#{name.gsub(/_id$/, '')}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
module DynamicContent
|
2
|
+
class Processor
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
initial_ar_logger = ActiveRecord::Base.logger
|
6
|
+
ActiveRecord::Base.logger = nil
|
7
|
+
|
8
|
+
puts_logger("\nFormaweb Dynamic Content #{VERSION}\n\nVerifing changes on Dynamic Contents...\n")
|
9
|
+
data = DynamicContent.structure_file
|
10
|
+
|
11
|
+
@messages = []
|
12
|
+
|
13
|
+
current_pages = Page.all.map{ |a| [a.slug.to_sym, a] }.to_h
|
14
|
+
page_order = 1
|
15
|
+
|
16
|
+
data.each do |page_slug, page|
|
17
|
+
current_page = current_pages[page_slug.to_sym]
|
18
|
+
|
19
|
+
if current_page
|
20
|
+
puts_logger("\n#{page['name']} (#{page_slug})")
|
21
|
+
else
|
22
|
+
puts_logger("\n#{page['name']} (#{page_slug}) [ NEW ]")
|
23
|
+
current_page = Page.new(
|
24
|
+
title: page['title'], slug: page_slug,
|
25
|
+
description: page['description'], keywords: page['keywords']
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
current_page.name = page['name']
|
30
|
+
current_page.order = page_order
|
31
|
+
current_page.save
|
32
|
+
|
33
|
+
## Sections
|
34
|
+
current_sections = current_page.sections.map{ |a| [a.slug.to_sym, a] }.to_h
|
35
|
+
section_order = 1
|
36
|
+
|
37
|
+
page['sections'] = [] unless page['sections']
|
38
|
+
|
39
|
+
page['sections'].each do |section_slug, section|
|
40
|
+
current_section = current_sections[section_slug.to_sym]
|
41
|
+
|
42
|
+
if current_section
|
43
|
+
puts_logger(" #{section['name']} (#{section_slug})")
|
44
|
+
else
|
45
|
+
puts_logger(" #{section['name']} (#{section_slug}) [ NEW ]")
|
46
|
+
current_section = current_page.sections.new(slug: section_slug)
|
47
|
+
end
|
48
|
+
|
49
|
+
current_section.assign_attributes(
|
50
|
+
name: section['name'], order: section_order,
|
51
|
+
on_application: (section['on_application'].to_s == 'true')
|
52
|
+
)
|
53
|
+
current_section.save
|
54
|
+
|
55
|
+
## Contents
|
56
|
+
current_contents = current_section.contents.map{ |a| [a.slug.to_sym, a] }.to_h
|
57
|
+
content_order = 1
|
58
|
+
|
59
|
+
raise InvalidStructureError, "Error: #{page_slug}/#{section_slug} has no contents! Unable to continue." unless section['contents']
|
60
|
+
|
61
|
+
section['contents'].each do |content_slug, content|
|
62
|
+
current_content = current_contents[content_slug.to_sym]
|
63
|
+
|
64
|
+
if current_content
|
65
|
+
puts_logger(" #{content['name']} (#{content_slug})")
|
66
|
+
else
|
67
|
+
puts_logger(" #{content['name']} (#{content_slug}) [ NEW ]")
|
68
|
+
current_content = current_section.contents.new({
|
69
|
+
slug: content_slug,
|
70
|
+
content: content['content'],
|
71
|
+
caption: content['caption'],
|
72
|
+
locale: DynamicContent.locale,
|
73
|
+
file: (content['file'] && !content['file'].blank? ? File.open(Rails.root.join(content['file'])) : nil),
|
74
|
+
date: content['date'],
|
75
|
+
}.delete_if { |k, v| v.nil? })
|
76
|
+
end
|
77
|
+
|
78
|
+
current_content.assign_attributes({
|
79
|
+
order: content_order,
|
80
|
+
name: content['name'],
|
81
|
+
has_caption: (content['has_caption'].to_s == 'true' || !content['caption'].to_s.blank?),
|
82
|
+
caption: (current_content.caption.blank? && !content['caption'].blank? ? content['caption'] : nil),
|
83
|
+
data_options: content['data_options'],
|
84
|
+
locale: content['locale'],
|
85
|
+
data_type: content['data_type'],
|
86
|
+
type_options: content['type_options'],
|
87
|
+
handler_class: content['handler_class'],
|
88
|
+
has_divisor: content['has_divisor'].to_s == 'true',
|
89
|
+
hint: content['hint'],
|
90
|
+
}.delete_if { |k, v| v.nil? })
|
91
|
+
|
92
|
+
current_content.save
|
93
|
+
|
94
|
+
current_contents.delete(content_slug.to_sym)
|
95
|
+
content_order += 1
|
96
|
+
end
|
97
|
+
|
98
|
+
puts_logger(" Contents to destroy:") if current_contents.count > 0
|
99
|
+
current_contents.each do |content_slug, content|
|
100
|
+
puts_warning " #{content.name} (#{content_slug}) [ DELETED ]"
|
101
|
+
content.destroy # TODO: may be a way to identify slug renames
|
102
|
+
end
|
103
|
+
|
104
|
+
current_sections.delete(section_slug.to_sym)
|
105
|
+
section_order += 1
|
106
|
+
end
|
107
|
+
|
108
|
+
puts_logger(" Sections to destroy:") if current_sections.count > 0
|
109
|
+
current_sections.each do |section_slug, section|
|
110
|
+
puts_warning " #{section.name} (#{section_slug}) [ DELETED ]"
|
111
|
+
section.destroy # TODO: may be a way to identify slug renames
|
112
|
+
end
|
113
|
+
|
114
|
+
current_pages.delete(page_slug.to_sym)
|
115
|
+
page_order += 1
|
116
|
+
end
|
117
|
+
|
118
|
+
puts_logger("\nPages to destroy:") if current_pages.count > 0
|
119
|
+
current_pages.each do |page_slug, page|
|
120
|
+
puts_warning "Page #{page.name} (#{page_slug}) [ DELETED ]"
|
121
|
+
page.destroy
|
122
|
+
end
|
123
|
+
|
124
|
+
if @messages.count > 0
|
125
|
+
puts_logger("\n\n\e[31mWarning messages:\e[0m")
|
126
|
+
@messages.map{ |m| puts_logger(" #{m}") }
|
127
|
+
end
|
128
|
+
|
129
|
+
puts_logger("\n\nProcess completed successfully.\n\n")
|
130
|
+
|
131
|
+
ActiveRecord::Base.logger = initial_ar_logger
|
132
|
+
return nil
|
133
|
+
end
|
134
|
+
|
135
|
+
def puts_warning message
|
136
|
+
@messages << message.strip
|
137
|
+
puts_logger("\e[31m#{message}\e[0m")
|
138
|
+
end
|
139
|
+
|
140
|
+
def puts_logger message
|
141
|
+
# TODO: option for puts or Rails.logger.info
|
142
|
+
puts message
|
143
|
+
end
|
144
|
+
|
145
|
+
def inspect; "Formaweb DynamicContent #{VERSION}" end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'active_support/core_ext'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
require 'dragonfly'
|
5
|
+
require 'mime-types'
|
6
|
+
|
7
|
+
module DynamicContent
|
8
|
+
autoload :VERSION, 'dynamic_content/version'
|
9
|
+
autoload :TagSerializer, 'dynamic_content/tag_serializer'
|
10
|
+
autoload :Models, 'dynamic_content/models'
|
11
|
+
autoload :Processor, 'dynamic_content/processor'
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# Structure file path
|
15
|
+
attr_accessor :structure_path
|
16
|
+
|
17
|
+
# Locale
|
18
|
+
attr_accessor :locale
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.locale
|
22
|
+
@locale || :en
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.structure_path
|
26
|
+
@structure_path || 'db/seeds/dynamic_content.yml'
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.structure_file
|
30
|
+
if File.exists? Rails.root.join(self.structure_path)
|
31
|
+
return YAML.load(File.read(Rails.root.join(self.structure_path)))
|
32
|
+
else
|
33
|
+
raise NoStructureFileError, "File #{self.structure_path} is not found."
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.setup(&block)
|
38
|
+
yield self
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.process
|
42
|
+
Processor.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.settings
|
46
|
+
{
|
47
|
+
locale: self.locale,
|
48
|
+
structure_path: self.structure_path
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
ActionController::Base.class_eval do
|
55
|
+
private
|
56
|
+
def load_dynamic_content finder_key = nil
|
57
|
+
unless dc_is_admin?
|
58
|
+
finder_key ||= controller_name
|
59
|
+
|
60
|
+
@application = DynamicContent::Page.cached_for('application')
|
61
|
+
@page = DynamicContent::Page.cached_for(finder_key)
|
62
|
+
@dynamic_content = @application.merge(@page)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def dc_is_admin?
|
67
|
+
params[:controller] =~ /admin/ || params[:controller] =~ /redactor/
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Require things that don't support autoload
|
72
|
+
require 'dynamic_content/engine'
|
73
|
+
require 'dynamic_content/error'
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module DynamicContent
|
4
|
+
module Generators
|
5
|
+
|
6
|
+
class InstallGenerator < ActiveRecord::Generators::Base
|
7
|
+
desc "Installs Dynamic Content and generates the necessary migrations"
|
8
|
+
|
9
|
+
argument :locale, type: :string, default: "en"
|
10
|
+
argument :name, type: :string, default: "nome"
|
11
|
+
|
12
|
+
class_option :skip_activeadmin, type: :boolean, default: false, desc: "Skip ActiveAdmin files"
|
13
|
+
class_option :skip_initializer, type: :boolean, default: false, desc: "Skip initializer file"
|
14
|
+
|
15
|
+
source_root File.expand_path("../templates", __FILE__)
|
16
|
+
|
17
|
+
def copy_initializer
|
18
|
+
return if options[:skip_initializer]
|
19
|
+
|
20
|
+
@locale = locale =~ /-/ ? "'#{locale}'" : locale
|
21
|
+
template 'initializer.rb.erb', 'config/initializers/dynamic_content.rb'
|
22
|
+
template 'dragonfly_initializer.rb.erb', 'config/initializers/dragonfly.rb'
|
23
|
+
end
|
24
|
+
|
25
|
+
def copy_structure_file
|
26
|
+
template 'structure.yml', 'db/seeds/dynamic_content.yml'
|
27
|
+
end
|
28
|
+
|
29
|
+
def setup_activeadmin
|
30
|
+
return if options[:skip_activeadmin]
|
31
|
+
|
32
|
+
empty_directory "app/views/admin"
|
33
|
+
empty_directory "app/admin"
|
34
|
+
template 'admin_pages.rb', 'app/admin/pages.rb'
|
35
|
+
copy_file '_dynamic_inputs.html.erb', 'app/views/admin/pages/_dynamic_inputs.html.erb'
|
36
|
+
copy_file '_forms.html.erb', 'app/views/admin/pages/_forms.html.erb'
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_rake_task
|
40
|
+
rakefile "dynamic_content.rake" do
|
41
|
+
%Q{
|
42
|
+
namespace :dynamic_content do
|
43
|
+
desc "Update Dynamic Content structure file"
|
44
|
+
task update: :environment do
|
45
|
+
Rails.logger = Logger.new(STDOUT)
|
46
|
+
DynamicContent.process
|
47
|
+
end
|
48
|
+
end
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_migrations
|
54
|
+
migration_template 'migrations/create_dynamic_content_pages.rb.erb', 'db/migrate/create_dynamic_content_pages.rb'
|
55
|
+
migration_template 'migrations/create_dynamic_content_sections.rb.erb', 'db/migrate/create_dynamic_content_sections.rb'
|
56
|
+
migration_template 'migrations/create_dynamic_content_contents.rb.erb', 'db/migrate/create_dynamic_content_contents.rb'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<%= f.fields_for :sections do |s| %>
|
2
|
+
<fieldset class="inputs dynamic_content" id="<%= s.object.slug %>">
|
3
|
+
<legend>
|
4
|
+
<span>
|
5
|
+
<%= s.object.name %>
|
6
|
+
<% if s.object.on_application %><small>Este conteúdo pode aparecer em outras páginas.</small><% end %>
|
7
|
+
</span>
|
8
|
+
</legend>
|
9
|
+
<ol>
|
10
|
+
<%= s.fields_for :contents, include_id: false do |c| %>
|
11
|
+
<% if c.object.formtastic_compatible? %>
|
12
|
+
<%= c.hidden_field :id %>
|
13
|
+
<% input_data = c.input c.object.get_type_options[:field], hint: c.object.hint, label: c.object.name, collection: c.object.data_options, as: c.object.get_type_options[:as], input_html: { class: c.object.get_type_options[:input_class] }, wrapper_html: { class: (c.object.has_divisor ? 'has-divisor' : nil), id: [s.object.slug, c.object.slug].join('-') } %>
|
14
|
+
<%= defined?(force_print) ? input_data : '' %>
|
15
|
+
<% else %>
|
16
|
+
|
17
|
+
<li class="input optional <%= c.object.get_type_options[:wrapper_class] %>" id="<%= s.object.slug %>-<%= c.object.slug %>">
|
18
|
+
<%= c.hidden_field :id %>
|
19
|
+
|
20
|
+
<%= c.label :content, c.object.name %>
|
21
|
+
<% case c.object.data_type %>
|
22
|
+
<% when 'text' %>
|
23
|
+
<%= c.text_area :content %>
|
24
|
+
<% when 'markdown' %>
|
25
|
+
<% if c.object.type_options == 'string' %><%= c.text_field :content %><% else %><%= c.text_area :content %><% end %>
|
26
|
+
<% when 'editor' %>
|
27
|
+
<%= c.text_area :content, class: (c.object.type_options.blank? ? 'simple-editor' : c.object.type_options) %>
|
28
|
+
<% when 'embed' %>
|
29
|
+
<%= c.text_area :content, class: 'ace-editor', style: 'display: none;' %>
|
30
|
+
<span class="ace-box inputs"><div id="ace-editor" style="width: 100%; height: 250px;"></div></span>
|
31
|
+
<% when 'uploader' %>
|
32
|
+
<%= c.file_field :file %>
|
33
|
+
<p class="inline-hints"><%= c.object.file ? 'Arquivo atual: ' + c.object.file.path.split('/').last : 'Ainda sem arquivo' %></p>
|
34
|
+
<% when 'image' %>
|
35
|
+
<%= c.file_field :file %>
|
36
|
+
<% if c.object.type_options != 'without_alt' %>
|
37
|
+
<br><%= c.text_field :content, style: 'margin: 10px 0 0 20%;', placeholder: 'Texto alternativo para a imagem.' %>
|
38
|
+
<% end %>
|
39
|
+
<p class="inline-hints"><%= c.object.file ? image_tag(c.object.file.thumb('150x').url, width: '150') : 'Ainda sem imagem' %></p>
|
40
|
+
<% else %>
|
41
|
+
<%= c.text_field :content %>
|
42
|
+
<% end %>
|
43
|
+
|
44
|
+
<% if c.object.has_caption %>
|
45
|
+
<%= c.label :caption, ' '.html_safe %>
|
46
|
+
<%= c.text_field :caption %>
|
47
|
+
<% end %>
|
48
|
+
|
49
|
+
<% unless c.object.hint.blank? %>
|
50
|
+
<p class="inline-hints"><%= c.object.hint.html_safe %></p>
|
51
|
+
<% end %>
|
52
|
+
</li>
|
53
|
+
<% end %>
|
54
|
+
<% end %>
|
55
|
+
</ol>
|
56
|
+
</fieldset>
|
57
|
+
<% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= semantic_form_for [:admin, @page] do |f| %>
|
2
|
+
|
3
|
+
<%= f.inputs "Detalhes" do %>
|
4
|
+
<%= f.input :title %>
|
5
|
+
<%= f.input :description %>
|
6
|
+
<%= f.input :keywords, as: :select, multiple: true, collection: f.object.keywords, input_html: { class: 'taggable' }, include_blank: false %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<%= render partial: 'dynamic_inputs', locals: { f: f, force_print: true } %>
|
10
|
+
|
11
|
+
<%= f.actions %>
|
12
|
+
<% end %>
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
ActiveAdmin.register Page do
|
4
|
+
menu label: 'Páginas', priority: 2, parent: 'Conteúdo'
|
5
|
+
config.sort_order = 'id_asc'
|
6
|
+
config.per_page = 20
|
7
|
+
|
8
|
+
actions :all, :except => [:destroy, :new, :create]
|
9
|
+
|
10
|
+
permit_params :title, :description, keywords: [], sections_attributes: [:id, contents_attributes: [:id, :content, :caption, :file, :date]]
|
11
|
+
|
12
|
+
filter :title
|
13
|
+
filter :description
|
14
|
+
filter :keywords
|
15
|
+
|
16
|
+
index do
|
17
|
+
column :name
|
18
|
+
column :title
|
19
|
+
column(:updated_at) { |page| l(page.updated_at, format: :short) }
|
20
|
+
actions
|
21
|
+
end
|
22
|
+
|
23
|
+
collection_action :search_address, :method => :get do
|
24
|
+
return render text: 'Not Found', status: 404 if params[:address].blank?
|
25
|
+
|
26
|
+
address = URI.encode(params[:address])
|
27
|
+
begin
|
28
|
+
json = JSON.parse(open("https://maps.googleapis.com/maps/api/geocode/json?address=#{address}").read)
|
29
|
+
|
30
|
+
latitude = json['results'][0]['geometry']['location']['lat']
|
31
|
+
longitude = json['results'][0]['geometry']['location']['lng']
|
32
|
+
|
33
|
+
return render json: { latitude: latitude, longitude: longitude }
|
34
|
+
rescue
|
35
|
+
return render text: 'Não encontrado latitude e longitude pelo GoogleMaps', status: 400
|
36
|
+
end
|
37
|
+
|
38
|
+
return render text: 'Not Found', status: 404
|
39
|
+
end
|
40
|
+
|
41
|
+
show do |page|
|
42
|
+
panel "Detalhes", :class => 'details' do
|
43
|
+
attributes_table_for page do
|
44
|
+
row :name
|
45
|
+
row :title
|
46
|
+
row :description
|
47
|
+
row(:keywords) { |page| page.keywords.blank? ? nil : page.keywords.to_sentence }
|
48
|
+
row :updated_at
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
page.sections.each do |section|
|
53
|
+
panel section.name, :class => section.slug do
|
54
|
+
attributes_table_for section do
|
55
|
+
section.contents.each do |content|
|
56
|
+
row_class = content.has_divisor ? 'with-divisor' : ''
|
57
|
+
|
58
|
+
case content.data_type
|
59
|
+
when 'select'
|
60
|
+
row(content.name, class: row_class) { !content.data_options.include?((content.content.to_i - 1)) ? content.data_options[(content.content.to_i-1)][0] : 'Não informado' }
|
61
|
+
when 'image'
|
62
|
+
row(content.name, class: row_class) { image_tag(content.file.thumb('150x').url, alt: content.content, title: content.content) }
|
63
|
+
when 'uploader'
|
64
|
+
row(content.name, class: row_class) { content.file ? link_to('baixar arquivo atual', content.file.url, target: '_blank') : nil }
|
65
|
+
when 'boolean'
|
66
|
+
row(content.name, class: row_class) { content.content.to_i == 1 ? status_tag('Sim', :ok) : status_tag('Não', :error) }
|
67
|
+
when 'currency'
|
68
|
+
row(content.name, class: row_class) { number_to_currency(content.content.gsub(',', '.').to_f) }
|
69
|
+
when 'date'
|
70
|
+
row(content.name, class: row_class) { content.date.blank? ? 'Não informado' : l(content.date.to_date) }
|
71
|
+
when 'datetime'
|
72
|
+
row(content.name, class: row_class) { content.date.blank? ? 'Não informado' : l(content.date) }
|
73
|
+
when 'text'
|
74
|
+
row(content.name, class: row_class) { simple_format(content.content.to_s) }
|
75
|
+
when 'markdown'
|
76
|
+
row(content.name, class: row_class) { (content.has_caption ? content.get_content.values.join('<br><hr>') : content.get_content.to_s).html_safe }
|
77
|
+
when 'hidden'
|
78
|
+
next
|
79
|
+
else
|
80
|
+
row(content.name, class: row_class) { (content.content.to_s + (content.has_caption ? '<br>' + content.caption : '')).html_safe }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
form :partial => 'form'
|
89
|
+
|
90
|
+
controller do
|
91
|
+
private
|
92
|
+
before_action :only => [:show] do
|
93
|
+
response.headers['X-XSS-Protection'] = "0"
|
94
|
+
end
|
95
|
+
|
96
|
+
def scoped_collection
|
97
|
+
return end_of_association_chain.where('id != 1')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'dragonfly'
|
2
|
+
|
3
|
+
# Configure
|
4
|
+
Dragonfly.app.configure do
|
5
|
+
plugin :imagemagick
|
6
|
+
|
7
|
+
secret "<%= SecureRandom.hex(32) %>"
|
8
|
+
|
9
|
+
url_format "/media/:job/:name"
|
10
|
+
|
11
|
+
datastore :file,
|
12
|
+
root_path: Rails.root.join('public/system/dragonfly', Rails.env),
|
13
|
+
server_root: Rails.root.join('public')
|
14
|
+
end
|
15
|
+
|
16
|
+
# Logger
|
17
|
+
Dragonfly.logger = Rails.logger
|
18
|
+
|
19
|
+
# Mount as middleware
|
20
|
+
Rails.application.middleware.use Dragonfly::Middleware
|
21
|
+
|
22
|
+
# Add model functionality
|
23
|
+
if defined?(ActiveRecord::Base)
|
24
|
+
ActiveRecord::Base.extend Dragonfly::Model
|
25
|
+
ActiveRecord::Base.extend Dragonfly::Model::Validations
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<%
|
2
|
+
parent_class = ActiveRecord::Migration
|
3
|
+
parent_class = parent_class[parent_class.current_version] if Rails::VERSION::MAJOR >= 5
|
4
|
+
-%>
|
5
|
+
class CreateDynamicContentContents < <%= parent_class.to_s %>
|
6
|
+
|
7
|
+
def change
|
8
|
+
create_table :dynamic_content_contents do |t|
|
9
|
+
t.integer :section_id
|
10
|
+
t.string :name
|
11
|
+
t.string :slug
|
12
|
+
t.integer :order
|
13
|
+
t.boolean :has_caption, default: false
|
14
|
+
t.string :caption
|
15
|
+
t.text :content
|
16
|
+
t.text :data_options
|
17
|
+
t.string :locale
|
18
|
+
t.string :data_type, default: "string"
|
19
|
+
t.string :type_options, default: ""
|
20
|
+
t.string :handler_class, default: ""
|
21
|
+
t.string :file_uid
|
22
|
+
t.string :file_name
|
23
|
+
t.datetime :date
|
24
|
+
t.boolean :has_divisor
|
25
|
+
t.string :hint
|
26
|
+
|
27
|
+
<%- if Rails::VERSION::MAJOR >= 5 -%>
|
28
|
+
t.timestamps
|
29
|
+
<%- else -%>
|
30
|
+
t.timestamps null: false
|
31
|
+
<%- end -%>
|
32
|
+
end
|
33
|
+
add_index :dynamic_content_contents, :slug
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/lib/generators/dynamic_content/install/templates/migrations/create_dynamic_content_pages.rb.erb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
<%
|
2
|
+
parent_class = ActiveRecord::Migration
|
3
|
+
parent_class = parent_class[parent_class.current_version] if Rails::VERSION::MAJOR >= 5
|
4
|
+
-%>
|
5
|
+
class CreateDynamicContentPages < <%= parent_class.to_s %>
|
6
|
+
|
7
|
+
def change
|
8
|
+
create_table :dynamic_content_pages do |t|
|
9
|
+
t.boolean :status, default: true
|
10
|
+
t.integer :order, default: 1
|
11
|
+
t.string :name
|
12
|
+
t.string :title
|
13
|
+
t.string :keywords
|
14
|
+
t.string :description
|
15
|
+
t.string :slug
|
16
|
+
|
17
|
+
<%- if Rails::VERSION::MAJOR >= 5 -%>
|
18
|
+
t.timestamps
|
19
|
+
<%- else -%>
|
20
|
+
t.timestamps null: false
|
21
|
+
<%- end -%>
|
22
|
+
end
|
23
|
+
add_index :dynamic_content_pages, :slug
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<%
|
2
|
+
parent_class = ActiveRecord::Migration
|
3
|
+
parent_class = parent_class[parent_class.current_version] if Rails::VERSION::MAJOR >= 5
|
4
|
+
-%>
|
5
|
+
class CreateDynamicContentSections < <%= parent_class.to_s %>
|
6
|
+
|
7
|
+
def change
|
8
|
+
create_table :dynamic_content_sections do |t|
|
9
|
+
t.integer :page_id
|
10
|
+
t.string :name
|
11
|
+
t.string :slug
|
12
|
+
t.boolean :on_application, default: false
|
13
|
+
t.integer :order
|
14
|
+
|
15
|
+
<%- if Rails::VERSION::MAJOR >= 5 -%>
|
16
|
+
t.timestamps
|
17
|
+
<%- else -%>
|
18
|
+
t.timestamps null: false
|
19
|
+
<%- end -%>
|
20
|
+
end
|
21
|
+
add_index :dynamic_content_sections, :slug
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
application:
|
2
|
+
name: General
|
3
|
+
title: My Application
|
4
|
+
keywords: ''
|
5
|
+
description: ''
|
6
|
+
sections:
|
7
|
+
sample:
|
8
|
+
name: Sample Section
|
9
|
+
contents:
|
10
|
+
sample_field:
|
11
|
+
name: Sample Field
|
12
|
+
content: 'Default content for sample field'
|
13
|
+
rich_sample:
|
14
|
+
name: HTML Field
|
15
|
+
content: '<p>Sample of HTML default content.</p>'
|
16
|
+
data_type: 'editor'
|
17
|
+
home:
|
18
|
+
name: Home Controller
|
19
|
+
title: Home
|
20
|
+
keywords: ''
|
21
|
+
description: ''
|
22
|
+
sections:
|
23
|
+
header_sample:
|
24
|
+
name: Some Home Section
|
25
|
+
contents:
|
26
|
+
boolean_sample:
|
27
|
+
name: Is awesome gem?
|
28
|
+
content: true
|
29
|
+
data_type: boolean
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dynamic_content
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hugo Demiglio
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dragonfly
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mime-types
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
description: Simple way to manage dynamic fields with editable content on database
|
42
|
+
for Rails and ActiveAdmin.
|
43
|
+
email:
|
44
|
+
- hugodemiglio@gmail.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- lib/dynamic_content.rb
|
50
|
+
- lib/dynamic_content/engine.rb
|
51
|
+
- lib/dynamic_content/error.rb
|
52
|
+
- lib/dynamic_content/generators/boilerplate.rb
|
53
|
+
- lib/dynamic_content/processor.rb
|
54
|
+
- lib/dynamic_content/tag_serializer.rb
|
55
|
+
- lib/dynamic_content/version.rb
|
56
|
+
- lib/generators/dynamic_content/install/install_generator.rb
|
57
|
+
- lib/generators/dynamic_content/install/templates/_dynamic_inputs.html.erb
|
58
|
+
- lib/generators/dynamic_content/install/templates/_forms.html.erb
|
59
|
+
- lib/generators/dynamic_content/install/templates/admin_pages.rb
|
60
|
+
- lib/generators/dynamic_content/install/templates/dragonfly_initializer.rb.erb
|
61
|
+
- lib/generators/dynamic_content/install/templates/initializer.rb.erb
|
62
|
+
- lib/generators/dynamic_content/install/templates/migrations/create_dynamic_content_contents.rb.erb
|
63
|
+
- lib/generators/dynamic_content/install/templates/migrations/create_dynamic_content_pages.rb.erb
|
64
|
+
- lib/generators/dynamic_content/install/templates/migrations/create_dynamic_content_sections.rb.erb
|
65
|
+
- lib/generators/dynamic_content/install/templates/structure.yml
|
66
|
+
homepage: http://github.com/formaweb/dynamic_content
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.6.14
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Editable content on dynamic fields.
|
90
|
+
test_files: []
|