simplec 0.1.1 → 0.1.2
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 +4 -4
- data/MIT-LICENSE +20 -0
- data/README.md +308 -0
- data/Rakefile +36 -0
- data/app/assets/config/simplec_manifest.js +2 -0
- data/app/assets/fonts/simplec/summernote.eot +0 -0
- data/app/assets/fonts/simplec/summernote.ttf +0 -0
- data/app/assets/fonts/simplec/summernote.woff +0 -0
- data/app/assets/javascripts/simplec/application.js +13 -0
- data/app/assets/javascripts/simplec/summernote-config.js +82 -0
- data/app/assets/javascripts/simplec/summernote.js +7046 -0
- data/app/assets/stylesheets/simplec/application.css +15 -0
- data/app/assets/stylesheets/simplec/summernote.scss +691 -0
- data/app/constraints/simplec/subdomains.rb +23 -0
- data/app/controllers/simplec/application_controller.rb +9 -0
- data/app/controllers/simplec/pages_controller.rb +19 -0
- data/app/helpers/simplec/application_helper.rb +4 -0
- data/app/jobs/simplec/application_job.rb +4 -0
- data/app/mailers/simplec/application_mailer.rb +6 -0
- data/app/models/simplec/application_record.rb +5 -0
- data/app/models/simplec/embedded_image.rb +15 -0
- data/app/models/simplec/page.rb +203 -0
- data/app/models/simplec/subdomain.rb +30 -0
- data/app/views/simplec/fields/_editor.html.erb +5 -0
- data/app/views/simplec/fields/_file.html.erb +16 -0
- data/app/views/simplec/fields/_image.html.erb +16 -0
- data/app/views/simplec/fields/_string.html.erb +4 -0
- data/app/views/simplec/fields/_text.html.erb +4 -0
- data/app/views/simplec/pages/show.html.erb +2 -0
- data/config/routes.rb +8 -0
- data/db/migrate/20170809204353_create_simplec_pages.rb +30 -0
- data/db/migrate/20170809204511_create_simplec_subdomains.rb +12 -0
- data/db/migrate/20170809210304_create_simplec_embedded_images.rb +15 -0
- data/lib/simplec/action_controller/extensions.rb +56 -0
- data/lib/simplec/action_view/helper.rb +118 -0
- data/lib/simplec/embedded_image_actions.rb +37 -0
- data/lib/simplec/engine.rb +18 -0
- data/lib/simplec/version.rb +3 -0
- data/lib/simplec.rb +5 -0
- data/lib/tasks/simplec_tasks.rake +4 -0
- metadata +41 -2
@@ -0,0 +1,19 @@
|
|
1
|
+
require_dependency "simplec/application_controller"
|
2
|
+
|
3
|
+
module Simplec
|
4
|
+
class PagesController < ApplicationController
|
5
|
+
|
6
|
+
def show
|
7
|
+
@page = page("/#{params[:path]}")
|
8
|
+
render layout: layout(@page)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def layout(page)
|
14
|
+
[page.layout, page.subdomain.default_layout, 'public']. # TODO allow config for public
|
15
|
+
reject(&:blank?).first
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Simplec
|
2
|
+
class EmbeddedImage < ApplicationRecord
|
3
|
+
belongs_to :embeddable,
|
4
|
+
polymorphic: true
|
5
|
+
|
6
|
+
dragonfly_accessor :asset
|
7
|
+
|
8
|
+
def url
|
9
|
+
return unless self.asset
|
10
|
+
return self.asset.url unless persisted?
|
11
|
+
self.asset.url(ei: Base64.urlsafe_encode64(self.id.to_s))
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
# Simplec::Page
|
2
|
+
#
|
3
|
+
# This class represents a page in the system.
|
4
|
+
#
|
5
|
+
# Each page has a class located in:
|
6
|
+
# app/models/page/NAME.html.erb
|
7
|
+
#
|
8
|
+
# Each page has a partial template in:
|
9
|
+
# app/views/pages/_NAME.html.erb
|
10
|
+
#
|
11
|
+
# Where NAME is the demodulized, snake-case name of the Page Subclasss. For
|
12
|
+
# example:
|
13
|
+
#
|
14
|
+
# class Page::Home < Page
|
15
|
+
# field :h1
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# Would live in app/models/page/home.html.erb and have a template in
|
19
|
+
# app/views/pages/_home.html.erb.
|
20
|
+
#
|
21
|
+
# Each page has the following attributes by default:
|
22
|
+
# - page.title
|
23
|
+
#
|
24
|
+
# Read the documentation below for the class method .field, it is the most
|
25
|
+
# used method.
|
26
|
+
#
|
27
|
+
#
|
28
|
+
module Simplec
|
29
|
+
class Page < ApplicationRecord
|
30
|
+
|
31
|
+
|
32
|
+
# TODO Document FILE_FIELDS constant
|
33
|
+
#
|
34
|
+
FILE_FIELDS = [:file, :image].freeze
|
35
|
+
|
36
|
+
belongs_to :subdomain,
|
37
|
+
optional: false
|
38
|
+
belongs_to :parent,
|
39
|
+
class_name: 'Page',
|
40
|
+
optional: true
|
41
|
+
has_many :childern,
|
42
|
+
class_name: 'Page',
|
43
|
+
foreign_key: :parent_id
|
44
|
+
has_many :embedded_images,
|
45
|
+
as: :embeddable,
|
46
|
+
dependent: :delete_all
|
47
|
+
|
48
|
+
validates :type,
|
49
|
+
presence: true
|
50
|
+
validates :path,
|
51
|
+
presence: true,
|
52
|
+
uniqueness: { scope: :subdomain_id }
|
53
|
+
validates :layout,
|
54
|
+
inclusion: {in: :layouts, allow_blank: true}
|
55
|
+
validates :title,
|
56
|
+
presence: true
|
57
|
+
|
58
|
+
before_validation :match_parent_subdomain
|
59
|
+
before_validation :build_path
|
60
|
+
after_save :link_embedded_images!
|
61
|
+
|
62
|
+
# Define a field on the page.
|
63
|
+
#
|
64
|
+
# - name - name of field
|
65
|
+
# - options[:type] - :string (default), :text, :editor, :file, :image
|
66
|
+
# :string - yields a text input
|
67
|
+
# :text - yields a textarea
|
68
|
+
# :editor - yields a summernote editor
|
69
|
+
# :file - yields a file field
|
70
|
+
# :image - yields a file field with image preview
|
71
|
+
#
|
72
|
+
# There is as template for each type for customization located in:
|
73
|
+
# app/views/shared/fields/_TYPE.html.erb
|
74
|
+
#
|
75
|
+
# Defines a field on a subclass. This creates a getter and setter for the
|
76
|
+
# name passed in. The options are used when building the administration forms.
|
77
|
+
#
|
78
|
+
# Regular dragonfly validations are available on :file and :image fields.
|
79
|
+
# http://markevans.github.io/dragonfly/models#validations
|
80
|
+
#
|
81
|
+
def self.field(name, options={})
|
82
|
+
fields[name] = {name: name, type: :string}.merge(options)
|
83
|
+
if FILE_FIELDS.member?(fields[name][:type])
|
84
|
+
dragonfly_accessor name
|
85
|
+
data_field :"#{name}_uid"
|
86
|
+
data_field :"#{name}_name"
|
87
|
+
else
|
88
|
+
data_field(name)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# List fields
|
93
|
+
#
|
94
|
+
def self.fields
|
95
|
+
@fields ||= Hash.new
|
96
|
+
end
|
97
|
+
|
98
|
+
# Return a constantized type, whitelisted by known subclasses.
|
99
|
+
#
|
100
|
+
def self.type(type)
|
101
|
+
::Page rescue raise '::Page not defined, define it in app/models'
|
102
|
+
raise 'Unsupported Page Type; define in app/models/page/' unless ::Page.subclasses.map(&:name).
|
103
|
+
member?(type)
|
104
|
+
type.constantize
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return names of fields.
|
108
|
+
#
|
109
|
+
# type: :file, is the only option
|
110
|
+
#
|
111
|
+
def self.field_names(type=nil)
|
112
|
+
_fields = case type
|
113
|
+
when :file
|
114
|
+
fields.select {|k, v| FILE_FIELDS.member?(v[:type])}
|
115
|
+
else
|
116
|
+
fields
|
117
|
+
end
|
118
|
+
_fields.keys
|
119
|
+
end
|
120
|
+
|
121
|
+
# Return field options for building forms.
|
122
|
+
#
|
123
|
+
def field_options
|
124
|
+
self.class.fields.values
|
125
|
+
end
|
126
|
+
|
127
|
+
# List parents, closest to furthest.
|
128
|
+
#
|
129
|
+
def parents
|
130
|
+
page, parents = self, Array.new
|
131
|
+
while page.parent
|
132
|
+
page = page.parent
|
133
|
+
parents << page
|
134
|
+
end
|
135
|
+
parents
|
136
|
+
end
|
137
|
+
|
138
|
+
# Before validation hook.
|
139
|
+
#
|
140
|
+
# Build the path of the page to be used in routing.
|
141
|
+
#
|
142
|
+
def build_path
|
143
|
+
_pages = self.parents.reverse + [self]
|
144
|
+
self.path = "/#{_pages.map(&:slug).reject(&:blank?).join('/')}"
|
145
|
+
end
|
146
|
+
|
147
|
+
# Before validation hook
|
148
|
+
#
|
149
|
+
# All pages need to have a matching subdomain to parent page
|
150
|
+
#
|
151
|
+
def match_parent_subdomain
|
152
|
+
return unless self.parent
|
153
|
+
self.subdomain = self.parent.subdomain
|
154
|
+
end
|
155
|
+
|
156
|
+
def find_embedded_images
|
157
|
+
text = self.fields.values.join(' ')
|
158
|
+
matches = text.scan(/ei=([^&]*)/)
|
159
|
+
encoded_ids = matches.map(&:first)
|
160
|
+
ids = encoded_ids.map { |eid| Base64.urlsafe_decode64(URI.unescape(eid)) }
|
161
|
+
EmbeddedImage.includes(:embeddable).find(ids)
|
162
|
+
end
|
163
|
+
|
164
|
+
def link_embedded_images!
|
165
|
+
images = self.find_embedded_images
|
166
|
+
images.each do |image|
|
167
|
+
raise AlreadyLinkedEmbeddedImage if image.embeddable &&
|
168
|
+
image.embeddable != self
|
169
|
+
image.update!(embeddable: self)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def layouts
|
174
|
+
@layouts ||= Subdomain.new.layouts
|
175
|
+
end
|
176
|
+
|
177
|
+
module Normalizers
|
178
|
+
def slug=(val)
|
179
|
+
val = val ? val.to_s.split('/').reject(&:blank?).join('/') : val
|
180
|
+
super val
|
181
|
+
end
|
182
|
+
|
183
|
+
def slug
|
184
|
+
if self.parent_id && self.parent.nil?
|
185
|
+
self.path.to_s.split('/').reject(&:blank?).join('/')
|
186
|
+
else
|
187
|
+
super
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
prepend Normalizers
|
192
|
+
|
193
|
+
class AlreadyLinkedEmbeddedImage < StandardError; end
|
194
|
+
|
195
|
+
private
|
196
|
+
|
197
|
+
def self.data_field(name)
|
198
|
+
define_method(name) { fields[name.to_s] }
|
199
|
+
define_method("#{name}=") { |val| fields[name.to_s] = val }
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Simplec
|
2
|
+
class Subdomain < ApplicationRecord
|
3
|
+
has_many :pages
|
4
|
+
has_and_belongs_to_many :document_sets
|
5
|
+
has_and_belongs_to_many :documents
|
6
|
+
|
7
|
+
validates :name,
|
8
|
+
presence: true,
|
9
|
+
exclusion: { in: %w(admin) }
|
10
|
+
validates :default_layout,
|
11
|
+
inclusion: {in: :layouts, allow_blank: true}
|
12
|
+
|
13
|
+
def layouts
|
14
|
+
@layouts ||= Dir[Rails.root.join('app/views/layouts').to_s + "/*.html.*"].
|
15
|
+
map{|n| File.basename(n).split('.', 2).first }.
|
16
|
+
reject{|n| n =~ /\A_/ || n =~ /mailer/ || n =~ /application/ || n =~ /sessions/}.
|
17
|
+
sort
|
18
|
+
end
|
19
|
+
|
20
|
+
module Normalizers
|
21
|
+
|
22
|
+
# Force lowercase name
|
23
|
+
#
|
24
|
+
def name=(val)
|
25
|
+
super (val ? val.to_s.strip.downcase : val)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
prepend Normalizers
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<div class="form-group">
|
2
|
+
<%= f.label name, class: 'control-label' %>
|
3
|
+
<% if f.object.send(name) %>
|
4
|
+
<div>
|
5
|
+
<p class="form-control-static"><%= f.object.send(name).name %></p>
|
6
|
+
<div class="checkbox">
|
7
|
+
<label>
|
8
|
+
<%= f.check_box :"remove_#{name}" %>
|
9
|
+
Remove
|
10
|
+
</label>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
14
|
+
<%= f.file_field name %>
|
15
|
+
<%= f.hidden_field :"retained_#{name}" %>
|
16
|
+
</div>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<div class="form-group">
|
2
|
+
<%= f.label name, class: 'control-label' %>
|
3
|
+
<% if f.object.send(name) %>
|
4
|
+
<div>
|
5
|
+
<%= image_tag f.object.send(name).thumb('100x').url %>
|
6
|
+
<div class="checkbox">
|
7
|
+
<label>
|
8
|
+
<%= f.check_box :"remove_#{name}" %>
|
9
|
+
Remove
|
10
|
+
</label>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
14
|
+
<%= f.file_field name %>
|
15
|
+
<%= f.hidden_field :"retained_#{name}" %>
|
16
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
class CreateSimplecPages < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
create_table :simplec_pages, id: :uuid, default: 'gen_random_uuid()' do |t|
|
4
|
+
t.string :type
|
5
|
+
t.uuid :subdomain_id
|
6
|
+
t.uuid :parent_id
|
7
|
+
t.string :path
|
8
|
+
t.string :slug
|
9
|
+
t.string :title
|
10
|
+
t.string :meta_description
|
11
|
+
t.jsonb :fields
|
12
|
+
t.string :layout
|
13
|
+
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
|
17
|
+
add_index :simplec_pages, :type
|
18
|
+
add_index :simplec_pages, :subdomain_id
|
19
|
+
add_index :simplec_pages, :parent_id
|
20
|
+
add_index :simplec_pages, :path
|
21
|
+
add_index :simplec_pages, [:subdomain_id, :path], unique: true
|
22
|
+
|
23
|
+
reversible do |dir|
|
24
|
+
dir.up {
|
25
|
+
execute "ALTER TABLE simplec_pages ALTER COLUMN fields SET DEFAULT '{}'::JSONB"
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateSimplecSubdomains < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
create_table :simplec_subdomains, id: :uuid, default: 'gen_random_uuid()' do |t|
|
4
|
+
t.string :name
|
5
|
+
t.string :default_layout
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :simplec_subdomains, :name, unique: true
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateSimplecEmbeddedImages < ActiveRecord::Migration[5.0]
|
2
|
+
def change
|
3
|
+
create_table :simplec_embedded_images, id: :uuid, default: 'gen_random_uuid()' do |t|
|
4
|
+
t.string :embeddable_type
|
5
|
+
t.integer :embeddable_id
|
6
|
+
t.string :asset_uid
|
7
|
+
t.string :asset_name
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :simplec_embedded_images, [:embeddable_type, :embeddable_id],
|
13
|
+
name: 'simplec_embedded_images_type_id_index'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Simplec
|
2
|
+
module ActionController
|
3
|
+
module Extensions
|
4
|
+
|
5
|
+
def self.included(receiver)
|
6
|
+
receiver.helper_method :subdomain, :page,
|
7
|
+
:simplec_path, :simplec_url
|
8
|
+
end
|
9
|
+
|
10
|
+
def subdomain(name=nil)
|
11
|
+
name ||= request.subdomain
|
12
|
+
@_subdomains ||= Hash.new
|
13
|
+
return @_subdomains[name] if @_subdomains[name]
|
14
|
+
@_subdomains[name] = Subdomain.find_by!(name: name)
|
15
|
+
end
|
16
|
+
|
17
|
+
def page(path, options={})
|
18
|
+
@_page ||= Hash.new
|
19
|
+
return @_page[path] if @_page[path]
|
20
|
+
|
21
|
+
_subdomain = subdomain
|
22
|
+
_subdomain = Subdomain.find_by!(
|
23
|
+
name: options[:subdomain]
|
24
|
+
) if options[:subdomain]
|
25
|
+
|
26
|
+
@_page[path] = _subdomain.pages.find_by!(path: path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def simplec_path(page_or_path, options={})
|
30
|
+
# TODO cache page_paths
|
31
|
+
_page = page_or_path.is_a?(Page) ?
|
32
|
+
page_or_path : page(page_or_path, options)
|
33
|
+
|
34
|
+
unless _page
|
35
|
+
raise ActiveRecord::RecordNotFound if options[:raise]
|
36
|
+
return nil
|
37
|
+
end
|
38
|
+
|
39
|
+
_page.path
|
40
|
+
end
|
41
|
+
|
42
|
+
def simplec_url(page_or_path, options={})
|
43
|
+
# TODO cache page_urls
|
44
|
+
_page = page_or_path.is_a?(Page) ?
|
45
|
+
page_or_path : page(page_or_path, options)
|
46
|
+
|
47
|
+
unless _page
|
48
|
+
raise ActiveRecord::RecordNotFound if options[:raise]
|
49
|
+
return nil
|
50
|
+
end
|
51
|
+
|
52
|
+
URI.join(root_url(subdomain: _page.subdomain.try(:name)), _page.path).to_s
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Simplec
|
2
|
+
module ActionView
|
3
|
+
module Helper
|
4
|
+
|
5
|
+
def head(page)
|
6
|
+
content_for :title, page.title
|
7
|
+
content_for :meta_description, page.meta_description
|
8
|
+
end
|
9
|
+
|
10
|
+
def title
|
11
|
+
content_for :title
|
12
|
+
end
|
13
|
+
|
14
|
+
def meta_description_tag
|
15
|
+
tag :meta, name: 'description', content: content_for(:meta_description)
|
16
|
+
end
|
17
|
+
|
18
|
+
def template(page)
|
19
|
+
_template = page.type.demodulize.downcase
|
20
|
+
render "pages/#{_template}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def page_field(f, options={})
|
24
|
+
render "simplec/fields/#{options[:type]}", options.merge(f: f)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Retreive a document.
|
28
|
+
#
|
29
|
+
# slug - matching a Document slug.
|
30
|
+
# options[:subdomain] - a string matching a Subdomain name, find a document
|
31
|
+
# from another subdomain
|
32
|
+
# options[:raise] - if true, casuse a 404 if document isn't found
|
33
|
+
#
|
34
|
+
# Example:
|
35
|
+
#
|
36
|
+
# -# Save as...
|
37
|
+
# <%= link_to doc('/permission/general').name,
|
38
|
+
# doc('/permission/general').path,
|
39
|
+
# download: true %>
|
40
|
+
#
|
41
|
+
# -# Display in new window...
|
42
|
+
# <%= link_to doc('/permission/general').name,
|
43
|
+
# doc('/permission/general').path,
|
44
|
+
# target: '_blank' %>
|
45
|
+
#
|
46
|
+
def doc(slug, options={})
|
47
|
+
@_docs ||= Hash.new
|
48
|
+
key = "[#{options[:subdomain]}][#{slug}]"
|
49
|
+
return @_docs[key] if @_docs[key]
|
50
|
+
@_docs[key] = subdomain(options[:subdomain]).
|
51
|
+
documents.find_by(slug: slug)
|
52
|
+
raise ActiveRecord::RecordNotFound if options[:raise] && !@_docs[key]
|
53
|
+
@_docs[key]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Retreive a document.
|
57
|
+
#
|
58
|
+
# slug - matching a Document slug.
|
59
|
+
# options[:subdomain] - a string matching a Subdomain name, find a document
|
60
|
+
# set from another subdomain
|
61
|
+
# options[:raise] - if true, casuse a 404 if document set isn't found
|
62
|
+
#
|
63
|
+
# Example:
|
64
|
+
#
|
65
|
+
# <% docset('/faith').each do |doc| %>
|
66
|
+
# <%= link_to doc.name, doc.path %>
|
67
|
+
# <% end %>
|
68
|
+
#
|
69
|
+
def docset(slug, options={})
|
70
|
+
@_docsets ||= Hash.new
|
71
|
+
key = "[#{options[:subdomain]}][#{slug}]"
|
72
|
+
return @_docsets[key] if @_docsets[key]
|
73
|
+
set = subdomain(options[:subdomain]).
|
74
|
+
document_sets.find_by(slug: slug)
|
75
|
+
raise ActiveRecord::RecordNotFound if options[:raise] && !set
|
76
|
+
@_docsets[key] = set.documents
|
77
|
+
end
|
78
|
+
|
79
|
+
# page_or_path - a page object or a path of a page
|
80
|
+
# options[:subdomain] - a string matching a Subdomain name, find a page
|
81
|
+
# from another subdomain
|
82
|
+
# options[:raise] - if true, casuse a 404 if a page set isn't found
|
83
|
+
#
|
84
|
+
# Example:
|
85
|
+
#
|
86
|
+
# <% subpages('/give-volunteer', conditions: ->{ order(title: :asc) }).each do |page| %>
|
87
|
+
# ... do something with page ...
|
88
|
+
# <% end%>
|
89
|
+
def subpages(page_or_path, options={})
|
90
|
+
if options[:conditions] && !options[:conditions].respond_to?(:call)
|
91
|
+
raise ArgumentError, <<-ERROR
|
92
|
+
#{options[:conditions]} was passed as :conditions but is not callable.
|
93
|
+
"Pass a callable instead: `conditions: -> { where(approved: true) }`
|
94
|
+
ERROR
|
95
|
+
end
|
96
|
+
|
97
|
+
@_subpages ||= Hash.new # TODO apply new conditions after cache
|
98
|
+
key = "[#{options[:subdomain]}][#{page_or_path}]"
|
99
|
+
|
100
|
+
unless @_subpages[key]
|
101
|
+
page = page_or_path.is_a?(Page) ? page_or_path : nil
|
102
|
+
page ||= subdomain(options[:subdomain]).pages.find_by(path: page_or_path)
|
103
|
+
|
104
|
+
unless page
|
105
|
+
raise ActiveRecord::RecordNotFound if options[:raise]
|
106
|
+
return @_subpages[key] = Array.new
|
107
|
+
end
|
108
|
+
|
109
|
+
@_subpages[key] = page.subpages
|
110
|
+
end
|
111
|
+
|
112
|
+
@_subpages[key].respond_to?(:merge) && options[:conditions] ?
|
113
|
+
@_subpages[key].merge(options[:conditions]) : @_subpages[key]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Simplec
|
2
|
+
module EmbeddedImageActions
|
3
|
+
module ClassMethods; end
|
4
|
+
|
5
|
+
module InstanceMethods
|
6
|
+
|
7
|
+
def create
|
8
|
+
@embedded_image = EmbeddedImage.new(embedded_image_params)
|
9
|
+
if @embedded_image.save
|
10
|
+
respond_to do |format|
|
11
|
+
format.json {
|
12
|
+
render :show, status: 201, location: @embedded_image.url
|
13
|
+
}
|
14
|
+
end
|
15
|
+
else
|
16
|
+
respond_to do |format|
|
17
|
+
format.json {
|
18
|
+
render status: 422, json: @embedded_image.errors
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def embedded_image_params
|
27
|
+
params.permit(:asset_url, :asset_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.included(receiver)
|
33
|
+
receiver.extend ClassMethods
|
34
|
+
receiver.send :include, InstanceMethods
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'simplec/action_controller/extensions'
|
2
|
+
require 'simplec/action_view/helper'
|
3
|
+
|
4
|
+
module Simplec
|
5
|
+
class Engine < ::Rails::Engine
|
6
|
+
isolate_namespace Simplec
|
7
|
+
|
8
|
+
initializer "simplec_controller_extensions" do
|
9
|
+
ActiveSupport.on_load(:action_controller_base) {
|
10
|
+
prepend Simplec::ActionController::Extensions
|
11
|
+
helper Simplec::ActionView::Helper
|
12
|
+
}
|
13
|
+
ActiveSupport.on_load(:active_record) {
|
14
|
+
Dir["#{Rails.root}/app/models/page/*.rb"].each {|file| require_dependency file }
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/simplec.rb
ADDED